adds ifxmips, uboot-ifxmips and removes etrax from 8.09 branch
authorJohn Crispin <john@openwrt.org>
Tue, 30 Sep 2008 08:12:06 +0000 (08:12 +0000)
committerJohn Crispin <john@openwrt.org>
Tue, 30 Sep 2008 08:12:06 +0000 (08:12 +0000)
SVN-Revision: 12811

158 files changed:
package/uboot-ifxmips/Makefile [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/Makefile [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/README [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/config.mk [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/danube.c [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings_111.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings_166.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings_PROMOSDDR400.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings_Samsung_166.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings_e111.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings_e166.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings_psc_166.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings_r111.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/ddr_settings_r166.h [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/flash.c [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/lowlevel_init.S [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/pmuenable.S [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/u-boot-bootstrap.lds [new file with mode: 0644]
package/uboot-ifxmips/files/board/danube/u-boot.lds [new file with mode: 0644]
package/uboot-ifxmips/files/common/flash_danube.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/Makefile [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/asc_serial.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/asc_serial.h [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/au1x00_eth.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/au1x00_serial.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/au1x00_usb_ohci.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/au1x00_usb_ohci.h [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/cache.S [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/config.mk [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/cpu.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/ifx_asc.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/ifx_cache.S [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/ifx_cgu.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/ifx_cgu.h [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/ifx_clock.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/ifx_cpu.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/ifx_start.S [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/incaip_clock.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/incaip_wdt.S [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/interrupts.c [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/start.S [new file with mode: 0644]
package/uboot-ifxmips/files/cpu/mips/danube/start_bootstrap.S [new file with mode: 0644]
package/uboot-ifxmips/files/drivers/ifx_sw.c [new file with mode: 0644]
package/uboot-ifxmips/files/include/LzmaWrapper.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/asm-mips/danube.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/asm-mips/errno.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/asm-mips/ifx_asc.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/asm-mips/inca-ip2.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/asm-mips/pinstrap.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/asm-mips/romconfig.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/boot.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/configs/danube.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/configs/ifx_cfg.h [new file with mode: 0644]
package/uboot-ifxmips/files/include/configs/ifx_extra_env.h [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/LzmaDecode.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/LzmaDecode.h [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/LzmaTypes.h [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/LzmaWrapper.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/Makefile [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/bootstrap_board_danube.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/console.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/crc32.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/ctype.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/devices.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/display_options.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/lists.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/string.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/time.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_bootstrap/vsprintf.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_generic/LzmaDecode.c [new file with mode: 0644]
package/uboot-ifxmips/files/lib_generic/LzmaDecode.h [new file with mode: 0644]
package/uboot-ifxmips/files/lib_generic/LzmaTypes.h [new file with mode: 0644]
package/uboot-ifxmips/files/lib_generic/LzmaWrapper.c [new file with mode: 0644]
package/uboot-ifxmips/files/net/ifx_eth.c [new file with mode: 0644]
package/uboot-ifxmips/files/net/net_danube.c [new file with mode: 0644]
package/uboot-ifxmips/files/net/nfs_danube.c [new file with mode: 0644]
package/uboot-ifxmips/files/net/tftp_danube.c [new file with mode: 0644]
package/uboot-ifxmips/files/tools/crc32_danube.c [new file with mode: 0644]
package/uboot-ifxmips/files/tools/environment_danube.c [new file with mode: 0644]
package/uboot-ifxmips/patches/100-ifx.patch [new file with mode: 0644]
target/linux/etrax/Makefile [deleted file]
target/linux/etrax/config-default [deleted file]
target/linux/etrax/files/drivers/usb/host/hc_crisv10.c [deleted file]
target/linux/etrax/files/drivers/usb/host/hc_crisv10.h [deleted file]
target/linux/etrax/image/Config.in [deleted file]
target/linux/etrax/image/Makefile [deleted file]
target/linux/etrax/image/boot_linux [deleted file]
target/linux/etrax/image/e100boot/Makefile [deleted file]
target/linux/etrax/image/mkfimage/Makefile [deleted file]
target/linux/etrax/image/mkfimage/src/Makefile [deleted file]
target/linux/etrax/image/mkfimage/src/mkfimage.c [deleted file]
target/linux/etrax/patches/100-compile_fixes.patch [deleted file]
target/linux/etrax/patches/101-cris-eth-driver.patch [deleted file]
target/linux/etrax/patches/102-missing_arch_include.patch [deleted file]
target/linux/etrax/patches/200-samsung_flash.patch [deleted file]
target/linux/etrax/patches/201-flashsize.patch [deleted file]
target/linux/etrax/patches/300-sysfs.patch [deleted file]
target/linux/etrax/patches/301-usb_support.patch [deleted file]
target/linux/etrax/profiles/100-generic.mk [deleted file]
target/linux/etrax/profiles/101-vhdl-nofb.mk [deleted file]
target/linux/ifxmips/Makefile [new file with mode: 0644]
target/linux/ifxmips/base-files/etc/hotplug.d/button/00-reset [new file with mode: 0644]
target/linux/ifxmips/base-files/etc/inittab [new file with mode: 0644]
target/linux/ifxmips/config-2.6.26 [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/Kconfig [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/Makefile [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/board.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/clock.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/dma-core.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/gpio.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/interrupt.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/pmu.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/prom.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/reset.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/setup.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/ifxmips/timer.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/pci/ops-ifxmips.c [new file with mode: 0644]
target/linux/ifxmips/files/arch/mips/pci/pci-ifxmips.c [new file with mode: 0644]
target/linux/ifxmips/files/drivers/char/ifxmips_eeprom.c [new file with mode: 0644]
target/linux/ifxmips/files/drivers/char/ifxmips_mei_core.c [new file with mode: 0644]
target/linux/ifxmips/files/drivers/char/ifxmips_ssc.c [new file with mode: 0644]
target/linux/ifxmips/files/drivers/leds/leds-ifxmips.c [new file with mode: 0644]
target/linux/ifxmips/files/drivers/mtd/maps/ifxmips.c [new file with mode: 0644]
target/linux/ifxmips/files/drivers/net/ifxmips_mii0.c [new file with mode: 0644]
target/linux/ifxmips/files/drivers/serial/ifxmips_asc.c [new file with mode: 0644]
target/linux/ifxmips/files/drivers/watchdog/ifxmips_wdt.c [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifx_peripheral_definitions.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifx_ssc.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifx_ssc_defines.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_cgu.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_dma.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_ebu.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_gpio.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_gptu.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_irq.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_led.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_app.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_app_ioctl.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_bsp.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_ioctl.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_linux.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_pmu.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_prom.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/gpio.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/irq.h [new file with mode: 0644]
target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/war.h [new file with mode: 0644]
target/linux/ifxmips/image/Makefile [new file with mode: 0644]
target/linux/ifxmips/patches/100-board.patch [new file with mode: 0644]
target/linux/ifxmips/patches/110-drivers.patch [new file with mode: 0644]
target/linux/ifxmips/patches/160-cfi-swap.patch [new file with mode: 0644]
target/linux/ifxmips/patches/170-dma_hack.patch [new file with mode: 0644]
target/linux/ifxmips/profiles/100-Atheros.mk [new file with mode: 0644]
target/linux/ifxmips/profiles/200-Ralink.mk [new file with mode: 0644]
target/linux/ifxmips/series [new file with mode: 0644]
target/linux/ifxmips/wget-log [new file with mode: 0644]

diff --git a/package/uboot-ifxmips/Makefile b/package/uboot-ifxmips/Makefile
new file mode 100644 (file)
index 0000000..7895502
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=1.1.5
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=579707c8ecbf1ab4127285d2aac2a9ee
+PKG_CAT:=bzcat
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/uboot-ifxmips
+  SECTION:=boot
+  CATEGORY:=Boot Loaders
+  DEPENDS:=@TARGET_ifxmips
+  TITLE:=U-Boot for Infineon MIPS boards
+  URL:=http://www.denx.de/wiki/UBoot/WebHome
+endef
+
+define Build/Prepare
+       $(call Build/Prepare/Default)
+       cp -r ./files/* $(PKG_BUILD_DIR)
+       find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf
+endef
+
+define Build/Compile
+       cd $(PKG_BUILD_DIR);chmod a+x build_danube.sh;./build_danube.sh
+endef
+
+define Package/uboot-ifxmips/install
+       mkdir -p $(1)
+       dd if=$(PKG_BUILD_DIR)/u-boot.ifx of=$(1)/u-boot.ifx bs=64k conv=sync
+endef
+
+$(eval $(call BuildPackage,uboot-ifxmips))
diff --git a/package/uboot-ifxmips/files/board/danube/Makefile b/package/uboot-ifxmips/files/board/danube/Makefile
new file mode 100644 (file)
index 0000000..0163fd9
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    = lib$(BOARD).a
+
+OBJS   = $(BOARD).o flash.o
+SOBJS  = lowlevel_init.o pmuenable.o
+
+$(LIB):        .depend $(OBJS) $(SOBJS)
+       $(AR) crv $@ $^
+
+#########################################################################
+
+.depend:       Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/package/uboot-ifxmips/files/board/danube/README b/package/uboot-ifxmips/files/board/danube/README
new file mode 100644 (file)
index 0000000..d1c5c1e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+** Copyright (C) 2005 Wu Qi Ming <Qi-Ming.Wu@infineon.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.
+*/
+
+To build a u-boot for danube board, user need to do the following things:
+To configure u-boot for a proper board, user need to modify two files accordingly.
+
+To configure u-boot for evaluation board, in danube-uboot/include/configs/danube.h, set
+#define USE_EVALUATION_BOARD
+#undef  USE_REFERENCE_BOARD
+and vice-versa.
+
+To let u-boot boot from ebu(flash,e.g), in danube-uboot/include/configus/danube.h, set 
+#define   DANUBE_BOOT_FROM_EBU
+Otherwise u-boot will be compiled for booting from RAM.
+
+To use DDR RAM running at 111M, in danube-uboot/include/configus/danube.
+h, set
+#define  DANUBE_DDR_RAM_111M
+#undef   DANUBE_DDR_RAM_166M
+and vice-versa.
+
+To define RAM size of RAM, in danube-uboot/include/configus/danube.
+h, set
+#define RAM_SIZE                0x2000000 /*32M ram*/
+This is an example for a 32M RAM.
+
+
+Besides above settings, user need to change danube-uboot/board/danube/config.mk to set the loading address of u-boot.
+If U-Boot is to boot from EBU(flash), user needs to set
+TEXT_BASE=0xB0000000
+If u-boot is to boot from RAM, user needs to set
+TEXT_BASE=0xa0400000
+
+Use the script gct to build a uart downloadable u-boot image:
+./gct danube_ref_ddr166.conf u-boot.srec u-boot.asc
+
+
+
+
+
diff --git a/package/uboot-ifxmips/files/board/danube/config.mk b/package/uboot-ifxmips/files/board/danube/config.mk
new file mode 100644 (file)
index 0000000..e6fcbc6
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# Danube board with MIPS 24Kec CPU core
+#boot from ebu
+TEXT_BASE = 0xB0000000
+BOOTSTRAP_TEXT_BASE = 0xB0000000
+
+#boot from ram
+#TEXT_BASE = 0xa0400000
+#TEXT_BASE = 0x807c0000
+
diff --git a/package/uboot-ifxmips/files/board/danube/danube.c b/package/uboot-ifxmips/files/board/danube/danube.c
new file mode 100644 (file)
index 0000000..b6174ba
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/addrspace.h>
+#include <asm/danube.h>
+
+#ifdef DANUBE_USE_DDR_RAM
+long int initdram(int board_type)
+{
+       return (1024*1024*DANUBE_DDR_RAM_SIZE);
+}
+#else
+extern uint danube_get_cpuclk(void);
+
+static ulong max_sdram_size(void)     /* per Chip Select */
+{
+       /* The only supported SDRAM data width is 16bit.
+        */
+#define CFG_DW 4
+
+       /* The only supported number of SDRAM banks is 4.
+        */
+#define CFG_NB 4
+
+       ulong cfgpb0 = *DANUBE_SDRAM_MC_CFGPB0;
+       int   cols   = cfgpb0 & 0xF;
+       int   rows   = (cfgpb0 & 0xF0) >> 4;
+       ulong size   = (1 << (rows + cols)) * CFG_DW * CFG_NB;
+
+       return size;
+}
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. 
+ */
+
+static long int dram_size(long int *base, long int maxsize)
+{
+       volatile long int *addr;
+       ulong cnt, val;
+       ulong save[32];                 /* to make test non-destructive */
+       unsigned char i = 0;
+
+       for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
+               addr = base + cnt;              /* pointer arith! */
+
+               save[i++] = *addr;
+               *addr = ~cnt;
+       }
+
+       /* write 0 to base address */
+       addr = base;
+       save[i] = *addr;
+       *addr = 0;
+
+       /* check at base address */
+       if ((val = *addr) != 0) {
+               *addr = save[i];
+               return (0);
+       }
+
+       for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
+               addr = base + cnt;              /* pointer arith! */
+
+               val = *addr;
+               *addr = save[--i];
+
+               if (val != (~cnt)) {
+                       return (cnt * sizeof (long));
+               }
+       }
+       return (maxsize);
+}
+
+long int initdram(int board_type)
+{
+       int   rows, cols, best_val = *DANUBE_SDRAM_MC_CFGPB0;
+       ulong size, max_size       = 0;
+       ulong our_address;
+
+       /* load t9 into our_address */  
+       asm volatile ("move %0, $25" : "=r" (our_address) :);
+
+       /* Can't probe for RAM size unless we are running from Flash.
+        * find out whether running from DRAM or Flash.
+        */
+       if (PHYSADDR(our_address) < PHYSADDR(PHYS_FLASH_1))
+       {
+               return max_sdram_size();
+       }
+
+       for (cols = 0x8; cols <= 0xC; cols++)
+       {
+               for (rows = 0xB; rows <= 0xD; rows++)
+               {
+                       *DANUBE_SDRAM_MC_CFGPB0 = (0x14 << 8) |
+                                                  (rows << 4) | cols;
+                       size = dram_size((ulong *)CFG_SDRAM_BASE,
+                                                            max_sdram_size());
+
+                       if (size > max_size)
+                       {
+                               best_val = *DANUBE_SDRAM_MC_CFGPB0;
+                               max_size = size;
+                       }
+               }
+       }
+
+       *DANUBE_SDRAM_MC_CFGPB0 = best_val;
+       return max_size;
+}
+#endif
+
+int checkboard (void)
+{
+       /*    No such register in Amazon */
+#if 0
+       unsigned long chipid = *AMAZON_MCD_CHIPID;
+       int part_num;
+
+       puts ("Board: AMAZON ");
+       part_num = AMAZON_MCD_CHIPID_PART_NUMBER_GET(chipid);
+       switch (part_num) {
+       case AMAZON_CHIPID_STANDARD:
+               printf ("Standard Version, ");
+               break;
+       case AMAZON_CHIPID_YANGTSE:
+               printf ("Yangtse Version, ");
+               break;
+       default:
+               printf ("Unknown Part Number 0x%x ", part_num);
+               break;
+       }
+
+       printf ("Chip V1.%ld, ", AMAZON_MCD_CHIPID_VERSION_GET(chipid));
+     
+
+       printf("CPU Speed %d MHz\n", danube_get_cpuclk()/1000000);
+       
+#endif
+       return 0;
+}
+
+
+/*
+ * Disk On Chip (NAND) Millenium initialization.
+ * The NAND lives in the CS2* space
+ */
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+extern void
+nand_probe(ulong physadr);
+
+#define AT91_SMARTMEDIA_BASE 0x40000000  /* physical address to access memory on NCS3 */
+void
+nand_init(void)
+{
+               int devtype;
+       /* Configure EBU */
+//TODO: should we keep this?
+        //Set GPIO23 to be Flash CS1;
+       *DANUBE_GPIO_P1_ALTSEL0 = *DANUBE_GPIO_P1_ALTSEL0 | (1<<7);
+       *DANUBE_GPIO_P1_ALTSEL1 = *DANUBE_GPIO_P1_ALTSEL1 & ~(1<<7);
+       *DANUBE_GPIO_P1_DIR = *DANUBE_GPIO_P1_DIR | (1<<7) ;
+       *DANUBE_GPIO_P1_OD = *DANUBE_GPIO_P1_OD | (1<<7) ;
+       
+       *EBU_ADDR_SEL_1 = (NAND_BASE_ADDRESS&0x1fffff00)|0x31;
+       /* byte swap;minimum delay*/
+       *EBU_CON_1      = 0x40C155;
+       *EBU_NAND_CON   = 0x000005F3;
+
+       /* Set bus signals to inactive */
+        NAND_READY_CLEAR;
+
+        NAND_CE_CLEAR;
+         nand_probe(NAND_BASE_ADDRESS);
+
+
+
+       //nand_probe(AT91_SMARTMEDIA_BASE);
+}
+#endif
+
+
+
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings.h b/package/uboot-ifxmips/files/board/danube/ddr_settings.h
new file mode 100644 (file)
index 0000000..cecd279
--- /dev/null
@@ -0,0 +1,50 @@
+/* Settings for Denali DDR SDRAM controller */\r
+/* Optimise for Danube Eval Board DDR 167 Mhz - by Ng Aik Ann 29th April */\r
+#define MC_DC0_VALUE   0x1B1B\r
+#define MC_DC1_VALUE   0x0\r
+#define MC_DC2_VALUE   0x0\r
+#define MC_DC3_VALUE   0x0\r
+#define MC_DC4_VALUE   0x0\r
+#define MC_DC5_VALUE   0x200\r
+#define MC_DC6_VALUE   0x605\r
+#define MC_DC7_VALUE   0x303\r
+#define MC_DC8_VALUE   0x102\r
+#define MC_DC9_VALUE   0x70a\r
+#define MC_DC10_VALUE  0x203\r
+#define MC_DC11_VALUE  0xc02\r
+#define MC_DC12_VALUE  0x1C8\r
+#define MC_DC13_VALUE  0x1\r
+#define MC_DC14_VALUE  0x0\r
+#define MC_DC15_VALUE  0xf3c\r
+#define MC_DC16_VALUE  0xC800\r
+#define MC_DC17_VALUE  0xd\r
+#define MC_DC18_VALUE  0x300\r
+#define MC_DC19_VALUE  0x200\r
+#define MC_DC20_VALUE  0xA03\r
+#define MC_DC21_VALUE  0x1d00\r
+#define MC_DC22_VALUE  0x1d1d\r
+#define MC_DC23_VALUE  0x0\r
+#define MC_DC24_VALUE  0x5e   /* was 0x7f */\r
+#define MC_DC25_VALUE  0x0\r
+#define MC_DC26_VALUE  0x0\r
+#define MC_DC27_VALUE  0x0\r
+#define MC_DC28_VALUE  0x510\r
+#define MC_DC29_VALUE  0x2d89\r
+#define MC_DC30_VALUE  0x8300\r
+#define MC_DC31_VALUE  0x0\r
+#define MC_DC32_VALUE  0x0\r
+#define MC_DC33_VALUE  0x0\r
+#define MC_DC34_VALUE  0x0\r
+#define MC_DC35_VALUE  0x0\r
+#define MC_DC36_VALUE  0x0\r
+#define MC_DC37_VALUE  0x0\r
+#define MC_DC38_VALUE  0x0\r
+#define MC_DC39_VALUE  0x0\r
+#define MC_DC40_VALUE  0x0\r
+#define MC_DC41_VALUE  0x0\r
+#define MC_DC42_VALUE  0x0\r
+#define MC_DC43_VALUE  0x0\r
+#define MC_DC44_VALUE  0x0\r
+#define MC_DC45_VALUE  0x500\r
+//#define MC_DC45_VALUE        0x400\r
+#define MC_DC46_VALUE  0x0\r
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings_111.h b/package/uboot-ifxmips/files/board/danube/ddr_settings_111.h
new file mode 100644 (file)
index 0000000..b655ca2
--- /dev/null
@@ -0,0 +1,50 @@
+/* Settings for Denali DDR SDRAM controller */
+/* Optimise for Danube Eval Board DDR 167 Mhz - by Ng Aik Ann 29th April */
+#define MC_DC0_VALUE   0x1B1B
+#define MC_DC1_VALUE   0x0
+#define MC_DC2_VALUE   0x0
+#define MC_DC3_VALUE   0x0
+#define MC_DC4_VALUE   0x0
+#define MC_DC5_VALUE   0x200
+#define MC_DC6_VALUE   0x605
+#define MC_DC7_VALUE   0x303
+#define MC_DC8_VALUE   0x102
+#define MC_DC9_VALUE   0x70a
+#define MC_DC10_VALUE  0x203
+#define MC_DC11_VALUE  0xc02
+#define MC_DC12_VALUE  0x1C8
+#define MC_DC13_VALUE  0x1
+#define MC_DC14_VALUE  0x0
+#define MC_DC15_VALUE  0xf3c  /* WDQS tuning for clk_wr*/
+#define MC_DC16_VALUE  0xC800
+#define MC_DC17_VALUE  0xd
+#define MC_DC18_VALUE  0x300
+#define MC_DC19_VALUE  0x200
+#define MC_DC20_VALUE  0xA03  /* A04 for reference board, A03 for Eval board */
+#define MC_DC21_VALUE  0x1800
+#define MC_DC22_VALUE  0x1818
+#define MC_DC23_VALUE  0x0
+#define MC_DC24_VALUE  0x5e   /* WDQS Tuning for DQS */
+#define MC_DC25_VALUE  0x0
+#define MC_DC26_VALUE  0x0
+#define MC_DC27_VALUE  0x0
+#define MC_DC28_VALUE  0x510
+#define MC_DC29_VALUE  0x2d89
+#define MC_DC30_VALUE  0x8300
+#define MC_DC31_VALUE  0x0
+#define MC_DC32_VALUE  0x0
+#define MC_DC33_VALUE  0x0
+#define MC_DC34_VALUE  0x0
+#define MC_DC35_VALUE  0x0
+#define MC_DC36_VALUE  0x0
+#define MC_DC37_VALUE  0x0
+#define MC_DC38_VALUE  0x0
+#define MC_DC39_VALUE  0x0
+#define MC_DC40_VALUE  0x0
+#define MC_DC41_VALUE  0x0
+#define MC_DC42_VALUE  0x0
+#define MC_DC43_VALUE  0x0
+#define MC_DC44_VALUE  0x0
+#define MC_DC45_VALUE  0x500
+//#define MC_DC45_VALUE        0x400
+#define MC_DC46_VALUE  0x0
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings_166.h b/package/uboot-ifxmips/files/board/danube/ddr_settings_166.h
new file mode 100644 (file)
index 0000000..b655ca2
--- /dev/null
@@ -0,0 +1,50 @@
+/* Settings for Denali DDR SDRAM controller */
+/* Optimise for Danube Eval Board DDR 167 Mhz - by Ng Aik Ann 29th April */
+#define MC_DC0_VALUE   0x1B1B
+#define MC_DC1_VALUE   0x0
+#define MC_DC2_VALUE   0x0
+#define MC_DC3_VALUE   0x0
+#define MC_DC4_VALUE   0x0
+#define MC_DC5_VALUE   0x200
+#define MC_DC6_VALUE   0x605
+#define MC_DC7_VALUE   0x303
+#define MC_DC8_VALUE   0x102
+#define MC_DC9_VALUE   0x70a
+#define MC_DC10_VALUE  0x203
+#define MC_DC11_VALUE  0xc02
+#define MC_DC12_VALUE  0x1C8
+#define MC_DC13_VALUE  0x1
+#define MC_DC14_VALUE  0x0
+#define MC_DC15_VALUE  0xf3c  /* WDQS tuning for clk_wr*/
+#define MC_DC16_VALUE  0xC800
+#define MC_DC17_VALUE  0xd
+#define MC_DC18_VALUE  0x300
+#define MC_DC19_VALUE  0x200
+#define MC_DC20_VALUE  0xA03  /* A04 for reference board, A03 for Eval board */
+#define MC_DC21_VALUE  0x1800
+#define MC_DC22_VALUE  0x1818
+#define MC_DC23_VALUE  0x0
+#define MC_DC24_VALUE  0x5e   /* WDQS Tuning for DQS */
+#define MC_DC25_VALUE  0x0
+#define MC_DC26_VALUE  0x0
+#define MC_DC27_VALUE  0x0
+#define MC_DC28_VALUE  0x510
+#define MC_DC29_VALUE  0x2d89
+#define MC_DC30_VALUE  0x8300
+#define MC_DC31_VALUE  0x0
+#define MC_DC32_VALUE  0x0
+#define MC_DC33_VALUE  0x0
+#define MC_DC34_VALUE  0x0
+#define MC_DC35_VALUE  0x0
+#define MC_DC36_VALUE  0x0
+#define MC_DC37_VALUE  0x0
+#define MC_DC38_VALUE  0x0
+#define MC_DC39_VALUE  0x0
+#define MC_DC40_VALUE  0x0
+#define MC_DC41_VALUE  0x0
+#define MC_DC42_VALUE  0x0
+#define MC_DC43_VALUE  0x0
+#define MC_DC44_VALUE  0x0
+#define MC_DC45_VALUE  0x500
+//#define MC_DC45_VALUE        0x400
+#define MC_DC46_VALUE  0x0
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings_PROMOSDDR400.h b/package/uboot-ifxmips/files/board/danube/ddr_settings_PROMOSDDR400.h
new file mode 100644 (file)
index 0000000..54bb6c9
--- /dev/null
@@ -0,0 +1,50 @@
+/* Settings for Denali DDR SDRAM controller */
+/* Optimise for Danube Ref Board DDR 166 Mhz - by Ng Aik Ann 29th April */
+#define MC_DC0_VALUE   0x1B1B
+#define MC_DC1_VALUE   0x0
+#define MC_DC2_VALUE   0x0
+#define MC_DC3_VALUE   0x0
+#define MC_DC4_VALUE   0x0
+#define MC_DC5_VALUE   0x200
+#define MC_DC6_VALUE   0x605
+#define MC_DC7_VALUE   0x303
+#define MC_DC8_VALUE   0x102
+#define MC_DC9_VALUE   0x70a
+#define MC_DC10_VALUE  0x203
+#define MC_DC11_VALUE  0xa02
+#define MC_DC12_VALUE  0x1C8
+#define MC_DC13_VALUE  0x0
+#define MC_DC14_VALUE  0x0
+#define MC_DC15_VALUE  0xf3c  /* WDQS tuning for clk_wr*/
+#define MC_DC16_VALUE  0xC800
+#define MC_DC17_VALUE  0xd
+#define MC_DC18_VALUE  0x300
+#define MC_DC19_VALUE  0x200
+#define MC_DC20_VALUE  0xA04  /* A04 for reference board, A03 for Eval board */
+#define MC_DC21_VALUE  0x1200
+#define MC_DC22_VALUE  0x1212
+#define MC_DC23_VALUE  0x0
+#define MC_DC24_VALUE  0x62   /* WDQS Tuning for DQS */
+#define MC_DC25_VALUE  0x0
+#define MC_DC26_VALUE  0x0
+#define MC_DC27_VALUE  0x0
+#define MC_DC28_VALUE  0x510
+#define MC_DC29_VALUE  0x4e20
+#define MC_DC30_VALUE  0x8300
+#define MC_DC31_VALUE  0x0
+#define MC_DC32_VALUE  0x0
+#define MC_DC33_VALUE  0x0
+#define MC_DC34_VALUE  0x0
+#define MC_DC35_VALUE  0x0
+#define MC_DC36_VALUE  0x0
+#define MC_DC37_VALUE  0x0
+#define MC_DC38_VALUE  0x0
+#define MC_DC39_VALUE  0x0
+#define MC_DC40_VALUE  0x0
+#define MC_DC41_VALUE  0x0
+#define MC_DC42_VALUE  0x0
+#define MC_DC43_VALUE  0x0
+#define MC_DC44_VALUE  0x0
+#define MC_DC45_VALUE  0x500
+//#define MC_DC45_VALUE        0x400
+#define MC_DC46_VALUE  0x0
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings_Samsung_166.h b/package/uboot-ifxmips/files/board/danube/ddr_settings_Samsung_166.h
new file mode 100644 (file)
index 0000000..7975c3e
--- /dev/null
@@ -0,0 +1,51 @@
+/* Settings for Denali DDR SDRAM controller */
+/* Optimise for Samsung DDR K4H561638H Danube Ref Board DDR 166 Mhz - by Ng Aik Ann 27th Nov 2006 */
+
+#define MC_DC0_VALUE   0x1B1B
+#define MC_DC1_VALUE   0x0
+#define MC_DC2_VALUE   0x0
+#define MC_DC3_VALUE   0x0
+#define MC_DC4_VALUE   0x0
+#define MC_DC5_VALUE   0x200
+#define MC_DC6_VALUE   0x605
+#define MC_DC7_VALUE   0x303
+#define MC_DC8_VALUE   0x102
+#define MC_DC9_VALUE   0x70a
+#define MC_DC10_VALUE  0x203
+#define MC_DC11_VALUE  0xc02
+#define MC_DC12_VALUE  0x1C8
+#define MC_DC13_VALUE  0x1
+#define MC_DC14_VALUE  0x0
+#define MC_DC15_VALUE  0x120  /* WDQS tuning for clk_wr*/
+#define MC_DC16_VALUE  0xC800
+#define MC_DC17_VALUE  0xd
+#define MC_DC18_VALUE  0x301
+#define MC_DC19_VALUE  0x200
+#define MC_DC20_VALUE  0xA04  /* A04 for reference board, A03 for Eval board */
+#define MC_DC21_VALUE  0x1400
+#define MC_DC22_VALUE  0x1414
+#define MC_DC23_VALUE  0x0
+#define MC_DC24_VALUE  0x4e   /* WDQS Tuning for DQS */
+#define MC_DC25_VALUE  0x0
+#define MC_DC26_VALUE  0x0
+#define MC_DC27_VALUE  0x0
+#define MC_DC28_VALUE  0x510
+#define MC_DC29_VALUE  0x2d93
+#define MC_DC30_VALUE  0x8235
+#define MC_DC31_VALUE  0x0
+#define MC_DC32_VALUE  0x0
+#define MC_DC33_VALUE  0x0
+#define MC_DC34_VALUE  0x0
+#define MC_DC35_VALUE  0x0
+#define MC_DC36_VALUE  0x0
+#define MC_DC37_VALUE  0x0
+#define MC_DC38_VALUE  0x0
+#define MC_DC39_VALUE  0x0
+#define MC_DC40_VALUE  0x0
+#define MC_DC41_VALUE  0x0
+#define MC_DC42_VALUE  0x0
+#define MC_DC43_VALUE  0x0
+#define MC_DC44_VALUE  0x0
+#define MC_DC45_VALUE  0x500
+//#define MC_DC45_VALUE        0x400
+#define MC_DC46_VALUE  0x0
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings_e111.h b/package/uboot-ifxmips/files/board/danube/ddr_settings_e111.h
new file mode 100644 (file)
index 0000000..b655ca2
--- /dev/null
@@ -0,0 +1,50 @@
+/* Settings for Denali DDR SDRAM controller */
+/* Optimise for Danube Eval Board DDR 167 Mhz - by Ng Aik Ann 29th April */
+#define MC_DC0_VALUE   0x1B1B
+#define MC_DC1_VALUE   0x0
+#define MC_DC2_VALUE   0x0
+#define MC_DC3_VALUE   0x0
+#define MC_DC4_VALUE   0x0
+#define MC_DC5_VALUE   0x200
+#define MC_DC6_VALUE   0x605
+#define MC_DC7_VALUE   0x303
+#define MC_DC8_VALUE   0x102
+#define MC_DC9_VALUE   0x70a
+#define MC_DC10_VALUE  0x203
+#define MC_DC11_VALUE  0xc02
+#define MC_DC12_VALUE  0x1C8
+#define MC_DC13_VALUE  0x1
+#define MC_DC14_VALUE  0x0
+#define MC_DC15_VALUE  0xf3c  /* WDQS tuning for clk_wr*/
+#define MC_DC16_VALUE  0xC800
+#define MC_DC17_VALUE  0xd
+#define MC_DC18_VALUE  0x300
+#define MC_DC19_VALUE  0x200
+#define MC_DC20_VALUE  0xA03  /* A04 for reference board, A03 for Eval board */
+#define MC_DC21_VALUE  0x1800
+#define MC_DC22_VALUE  0x1818
+#define MC_DC23_VALUE  0x0
+#define MC_DC24_VALUE  0x5e   /* WDQS Tuning for DQS */
+#define MC_DC25_VALUE  0x0
+#define MC_DC26_VALUE  0x0
+#define MC_DC27_VALUE  0x0
+#define MC_DC28_VALUE  0x510
+#define MC_DC29_VALUE  0x2d89
+#define MC_DC30_VALUE  0x8300
+#define MC_DC31_VALUE  0x0
+#define MC_DC32_VALUE  0x0
+#define MC_DC33_VALUE  0x0
+#define MC_DC34_VALUE  0x0
+#define MC_DC35_VALUE  0x0
+#define MC_DC36_VALUE  0x0
+#define MC_DC37_VALUE  0x0
+#define MC_DC38_VALUE  0x0
+#define MC_DC39_VALUE  0x0
+#define MC_DC40_VALUE  0x0
+#define MC_DC41_VALUE  0x0
+#define MC_DC42_VALUE  0x0
+#define MC_DC43_VALUE  0x0
+#define MC_DC44_VALUE  0x0
+#define MC_DC45_VALUE  0x500
+//#define MC_DC45_VALUE        0x400
+#define MC_DC46_VALUE  0x0
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings_e166.h b/package/uboot-ifxmips/files/board/danube/ddr_settings_e166.h
new file mode 100644 (file)
index 0000000..b655ca2
--- /dev/null
@@ -0,0 +1,50 @@
+/* Settings for Denali DDR SDRAM controller */
+/* Optimise for Danube Eval Board DDR 167 Mhz - by Ng Aik Ann 29th April */
+#define MC_DC0_VALUE   0x1B1B
+#define MC_DC1_VALUE   0x0
+#define MC_DC2_VALUE   0x0
+#define MC_DC3_VALUE   0x0
+#define MC_DC4_VALUE   0x0
+#define MC_DC5_VALUE   0x200
+#define MC_DC6_VALUE   0x605
+#define MC_DC7_VALUE   0x303
+#define MC_DC8_VALUE   0x102
+#define MC_DC9_VALUE   0x70a
+#define MC_DC10_VALUE  0x203
+#define MC_DC11_VALUE  0xc02
+#define MC_DC12_VALUE  0x1C8
+#define MC_DC13_VALUE  0x1
+#define MC_DC14_VALUE  0x0
+#define MC_DC15_VALUE  0xf3c  /* WDQS tuning for clk_wr*/
+#define MC_DC16_VALUE  0xC800
+#define MC_DC17_VALUE  0xd
+#define MC_DC18_VALUE  0x300
+#define MC_DC19_VALUE  0x200
+#define MC_DC20_VALUE  0xA03  /* A04 for reference board, A03 for Eval board */
+#define MC_DC21_VALUE  0x1800
+#define MC_DC22_VALUE  0x1818
+#define MC_DC23_VALUE  0x0
+#define MC_DC24_VALUE  0x5e   /* WDQS Tuning for DQS */
+#define MC_DC25_VALUE  0x0
+#define MC_DC26_VALUE  0x0
+#define MC_DC27_VALUE  0x0
+#define MC_DC28_VALUE  0x510
+#define MC_DC29_VALUE  0x2d89
+#define MC_DC30_VALUE  0x8300
+#define MC_DC31_VALUE  0x0
+#define MC_DC32_VALUE  0x0
+#define MC_DC33_VALUE  0x0
+#define MC_DC34_VALUE  0x0
+#define MC_DC35_VALUE  0x0
+#define MC_DC36_VALUE  0x0
+#define MC_DC37_VALUE  0x0
+#define MC_DC38_VALUE  0x0
+#define MC_DC39_VALUE  0x0
+#define MC_DC40_VALUE  0x0
+#define MC_DC41_VALUE  0x0
+#define MC_DC42_VALUE  0x0
+#define MC_DC43_VALUE  0x0
+#define MC_DC44_VALUE  0x0
+#define MC_DC45_VALUE  0x500
+//#define MC_DC45_VALUE        0x400
+#define MC_DC46_VALUE  0x0
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings_psc_166.h b/package/uboot-ifxmips/files/board/danube/ddr_settings_psc_166.h
new file mode 100644 (file)
index 0000000..445b7da
--- /dev/null
@@ -0,0 +1,51 @@
+/* Settings for Denali DDR SDRAM controller */
+/* Optimise for PSC DDR A2S56D40CTP for Danube Ref Board DDR 166 Mhz - by Ng Aik Ann 27th Nov 2006 */
+
+#define MC_DC0_VALUE   0x1B1B
+#define MC_DC1_VALUE   0x0
+#define MC_DC2_VALUE   0x0
+#define MC_DC3_VALUE   0x0
+#define MC_DC4_VALUE   0x0
+#define MC_DC5_VALUE   0x200
+#define MC_DC6_VALUE   0x605
+#define MC_DC7_VALUE   0x303
+#define MC_DC8_VALUE   0x102
+#define MC_DC9_VALUE   0x70a
+#define MC_DC10_VALUE  0x203
+#define MC_DC11_VALUE  0xc02
+#define MC_DC12_VALUE  0x1C8
+#define MC_DC13_VALUE  0x1
+#define MC_DC14_VALUE  0x0
+#define MC_DC15_VALUE  0x120  /* WDQS tuning for clk_wr*/
+#define MC_DC16_VALUE  0xC800
+#define MC_DC17_VALUE  0xd
+#define MC_DC18_VALUE  0x301
+#define MC_DC19_VALUE  0x200
+#define MC_DC20_VALUE  0xA04  /* A04 for reference board, A03 for Eval board */
+#define MC_DC21_VALUE  0x1700
+#define MC_DC22_VALUE  0x1717
+#define MC_DC23_VALUE  0x0
+#define MC_DC24_VALUE  0x52   /* WDQS Tuning for DQS */
+#define MC_DC25_VALUE  0x0
+#define MC_DC26_VALUE  0x0
+#define MC_DC27_VALUE  0x0
+#define MC_DC28_VALUE  0x510
+#define MC_DC29_VALUE  0x4e20
+#define MC_DC30_VALUE  0x8235
+#define MC_DC31_VALUE  0x0
+#define MC_DC32_VALUE  0x0
+#define MC_DC33_VALUE  0x0
+#define MC_DC34_VALUE  0x0
+#define MC_DC35_VALUE  0x0
+#define MC_DC36_VALUE  0x0
+#define MC_DC37_VALUE  0x0
+#define MC_DC38_VALUE  0x0
+#define MC_DC39_VALUE  0x0
+#define MC_DC40_VALUE  0x0
+#define MC_DC41_VALUE  0x0
+#define MC_DC42_VALUE  0x0
+#define MC_DC43_VALUE  0x0
+#define MC_DC44_VALUE  0x0
+#define MC_DC45_VALUE  0x500
+//#define MC_DC45_VALUE        0x400
+#define MC_DC46_VALUE  0x0
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings_r111.h b/package/uboot-ifxmips/files/board/danube/ddr_settings_r111.h
new file mode 100644 (file)
index 0000000..385f7e4
--- /dev/null
@@ -0,0 +1,50 @@
+/* Settings for Denali DDR SDRAM controller */\r
+/* Optimise for Danube Ref Board DDR 166 Mhz - by Ng Aik Ann 29th April */\r
+#define MC_DC0_VALUE   0x1B1B\r
+#define MC_DC1_VALUE   0x0\r
+#define MC_DC2_VALUE   0x0\r
+#define MC_DC3_VALUE   0x0\r
+#define MC_DC4_VALUE   0x0\r
+#define MC_DC5_VALUE   0x200\r
+#define MC_DC6_VALUE   0x605\r
+#define MC_DC7_VALUE   0x303\r
+#define MC_DC8_VALUE   0x102\r
+#define MC_DC9_VALUE   0x70a\r
+#define MC_DC10_VALUE  0x203\r
+#define MC_DC11_VALUE  0xc02\r
+#define MC_DC12_VALUE  0x1C8\r
+#define MC_DC13_VALUE  0x1\r
+#define MC_DC14_VALUE  0x0\r
+#define MC_DC15_VALUE  0xf3c  /* WDQS tuning for clk_wr*/\r
+#define MC_DC16_VALUE  0xC800\r
+#define MC_DC17_VALUE  0xd\r
+#define MC_DC18_VALUE  0x300\r
+#define MC_DC19_VALUE  0x200\r
+#define MC_DC20_VALUE  0xA04  /* A04 for reference board, A03 for Eval board */\r
+#define MC_DC21_VALUE  0x1200\r
+#define MC_DC22_VALUE  0x1212\r
+#define MC_DC23_VALUE  0x0\r
+#define MC_DC24_VALUE  0x5e   /* WDQS Tuning for DQS */\r
+#define MC_DC25_VALUE  0x0\r
+#define MC_DC26_VALUE  0x0\r
+#define MC_DC27_VALUE  0x0\r
+#define MC_DC28_VALUE  0x510\r
+#define MC_DC29_VALUE  0x2d89\r
+#define MC_DC30_VALUE  0x8300\r
+#define MC_DC31_VALUE  0x0\r
+#define MC_DC32_VALUE  0x0\r
+#define MC_DC33_VALUE  0x0\r
+#define MC_DC34_VALUE  0x0\r
+#define MC_DC35_VALUE  0x0\r
+#define MC_DC36_VALUE  0x0\r
+#define MC_DC37_VALUE  0x0\r
+#define MC_DC38_VALUE  0x0\r
+#define MC_DC39_VALUE  0x0\r
+#define MC_DC40_VALUE  0x0\r
+#define MC_DC41_VALUE  0x0\r
+#define MC_DC42_VALUE  0x0\r
+#define MC_DC43_VALUE  0x0\r
+#define MC_DC44_VALUE  0x0\r
+#define MC_DC45_VALUE  0x500\r
+//#define MC_DC45_VALUE        0x400\r
+#define MC_DC46_VALUE  0x0\r
diff --git a/package/uboot-ifxmips/files/board/danube/ddr_settings_r166.h b/package/uboot-ifxmips/files/board/danube/ddr_settings_r166.h
new file mode 100644 (file)
index 0000000..742d34f
--- /dev/null
@@ -0,0 +1,50 @@
+/* Settings for Denali DDR SDRAM controller */
+/* Optimise for Danube Ref Board DDR 166 Mhz - by Ng Aik Ann 29th April */
+#define MC_DC0_VALUE   0x1B1B
+#define MC_DC1_VALUE   0x0
+#define MC_DC2_VALUE   0x0
+#define MC_DC3_VALUE   0x0
+#define MC_DC4_VALUE   0x0
+#define MC_DC5_VALUE   0x200
+#define MC_DC6_VALUE   0x605
+#define MC_DC7_VALUE   0x303
+#define MC_DC8_VALUE   0x102
+#define MC_DC9_VALUE   0x70a
+#define MC_DC10_VALUE  0x203
+#define MC_DC11_VALUE  0xc02
+#define MC_DC12_VALUE  0x1C8
+#define MC_DC13_VALUE  0x1
+#define MC_DC14_VALUE  0x0
+#define MC_DC15_VALUE  0xf3c  /* WDQS tuning for clk_wr*/
+#define MC_DC16_VALUE  0xC800
+#define MC_DC17_VALUE  0xd
+#define MC_DC18_VALUE  0x300
+#define MC_DC19_VALUE  0x200
+#define MC_DC20_VALUE  0xA04  /* A04 for reference board, A03 for Eval board */
+#define MC_DC21_VALUE  0xd00
+#define MC_DC22_VALUE  0xd0d
+#define MC_DC23_VALUE  0x0
+#define MC_DC24_VALUE  0x62   /* WDQS Tuning for DQS */
+#define MC_DC25_VALUE  0x0
+#define MC_DC26_VALUE  0x0
+#define MC_DC27_VALUE  0x0
+#define MC_DC28_VALUE  0x510
+#define MC_DC29_VALUE  0x2d89
+#define MC_DC30_VALUE  0x8300
+#define MC_DC31_VALUE  0x0
+#define MC_DC32_VALUE  0x0
+#define MC_DC33_VALUE  0x0
+#define MC_DC34_VALUE  0x0
+#define MC_DC35_VALUE  0x0
+#define MC_DC36_VALUE  0x0
+#define MC_DC37_VALUE  0x0
+#define MC_DC38_VALUE  0x0
+#define MC_DC39_VALUE  0x0
+#define MC_DC40_VALUE  0x0
+#define MC_DC41_VALUE  0x0
+#define MC_DC42_VALUE  0x0
+#define MC_DC43_VALUE  0x0
+#define MC_DC44_VALUE  0x0
+#define MC_DC45_VALUE  0x500
+//#define MC_DC45_VALUE        0x400
+#define MC_DC46_VALUE  0x0
diff --git a/package/uboot-ifxmips/files/board/danube/flash.c b/package/uboot-ifxmips/files/board/danube/flash.c
new file mode 100644 (file)
index 0000000..587c072
--- /dev/null
@@ -0,0 +1,892 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+//joelin 10/07/2004 for MXIC MX29LV320ABTC-90
+#include <common.h>
+#include <asm/danube.h>
+
+/*
+#ifdef CONFIG_AMAZON
+       #define FLASH_DELAY     {int i; \
+                               for(i=0;i<800;i++) \
+                                       *((volatile u32 *)CFG_SDRAM_BASE_UNCACHE); \
+                               }
+#else
+       #define FLASH_DELAY
+#endif
+*/     
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+/* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
+ *        has nothing to do with the flash chip being 8-bit or 16-bit.
+ */
+#ifdef CONFIG_FLASH_16BIT
+typedef unsigned short FLASH_PORT_WIDTH;
+typedef volatile unsigned short FLASH_PORT_WIDTHV;
+#define        FLASH_ID_MASK   0xFFFF
+#else
+typedef unsigned long FLASH_PORT_WIDTH;
+typedef volatile unsigned long FLASH_PORT_WIDTHV;
+#define        FLASH_ID_MASK   0xFFFFFFFF
+#endif
+
+#define FPW    FLASH_PORT_WIDTH
+#define FPWV   FLASH_PORT_WIDTHV
+
+#define ORMASK(size) ((-size) & OR_AM_MSK)     // 0xffff8000
+
+#if 0
+#define FLASH_CYCLE1   0x0555
+#define FLASH_CYCLE2   0x02aa
+#else
+#define FLASH_CYCLE1   0x0554                  //joelin for MX29LV320AT/B  0x0555 
+#define FLASH_CYCLE2   0x02ab                  //joelin for MX29LV320AT/B  0x02aa 
+#endif
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size(FPWV *addr, flash_info_t *info);
+static void flash_reset(flash_info_t *info);
+static int write_word_intel(flash_info_t *info, FPWV *dest, FPW data);
+static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
+static void flash_get_offsets(ulong base, flash_info_t *info);
+static flash_info_t *flash_get_info(ulong base);
+
+/*-----------------------------------------------------------------------
+ * flash_init()
+ *
+ * sets up flash_info and returns size of FLASH (bytes)
+ */
+unsigned long flash_init (void)
+{
+       unsigned long size = 0;
+       int i;
+
+       /* Init: no FLASHes known */
+       for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {         // 1 bank 
+               ulong flashbase = (i == 0) ? PHYS_FLASH_1 : PHYS_FLASH_2;      // 0xb0000000,  0xb4000000
+
+       volatile ulong * buscon = (ulong *)
+                       ((i == 0) ? DANUBE_EBU_BUSCON0 : DANUBE_EBU_BUSCON1);
+
+               /* Disable write protection */
+//             *buscon &= ~AMAZON_EBU_BUSCON0_WRDIS;
+               /* Enable write protection */
+               *buscon |= DANUBE_EBU_BUSCON0_WRDIS;
+
+#if 1
+               memset(&flash_info[i], 0, sizeof(flash_info_t));
+#endif
+
+               flash_info[i].size = 
+                       flash_get_size((FPW *)flashbase, &flash_info[i]);
+
+               if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
+                       i, flash_info[i].size);
+               }
+               
+               size += flash_info[i].size;
+       }
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE    // TEXT_BASE >= 0xB3000000
+       /* monitor protection ON by default */  /* only use software protection, info->protect[i]=0/1 */
+/*     flash_protect(FLAG_PROTECT_SET,
+                     CFG_MONITOR_BASE,
+                     CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+                     flash_get_info(CFG_MONITOR_BASE));
+*/
+       flash_protect(FLAG_PROTECT_CLEAR,    // clear protect
+                     CFG_MONITOR_BASE,
+                     CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+                     flash_get_info(CFG_MONITOR_BASE));
+
+#endif
+
+#ifdef CFG_ENV_IS_IN_FLASH     /* 1 */
+       /* ENV protection ON by default */
+/*     flash_protect(FLAG_PROTECT_SET,
+                     CFG_ENV_ADDR,
+                     CFG_ENV_ADDR+CFG_ENV_SIZE-1,
+                     flash_get_info(CFG_ENV_ADDR));
+*/
+       flash_protect(FLAG_PROTECT_CLEAR,
+                     CFG_ENV_ADDR,
+                     CFG_ENV_ADDR+CFG_ENV_SIZE-1,
+                     flash_get_info(CFG_ENV_ADDR));
+
+#endif
+
+
+       return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_reset(flash_info_t *info)
+{
+       FPWV *base = (FPWV *)(info->start[0]);
+
+       (*DANUBE_EBU_BUSCON0)&=(~0x80000000);   // enable writing
+       (*DANUBE_EBU_BUSCON1)&=(~0x80000000);   // enable writing
+       (*EBU_NAND_CON)=0;      
+       /* Put FLASH back in read mode */
+       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
+               *base = (FPW)0x00FF00FF;        /* Intel Read Mode */
+               asm("SYNC");
+       }
+       else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD){
+               *base = (FPW)0x00F000F0;        /* AMD Read Mode */
+               asm("SYNC");                    //joelin
+       }
+       else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_MX){
+               *base = (FPW)0x00F000F0;        /* MXIC Read Mode */
+               asm("SYNC");                    //joelin
+       }               
+
+       (*DANUBE_EBU_BUSCON0)|=0x80000000;      // disable writing
+       (*DANUBE_EBU_BUSCON1)|=0x80000000;      // disable writing
+
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       /* set up sector start address table */
+       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL
+           && (info->flash_id & FLASH_BTYPE)) {
+               int bootsect_size;      /* number of bytes/boot sector  */
+               int sect_size;          /* number of bytes/regular sector */
+
+               bootsect_size = 0x00002000 * (sizeof(FPW)/2);
+               sect_size =     0x00010000 * (sizeof(FPW)/2);
+
+               /* set sector offsets for bottom boot block type        */
+               for (i = 0; i < 8; ++i) {
+                       info->start[i] = base + (i * bootsect_size);
+               }
+               for (i = 8; i < info->sector_count; i++) {
+                       info->start[i] = base + ((i - 7) * sect_size);
+               }
+       }
+       else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
+                && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
+
+               int sect_size;          /* number of bytes/sector */
+
+               sect_size = 0x00010000 * (sizeof(FPW)/2);
+
+               /* set up sector start address table (uniform sector type) */
+               for( i = 0; i < info->sector_count; i++ )
+                       info->start[i] = base + (i * sect_size);
+       }
+       else if(((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
+               && ((info->flash_id & FLASH_TYPEMASK)==FLASH_28F128J3A)){
+               int sect_size;
+               sect_size = 0x20000;
+               for(i=0;i < info->sector_count; i++)
+                       info->start[i]= base + (i*sect_size);
+       }
+       else if(((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
+               && ((info->flash_id & FLASH_TYPEMASK)==FLASH_28F320J3A)){
+               int sect_size;
+               sect_size = 0x20000;
+               for(i=0;i < info->sector_count; i++)
+                       info->start[i]= base + (i*sect_size);
+       }
+//joelin add for MX29LV320AB-- SA0~SA7:sector size=8K bytes ,SA9~SA70 :sector size=64k bytes   
+       else if(((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_MX)
+               && ((info->flash_id & FLASH_TYPEMASK)==FLASH_29LV320AB)){
+               int bootsect_size;      /* number of bytes/boot sector  */
+               int sect_size;          /* number of bytes/regular sector */
+
+               bootsect_size = 0x00002000 * (sizeof(FPW)/2);
+               sect_size =     0x00010000 * (sizeof(FPW)/2);
+
+               /* set sector offsets for bottom boot block type        */
+               for (i = 0; i < 8; ++i) {
+                       info->start[i] = base + (i * bootsect_size);
+               }
+               for (i = 8; i < info->sector_count; i++) {
+                       info->start[i] = base + ((i - 7) * sect_size);
+               }
+       }       
+//joelin add for MX29LV160BB-- SA0=16K,SA1,SA2=8K,SA3=32K bytes ,SA4~SA34 :sector size=64k bytes                       
+       else if(((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_MX)
+               && ((info->flash_id & FLASH_TYPEMASK)==FLASH_29LV160BB)){
+               int bootsect_size;      /* number of bytes/boot sector  */
+               int sect_size;          /* number of bytes/regular sector */
+
+               bootsect_size = 0x00002000 * (sizeof(FPW)/2);
+               sect_size =     0x00010000 * (sizeof(FPW)/2);
+/* set sector offsets for bottom boot block type       */              
+//MX29LV160BB
+               info->start[0] = base ;                         //SA0=16K bytes
+               info->start[1] = info->start[0]  + (1 * 0x00004000 * (sizeof(FPW)/2)); //SA1=8K bytes
+               info->start[2] = info->start[1]  + (1 * 0x00002000 * (sizeof(FPW)/2)); //SA2=8K bytes
+               info->start[3] = info->start[2]  + (1 * 0x00002000 * (sizeof(FPW)/2)); //SA3=32K bytes
+
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = base + ((i - 3) * sect_size);
+               }               
+       }       
+//liupeng add for MX29LV640BB-- SA0~SA7:sector size=8k bytes ,SA8~SA134 :sector size=64k bytes 
+       else if(((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_MX)
+               && ((info->flash_id & FLASH_TYPEMASK)==FLASH_29LV640BB)){
+               int bootsect_size;      /* number of bytes/boot sector  */
+               int sect_size;          /* number of bytes/regular sector */
+
+               bootsect_size = 0x00002000 * (sizeof(FPW)/2);
+               sect_size =     0x00010000 * (sizeof(FPW)/2);
+
+               /* set sector offsets for bottom boot block type        */
+               for (i = 0; i < 8; ++i) {
+                       info->start[i] = base + (i * bootsect_size);
+               }
+               for (i = 8; i < info->sector_count; i++) {
+                       info->start[i] = base + ((i - 7) * sect_size);
+               }
+       }       
+       else{
+               printf("flash get offsets fail\n");
+       }
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+static flash_info_t *flash_get_info(ulong base)
+{
+       int i;
+       flash_info_t * info;
+       
+       for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
+               info = & flash_info[i];
+               if (info->start[0] <= base && base < info->start[0] + info->size)
+                       break;
+       }
+       
+       return i == CFG_MAX_FLASH_BANKS ? 0 : info;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+void flash_print_info (flash_info_t *info)
+{
+       int i;
+       uchar *boottype;
+       uchar *bootletter;
+       uchar *fmt;
+       uchar botbootletter[] = "B";
+       uchar topbootletter[] = "T";
+       uchar botboottype[] = "bottom boot sector";
+       uchar topboottype[] = "top boot sector";
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       case FLASH_MAN_BM:      printf ("BRIGHT MICRO ");       break;
+       case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
+       case FLASH_MAN_SST:     printf ("SST ");                break;
+       case FLASH_MAN_STM:     printf ("STM ");                break;
+       case FLASH_MAN_INTEL:   printf ("INTEL ");              break;
+       case FLASH_MAN_MX:      printf ("MXIC  ");              break;  
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       /* check for top or bottom boot, if it applies */
+       if (info->flash_id & FLASH_BTYPE) {
+               boottype = botboottype;
+               bootletter = botbootletter;
+       }
+       else {
+               boottype = topboottype;
+               bootletter = topbootletter;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM640U:
+               fmt = "29LV641D (64 Mbit, uniform sectors)\n";
+               break;
+        case FLASH_28F800C3B:
+        case FLASH_28F800C3T:
+               fmt = "28F800C3%s (8 Mbit, %s)\n";
+               break;
+       case FLASH_INTEL800B:
+       case FLASH_INTEL800T:
+               fmt = "28F800B3%s (8 Mbit, %s)\n";
+               break;
+        case FLASH_28F160C3B:
+        case FLASH_28F160C3T:
+               fmt = "28F160C3%s (16 Mbit, %s)\n";
+               break;
+       case FLASH_INTEL160B:
+       case FLASH_INTEL160T:
+               fmt = "28F160B3%s (16 Mbit, %s)\n";
+               break;
+        case FLASH_28F320C3B:
+        case FLASH_28F320C3T:
+               fmt = "28F320C3%s (32 Mbit, %s)\n";
+               break;
+       case FLASH_INTEL320B:
+       case FLASH_INTEL320T:
+               fmt = "28F320B3%s (32 Mbit, %s)\n";
+               break;
+        case FLASH_28F640C3B:
+        case FLASH_28F640C3T:
+               fmt = "28F640C3%s (64 Mbit, %s)\n";
+               break;
+       case FLASH_INTEL640B:
+       case FLASH_INTEL640T:
+               fmt = "28F640B3%s (64 Mbit, %s)\n";
+               break;
+       case FLASH_28F128J3A:
+               fmt = "28F128J3A (128 Mbit, 128 uniform sectors)\n";
+               break;
+       case FLASH_28F320J3A:
+               fmt = "28F320J3A (32 Mbit, 32 uniform sectors)\n";
+               break;
+       case FLASH_29LV640BB:           //liupeng for MXIC FLASH_29LV640BB
+               fmt = "29LV640BB (64 Mbit, boot sector SA0~SA126 size 64k bytes,other sectors SA127~SA135 size 8k bytes)\n";
+               break;  
+       case FLASH_29LV320AB:           //joelin for MXIC FLASH_29LV320AB
+               fmt = "29LV320AB (32 Mbit, boot sector SA0~SA7 size 8K bytes,other sectors SA8~SA70 size 64K bytes)\n";
+               break;  
+       case FLASH_29LV160BB:           //joelin for MXIC FLASH_29LV160BB
+               fmt = "29LV160BB (16 Mbit, boot sector SA0 size 16K bytes,SA1,SA2 size 8K bytes,SA3 size 32k bytes,other sectors SA4~SA34 size 64K bytes)\n";
+               break;                                  
+       default:
+               fmt = "Unknown Chip Type\n";
+               break;
+       }
+
+       printf (fmt, bootletter, boottype);
+
+       printf ("  Size: %ld MB in %d Sectors\n",
+               info->size >> 20,
+               info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+
+       for (i=0; i<info->sector_count; ++i) {
+               if ((i % 5) == 0) {
+                       printf ("\n   ");
+               }
+
+               printf (" %08lX%s", info->start[i],
+                       info->protect[i] ? " (RO)" : "     ");
+       }
+
+       printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+ulong flash_get_size (FPWV *addr, flash_info_t *info)
+{
+        (*DANUBE_EBU_BUSCON0)=0x1d7ff;  //value from Aikann, should be used on the real chip
+       (*EBU_ADDR_SEL_0) = 0x10000031; //starting address from 0xb0000000
+       (*EBU_NAND_CON)=0;
+       (*DANUBE_EBU_BUSCON0)&=(~0x80000000);   // enable writing
+       (*DANUBE_EBU_BUSCON1)&=(~0x80000000);   // enable writing
+       /* Write auto select command: read Manufacturer ID */
+
+       /* Write auto select command sequence and test FLASH answer */
+       addr[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* for AMD, Intel ignores this */
+       asm("SYNC");    
+       addr[FLASH_CYCLE2] = (FPW)0x00550055;   /* for AMD, Intel ignores this */
+       asm("SYNC");
+       addr[FLASH_CYCLE1] = (FPW)0x00900090;   /* selects Intel or AMD */
+       asm("SYNC");
+       
+       /* The manufacturer codes are only 1 byte, so just use 1 byte.
+        * This works for any bus width and any FLASH device width.
+        */
+//     printf("\n type is %08lx", addr[1] & 0xff);     //joelin 10/06/2004 flash type
+//     printf("\n type is %08lx", addr[0] & 0xff);     //joelin 10/06/2004 flash type
+//             asm("SYNC");     
+       switch (addr[1] & 0xff) {
+       case (uchar)AMD_MANUFACT:
+               info->flash_id = FLASH_MAN_AMD;
+               break;
+
+       case (uchar)INTEL_MANUFACT:                     // 0x0089
+               info->flash_id = FLASH_MAN_INTEL; //0x00300000
+               break;
+               
+//joelin for MXIC              
+       case (uchar)MX_MANUFACT:                // 0x00c2
+               info->flash_id = FLASH_MAN_MX ;//0x00030000
+               break;
+               
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               break;
+/*     default:
+               info->flash_id = FLASH_MAN_INTEL; //0x00300000
+               break;*/
+       }
+
+       /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
+       if (info->flash_id != FLASH_UNKNOWN) switch (addr[0]) {
+       case (FPW)AMD_ID_LV640U:        /* 29LV640 and 29LV641 have same ID */
+               info->flash_id += FLASH_AM640U;
+               info->sector_count = 128;
+               info->size = 0x00800000 * (sizeof(FPW)/2);
+               break;                          /* => 8 or 16 MB        */
+
+       case (FPW)INTEL_ID_28F800C3B:
+               info->flash_id += FLASH_28F800C3B;
+               info->sector_count = 23;
+               info->size = 0x00100000 * (sizeof(FPW)/2);
+               break;                          /* => 1 or 2 MB         */
+
+       case (FPW)INTEL_ID_28F800B3B:
+               info->flash_id += FLASH_INTEL800B;
+               info->sector_count = 23;
+               info->size = 0x00100000 * (sizeof(FPW)/2);
+               break;                          /* => 1 or 2 MB         */
+
+       case (FPW)INTEL_ID_28F160C3B:
+               info->flash_id += FLASH_28F160C3B;
+               info->sector_count = 39;
+               info->size = 0x00200000 * (sizeof(FPW)/2);
+               break;                          /* => 2 or 4 MB         */
+
+       case (FPW)INTEL_ID_28F160B3B:
+               info->flash_id += FLASH_INTEL160B;
+               info->sector_count = 39;
+               info->size = 0x00200000 * (sizeof(FPW)/2);
+               break;                          /* => 2 or 4 MB         */
+
+       case (FPW)INTEL_ID_28F320C3B:
+               info->flash_id += FLASH_28F320C3B;
+               info->sector_count = 71;
+               info->size = 0x00400000 * (sizeof(FPW)/2);
+               break;                          /* => 4 or 8 MB         */
+
+       case (FPW)INTEL_ID_28F320B3B:
+               info->flash_id += FLASH_INTEL320B;
+               info->sector_count = 71;
+               info->size = 0x00400000 * (sizeof(FPW)/2);
+               break;                          /* => 4 or 8 MB         */
+
+       case (FPW)INTEL_ID_28F640C3B:
+               info->flash_id += FLASH_28F640C3B;
+               info->sector_count = 135;
+               info->size = 0x00800000 * (sizeof(FPW)/2);
+               break;                          /* => 8 or 16 MB        */
+
+       case (FPW)INTEL_ID_28F640B3B:
+               info->flash_id += FLASH_INTEL640B;
+               info->sector_count = 135;
+               info->size = 0x00800000 * (sizeof(FPW)/2);
+               break;                          /* => 8 or 16 MB        */
+       
+       case (FPW)INTEL_ID_28F128J3A:
+               info->flash_id +=FLASH_28F128J3A;
+               info->sector_count = 128;
+               info->size = 0x01000000 * (sizeof(FPW)/2);
+               break;                          /* => 16 MB */
+       case (FPW)INTEL_ID_28F320J3A:
+               info->flash_id += FLASH_28F320J3A;
+               info->sector_count = 32;
+               info->size = 0x00400000 * (sizeof(FPW)/2);
+               break;  
+//joelin for MXIC
+       case (FPW)MX_ID_29LV320AB:
+               info->flash_id += FLASH_29LV320AB;
+               info->sector_count = 71;
+               info->size = 0x00400000 * (sizeof(FPW)/2);
+               break;                          /* => 4 MB              */              
+                                       /* => 4 MB */
+//joelin for MXIC
+       case (FPW)MX_ID_29LV160BB:
+               info->flash_id += FLASH_29LV160BB;
+               info->sector_count = 35;
+               info->size = 0x00200000 * (sizeof(FPW)/2);
+               break;                          /* => 2 MB              */              
+                                       /* => 2 MB */                                   
+       /* liupeng*/
+       case (FPW)MX_ID_29LV640BB:
+               info->flash_id += FLASH_29LV640BB;
+               info->sector_count = 135;
+               info->size = 0x00800000 * (sizeof(FPW)/2);
+               break;                          /* => 2 MB              */              
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* => no or unknown flash */
+/*     default:
+               info->flash_id += FLASH_28F320J3A;
+               info->sector_count = 32;
+               info->size = 0x00400000 * (sizeof(FPW)/2);
+               break;*/
+       }
+
+
+       (*DANUBE_EBU_BUSCON0)|=0x80000000;      // disable writing
+       (*DANUBE_EBU_BUSCON1)|=0x80000000;      // disable writing
+       
+       flash_get_offsets((ulong)addr, info);
+
+       /* Put FLASH back in read mode */
+       flash_reset(info);
+       
+       return (info->size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int    flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       FPWV *addr;
+       int flag, prot, sect;
+       int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
+       ulong start, now, last;
+       int rcode = 0;
+       if ((s_first < 0) || (s_first > s_last)) {
+               if (info->flash_id == FLASH_UNKNOWN) {
+                       printf ("- missing\n");
+               } else {
+                       printf ("- no sectors to erase\n");
+               }
+               return 1;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_INTEL800B:
+       case FLASH_INTEL160B:
+       case FLASH_INTEL320B:
+       case FLASH_INTEL640B:
+       case FLASH_28F800C3B:
+       case FLASH_28F160C3B:
+       case FLASH_28F320C3B:
+       case FLASH_28F640C3B:
+       case FLASH_28F128J3A:
+       case FLASH_28F320J3A:
+       case FLASH_AM640U:
+       case FLASH_29LV640BB:   //liupeng for MXIC MX29LV640BB
+       case FLASH_29LV320AB:   //joelin for MXIC MX29LV320AB
+       case FLASH_29LV160BB:   //joelin for MXIC MX29LV160BB
+               break;
+       case FLASH_UNKNOWN:
+       default:
+               printf ("Can't erase unknown flash type %08lx - aborted\n",
+                       info->flash_id);
+               return 1;
+       }
+
+       prot = 0;
+       for (sect=s_first; sect<=s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                       prot);
+       } else {
+               printf ("\n");
+       }
+
+       last  = get_timer(0);
+
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
+
+               if (info->protect[sect] != 0)   /* protected, skip it */
+                       continue;
+
+               /* Disable interrupts which might cause a timeout here */
+               flag = disable_interrupts();
+               
+               (*DANUBE_EBU_BUSCON0)&=(~0x80000000);   // enable writing
+               (*DANUBE_EBU_BUSCON1)&=(~0x80000000);   // enable writing
+               (*EBU_NAND_CON)=0;
+               addr = (FPWV *)(info->start[sect]);
+               if (intel) {
+                       *addr = (FPW)0x00500050; /* clear status register */
+                       *addr = (FPW)0x00200020; /* erase setup */
+                       *addr = (FPW)0x00D000D0; /* erase confirm */
+                       asm("SYNC");
+               }
+               else {
+                       /* must be AMD style if not Intel */
+                       FPWV *base;             /* first address in bank */
+
+                       base = (FPWV *)(info->start[0]);
+                       base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
+                       base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
+                       base[FLASH_CYCLE1] = (FPW)0x00800080;   /* erase mode */
+                       base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
+                       base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
+                       *addr = (FPW)0x00300030;        /* erase sector */
+               }
+
+               /* re-enable interrupts if necessary */
+               if (flag)
+                       enable_interrupts();
+
+               start = get_timer(0);
+
+               /* wait at least 50us for AMD, 80us for Intel.
+                * Let's wait 1 ms.
+                */
+               udelay (1000);
+
+               while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
+                       if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                               printf ("Erase Timeout\n");
+
+                               if (intel) {
+                                       /* suspend erase        */
+                                       *addr = (FPW)0x00B000B0;
+                               }
+
+                               flash_reset(info);      /* reset to read mode */
+                               rcode = 1;              /* failed */
+                               break;
+                       }
+
+                       /* show that we're waiting */
+                       if ((get_timer(last)) > CFG_HZ) {/* every second */
+                               putc ('.');
+                               last = get_timer(0);
+                       }
+               }
+               
+                       
+//joelin for MXIC 
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_MX:              //joelin for MXIC       
+               break;
+       default:
+               if((*addr & (FPW)0x00200020) != (FPW)0x0)
+                       printf("Erase Error\n");
+               break;
+       }                       
+                       
+                       
+
+               /* show that we're waiting */
+               if ((get_timer(last)) > CFG_HZ) {       /* every second */
+                       putc ('.');
+                       last = get_timer(0);
+               }
+
+               //flash_reset(info);    /* reset to read mode   */
+       }
+
+       (*DANUBE_EBU_BUSCON0)|=0x80000000;      // disable writing
+       (*DANUBE_EBU_BUSCON1)|=0x80000000;      // disable writing
+       printf (" done\n");
+       return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
+    int bytes;   /* number of bytes to program in current word         */
+    int left;    /* number of bytes left to program                    */
+    int i, res;
+
+    for (left = cnt, res = 0;
+        left > 0 && res == 0;
+        addr += sizeof(data), left -= sizeof(data) - bytes) {
+
+        bytes = addr & (sizeof(data) - 1);
+        addr &= ~(sizeof(data) - 1);
+
+       /* combine source and destination data so can program
+        * an entire word of 16 or 32 bits
+        */
+        for (i = 0; i < sizeof(data); i++) {
+            data <<= 8;
+            if (i < bytes || i - bytes >= left )
+               data += *((uchar *)addr + i);
+           else
+               data += *src++;
+       }
+
+       /* write one word to the flash */
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:
+       case FLASH_MAN_MX:              //joelin for MXIC       
+               res = write_word_amd(info, (FPWV *)addr, data);
+               break;
+       case FLASH_MAN_INTEL:
+               res = write_word_intel(info, (FPWV *)addr, data);
+               break;
+       default:
+               /* unknown flash type, error! */
+               printf ("missing or unknown FLASH type\n");
+               res = 1;        /* not really a timeout, but gives error */
+               break;
+       }
+    }
+
+    return (res);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash for AMD FLASH
+ * A word is 16 or 32 bits, whichever the bus width of the flash bank
+ * (not an individual chip) is.
+ *
+ * returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
+{
+    ulong start;
+    int flag;
+    int res = 0;       /* result, assume success       */
+    FPWV *base;                /* first address in flash bank  */
+
+    /* Check if Flash is (sufficiently) erased */
+    if ((*dest & data) != data) {
+       return (2);
+    }
+
+    base = (FPWV *)(info->start[0]);
+
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+  
+    (*DANUBE_EBU_BUSCON0)&=(~0x80000000);      // enable writing
+    (*DANUBE_EBU_BUSCON1)&=(~0x80000000);      // enable writing
+    (*EBU_NAND_CON)=0;
+       
+    base[FLASH_CYCLE1] = (FPW)0x00AA00AA;      /* unlock */
+    base[FLASH_CYCLE2] = (FPW)0x00550055;      /* unlock */
+    base[FLASH_CYCLE1] = (FPW)0x00A000A0;      /* selects program mode */
+
+    *dest = data;              /* start programming the data   */
+
+    /* re-enable interrupts if necessary */
+    if (flag)
+       enable_interrupts();
+
+    start = get_timer (0);
+
+    /* data polling for D7 */
+    while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
+       if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+           *dest = (FPW)0x00F000F0;    /* reset bank */
+           res = 1;
+       }
+    }
+       (*DANUBE_EBU_BUSCON0)|=0x80000000;      // disable writing
+       (*DANUBE_EBU_BUSCON1)|=0x80000000;      // disable writing
+        return (res);
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash for Intel FLASH
+ * A word is 16 or 32 bits, whichever the bus width of the flash bank
+ * (not an individual chip) is.
+ *
+ * returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word_intel (flash_info_t *info, FPWV *dest, FPW data)
+{
+    ulong start;
+    int flag;
+    int res = 0;       /* result, assume success       */
+       
+    /* Check if Flash is (sufficiently) erased */
+    if ((*dest & data) != data) {
+       return (2);
+    }
+
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    (*DANUBE_EBU_BUSCON0)&=(~0x80000000);      // enable writing
+    (*DANUBE_EBU_BUSCON1)&=(~0x80000000);      // enable writing
+    (*EBU_NAND_CON)=0;
+    *dest = (FPW)0x00500050;   /* clear status register        */
+    *dest = (FPW)0x00FF00FF;   /* make sure in read mode       */
+    *dest = (FPW)0x00400040;   /* program setup                */
+    *dest = data;              /* start programming the data   */
+    asm("SYNC");
+    
+    /* re-enable interrupts if necessary */
+    if (flag)
+       enable_interrupts();
+
+    start = get_timer (0);
+
+    while (res == 0 && (*dest & (FPW)0x00800080) != (FPW)0x00800080) {
+       if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+           *dest = (FPW)0x00B000B0;    /* Suspend program      */
+           res = 1;
+       }
+    }
+
+    if (res == 0 && (*dest & (FPW)0x00100010))
+       res = 1;        /* write failed, time out error is close enough */
+
+    *dest = (FPW)0x00500050;   /* clear status register        */
+    flash_reset(info);
+
+    (*DANUBE_EBU_BUSCON0)|=0x80000000; // disable writing
+    (*DANUBE_EBU_BUSCON1)|=0x80000000; // disable writing
+        return (res);
+}
diff --git a/package/uboot-ifxmips/files/board/danube/lowlevel_init.S b/package/uboot-ifxmips/files/board/danube/lowlevel_init.S
new file mode 100644 (file)
index 0000000..f5f24a4
--- /dev/null
@@ -0,0 +1,582 @@
+
+/*
+ *  Memory sub-system initialization code for INCA-IP2 development board.
+ *  Andre Messerschmidt
+ *  Copyright (c) 2005 Infineon Technologies AG 
+ *
+ *  Based on Inca-IP code 
+ *  Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+/* History:
+      peng liu May 25, 2006, for PLL setting after reset, 05252006
+ */
+#include <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+#include <configs/danube.h>
+
+
+#ifdef USE_REFERENCE_BOARD
+#ifdef DANUBE_DDR_RAM_111M
+#include "ddr_settings_r111.h"
+#elif defined(PROMOSDDR400)
+#include "ddr_settings_PROMOSDDR400.h"
+#elif defined(DDR_SAMSUNG_166M)
+#include "ddr_settings_Samsung_166.h"
+#elif defined(DDR_PSC_166M)
+#include "ddr_settings_psc_166.h"
+#else
+#include "ddr_settings_r166.h"
+#endif
+#endif
+
+#ifdef USE_EVALUATION_BOARD
+#ifdef DANUBE_DDR_RAM_111M
+#include "ddr_settings_e111.h"
+#else
+#include "ddr_settings_e166.h"
+#endif
+#endif
+
+
+
+/*TODO: liupeng check !!! */
+#define EBU_MODUL_BASE         0xB4102000
+#define EBU_CLC(value)         0x0000(value)
+#define EBU_CON(value)         0x0010(value)
+#define EBU_ADDSEL0(value)     0x0020(value)
+#define EBU_ADDSEL1(value)     0x0024(value)
+#define EBU_ADDSEL2(value)     0x0028(value)
+#define EBU_ADDSEL3(value)     0x002C(value)
+#define EBU_BUSCON0(value)     0x0060(value)
+#define EBU_BUSCON1(value)     0x0064(value)
+#define EBU_BUSCON2(value)     0x0068(value)
+#define EBU_BUSCON3(value)     0x006C(value)
+
+#define MC_MODUL_BASE          0xBF800000
+#define MC_ERRCAUSE(value)     0x0010(value)
+#define MC_ERRADDR(value)      0x0020(value)
+#define MC_CON(value)          0x0060(value)
+
+#define MC_SRAM_ENABLE         0x00000004
+#define MC_SDRAM_ENABLE                0x00000002
+#define MC_DDRRAM_ENABLE       0x00000001
+
+#define MC_SDR_MODUL_BASE      0xBF800200
+#define MC_IOGP(value)         0x0000(value)
+#define MC_CTRLENA(value)      0x0010(value)
+#define MC_MRSCODE(value)      0x0020(value)
+#define MC_CFGDW(value)                0x0030(value)
+#define MC_CFGPB0(value)       0x0040(value)
+#define MC_LATENCY(value)      0x0080(value)
+#define MC_TREFRESH(value)     0x0090(value)
+#define MC_SELFRFSH(value)     0x00A0(value)
+
+#define MC_DDR_MODUL_BASE      0xBF801000
+#define MC_DC00(value)         0x0000(value)
+#define MC_DC01(value)         0x0010(value)
+#define MC_DC02(value)         0x0020(value)
+#define MC_DC03(value)         0x0030(value)
+#define MC_DC04(value)         0x0040(value)
+#define MC_DC05(value)         0x0050(value)
+#define MC_DC06(value)         0x0060(value)
+#define MC_DC07(value)         0x0070(value)
+#define MC_DC08(value)         0x0080(value)
+#define MC_DC09(value)         0x0090(value)
+#define MC_DC10(value)         0x00A0(value)
+#define MC_DC11(value)         0x00B0(value)
+#define MC_DC12(value)         0x00C0(value)
+#define MC_DC13(value)         0x00D0(value)
+#define MC_DC14(value)         0x00E0(value)
+#define MC_DC15(value)         0x00F0(value)
+#define MC_DC16(value)         0x0100(value)
+#define MC_DC17(value)         0x0110(value)
+#define MC_DC18(value)         0x0120(value)
+#define MC_DC19(value)         0x0130(value)
+#define MC_DC20(value)         0x0140(value)
+#define MC_DC21(value)         0x0150(value)
+#define MC_DC22(value)         0x0160(value)
+#define MC_DC23(value)         0x0170(value)
+#define MC_DC24(value)         0x0180(value)
+#define MC_DC25(value)         0x0190(value)
+#define MC_DC26(value)         0x01A0(value)
+#define MC_DC27(value)         0x01B0(value)
+#define MC_DC28(value)         0x01C0(value)
+#define MC_DC29(value)         0x01D0(value)
+#define MC_DC30(value)         0x01E0(value)
+#define MC_DC31(value)         0x01F0(value)
+#define MC_DC32(value)         0x0200(value)
+#define MC_DC33(value)         0x0210(value)
+#define MC_DC34(value)         0x0220(value)
+#define MC_DC35(value)         0x0230(value)
+#define MC_DC36(value)         0x0240(value)
+#define MC_DC37(value)         0x0250(value)
+#define MC_DC38(value)         0x0260(value)
+#define MC_DC39(value)         0x0270(value)
+#define MC_DC40(value)         0x0280(value)
+#define MC_DC41(value)         0x0290(value)
+#define MC_DC42(value)         0x02A0(value)
+#define MC_DC43(value)         0x02B0(value)
+#define MC_DC44(value)         0x02C0(value)
+#define MC_DC45(value)         0x02D0(value)
+#define MC_DC46(value)         0x02E0(value)
+
+#define RCU_OFFSET  0xBF203000
+#define RCU_RST_REQ      (RCU_OFFSET + 0x0010)
+#define RCU_STS          (RCU_OFFSET + 0x0014)
+
+#define CGU_OFFSET  0xBF103000
+#define  PLL0_CFG     (CGU_OFFSET + 0x0004)
+#define  PLL1_CFG     (CGU_OFFSET + 0x0008)
+#define  PLL2_CFG     (CGU_OFFSET + 0x000C)
+#define  CGU_SYS      (CGU_OFFSET + 0x0010)
+#define  CGU_UPDATE   (CGU_OFFSET + 0x0014)
+#define  IF_CLK       (CGU_OFFSET + 0x0018)
+#define  CGU_SMD      (CGU_OFFSET + 0x0020)
+#define  CGU_CT1SR    (CGU_OFFSET + 0x0028)
+#define  CGU_CT2SR    (CGU_OFFSET + 0x002C)
+#define  CGU_PCMCR    (CGU_OFFSET + 0x0030)
+#define  PCI_CR_PCI   (CGU_OFFSET + 0x0034)
+#define  CGU_OSC_CTRL (CGU_OFFSET + 0x001C)
+#define  CGU_MIPS_PWR_DWN (CGU_OFFSET + 0x0038)
+#define  CLK_MEASURE  (CGU_OFFSET + 0x003C)
+
+//05252006
+#define  pll0_35MHz_CONFIG 0x9D861059
+#define  pll1_35MHz_CONFIG 0x1A260CD9
+#define  pll2_35MHz_CONFIG 0x8000f1e5
+#define  pll0_36MHz_CONFIG 0x1000125D 
+#define  pll1_36MHz_CONFIG 0x1B1E0C99
+#define  pll2_36MHz_CONFIG 0x8002f2a1 
+//05252006
+
+//06063001-joelin disable the PCI CFRAME mask -start
+/*CFRAME is an I/O signal, in the chip, the output CFRAME is selected via GPIO altsel pins, so if you select MII1 RXD1, the CFRAME will not come out.
+But the CFRAME input still take the signal from the pad and not disabled when altsel choose other function. So when MII1_RXD1 is low from other device, the EBU interface will be disabled.
+
+The chip function in such a way that disable the CFRAME mask mean EBU not longer check CFRAME to be the device using the bus.
+The side effect is the entire PCI block will see CFRAME low all the time meaning PCI cannot use the bus at all so no more PCI function.
+*/
+#define PCI_CR_PR_OFFSET  0xBE105400
+#define PCI_CR_PCI_MOD_REG          (PCI_CR_PR_OFFSET + 0x0030)
+#define PCI_CONFIG_SPACE  0xB7000000
+#define CS_CFM         (PCI_CONFIG_SPACE + 0x6C)
+//06063001-joelin disable the PCI CFRAME mask -end
+       .set    noreorder
+
+
+/*
+ * void ebu_init(long)
+ *
+ * a0 has the clock value we are going to run at
+ */
+       .globl  ebu_init
+       .ent    ebu_init
+ebu_init:
+/*TODO:liupeng */
+       j       ra
+       nop
+
+       .end    ebu_init
+
+
+/*
+ * void cgu_init(long)
+ *
+ * a0 has the clock value
+ */
+       .globl  cgu_init
+       .ent    cgu_init
+cgu_init:
+       li  t2, CGU_SYS
+  lw  t2,0(t2)
+  beq t2,a0,freq_up2date
+  nop
+
+       li  t2, RCU_STS
+       lw  t2, 0(t2)
+       and t2,0x00020000
+       beq t2,0x00020000,boot_36MHZ
+  nop
+//05252006
+       li  t1, PLL0_CFG
+       li  t2, pll0_35MHz_CONFIG
+       sw      t2,0(t1)
+       li  t1, PLL1_CFG
+       li  t2, pll1_35MHz_CONFIG
+       sw      t2,0(t1)
+       li  t1, PLL2_CFG
+       li  t2, pll2_35MHz_CONFIG
+       sw      t2,0(t1)
+       li  t1, CGU_SYS
+       sw      a0,0(t1)
+       li  t1, RCU_RST_REQ
+       li  t2, 0x40000008
+       sw      t2,0(t1)
+       b   wait_reset
+       nop
+boot_36MHZ:
+       li  t1, PLL0_CFG
+       li  t2, pll0_36MHz_CONFIG
+       sw      t2,0(t1)
+       li  t1, PLL1_CFG
+       li  t2, pll1_36MHz_CONFIG
+       sw      t2,0(t1)
+       li  t1, PLL2_CFG
+       li  t2, pll2_36MHz_CONFIG
+       sw      t2,0(t1)
+       li  t1, CGU_SYS
+       sw      a0,0(t1)
+       li  t1, RCU_RST_REQ
+       li  t2, 0x40000008
+       sw      t2,0(t1)
+//05252006
+
+wait_reset:
+    b   wait_reset
+    nop
+freq_up2date:
+    j ra 
+    nop
+       .end    cgu_init
+
+
+/*
+ * void sdram_init(long)
+ *
+ * a0 has the clock value
+ */
+       .globl  sdram_init
+       .ent    sdram_init
+sdram_init:
+       
+       /* SDRAM Initialization
+        */
+       li      t1, MC_MODUL_BASE
+
+       /* Clear Error log registers */
+       sw      zero, MC_ERRCAUSE(t1)
+       sw      zero, MC_ERRADDR(t1)
+       
+       /* Enable SDRAM module in memory controller */
+       li      t3, MC_SDRAM_ENABLE
+       lw      t2, MC_CON(t1)
+       or      t3, t2, t3
+       sw      t3, MC_CON(t1)
+       
+       li      t1, MC_SDR_MODUL_BASE
+       
+       /* disable the controller */
+       li      t2, 0
+       sw      t2, MC_CTRLENA(t1)
+     
+       li      t2, 0x822       
+       sw      t2, MC_IOGP(t1)
+
+       li      t2, 0x2
+       sw      t2, MC_CFGDW(t1)
+       
+       /* Set CAS Latency */
+       li      t2, 0x00000020          
+       sw      t2, MC_MRSCODE(t1)
+       
+       /* Set CS0 to SDRAM parameters */
+       li      t2, 0x000014d8
+       sw      t2, MC_CFGPB0(t1)
+       
+       /* Set SDRAM latency parameters */
+       li      t2, 0x00036325;   /* BC PC100 */
+       sw      t2, MC_LATENCY(t1)
+       
+       /* Set SDRAM refresh rate */
+       li      t2, 0x00000C30          
+       sw      t2, MC_TREFRESH(t1)
+       
+       /* Clear Power-down registers */
+       sw      zero, MC_SELFRFSH(t1)
+
+       /* Finally enable the controller */
+       li      t2, 1
+       sw      t2, MC_CTRLENA(t1)
+
+       
+       j       ra
+       nop
+
+
+       .end    sdram_init
+
+/*
+ * void ddrram_init(long)
+ *
+ * a0 has the clock value
+ */
+       .globl  ddrram_init
+       .ent    ddrram_init
+ddrram_init:
+       
+       /* DDR-DRAM Initialization
+        */
+       li      t1, MC_MODUL_BASE
+
+       /* Clear Error log registers */
+       sw      zero, MC_ERRCAUSE(t1)
+       sw      zero, MC_ERRADDR(t1)
+       
+       /* Enable DDR module in memory controller */
+       li      t3, MC_DDRRAM_ENABLE
+       lw      t2, MC_CON(t1)
+       or      t3, t2, t3
+       sw      t3, MC_CON(t1)
+       
+       li      t1, MC_DDR_MODUL_BASE
+       
+    /* Write configuration to DDR controller registers */
+       li      t2, MC_DC0_VALUE
+       sw      t2, MC_DC00(t1)
+     
+       li      t2, MC_DC1_VALUE
+       sw      t2, MC_DC01(t1)
+
+       li      t2, MC_DC2_VALUE
+       sw      t2, MC_DC02(t1)
+
+       li      t2, MC_DC3_VALUE
+       sw      t2, MC_DC03(t1)
+
+       li      t2, MC_DC4_VALUE
+       sw      t2, MC_DC04(t1)
+
+       li      t2, MC_DC5_VALUE
+       sw      t2, MC_DC05(t1)
+
+       li      t2, MC_DC6_VALUE
+       sw      t2, MC_DC06(t1)
+       
+       li      t2, MC_DC7_VALUE
+       sw      t2, MC_DC07(t1)
+       
+       li      t2, MC_DC8_VALUE
+       sw      t2, MC_DC08(t1)
+       
+       li      t2, MC_DC9_VALUE
+       sw      t2, MC_DC09(t1)
+       
+       li      t2, MC_DC10_VALUE
+       sw      t2, MC_DC10(t1)
+
+       li      t2, MC_DC11_VALUE
+       sw      t2, MC_DC11(t1)
+
+       li      t2, MC_DC12_VALUE
+       sw      t2, MC_DC12(t1)
+
+       li      t2, MC_DC13_VALUE
+       sw      t2, MC_DC13(t1)
+
+       li      t2, MC_DC14_VALUE
+       sw      t2, MC_DC14(t1)
+
+       li      t2, MC_DC15_VALUE
+       sw      t2, MC_DC15(t1)
+
+       li      t2, MC_DC16_VALUE
+       sw      t2, MC_DC16(t1)
+
+       li      t2, MC_DC17_VALUE
+       sw      t2, MC_DC17(t1)
+
+       li      t2, MC_DC18_VALUE
+       sw      t2, MC_DC18(t1)
+
+       li      t2, MC_DC19_VALUE
+       sw      t2, MC_DC19(t1)
+
+       li      t2, MC_DC20_VALUE
+       sw      t2, MC_DC20(t1)
+
+       li      t2, MC_DC21_VALUE
+       sw      t2, MC_DC21(t1)
+
+       li      t2, MC_DC22_VALUE
+       sw      t2, MC_DC22(t1)
+
+       li      t2, MC_DC23_VALUE
+       sw      t2, MC_DC23(t1)
+
+       li      t2, MC_DC24_VALUE
+       sw      t2, MC_DC24(t1)
+
+       li      t2, MC_DC25_VALUE
+       sw      t2, MC_DC25(t1)
+
+       li      t2, MC_DC26_VALUE
+       sw      t2, MC_DC26(t1)
+
+       li      t2, MC_DC27_VALUE
+       sw      t2, MC_DC27(t1)
+
+       li      t2, MC_DC28_VALUE
+       sw      t2, MC_DC28(t1)
+
+       li      t2, MC_DC29_VALUE
+       sw      t2, MC_DC29(t1)
+
+       li      t2, MC_DC30_VALUE
+       sw      t2, MC_DC30(t1)
+
+       li      t2, MC_DC31_VALUE
+       sw      t2, MC_DC31(t1)
+
+       li      t2, MC_DC32_VALUE
+       sw      t2, MC_DC32(t1)
+
+       li      t2, MC_DC33_VALUE
+       sw      t2, MC_DC33(t1)
+
+       li      t2, MC_DC34_VALUE
+       sw      t2, MC_DC34(t1)
+
+       li      t2, MC_DC35_VALUE
+       sw      t2, MC_DC35(t1)
+
+       li      t2, MC_DC36_VALUE
+       sw      t2, MC_DC36(t1)
+
+       li      t2, MC_DC37_VALUE
+       sw      t2, MC_DC37(t1)
+
+       li      t2, MC_DC38_VALUE
+       sw      t2, MC_DC38(t1)
+
+       li      t2, MC_DC39_VALUE
+       sw      t2, MC_DC39(t1)
+
+       li      t2, MC_DC40_VALUE
+       sw      t2, MC_DC40(t1)
+
+       li      t2, MC_DC41_VALUE
+       sw      t2, MC_DC41(t1)
+
+       li      t2, MC_DC42_VALUE
+       sw      t2, MC_DC42(t1)
+
+       li      t2, MC_DC43_VALUE
+       sw      t2, MC_DC43(t1)
+
+       li      t2, MC_DC44_VALUE
+       sw      t2, MC_DC44(t1)
+    
+       li      t2, MC_DC45_VALUE
+       sw      t2, MC_DC45(t1)
+
+       li      t2, MC_DC46_VALUE
+       sw      t2, MC_DC46(t1)
+
+       li      t2, 0x00000100
+       sw      t2, MC_DC03(t1)
+
+       j       ra
+       nop
+
+
+       .end    ddrram_init
+
+       .globl  lowlevel_init
+       .ent    lowlevel_init
+lowlevel_init:
+       /* EBU, CGU and SDRAM/DDR-RAM Initialization.
+        */
+       move    t0, ra
+       /* We rely on the fact that neither cgu_init() nor sdram_init()
+        * modify t0
+        */
+#ifdef DANUBE_BOOT_FROM_EBU 
+#ifdef DANUBE_DDR_RAM_166M
+//05252006
+  /* 0xe8 means CPU0/CPU1 333M, DDR 167M, FPI 83M, PPE 240M */
+        li  a0,0xe8
+        bal cgu_init
+        nop
+#endif
+#ifdef PROMOSDDR400
+        li  a0,0xe8
+        bal cgu_init
+        nop
+#endif
+#ifdef DDR_SAMSUNG_166M
+        li  a0,0xe8
+        bal cgu_init
+        nop
+#endif
+#ifdef DDR_PSC_166M
+       li  a0,0xe8
+       bal cgu_init
+       nop
+#endif
+#ifdef  DANUBE_DDR_RAM_133M
+        li  a0,0xe9
+//05252006
+       bal     cgu_init
+       nop
+#endif
+#endif
+/*TODO:liupeng add this define !!!! */
+/*
+  #define DANUBE_BOOT_FROM_EBU
+  #define DANUBE_USE_DDR_RAM
+*/
+
+//06063001-joelin disable the PCI CFRAME mask-start
+#ifdef DISABLE_CFRAME
+       li  t1, PCI_CR_PCI      //mw bf103034 80000000
+       li  t2, 0x80000000
+       sw      t2,0(t1)
+
+       li  t1, PCI_CR_PCI_MOD_REG      //mw be105430 103
+       li  t2, 0x103
+       sw  t2,0(t1)
+       
+       li  t1, CS_CFM                  //mw b700006c 0 
+       li  t2, 0x00
+       sw  t2, 0(t1)           
+       
+       li  t1, PCI_CR_PCI_MOD_REG      //mw be105430 103
+       li  t2, 0x1000103
+       sw  t2, 0(t1)   
+#endif 
+//06063001-joelin disable the PCI CFRAME mask-end
+
+#ifdef DANUBE_BOOT_FROM_EBU
+#ifdef DANUBE_USE_DDR_RAM
+       bal     ddrram_init
+       nop
+#else
+       bal     sdram_init
+       nop
+#endif
+#endif
+
+       move    ra, t0
+       j       ra
+       nop
+
+       .end    lowlevel_init
diff --git a/package/uboot-ifxmips/files/board/danube/pmuenable.S b/package/uboot-ifxmips/files/board/danube/pmuenable.S
new file mode 100644 (file)
index 0000000..e0d7971
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Power Management unit initialization code for AMAZON development board.
+ *
+ *  Copyright (c) 2003 Ou Ke, Infineon.
+ *
+ * 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/regdef.h>
+
+#define PMU_PWDCR              0xBF10201C
+#define PMU_SR                 0xBF102020
+
+       .globl  pmuenable
+
+pmuenable:
+       li      t0, PMU_PWDCR
+       li      t1, 0x2         /* enable everything */
+       sw      t1, 0(t0)
+#if 0
+1:
+       li      t0, PMU_SR
+       lw      t2, 0(t0)
+       bne     t1, t2, 1b
+       nop
+#endif
+       j       ra
+       nop
+
+
diff --git a/package/uboot-ifxmips/files/board/danube/u-boot-bootstrap.lds b/package/uboot-ifxmips/files/board/danube/u-boot-bootstrap.lds
new file mode 100644 (file)
index 0000000..8738ca8
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk Engineering, <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-bigmips")
+*/
+OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips")
+OUTPUT_ARCH(mips)
+ENTRY(_start_bootstrap)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+       .text       :
+       {
+         *(.text)
+       }
+
+        . = ALIGN(4);
+        .rodata  : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data  : { *(.data) }
+
+       . = ALIGN(4);
+       .sdata  : { *(.sdata) }
+
+       _gp = ALIGN(16);
+
+       __got_start_bootstrap = .;
+       .got  : { *(.got) }
+       __got_end_bootstrap = .;
+
+       .sdata  : { *(.sdata) }
+
+       . = .;
+       __u_boot_cmd_start_bootstrap = .;
+       .u_boot_cmd : { *(.u_boot_cmd) }
+       __u_boot_cmd_end_bootstrap = .;
+
+       uboot_end_data_bootstrap = .;
+       num_got_entries = (__got_end_bootstrap - __got_start_bootstrap) >> 2;
+
+        . = ALIGN(4);
+       .sbss  : { *(.sbss) }
+        .bss  : { *(.bss) }
+       uboot_end_bootstrap = .;
+}
diff --git a/package/uboot-ifxmips/files/board/danube/u-boot.lds b/package/uboot-ifxmips/files/board/danube/u-boot.lds
new file mode 100644 (file)
index 0000000..ad3ec31
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk Engineering, <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-bigmips")
+*/
+OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips")
+OUTPUT_ARCH(mips)
+ENTRY(_start)
+SECTIONS
+{
+        . = 0x00000000;
+
+        . = ALIGN(4);
+       .text       :
+       {
+         *(.text)
+       }
+
+        . = ALIGN(4);
+        .rodata  : { *(.rodata) }
+
+        . = ALIGN(4);
+        .data  : { *(.data) }
+
+       . = ALIGN(4);
+       .sdata  : { *(.sdata) }
+
+       _gp = ALIGN(16);
+
+       __got_start = .;
+       .got  : { *(.got) }
+       __got_end = .;
+
+       .sdata  : { *(.sdata) }
+
+       . = .;
+        __u_boot_cmd_start = .;
+        .u_boot_cmd : { *(.u_boot_cmd) }
+        __u_boot_cmd_end = .;
+
+       uboot_end_data = .;
+       num_got_entries = (__got_end - __got_start) >> 2;
+
+        . = ALIGN(4);
+       .sbss  : { *(.sbss) }
+        .bss  : { *(.bss) }
+       uboot_end = .;
+}
diff --git a/package/uboot-ifxmips/files/common/flash_danube.c b/package/uboot-ifxmips/files/common/flash_danube.c
new file mode 100644 (file)
index 0000000..a64bc98
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * (C) Copyright 2000
+ * 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
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <flash.h>
+
+#if !defined(CFG_NO_FLASH)
+
+extern flash_info_t  flash_info[]; /* info for FLASH chips */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+
+/*-----------------------------------------------------------------------
+ * Set protection status for monitor sectors
+ *
+ * The monitor is always located in the _first_ Flash bank.
+ * If necessary you have to map the second bank at lower addresses.
+ */
+void
+flash_protect (int flag, ulong from, ulong to, flash_info_t *info)
+{
+       ulong b_end = info->start[0] + info->size - 1;  /* bank end address */
+       short s_end = info->sector_count - 1;   /* index of last sector */
+       int i;
+
+       debug ("flash_protect %s: from 0x%08lX to 0x%08lX\n",
+               (flag & FLAG_PROTECT_SET) ? "ON" :
+                       (flag & FLAG_PROTECT_CLEAR) ? "OFF" : "???",
+               from, to);
+
+       /* Do nothing if input data is bad. */
+       if (info->sector_count == 0 || info->size == 0 || to < from) {
+               return;
+       }
+
+       /* There is nothing to do if we have no data about the flash
+        * or the protect range and flash range don't overlap.
+        */
+       if (info->flash_id == FLASH_UNKNOWN ||
+           to < info->start[0] || from > b_end) {
+               return;
+       }
+
+       for (i=0; i<info->sector_count; ++i) {
+               ulong end;              /* last address in current sect */
+
+               end = (i == s_end) ? b_end : info->start[i + 1] - 1;
+
+               /* Update protection if any part of the sector
+                * is in the specified range.
+                */
+               if (from <= end && to >= info->start[i]) {
+                       if (flag & FLAG_PROTECT_CLEAR) {
+#if defined(CFG_FLASH_PROTECTION)
+                               flash_real_protect(info, i, 0);
+#else
+                               info->protect[i] = 0;
+#endif /* CFG_FLASH_PROTECTION */
+                               debug ("protect off %d\n", i);
+                       }
+                       else if (flag & FLAG_PROTECT_SET) {
+#if defined(CFG_FLASH_PROTECTION)
+                               flash_real_protect(info, i, 1);
+#else
+                               info->protect[i] = 1;
+#endif /* CFG_FLASH_PROTECTION */
+                               debug ("protect on %d\n", i);
+                       }
+               }
+       }
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+flash_info_t *
+addr2info (ulong addr)
+{
+#ifndef CONFIG_SPD823TS
+       flash_info_t *info;
+       int i;
+
+       for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
+               if (info->flash_id != FLASH_UNKNOWN &&
+                   addr >= info->start[0] &&
+                   /* WARNING - The '- 1' is needed if the flash
+                    * is at the end of the address space, since
+                    * info->start[0] + info->size wraps back to 0.
+                    * Please don't change this unless you understand this.
+                    */
+                   addr <= info->start[0] + info->size - 1) {
+                       return (info);
+               }
+       }
+#endif /* CONFIG_SPD823TS */
+
+       return (NULL);
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ * Make sure all target addresses are within Flash bounds,
+ * and no protected sectors are hit.
+ * Returns:
+ * ERR_OK          0 - OK
+ * ERR_TIMOUT      1 - write timeout
+ * ERR_NOT_ERASED  2 - Flash not erased
+ * ERR_PROTECTED   4 - target range includes protected sectors
+ * ERR_INVAL       8 - target address not in Flash memory
+ * ERR_ALIGN       16 - target address not aligned on boundary
+ *                     (only some targets require alignment)
+ */
+int
+flash_write (char *src, ulong addr, ulong cnt)
+{
+#ifdef CONFIG_SPD823TS
+       return (ERR_TIMOUT);    /* any other error codes are possible as well */
+#else
+       int i;
+       ulong         end        = addr + cnt - 1;
+       flash_info_t *info_first = addr2info (addr);
+       flash_info_t *info_last  = addr2info (end );
+       flash_info_t *info;
+
+       if (cnt == 0) {
+               return (ERR_OK);
+       }
+
+       if (!info_first || !info_last) {
+               return (ERR_INVAL);
+       }
+
+       for (info = info_first; info <= info_last; ++info) {
+               ulong b_end = info->start[0] + info->size;      /* bank end addr */
+               short s_end = info->sector_count - 1;
+               for (i=0; i<info->sector_count; ++i) {
+                       ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
+
+                       if ((end >= info->start[i]) && (addr < e_addr) &&
+                           (info->protect[i] != 0) ) {
+                               return (ERR_PROTECTED);
+                       }
+               }
+       }
+
+       /* finally write data to flash */
+       for (info = info_first; info <= info_last && cnt>0; ++info) {
+               ulong len;
+
+               len = info->start[0] + info->size - addr;
+               if (len > cnt)
+                       len = cnt;
+               if ((i = write_buff(info, (uchar *)src, addr, len)) != 0) {
+                       return (i);
+               }
+               cnt  -= len;
+               addr += len;
+               src  += len;
+       }
+       return (ERR_OK);
+#endif /* CONFIG_SPD823TS */
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+void flash_perror (int err)
+{
+       switch (err) {
+       case ERR_OK:
+               break;
+       case ERR_TIMOUT:
+               puts ("Timeout writing to Flash\n");
+               break;
+       case ERR_NOT_ERASED:
+               puts ("Flash not Erased\n");
+               break;
+       case ERR_PROTECTED:
+               puts ("Can't write to protected Flash sectors\n");
+               break;
+       case ERR_INVAL:
+               puts ("Outside available Flash\n");
+               break;
+       case ERR_ALIGN:
+               puts ("Start and/or end address not on sector boundary\n");
+               break;
+       case ERR_UNKNOWN_FLASH_VENDOR:
+               puts ("Unknown Vendor of Flash\n");
+               break;
+       case ERR_UNKNOWN_FLASH_TYPE:
+               puts ("Unknown Type of Flash\n");
+               break;
+       case ERR_PROG_ERROR:
+               puts ("General Flash Programming Error\n");
+               break;
+       default:
+               printf ("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
+               break;
+       }
+}
+
+/*-----------------------------------------------------------------------
+ */
+#endif /* !CFG_NO_FLASH */
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/Makefile b/package/uboot-ifxmips/files/cpu/mips/danube/Makefile
new file mode 100644 (file)
index 0000000..da329b3
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2003-2006
+# 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    = $(obj)lib$(CPU).a
+
+START  = start.o
+COBJS  = asc_serial.o au1x00_serial.o au1x00_eth.o au1x00_usb_ohci.o \
+         cpu.o interrupts.o incaip_clock.o ifx_asc.o ifx_clock.o
+SOBJS  = incaip_wdt.o cache.o
+
+SRCS   := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START  := $(addprefix $(obj),$(START))
+
+all:   $(obj).depend $(START) $(LIB)
+
+$(LIB):        $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/asc_serial.c b/package/uboot-ifxmips/files/cpu/mips/danube/asc_serial.c
new file mode 100644 (file)
index 0000000..d95ec3f
--- /dev/null
@@ -0,0 +1,371 @@
+/*
+ * (INCA) ASC UART support
+ */
+
+#include <config.h>
+
+#if defined(CONFIG_PURPLE) || defined(CONFIG_INCA_IP)
+
+#ifdef CONFIG_PURPLE
+#define        serial_init     asc_serial_init
+#define        serial_putc     asc_serial_putc
+#define        serial_puts     asc_serial_puts
+#define        serial_getc     asc_serial_getc
+#define        serial_tstc     asc_serial_tstc
+#define        serial_setbrg   asc_serial_setbrg
+#endif
+
+#include <common.h>
+#include <asm/inca-ip.h>
+#include "asc_serial.h"
+
+#ifdef CONFIG_PURPLE
+
+#undef ASC_FIFO_PRESENT
+#define TOUT_LOOP      100000
+
+/* Set base address for second FPI interrupt control register bank */
+#define SFPI_INTCON_BASEADDR   0xBF0F0000
+
+/* Register offset from base address */
+#define FBS_ISR                0x00000000      /* Interrupt status register */
+#define FBS_IMR                0x00000008      /* Interrupt mask register */
+#define FBS_IDIS       0x00000010      /* Interrupt disable register */
+
+/* Interrupt status register bits */
+#define FBS_ISR_AT     0x00000040      /* ASC transmit interrupt */
+#define FBS_ISR_AR     0x00000020      /* ASC receive interrupt */
+#define FBS_ISR_AE     0x00000010      /* ASC error interrupt */
+#define FBS_ISR_AB     0x00000008      /* ASC transmit buffer interrupt */
+#define FBS_ISR_AS      0x00000004     /* ASC start of autobaud detection interrupt */
+#define FBS_ISR_AF     0x00000002      /* ASC end of autobaud detection interrupt */
+
+#else
+
+#define ASC_FIFO_PRESENT
+
+#endif
+
+
+#define SET_BIT(reg, mask)                  reg |= (mask)
+#define CLEAR_BIT(reg, mask)                reg &= (~mask)
+#define CLEAR_BITS(reg, mask)               CLEAR_BIT(reg, mask)
+#define SET_BITS(reg, mask)                 SET_BIT(reg, mask)
+#define SET_BITFIELD(reg, mask, off, val)   {reg &= (~mask); reg |= (val << off);}
+
+extern uint incaip_get_fpiclk(void);
+
+static int serial_setopt (void);
+
+/* pointer to ASC register base address */
+static volatile incaAsc_t *pAsc = (incaAsc_t *)INCA_IP_ASC;
+
+/******************************************************************************
+*
+* serial_init - initialize a INCAASC channel
+*
+* This routine initializes the number of data bits, parity
+* and set the selected baud rate. Interrupts are disabled.
+* Set the modem control signals if the option is selected.
+*
+* RETURNS: N/A
+*/
+
+int serial_init (void)
+{
+#ifdef CONFIG_INCA_IP
+    /* we have to set PMU.EN13 bit to enable an ASC device*/
+    INCAASC_PMU_ENABLE(13);
+#endif
+
+    /* and we have to set CLC register*/
+    CLEAR_BIT(pAsc->asc_clc, ASCCLC_DISS);
+    SET_BITFIELD(pAsc->asc_clc, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 0x0001);
+
+    /* initialy we are in async mode */
+    pAsc->asc_con = ASCCON_M_8ASYNC;
+
+    /* select input port */
+    pAsc->asc_pisel = (CONSOLE_TTY & 0x1);
+
+#ifdef ASC_FIFO_PRESENT
+    /* TXFIFO's filling level */
+    SET_BITFIELD(pAsc->asc_txfcon, ASCTXFCON_TXFITLMASK,
+                   ASCTXFCON_TXFITLOFF, INCAASC_TXFIFO_FL);
+    /* enable TXFIFO */
+    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXFEN);
+
+    /* RXFIFO's filling level */
+    SET_BITFIELD(pAsc->asc_txfcon, ASCRXFCON_RXFITLMASK,
+                   ASCRXFCON_RXFITLOFF, INCAASC_RXFIFO_FL);
+    /* enable RXFIFO */
+    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXFEN);
+#endif
+
+    /* enable error signals */
+    SET_BIT(pAsc->asc_con, ASCCON_FEN);
+    SET_BIT(pAsc->asc_con, ASCCON_OEN);
+
+#ifdef CONFIG_INCA_IP
+    /* acknowledge ASC interrupts */
+    ASC_INTERRUPTS_CLEAR(INCAASC_IRQ_LINE_ALL);
+
+    /* disable ASC interrupts */
+    ASC_INTERRUPTS_DISABLE(INCAASC_IRQ_LINE_ALL);
+#endif
+
+#ifdef ASC_FIFO_PRESENT
+    /* set FIFOs into the transparent mode */
+    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXTMEN);
+    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXTMEN);
+#endif
+
+    /* set baud rate */
+    serial_setbrg();
+
+    /* set the options */
+    serial_setopt();
+
+    return 0;
+}
+
+void serial_setbrg (void)
+{
+    ulong      uiReloadValue, fdv;
+    ulong      f_ASC;
+
+#ifdef CONFIG_INCA_IP
+    f_ASC = incaip_get_fpiclk();
+#else
+    f_ASC = ASC_CLOCK_RATE;
+#endif
+
+#ifndef INCAASC_USE_FDV
+    fdv = 2;
+    uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
+#else
+    fdv = INCAASC_FDV_HIGH_BAUDRATE;
+    uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
+#endif /* INCAASC_USE_FDV */
+
+    if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
+    {
+#ifndef INCAASC_USE_FDV
+       fdv = 3;
+       uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1;
+#else
+       fdv = INCAASC_FDV_LOW_BAUDRATE;
+       uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1;
+#endif /* INCAASC_USE_FDV */
+
+       if ( (uiReloadValue < 0) || (uiReloadValue > 8191) )
+       {
+           return;    /* can't impossibly generate that baud rate */
+       }
+    }
+
+    /* Disable Baud Rate Generator; BG should only be written when R=0 */
+    CLEAR_BIT(pAsc->asc_con, ASCCON_R);
+
+#ifndef INCAASC_USE_FDV
+    /*
+     * Disable Fractional Divider (FDE)
+     * Divide clock by reload-value + constant (BRS)
+     */
+    /* FDE = 0 */
+    CLEAR_BIT(pAsc->asc_con, ASCCON_FDE);
+
+    if ( fdv == 2 )
+       CLEAR_BIT(pAsc->asc_con, ASCCON_BRS);   /* BRS = 0 */
+    else
+       SET_BIT(pAsc->asc_con, ASCCON_BRS); /* BRS = 1 */
+
+#else /* INCAASC_USE_FDV */
+
+    /* Enable Fractional Divider */
+    SET_BIT(pAsc->asc_con, ASCCON_FDE); /* FDE = 1 */
+
+    /* Set fractional divider value */
+    pAsc->asc_fdv = fdv & ASCFDV_VALUE_MASK;
+
+#endif /* INCAASC_USE_FDV */
+
+    /* Set reload value in BG */
+    pAsc->asc_bg = uiReloadValue;
+
+    /* Enable Baud Rate Generator */
+    SET_BIT(pAsc->asc_con, ASCCON_R);           /* R = 1 */
+}
+
+/*******************************************************************************
+*
+* serial_setopt - set the serial options
+*
+* Set the channel operating mode to that specified. Following options
+* are supported: CREAD, CSIZE, PARENB, and PARODD.
+*
+* Note, this routine disables the transmitter.  The calling routine
+* may have to re-enable it.
+*
+* RETURNS:
+* Returns 0 to indicate success, otherwise -1 is returned
+*/
+
+static int serial_setopt (void)
+{
+    ulong  con;
+
+    switch ( ASC_OPTIONS & ASCOPT_CSIZE )
+    {
+    /* 7-bit-data */
+    case ASCOPT_CS7:
+       con = ASCCON_M_7ASYNCPAR;   /* 7-bit-data and parity bit */
+       break;
+
+    /* 8-bit-data */
+    case ASCOPT_CS8:
+       if ( ASC_OPTIONS & ASCOPT_PARENB )
+           con = ASCCON_M_8ASYNCPAR;   /* 8-bit-data and parity bit */
+       else
+           con = ASCCON_M_8ASYNC;      /* 8-bit-data no parity */
+       break;
+
+    /*
+     *  only 7 and 8-bit frames are supported
+     *  if we don't use IOCTL extensions
+     */
+    default:
+       return -1;
+    }
+
+    if ( ASC_OPTIONS & ASCOPT_STOPB )
+       SET_BIT(con, ASCCON_STP);       /* 2 stop bits */
+    else
+       CLEAR_BIT(con, ASCCON_STP);     /* 1 stop bit */
+
+    if ( ASC_OPTIONS & ASCOPT_PARENB )
+       SET_BIT(con, ASCCON_PEN);           /* enable parity checking */
+    else
+       CLEAR_BIT(con, ASCCON_PEN);         /* disable parity checking */
+
+    if ( ASC_OPTIONS & ASCOPT_PARODD )
+       SET_BIT(con, ASCCON_ODD);       /* odd parity */
+    else
+       CLEAR_BIT(con, ASCCON_ODD);     /* even parity */
+
+    if ( ASC_OPTIONS & ASCOPT_CREAD )
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_SETREN); /* Receiver enable */
+
+    pAsc->asc_con |= con;
+
+    return 0;
+}
+
+void serial_putc (const char c)
+{
+#ifdef ASC_FIFO_PRESENT
+    uint txFl = 0;
+#else
+    uint timeout = 0;
+#endif
+
+    if (c == '\n') serial_putc ('\r');
+
+#ifdef ASC_FIFO_PRESENT
+    /* check do we have a free space in the TX FIFO */
+    /* get current filling level */
+    do
+    {
+       txFl = ( pAsc->asc_fstat & ASCFSTAT_TXFFLMASK ) >> ASCFSTAT_TXFFLOFF;
+    }
+    while ( txFl == INCAASC_TXFIFO_FULL );
+#else
+
+    while(!(*(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) &
+                          FBS_ISR_AB))
+    {
+           if (timeout++ > TOUT_LOOP)
+           {
+                   break;
+           }
+    }
+#endif
+
+    pAsc->asc_tbuf = c; /* write char to Transmit Buffer Register */
+
+#ifndef ASC_FIFO_PRESENT
+    *(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) = FBS_ISR_AB |
+                                                                FBS_ISR_AT;
+#endif
+
+    /* check for errors */
+    if ( pAsc->asc_con & ASCCON_OE )
+    {
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
+       return;
+    }
+}
+
+void serial_puts (const char *s)
+{
+    while (*s)
+    {
+       serial_putc (*s++);
+    }
+}
+
+int serial_getc (void)
+{
+    ulong symbol_mask;
+    char c;
+
+    while (!serial_tstc());
+
+    symbol_mask =
+       ((ASC_OPTIONS & ASCOPT_CSIZE) == ASCOPT_CS7) ? (0x7f) : (0xff);
+
+    c = (char)(pAsc->asc_rbuf & symbol_mask);
+
+#ifndef ASC_FIFO_PRESENT
+    *(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) = FBS_ISR_AR;
+#endif
+
+    return c;
+}
+
+int serial_tstc (void)
+{
+    int res = 1;
+
+#ifdef ASC_FIFO_PRESENT
+    if ( (pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 )
+    {
+       res = 0;
+    }
+#else
+    if (!(*(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) &
+                                                               FBS_ISR_AR))
+
+    {
+       res = 0;
+    }
+#endif
+    else if ( pAsc->asc_con & ASCCON_FE )
+    {
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRFE);
+       res = 0;
+    }
+    else if ( pAsc->asc_con & ASCCON_PE )
+    {
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRPE);
+       res = 0;
+    }
+    else if ( pAsc->asc_con & ASCCON_OE )
+    {
+       SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
+       res = 0;
+    }
+
+    return res;
+}
+#endif /* CONFIG_PURPLE || CONFIG_INCA_IP */
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/asc_serial.h b/package/uboot-ifxmips/files/cpu/mips/danube/asc_serial.h
new file mode 100644 (file)
index 0000000..7ffdcfa
--- /dev/null
@@ -0,0 +1,177 @@
+/* incaAscSio.h - (INCA) ASC UART tty driver header */
+
+#ifndef __INCincaAscSioh
+#define __INCincaAscSioh
+
+#include <asm/inca-ip.h>
+
+/* channel operating modes */
+#define        ASCOPT_CSIZE    0x00000003
+#define        ASCOPT_CS7      0x00000001
+#define        ASCOPT_CS8      0x00000002
+#define        ASCOPT_PARENB   0x00000004
+#define        ASCOPT_STOPB    0x00000008
+#define        ASCOPT_PARODD   0x00000010
+#define        ASCOPT_CREAD    0x00000020
+
+#define ASC_OPTIONS            (ASCOPT_CREAD | ASCOPT_CS8)
+
+/* ASC input select (0 or 1) */
+#define CONSOLE_TTY    0
+
+/* use fractional divider for baudrate settings */
+#define INCAASC_USE_FDV
+
+#ifdef INCAASC_USE_FDV
+   #define INCAASC_FDV_LOW_BAUDRATE        71
+   #define INCAASC_FDV_HIGH_BAUDRATE       453
+#endif /*INCAASC_USE_FDV*/
+
+
+#define INCAASC_TXFIFO_FL       1
+#define INCAASC_RXFIFO_FL       1
+#define INCAASC_TXFIFO_FULL     16
+
+/* interrupt lines masks for the ASC device interrupts*/
+/* change these macroses if it's necessary */
+#define INCAASC_IRQ_LINE_ALL        0x000F0000  /* all IRQs */
+
+#define INCAASC_IRQ_LINE_TIR            0x00010000      /* TIR - Tx */
+#define INCAASC_IRQ_LINE_RIR            0x00020000      /* RIR - Rx */
+#define INCAASC_IRQ_LINE_EIR            0x00040000      /* EIR - Err */
+#define INCAASC_IRQ_LINE_TBIR           0x00080000      /* TBIR - Tx Buf*/
+
+/* interrupt controller access macros */
+#define ASC_INTERRUPTS_ENABLE(X)  \
+   *((volatile unsigned int*) INCA_IP_ICU_IM2_IER) |= X;
+#define ASC_INTERRUPTS_DISABLE(X) \
+   *((volatile unsigned int*) INCA_IP_ICU_IM2_IER) &= ~X;
+#define ASC_INTERRUPTS_CLEAR(X)   \
+   *((volatile unsigned int*) INCA_IP_ICU_IM2_ISR) = X;
+
+/* CLC register's bits and bitfields */
+#define ASCCLC_DISR        0x00000001
+#define ASCCLC_DISS        0x00000002
+#define ASCCLC_RMCMASK     0x0000FF00
+#define ASCCLC_RMCOFFSET   8
+
+/* CON register's bits and bitfields */
+#define ASCCON_MODEMASK 0x0007
+    #define ASCCON_M_8SYNC          0x0
+    #define ASCCON_M_8ASYNC         0x1
+    #define ASCCON_M_8IRDAASYNC     0x2
+    #define ASCCON_M_7ASYNCPAR      0x3
+    #define ASCCON_M_9ASYNC         0x4
+    #define ASCCON_M_8WAKEUPASYNC   0x5
+    #define ASCCON_M_8ASYNCPAR      0x7
+#define ASCCON_STP      0x0008
+#define ASCCON_REN      0x0010
+#define ASCCON_PEN      0x0020
+#define ASCCON_FEN      0x0040
+#define ASCCON_OEN      0x0080
+#define ASCCON_PE       0x0100
+#define ASCCON_FE       0x0200
+#define ASCCON_OE       0x0400
+#define ASCCON_FDE      0x0800
+#define ASCCON_ODD      0x1000
+#define ASCCON_BRS      0x2000
+#define ASCCON_LB       0x4000
+#define ASCCON_R        0x8000
+
+/* WHBCON register's bits and bitfields */
+#define ASCWHBCON_CLRREN    0x0010
+#define ASCWHBCON_SETREN    0x0020
+#define ASCWHBCON_CLRPE     0x0100
+#define ASCWHBCON_CLRFE     0x0200
+#define ASCWHBCON_CLROE     0x0400
+#define ASCWHBCON_SETPE     0x0800
+#define ASCWHBCON_SETFE     0x1000
+#define ASCWHBCON_SETOE     0x2000
+
+/* ABCON register's bits and bitfields */
+#define ASCABCON_ABEN       0x0001
+#define ASCABCON_AUREN      0x0002
+#define ASCABCON_ABSTEN     0x0004
+#define ASCABCON_ABDETEN    0x0008
+#define ASCABCON_FCDETEN    0x0010
+#define ASCABCON_EMMASK     0x0300
+    #define ASCABCON_EMOFF          8
+       #define ASCABCON_EM_DISAB       0x0
+       #define ASCABCON_EM_DURAB       0x1
+       #define ASCABCON_EM_ALWAYS      0x2
+#define ASCABCON_TXINV      0x0400
+#define ASCABCON_RXINV      0x0800
+
+/* FDV register mask, offset and bitfields*/
+#define ASCFDV_VALUE_MASK     0x000001FF
+
+/* WHBABCON register's bits and bitfields */
+#define ASCWHBABCON_SETABEN     0x0001
+#define ASCWHBABCON_CLRABEN     0x0002
+
+/* ABSTAT register's bits and bitfields */
+#define ASCABSTAT_FCSDET    0x0001
+#define ASCABSTAT_FCCDET    0x0002
+#define ASCABSTAT_SCSDET    0x0004
+#define ASCABSTAT_SCCDET    0x0008
+#define ASCABSTAT_DETWAIT   0x0010
+
+/* WHBABSTAT register's bits and bitfields */
+#define ASCWHBABSTAT_CLRFCSDET  0x0001
+#define ASCWHBABSTAT_SETFCSDET  0x0002
+#define ASCWHBABSTAT_CLRFCCDET  0x0004
+#define ASCWHBABSTAT_SETFCCDET  0x0008
+#define ASCWHBABSTAT_CLRSCSDET  0x0010
+#define ASCWHBABSTAT_SETSCSDET  0x0020
+#define ASCWHBABSTAT_SETSCCDET  0x0040
+#define ASCWHBABSTAT_CLRSCCDET  0x0080
+#define ASCWHBABSTAT_CLRDETWAIT 0x0100
+#define ASCWHBABSTAT_SETDETWAIT 0x0200
+
+/* TXFCON register's bits and bitfields */
+#define ASCTXFCON_TXFEN         0x0001
+#define ASCTXFCON_TXFFLU        0x0002
+#define ASCTXFCON_TXTMEN        0x0004
+#define ASCTXFCON_TXFITLMASK    0x3F00
+#define ASCTXFCON_TXFITLOFF     8
+
+/* RXFCON register's bits and bitfields */
+#define ASCRXFCON_RXFEN         0x0001
+#define ASCRXFCON_RXFFLU        0x0002
+#define ASCRXFCON_RXTMEN        0x0004
+#define ASCRXFCON_RXFITLMASK    0x3F00
+#define ASCRXFCON_RXFITLOFF     8
+
+/* FSTAT register's bits and bitfields */
+#define ASCFSTAT_RXFFLMASK      0x003F
+#define ASCFSTAT_TXFFLMASK      0x3F00
+#define ASCFSTAT_TXFFLOFF       8
+
+#define INCAASC_PMU_ENABLE(BIT) *((volatile ulong*)0xBF102000) |= (0x1 << BIT);
+
+typedef  struct         /* incaAsc_t */
+{
+    volatile unsigned long  asc_clc;                            /*0x0000*/
+    volatile unsigned long  asc_pisel;                          /*0x0004*/
+    volatile unsigned long  asc_rsvd1[2];   /* for mapping */   /*0x0008*/
+    volatile unsigned long  asc_con;                            /*0x0010*/
+    volatile unsigned long  asc_bg;                             /*0x0014*/
+    volatile unsigned long  asc_fdv;                            /*0x0018*/
+    volatile unsigned long  asc_pmw;        /* not used */      /*0x001C*/
+    volatile unsigned long  asc_tbuf;                           /*0x0020*/
+    volatile unsigned long  asc_rbuf;                           /*0x0024*/
+    volatile unsigned long  asc_rsvd2[2];   /* for mapping */   /*0x0028*/
+    volatile unsigned long  asc_abcon;                          /*0x0030*/
+    volatile unsigned long  asc_abstat;     /* not used */      /*0x0034*/
+    volatile unsigned long  asc_rsvd3[2];   /* for mapping */   /*0x0038*/
+    volatile unsigned long  asc_rxfcon;                         /*0x0040*/
+    volatile unsigned long  asc_txfcon;                         /*0x0044*/
+    volatile unsigned long  asc_fstat;                          /*0x0048*/
+    volatile unsigned long  asc_rsvd4;      /* for mapping */   /*0x004C*/
+    volatile unsigned long  asc_whbcon;                         /*0x0050*/
+    volatile unsigned long  asc_whbabcon;                       /*0x0054*/
+    volatile unsigned long  asc_whbabstat;  /* not used */      /*0x0058*/
+
+} incaAsc_t;
+
+#endif /* __INCincaAscSioh */
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/au1x00_eth.c b/package/uboot-ifxmips/files/cpu/mips/danube/au1x00_eth.c
new file mode 100644 (file)
index 0000000..078e832
--- /dev/null
@@ -0,0 +1,311 @@
+/* Only eth0 supported for now
+ *
+ * (C) Copyright 2003
+ * Thomas.Lange@corelatus.se
+ *
+ * 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>
+
+#ifdef CONFIG_AU1X00
+
+#if defined(CFG_DISCOVER_PHY)
+#error "PHY not supported yet"
+/* We just assume that we are running 100FD for now */
+/* We all use switches, right? ;-) */
+#endif
+
+/* I assume ethernet behaves like au1000 */
+
+#ifdef CONFIG_AU1000
+/* Base address differ between cpu:s */
+#define ETH0_BASE AU1000_ETH0_BASE
+#define MAC0_ENABLE AU1000_MAC0_ENABLE
+#else
+#ifdef CONFIG_AU1100
+#define ETH0_BASE AU1100_ETH0_BASE
+#define MAC0_ENABLE AU1100_MAC0_ENABLE
+#else
+#ifdef CONFIG_AU1500
+#define ETH0_BASE AU1500_ETH0_BASE
+#define MAC0_ENABLE AU1500_MAC0_ENABLE
+#else
+#ifdef CONFIG_AU1550
+#define ETH0_BASE AU1550_ETH0_BASE
+#define MAC0_ENABLE AU1550_MAC0_ENABLE
+#else
+#error "No valid cpu set"
+#endif
+#endif
+#endif
+#endif
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <command.h>
+#include <asm/io.h>
+#include <asm/au1x00.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII)
+#include <miiphy.h>
+#endif
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH  1520
+#define PKT_MAXBUF_SIZE                1518
+
+static char txbuf[DBUF_LENGTH];
+
+static int next_tx;
+static int next_rx;
+
+/* 4 rx and 4 tx fifos */
+#define NO_OF_FIFOS 4
+
+typedef struct{
+       u32 status;
+       u32 addr;
+       u32 len; /* Only used for tx */
+       u32 not_used;
+} mac_fifo_t;
+
+mac_fifo_t mac_fifo[NO_OF_FIFOS];
+
+#define MAX_WAIT 1000
+
+static int au1x00_send(struct eth_device* dev, volatile void *packet, int length){
+       volatile mac_fifo_t *fifo_tx =
+               (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS);
+       int i;
+       int res;
+
+       /* tx fifo should always be idle */
+       fifo_tx[next_tx].len = length;
+       fifo_tx[next_tx].addr = (virt_to_phys(packet))|TX_DMA_ENABLE;
+       au_sync();
+
+       udelay(1);
+       i=0;
+       while(!(fifo_tx[next_tx].addr&TX_T_DONE)){
+               if(i>MAX_WAIT){
+                       printf("TX timeout\n");
+                       break;
+               }
+               udelay(1);
+               i++;
+       }
+
+       /* Clear done bit */
+       fifo_tx[next_tx].addr = 0;
+       fifo_tx[next_tx].len = 0;
+       au_sync();
+
+       res = fifo_tx[next_tx].status;
+
+       next_tx++;
+       if(next_tx>=NO_OF_FIFOS){
+               next_tx=0;
+       }
+       return(res);
+}
+
+static int au1x00_recv(struct eth_device* dev){
+       volatile mac_fifo_t *fifo_rx =
+               (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS);
+
+       int length;
+       u32 status;
+
+       for(;;){
+               if(!(fifo_rx[next_rx].addr&RX_T_DONE)){
+                       /* Nothing has been received */
+                       return(-1);
+               }
+
+               status = fifo_rx[next_rx].status;
+
+               length = status&0x3FFF;
+
+               if(status&RX_ERROR){
+                       printf("Rx error 0x%x\n", status);
+               }
+               else{
+                       /* Pass the packet up to the protocol layers. */
+                       NetReceive(NetRxPackets[next_rx], length - 4);
+               }
+
+               fifo_rx[next_rx].addr = (virt_to_phys(NetRxPackets[next_rx]))|RX_DMA_ENABLE;
+
+               next_rx++;
+               if(next_rx>=NO_OF_FIFOS){
+                       next_rx=0;
+               }
+       } /* for */
+
+       return(0); /* Does anyone use this? */
+}
+
+static int au1x00_init(struct eth_device* dev, bd_t * bd){
+
+       volatile u32 *macen = (volatile u32*)MAC0_ENABLE;
+       volatile u32 *mac_ctrl = (volatile u32*)(ETH0_BASE+MAC_CONTROL);
+       volatile u32 *mac_addr_high = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_HIGH);
+       volatile u32 *mac_addr_low = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_LOW);
+       volatile u32 *mac_mcast_high = (volatile u32*)(ETH0_BASE+MAC_MCAST_HIGH);
+       volatile u32 *mac_mcast_low = (volatile u32*)(ETH0_BASE+MAC_MCAST_LOW);
+       volatile mac_fifo_t *fifo_tx =
+               (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS);
+       volatile mac_fifo_t *fifo_rx =
+               (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS);
+       int i;
+
+       next_tx = TX_GET_DMA_BUFFER(fifo_tx[0].addr);
+       next_rx = RX_GET_DMA_BUFFER(fifo_rx[0].addr);
+
+       /* We have to enable clocks before releasing reset */
+       *macen = MAC_EN_CLOCK_ENABLE;
+       udelay(10);
+
+       /* Enable MAC0 */
+       /* We have to release reset before accessing registers */
+       *macen = MAC_EN_CLOCK_ENABLE|MAC_EN_RESET0|
+               MAC_EN_RESET1|MAC_EN_RESET2;
+       udelay(10);
+
+       for(i=0;i<NO_OF_FIFOS;i++){
+               fifo_tx[i].len = 0;
+               fifo_tx[i].addr = virt_to_phys(&txbuf[0]);
+               fifo_rx[i].addr = (virt_to_phys(NetRxPackets[i]))|RX_DMA_ENABLE;
+       }
+
+       /* Put mac addr in little endian */
+#define ea eth_get_dev()->enetaddr
+       *mac_addr_high  =       (ea[5] <<  8) | (ea[4]      ) ;
+       *mac_addr_low   =       (ea[3] << 24) | (ea[2] << 16) |
+               (ea[1] <<  8) | (ea[0]      ) ;
+#undef ea
+       *mac_mcast_low = 0;
+       *mac_mcast_high = 0;
+
+       /* Make sure the MAC buffer is in the correct endian mode */
+#ifdef __LITTLE_ENDIAN
+       *mac_ctrl = MAC_FULL_DUPLEX;
+       udelay(1);
+       *mac_ctrl = MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE;
+#else
+       *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX;
+       udelay(1);
+       *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE;
+#endif
+
+       return(1);
+}
+
+static void au1x00_halt(struct eth_device* dev){
+}
+
+int au1x00_enet_initialize(bd_t *bis){
+       struct eth_device* dev;
+
+       if ((dev = (struct eth_device*)malloc(sizeof *dev)) == NULL) {
+               puts ("malloc failed\n");
+               return 0;
+       }
+
+       memset(dev, 0, sizeof *dev);
+
+       sprintf(dev->name, "Au1X00 ethernet");
+       dev->iobase = 0;
+       dev->priv   = 0;
+       dev->init   = au1x00_init;
+       dev->halt   = au1x00_halt;
+       dev->send   = au1x00_send;
+       dev->recv   = au1x00_recv;
+
+       eth_register(dev);
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII)
+       miiphy_register(dev->name,
+               au1x00_miiphy_read, au1x00_miiphy_write);
+#endif
+
+       return 1;
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII)
+int  au1x00_miiphy_read(char *devname, unsigned char addr,
+               unsigned char reg, unsigned short * value)
+{
+       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
+       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
+       u32 mii_control;
+       unsigned int timedout = 20;
+
+       while (*mii_control_reg & MAC_MII_BUSY) {
+               udelay(1000);
+               if (--timedout == 0) {
+                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
+                       return -1;
+               }
+       }
+
+       mii_control = MAC_SET_MII_SELECT_REG(reg) |
+               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_READ;
+
+       *mii_control_reg = mii_control;
+
+       timedout = 20;
+       while (*mii_control_reg & MAC_MII_BUSY) {
+               udelay(1000);
+               if (--timedout == 0) {
+                       printf("au1x00_eth: miiphy_read busy timeout!!\n");
+                       return -1;
+               }
+       }
+       *value = *mii_data_reg;
+       return 0;
+}
+
+int  au1x00_miiphy_write(char *devname, unsigned char addr,
+               unsigned char reg, unsigned short value)
+{
+       volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
+       volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
+       u32 mii_control;
+       unsigned int timedout = 20;
+
+       while (*mii_control_reg & MAC_MII_BUSY) {
+               udelay(1000);
+               if (--timedout == 0) {
+                       printf("au1x00_eth: miiphy_write busy timeout!!\n");
+                       return;
+               }
+       }
+
+       mii_control = MAC_SET_MII_SELECT_REG(reg) |
+               MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_WRITE;
+
+       *mii_data_reg = value;
+       *mii_control_reg = mii_control;
+       return 0;
+}
+#endif /* CONFIG_COMMANDS & CFG_CMD_MII */
+
+#endif /* CONFIG_AU1X00 */
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/au1x00_serial.c b/package/uboot-ifxmips/files/cpu/mips/danube/au1x00_serial.c
new file mode 100644 (file)
index 0000000..42c668e
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * AU1X00 UART support
+ *
+ * Hardcoded to UART 0 for now
+ * Speed and options also hardcoded to 115200 8N1
+ *
+ *  Copyright (c) 2003 Thomas.Lange@corelatus.se
+ *
+ * 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>
+
+#ifdef CONFIG_AU1X00
+
+#include <common.h>
+#include <asm/au1x00.h>
+
+/******************************************************************************
+*
+* serial_init - initialize a channel
+*
+* This routine initializes the number of data bits, parity
+* and set the selected baud rate. Interrupts are disabled.
+* Set the modem control signals if the option is selected.
+*
+* RETURNS: N/A
+*/
+
+int serial_init (void)
+{
+       volatile u32 *uart_fifoctl = (volatile u32*)(UART0_ADDR+UART_FCR);
+       volatile u32 *uart_enable = (volatile u32*)(UART0_ADDR+UART_ENABLE);
+
+       /* Enable clocks first */
+       *uart_enable = UART_EN_CE;
+
+       /* Then release reset */
+       /* Must release reset before setting other regs */
+       *uart_enable = UART_EN_CE|UART_EN_E;
+
+       /* Activate fifos, reset tx and rx */
+       /* Set tx trigger level to 12 */
+       *uart_fifoctl = UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|
+               UART_FCR_CLEAR_XMIT|UART_FCR_T_TRIGGER_12;
+
+       serial_setbrg();
+
+       return 0;
+}
+
+
+void serial_setbrg (void)
+{
+       volatile u32 *uart_clk = (volatile u32*)(UART0_ADDR+UART_CLK);
+       volatile u32 *uart_lcr = (volatile u32*)(UART0_ADDR+UART_LCR);
+       volatile u32 *sys_powerctrl = (u32 *)SYS_POWERCTRL;
+       int sd;
+       int divisorx2;
+
+       /* sd is system clock divisor                   */
+       /* see section 10.4.5 in au1550 datasheet       */
+       sd = (*sys_powerctrl & 0x03) + 2;
+
+       /* calulate 2x baudrate and round */
+       divisorx2 = ((CFG_HZ/(sd * 16 * CONFIG_BAUDRATE)));
+
+       if (divisorx2 & 0x01)
+               divisorx2 = divisorx2 + 1;
+
+       *uart_clk = divisorx2 / 2;
+
+       /* Set parity, stop bits and word length to 8N1 */
+       *uart_lcr = UART_LCR_WLEN8;
+}
+
+void serial_putc (const char c)
+{
+       volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR);
+       volatile u32 *uart_tx = (volatile u32*)(UART0_ADDR+UART_TX);
+
+       if (c == '\n') serial_putc ('\r');
+
+       /* Wait for fifo to shift out some bytes */
+       while((*uart_lsr&UART_LSR_THRE)==0);
+
+       *uart_tx = (u32)c;
+}
+
+void serial_puts (const char *s)
+{
+       while (*s)
+       {
+               serial_putc (*s++);
+       }
+}
+
+int serial_getc (void)
+{
+       volatile u32 *uart_rx = (volatile u32*)(UART0_ADDR+UART_RX);
+       char c;
+
+       while (!serial_tstc());
+
+       c = (*uart_rx&0xFF);
+       return c;
+}
+
+int serial_tstc (void)
+{
+       volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR);
+
+       if(*uart_lsr&UART_LSR_DR){
+               /* Data in rfifo */
+               return(1);
+       }
+       return 0;
+}
+#endif /* CONFIG_SERIAL_AU1X00 */
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/au1x00_usb_ohci.c b/package/uboot-ifxmips/files/cpu/mips/danube/au1x00_usb_ohci.c
new file mode 100644 (file)
index 0000000..dbf72dc
--- /dev/null
@@ -0,0 +1,1727 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB on the AU1x00.
+ *
+ * (C) Copyright 2003
+ * 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
+ *
+ * Note: Part of this code has been derived from linux
+ *
+ */
+/*
+ * 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 <config.h>
+
+#if defined(CONFIG_AU1X00) && defined(CONFIG_USB_OHCI)
+
+/* #include <pci.h> no PCI on the AU1x00 */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/au1x00.h>
+#include <usb.h>
+#include "au1x00_usb_ohci.h"
+
+#define OHCI_USE_NPS           /* force NoPowerSwitching mode */
+#define OHCI_VERBOSE_DEBUG     /* not always helpful */
+#define OHCI_FILL_TRACE
+
+#define USBH_ENABLE_BE (1<<0)
+#define USBH_ENABLE_C  (1<<1)
+#define USBH_ENABLE_E  (1<<2)
+#define USBH_ENABLE_CE (1<<3)
+#define USBH_ENABLE_RD (1<<4)
+
+#ifdef LITTLEENDIAN
+#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C)
+#else
+#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | USBH_ENABLE_BE)
+#endif
+
+
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+       (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
+#undef readl
+#undef writel
+
+#define readl(a)     au_readl((long)(a))
+#define writel(v,a)  au_writel((v),(int)(a))
+
+#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+
+#define 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)
+#define 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);
+
+       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 ((long)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 ((long)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 (1 || ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && usb_pipeout(urb_priv->pipe))) {
+               for (i = 0; i < len; i++)
+               printf("td->data[%d] %#2x\n",i, ((unsigned char *)(td->data+0x80000000))[i]);
+       }
+#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 */
+
+#define kseg_to_phys(x)          ((void *)((__u32)(x) - 0x80000000))
+
+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 = kseg_to_phys(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, kseg_to_phys(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);
+       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;
+
+       timeout *= 4;
+       /* 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) {
+                       udelay(250); /* 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 */
+
+       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 {
+               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);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#define __read_32bit_c0_register(source, sel)                          \
+({ int __res;                                                          \
+       if (sel == 0)                                                   \
+               __asm__ __volatile__(                                   \
+                       "mfc0\t%0, " #source "\n\t"                     \
+                       : "=r" (__res));                                \
+       else                                                            \
+               __asm__ __volatile__(                                   \
+                       ".set\tmips32\n\t"                              \
+                       "mfc0\t%0, " #source ", " #sel "\n\t"           \
+                       ".set\tmips0\n\t"                               \
+                       : "=r" (__res));                                \
+       __res;                                                          \
+})
+
+#define read_c0_prid()         __read_32bit_c0_register($15, 0)
+
+/*
+ * low level initalisation routine, called from usb.c
+ */
+static char ohci_inited = 0;
+
+int usb_lowlevel_init(void)
+{
+       u32 pin_func;
+       u32 sys_freqctrl, sys_clksrc;
+       u32 prid = read_c0_prid();
+
+       dbg("in usb_lowlevel_init\n");
+
+       /* zero and disable FREQ2 */
+       sys_freqctrl = au_readl(SYS_FREQCTRL0);
+       sys_freqctrl &= ~0xFFF00000;
+       au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+       /* zero and disable USBH/USBD clocks */
+       sys_clksrc = au_readl(SYS_CLKSRC);
+       sys_clksrc &= ~0x00007FE0;
+       au_writel(sys_clksrc, SYS_CLKSRC);
+
+       sys_freqctrl = au_readl(SYS_FREQCTRL0);
+       sys_freqctrl &= ~0xFFF00000;
+
+       sys_clksrc = au_readl(SYS_CLKSRC);
+       sys_clksrc &= ~0x00007FE0;
+
+       switch (prid & 0x000000FF) {
+       case 0x00: /* DA */
+       case 0x01: /* HA */
+       case 0x02: /* HB */
+               /* CPU core freq to 48MHz to slow it way down... */
+               au_writel(4, SYS_CPUPLL);
+
+               /*
+                * Setup 48MHz FREQ2 from CPUPLL for USB Host
+                */
+               /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
+               sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
+               au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+               /* CPU core freq to 384MHz */
+               au_writel(0x20, SYS_CPUPLL);
+
+               printf("Au1000: 48MHz OHCI workaround enabled\n");
+               break;
+
+       default:  /* HC and newer */
+               /* FREQ2 = aux/2 = 48 MHz */
+               sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+               au_writel(sys_freqctrl, SYS_FREQCTRL0);
+               break;
+       }
+
+       /*
+        * Route 48MHz FREQ2 into USB Host and/or Device
+        */
+       sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+       au_writel(sys_clksrc, SYS_CLKSRC);
+
+       /* configure pins GPIO[14:9] as GPIO */
+       pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
+
+       au_writel(pin_func, SYS_PINFUNC);
+       au_writel(0x2800, SYS_TRIOUTCLR);
+       au_writel(0x0030, SYS_OUTPUTCLR);
+
+       dbg("OHCI board setup complete\n");
+
+       /* enable host controller */
+       au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
+       udelay(1000);
+       au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);
+       udelay(1000);
+
+       /* wait for reset complete (read register twice; see au1500 errata) */
+       while (au_readl(USB_HOST_CONFIG),
+              !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
+               udelay(1000);
+
+       dbg("OHCI clock running\n");
+
+       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 *)(USB_OHCI_BASE | 0xA0000000);
+
+       gohci.flags = 0;
+       gohci.slot_name = "au1x00";
+
+       dbg("OHCI revision: 0x%08x\n"
+              "  RH: a: 0x%08x b: 0x%08x\n",
+              readl(&gohci.regs->revision),
+              readl(&gohci.regs->roothub.a), readl(&gohci.regs->roothub.b));
+
+       if (hc_reset (&gohci) < 0)
+               goto errout;
+
+       /* 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)
+               goto errout;
+
+#ifdef DEBUG
+       ohci_dump (&gohci, 1);
+#else
+       wait_ms(1);
+#endif
+       ohci_inited = 1;
+       return 0;
+
+  errout:
+       err("OHCI initialization error\n");
+       hc_release_ohci (&gohci);
+       /* Initialization failed */
+       au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
+       return -1;
+}
+
+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 */
+       /* Disable clock */
+       au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
+       return 0;
+}
+
+#endif /* CONFIG_USB_OHCI */
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/au1x00_usb_ohci.h b/package/uboot-ifxmips/files/cpu/mips/danube/au1x00_usb_ohci.h
new file mode 100644 (file)
index 0000000..4ef06ff
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * 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/package/uboot-ifxmips/files/cpu/mips/danube/cache.S b/package/uboot-ifxmips/files/cpu/mips/danube/cache.S
new file mode 100644 (file)
index 0000000..9a39784
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ *  Cache-handling routined for MIPS 4K CPUs
+ *
+ *  Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+#if defined(CONFIG_IFX_MIPS)
+#      include "ifx_cache.S"
+#endif
+
+       /* 16KB is the maximum size of instruction and data caches on
+        * MIPS 4K.
+        */
+#define MIPS_MAX_CACHE_SIZE    0x4000
+
+
+/*
+ * cacheop macro to automate cache operations
+ * first some helpers...
+ */
+#define _mincache(size, maxsize) \
+   bltu  size,maxsize,9f ; \
+   move  size,maxsize ;    \
+9:
+
+#define _align(minaddr, maxaddr, linesize) \
+   .set noat ; \
+   subu  AT,linesize,1 ;   \
+   not   AT ;        \
+   and   minaddr,AT ;      \
+   addu  maxaddr,-1 ;      \
+   and   maxaddr,AT ;      \
+   .set at
+
+/* general operations */
+#define doop1(op1) \
+   cache op1,0(a0)
+#define doop2(op1, op2) \
+   cache op1,0(a0) ;    \
+   nop ;          \
+   cache op2,0(a0)
+
+/* specials for cache initialisation */
+#define doop1lw(op1) \
+   lw zero,0(a0)
+#define doop1lw1(op1) \
+   cache op1,0(a0) ;    \
+   lw zero,0(a0) ;      \
+   cache op1,0(a0)
+#define doop121(op1,op2) \
+   cache op1,0(a0) ;    \
+   nop;           \
+   cache op2,0(a0) ;    \
+   nop;           \
+   cache op1,0(a0)
+
+#define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
+   .set  noreorder ;    \
+10:   doop##tag##ops ;  \
+   bne     minaddr,maxaddr,10b ; \
+   add      minaddr,linesize ;   \
+   .set  reorder
+
+/* finally the cache operation macros */
+#define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
+   blez  n,11f ;        \
+   addu  n,kva ;        \
+   _align(kva, n, cacheLineSize) ; \
+   _oploopn(kva, n, cacheLineSize, tag, ops) ; \
+11:
+
+#define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
+   _mincache(n, cacheSize);   \
+   blez  n,11f ;        \
+   addu  n,kva ;        \
+   _align(kva, n, cacheLineSize) ; \
+   _oploopn(kva, n, cacheLineSize, tag, ops) ; \
+11:
+
+#define vcacheop(kva, n, cacheSize, cacheLineSize, op) \
+   vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
+
+#define icacheop(kva, n, cacheSize, cacheLineSize, op) \
+   icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
+
+/*******************************************************************************
+*
+* mips_cache_reset - low level initialisation of the primary caches
+*
+* This routine initialises the primary caches to ensure that they
+* have good parity.  It must be called by the ROM before any cached locations
+* are used to prevent the possibility of data with bad parity being written to
+* memory.
+* To initialise the instruction cache it is essential that a source of data
+* with good parity is available. This routine
+* will initialise an area of memory starting at location zero to be used as
+* a source of parity.
+*
+* RETURNS: N/A
+*
+*/
+       .globl  mips_cache_reset
+       .ent    mips_cache_reset
+mips_cache_reset:
+
+       li      t2, CFG_ICACHE_SIZE
+       li      t3, CFG_DCACHE_SIZE
+       li      t4, CFG_CACHELINE_SIZE
+       move    t5, t4
+
+
+       li      v0, MIPS_MAX_CACHE_SIZE
+
+       /* Now clear that much memory starting from zero.
+        */
+
+       li      a0, KSEG1
+       addu    a1, a0, v0
+
+2:     sw      zero, 0(a0)
+       sw      zero, 4(a0)
+       sw      zero, 8(a0)
+       sw      zero, 12(a0)
+       sw      zero, 16(a0)
+       sw      zero, 20(a0)
+       sw      zero, 24(a0)
+       sw      zero, 28(a0)
+       addu    a0, 32
+       bltu    a0, a1, 2b
+
+       /* Set invalid tag.
+        */
+
+       mtc0    zero, CP0_TAGLO
+#if defined(CONFIG_IFX_MIPS) && defined(IFX_CACHE_EXTRA_INVALID_TAG)
+       IFX_CACHE_EXTRA_INVALID_TAG
+#endif
+
+   /*
+    * The caches are probably in an indeterminate state,
+    * so we force good parity into them by doing an
+    * invalidate, load/fill, invalidate for each line.
+    */
+
+       /* Assume bottom of RAM will generate good parity for the cache.
+        */
+
+       li      a0, K0BASE
+       move    a2, t2          # icacheSize
+       move    a3, t4          # icacheLineSize
+       move    a1, a2
+       icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill))
+
+#if defined(CONFIG_IFX_MIPS) && defined(IFX_CACHE_EXTRA_OPERATION)
+       IFX_CACHE_EXTRA_OPERATION
+#else
+       /* To support Orion/R4600, we initialise the data cache in 3 passes.
+        */
+
+       /* 1: initialise dcache tags.
+        */
+
+       li      a0, K0BASE
+       move    a2, t3          # dcacheSize
+       move    a3, t5          # dcacheLineSize
+       move    a1, a2
+       icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
+
+       /* 2: fill dcache.
+        */
+
+       li      a0, K0BASE
+       move    a2, t3          # dcacheSize
+       move    a3, t5          # dcacheLineSize
+       move    a1, a2
+       icacheopn(a0,a1,a2,a3,1lw,(dummy))
+
+       /* 3: clear dcache tags.
+        */
+
+       li      a0, K0BASE
+       move    a2, t3          # dcacheSize
+       move    a3, t5          # dcacheLineSize
+       move    a1, a2
+       icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
+#endif
+
+       j  ra
+       .end  mips_cache_reset
+
+
+/*******************************************************************************
+*
+* dcache_status - get cache status
+*
+* RETURNS: 0 - cache disabled; 1 - cache enabled
+*
+*/
+       .globl  dcache_status
+       .ent    dcache_status
+dcache_status:
+
+       mfc0    v0, CP0_CONFIG
+       andi    v0, v0, 1
+       j       ra
+
+       .end  dcache_status
+
+/*******************************************************************************
+*
+* dcache_disable - disable cache
+*
+* RETURNS: N/A
+*
+*/
+       .globl  dcache_disable
+       .ent    dcache_disable
+dcache_disable:
+
+       mfc0    t0, CP0_CONFIG
+       li      t1, -8
+       and     t0, t0, t1
+       ori     t0, t0, CONF_CM_UNCACHED
+       mtc0    t0, CP0_CONFIG
+       j       ra
+
+       .end  dcache_disable
+
+
+/*******************************************************************************
+*
+* mips_cache_lock - lock RAM area pointed to by a0 in cache.
+*
+* RETURNS: N/A
+*
+*/
+#if defined(CONFIG_PURPLE)
+# define       CACHE_LOCK_SIZE (CFG_DCACHE_SIZE/2)
+#else
+# define       CACHE_LOCK_SIZE (CFG_DCACHE_SIZE)
+#endif
+       .globl  mips_cache_lock
+       .ent    mips_cache_lock
+mips_cache_lock:
+       li      a1, K0BASE - CACHE_LOCK_SIZE
+       addu    a0, a1
+       li      a2, CACHE_LOCK_SIZE
+       li      a3, CFG_CACHELINE_SIZE
+       move    a1, a2
+       icacheop(a0,a1,a2,a3,0x1d)
+
+       j       ra
+       .end    mips_cache_lock
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/config.mk b/package/uboot-ifxmips/files/cpu/mips/danube/config.mk
new file mode 100644 (file)
index 0000000..3414ad8
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+v=$(shell \
+$(CROSS_COMPILE)as --version|grep "GNU assembler"|awk '{print $$3}'|awk -F . '{print $$2}')
+
+ifndef PLATFORM_CPU
+PLATFORM_CPU = mips32r2
+endif
+
+MIPSFLAGS=$(shell \
+if [ "$v" -lt "14" ]; then \
+       echo "-mcpu=$(PLATFORM_CPU)"; \
+else \
+       echo "-march=$(PLATFORM_CPU) -mtune=$(PLATFORM_CPU)"; \
+fi)
+
+ifeq ($(CROSS_COMPILE_UCLIBC),1)
+ifneq (,$(findstring mipsel,$(CROSS_COMIPLE)))
+ENDIANNESS = -el
+else
+ENDIANNESS = -eb
+endif
+else
+ifneq (,$(findstring 4KCle,$(CROSS_COMPILE)))
+ENDIANNESS = -EL
+else
+ENDIANNESS = -EB
+endif
+endif
+
+MIPSFLAGS += $(ENDIANNESS) -mabicalls
+
+PLATFORM_CPPFLAGS += $(MIPSFLAGS)
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/cpu.c b/package/uboot-ifxmips/files/cpu/mips/danube/cpu.c
new file mode 100644 (file)
index 0000000..b9f90ce
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#if defined(CONFIG_INCA_IP)
+#      include <asm/inca-ip.h>
+#elif defined(CONFIG_IFX_MIPS)
+#      include <asm/danube.h>
+#      include "ifx_cpu.c"
+#endif
+#include <asm/mipsregs.h>
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#if defined(CONFIG_INCA_IP)
+       *INCA_IP_WDT_RST_REQ = 0x3f;
+#elif defined(CONFIG_PURPLE) || defined(CONFIG_TB0229)
+       void (*f)(void) = (void *) 0xbfc00000;
+
+       f();
+#elif defined(CONFIG_IFX_MIPS)
+       IFX_CPU_RESET;
+#endif
+       fprintf(stderr, "*** reset failed ***\n");
+       return 0;
+}
+
+void flush_cache (ulong start_addr, ulong size)
+{
+
+}
+
+void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 ){
+       write_32bit_cp0_register(CP0_ENTRYLO0, low0);
+       write_32bit_cp0_register(CP0_PAGEMASK, pagemask);
+       write_32bit_cp0_register(CP0_ENTRYLO1, low1);
+       write_32bit_cp0_register(CP0_ENTRYHI, hi);
+       write_32bit_cp0_register(CP0_INDEX, index);
+       tlb_write_indexed();
+}
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/ifx_asc.c b/package/uboot-ifxmips/files/cpu/mips/danube/ifx_asc.c
new file mode 100644 (file)
index 0000000..52c6cb2
--- /dev/null
@@ -0,0 +1,257 @@
+/*****************************************************************************
+ * DANUBE BootROM
+ * Copyright (c) 2005, Infineon Technologies AG, All rights reserved
+ * IFAP DC COM SD
+ *****************************************************************************/
+
+#include <config.h>
+//#include <lib.h>
+#include <asm/danube.h>
+#include <asm/addrspace.h>
+#include <asm/ifx_asc.h>
+
+
+#define ASC_FIFO_PRESENT
+#define SET_BIT(reg, mask)                  reg |= (mask)
+#define CLEAR_BIT(reg, mask)                reg &= (~mask)
+#define CLEAR_BITS(reg, mask)               CLEAR_BIT(reg, mask)
+#define SET_BITS(reg, mask)                 SET_BIT(reg, mask)
+#define SET_BITFIELD(reg, mask, off, val)   {reg &= (~mask); reg |= (val << off);}
+
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned long u32;
+typedef signed   long s32;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+typedef volatile unsigned short vuint;
+
+
+
+void serial_setbrg (void);
+
+/*TODO: undefine this !!!*/
+#undef DEBUG_ASC_RAW
+#ifdef DEBUG_ASC_RAW
+#define DEBUG_ASC_RAW_RX_BUF           0xA0800000
+#define DEBUG_ASC_RAW_TX_BUF           0xA0900000
+#endif
+
+static volatile DanubeAsc_t *pAsc = (DanubeAsc_t *)DANUBE_ASC1;
+
+typedef struct{
+  u16 fdv; /* 0~511 fractional divider value*/
+  u16 reload; /* 13 bit reload value*/
+} ifx_asc_baud_reg_t;
+
+#ifdef ON_VENUS
+/*9600 @1.25M rel 00.08*/
+//#define FDV 503
+//#define RELOAD 7
+/*9600 @0.625M rel final00.01 & rtl_freeze*/
+#define FDV 503
+#define RELOAD 3
+/* first index is DDR_SEL, second index is FPI_SEL */
+#endif
+static ifx_asc_baud_reg_t g_danube_asc_baud[4][2] = 
+{
+#ifdef ON_VENUS
+     {{503,3},{503,3}},   /* 1152000 @ 166.67M and half*/
+      {{503,3},{503,3}},   /* 1152000 @ 133.3M  and half*/
+      {{503,3},{503,3}},   /* 1152000 @ 111.11M and half*/
+      {{503.3},{503,3}}    /* 1152000 @ 83.33M  and half*/
+#else
+/*  TAPEOUT table */
+     {{436,76},{419,36}},   /* 1152000 @ 166.67M and half*/
+      {{453,63},{453,31}},   /* 1152000 @ 133.3M  and half*/
+      {{501,58},{510,29}},   /* 1152000 @ 111.11M and half*/
+      {{419.36},{453,19}}    /* 1152000 @ 83.33M  and half*/
+#endif
+};
+/******************************************************************************
+*
+* asc_init - initialize a Danube ASC channel
+*
+* This routine initializes the number of data bits, parity
+* and set the selected baud rate. Interrupts are disabled.
+* Set the modem control signals if the option is selected.
+*
+* RETURNS: N/A
+*/
+
+int serial_init (void)
+{
+
+       /* and we have to set CLC register*/
+       CLEAR_BIT(pAsc->asc_clc, ASCCLC_DISS);
+       SET_BITFIELD(pAsc->asc_clc, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 0x0001);
+
+       /* initialy we are in async mode */
+       pAsc->asc_con = ASCCON_M_8ASYNC;
+
+       /* select input port */
+       pAsc->asc_pisel = (CONSOLE_TTY & 0x1);
+
+       /* TXFIFO's filling level */
+       SET_BITFIELD(pAsc->asc_txfcon, ASCTXFCON_TXFITLMASK,
+                       ASCTXFCON_TXFITLOFF, DANUBEASC_TXFIFO_FL);
+       /* enable TXFIFO */
+       SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXFEN);
+
+       /* RXFIFO's filling level */
+       SET_BITFIELD(pAsc->asc_txfcon, ASCRXFCON_RXFITLMASK,
+                       ASCRXFCON_RXFITLOFF, DANUBEASC_RXFIFO_FL);
+       /* enable RXFIFO */
+       SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXFEN);
+
+       /* set baud rate */
+       serial_setbrg();
+
+       /* enable error signals &  Receiver enable  */
+       SET_BIT(pAsc->asc_whbstate, ASCWHBSTATE_SETREN|ASCCON_FEN|ASCCON_TOEN|ASCCON_ROEN);
+
+       return 0;
+}
+
+void serial_setbrg (void)
+{
+       u32 uiReloadValue, fdv;
+
+#if defined(ON_IKOS)
+       /*1200 @77K */
+       fdv=472;
+       uiReloadValue=5;
+#else
+       /*venus & tapeout */
+  u32 ddr_sel,fpi_sel;
+  ddr_sel = (* DANUBE_CGU_SYS) & 0x3;
+  fpi_sel = ((* DANUBE_CGU_SYS) & 0x40)?1:0;
+       fdv= g_danube_asc_baud[ddr_sel][fpi_sel].fdv;
+       uiReloadValue=g_danube_asc_baud[ddr_sel][fpi_sel].reload;
+#endif //ON_IKOS
+       /* Disable Baud Rate Generator; BG should only be written when R=0 */
+       CLEAR_BIT(pAsc->asc_con, ASCCON_R);
+
+       /* Enable Fractional Divider */
+       SET_BIT(pAsc->asc_con, ASCCON_FDE); /* FDE = 1 */
+
+       /* Set fractional divider value */
+       pAsc->asc_fdv = fdv & ASCFDV_VALUE_MASK;
+
+       /* Set reload value in BG */
+       pAsc->asc_bg = uiReloadValue;
+
+       /* Enable Baud Rate Generator */
+       SET_BIT(pAsc->asc_con, ASCCON_R);           /* R = 1 */
+}
+
+
+void serial_putc (const char c)
+{
+       u32 txFl = 0;
+#ifdef DEBUG_ASC_RAW
+       static u8 * debug = (u8 *) DEBUG_ASC_RAW_TX_BUF;
+       *debug++=c;
+#endif
+       if (c == '\n')
+               serial_putc ('\r');
+       /* check do we have a free space in the TX FIFO */
+       /* get current filling level */
+       do
+       {
+               txFl = ( pAsc->asc_fstat & ASCFSTAT_TXFFLMASK ) >> ASCFSTAT_TXFFLOFF;
+       }
+       while ( txFl == DANUBEASC_TXFIFO_FULL );
+
+       pAsc->asc_tbuf = c; /* write char to Transmit Buffer Register */
+
+       /* check for errors */
+       if ( pAsc->asc_state & ASCSTATE_TOE )
+       {
+               SET_BIT(pAsc->asc_whbstate, ASCWHBSTATE_CLRTOE);
+               return;
+       }
+}
+
+void serial_puts (const char *s)
+{
+       while (*s)
+       {
+               serial_putc (*s++);
+       }
+}
+
+int asc_inb(int timeout)
+{
+       u32 symbol_mask;
+       char c;
+       while ((pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 ) {
+       }
+       symbol_mask = ((ASC_OPTIONS & ASCOPT_CSIZE) == ASCOPT_CS7) ? (0x7f) : (0xff);
+       c = (char)(pAsc->asc_rbuf & symbol_mask);
+       return (c);
+}
+
+int serial_getc (void)
+{
+       char c;
+       while ((pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 );
+       c = (char)(pAsc->asc_rbuf & 0xff);
+
+#ifdef         DEBUG_ASC_RAW
+       static u8* debug=(u8*)(DEBUG_ASC_RAW_RX_BUF);
+       *debug++=c;
+#endif
+       return c;
+}
+
+
+
+int serial_tstc (void)
+{
+         int res = 1;
+
+#ifdef ASC_FIFO_PRESENT
+    if ( (pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 )
+    {
+        res = 0;
+    }
+#else
+    if (!(*(volatile unsigned long*)(SFPI_INTCON_BASEADDR + FBS_ISR) &
+                                                               FBS_ISR_AR))
+    
+    {
+        res = 0;
+    }
+#endif
+#if 0
+    else if ( pAsc->asc_con & ASCCON_FE )
+    {
+        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRFE);
+        res = 0;
+    }
+    else if ( pAsc->asc_con & ASCCON_PE )
+    {
+        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRPE);
+        res = 0;
+    }
+    else if ( pAsc->asc_con & ASCCON_OE )
+    {
+        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE);
+        res = 0;
+    }
+#endif
+  return res;
+}
+
+
+int serial_start(void)
+{
+   return 1;
+}
+
+int serial_stop(void)
+{
+   return 1;
+}
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/ifx_cache.S b/package/uboot-ifxmips/files/cpu/mips/danube/ifx_cache.S
new file mode 100644 (file)
index 0000000..fc482dc
--- /dev/null
@@ -0,0 +1,60 @@
+
+#define IFX_CACHE_EXTRA_INVALID_TAG                                            \
+       mtc0    zero, CP0_TAGLO, 1;                                             \
+       mtc0    zero, CP0_TAGLO, 2;                                             \
+       mtc0    zero, CP0_TAGLO, 3;                                             \
+       mtc0    zero, CP0_TAGLO, 4;
+
+#define IFX_CACHE_EXTRA_OPERATION                                              \
+       /* set WST bit */                                                       \
+       mfc0    a0, CP0_ECC;                                                    \
+       li      a1, ECCF_WST;                                                   \
+       or      a0, a1;                                                         \
+       mtc0    a0, CP0_ECC;                                                    \
+                                                                               \
+       li      a0, K0BASE;                                                     \
+       move    a2, t2;         /* icacheSize */                                \
+       move    a3, t4;         /* icacheLineSize */                            \
+       move    a1, a2;                                                         \
+       icacheop(a0,a1,a2,a3,(Index_Store_Tag_I));                              \
+                                                                               \
+       /* clear WST bit */                                                     \
+       mfc0    a0, CP0_ECC;                                                    \
+       li      a1, ~ECCF_WST;                                                  \
+       and     a0, a1;                                                         \
+       mtc0    a0, CP0_ECC;                                                    \
+                                                                               \
+       /* 1: initialise dcache tags. */                                        \
+                                                                               \
+       /* cache line size */                                                   \
+       li      a2, CFG_CACHELINE_SIZE;                                         \
+       /* kseg0 mem address */                                                 \
+       li      a1, 0;                                                          \
+       li      a3, CFG_CACHE_SETS * CFG_CACHE_WAYS;                            \
+1:                                                                             \
+       /* store tag (invalid, not locked) */                                   \
+       cache 0x8, 0(a1);                                                       \
+       cache 0x9, 0(a1);                                                       \
+                                                                               \
+       add     a3, -1;                                                         \
+       bne     a3, zero, 1b;                                                   \
+       add     a1, a2;                                                         \
+                                                                               \
+       /* set WST bit */                                                       \
+       mfc0    a0, CP0_ECC;                                                    \
+       li      a1, ECCF_WST;                                                   \
+       or      a0, a1;                                                         \
+       mtc0    a0, CP0_ECC;                                                    \
+                                                                               \
+       li      a0, K0BASE;                                                     \
+       move    a2, t3;         /* dcacheSize */                                \
+       move    a3, t5;         /* dcacheLineSize */                            \
+       move    a1, a2;                                                         \
+       icacheop(a0,a1,a2,a3,(Index_Store_Tag_D));                              \
+                                                                               \
+       /* clear WST bit */                                                     \
+       mfc0    a0, CP0_ECC;                                                    \
+       li      a1, ~ECCF_WST;                                                  \
+       and     a0, a1;                                                         \
+       mtc0    a0, CP0_ECC;
+
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/ifx_cgu.c b/package/uboot-ifxmips/files/cpu/mips/danube/ifx_cgu.c
new file mode 100644 (file)
index 0000000..3fe13dd
--- /dev/null
@@ -0,0 +1,1086 @@
+/*\r
+ * ########################################################################\r
+ *\r
+ *  This program is free software; you can distribute it and/or modify it\r
+ *  under the terms of the GNU General Public License (Version 2) as\r
+ *  published by the Free Software Foundation.\r
+ *\r
+ *  This program is distributed in the hope it will be useful, but WITHOUT\r
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
+ *  for more details.\r
+ *\r
+ *  You should have received a copy of the GNU General Public License along\r
+ *  with this program; if not, write to the Free Software Foundation, Inc.,\r
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.\r
+ *\r
+ * ########################################################################\r
+ *\r
+ * danube_cgu.c\r
+ *\r
+ *  Description:\r
+ *    device driver of clock generation unit of Danube chip\r
+ *  Author:\r
+ *    Samuels Xu Liang\r
+ *  Created:\r
+ *    19 Jul 2005\r
+ *  History & Modification Tag:\r
+ *  ___________________________________________________________________________\r
+ *  |  Tag   |                  Comments                   | Modifier & Time  |\r
+ *  |--------+---------------------------------------------+------------------|\r
+ *  |  S0.0  | First version of this driver and the tag is | Samuels Xu Liang |\r
+ *  |        | implied.                                    |   19 Jul 2005    |\r
+ *  ---------------------------------------------------------------------------\r
+ *\r
+ */\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *              Head File\r
+ * ####################################\r
+ */\r
+\r
+/*\r
+ *  Common Head File\r
+ */\r
+#include <linux/config.h>\r
+#include <linux/kernel.h>\r
+#include <linux/module.h>\r
+#include <linux/version.h>\r
+#include <linux/types.h>\r
+#include <linux/fs.h>\r
+#include <linux/miscdevice.h>\r
+#include <linux/init.h>\r
+#include <asm/uaccess.h>\r
+#include <asm/unistd.h>\r
+#include <asm/irq.h>\r
+#include <linux/errno.h>\r
+\r
+/*\r
+ *  Chip Specific Head File\r
+ */\r
+#include "ifx_cgu.h"\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *              Definition\r
+ * ####################################\r
+ */\r
+\r
+#define DEBUG_ON_AMAZON                 1\r
+#define DEBUG_PRINT_INFO                1\r
+\r
+/*\r
+ *  Frequency of Clock Direct Feed from The Analog Line Driver Chip\r
+ */\r
+#define BASIC_INPUT_CLOCK_FREQUENCY     35328000\r
+\r
+/*\r
+ *  Bits Operation\r
+ */\r
+#define GET_BITS(x, msb, lsb)           (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))\r
+#define SET_BITS(x, msb, lsb, value)    (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))\r
+\r
+/*\r
+ *  CGU Register Mapping\r
+ */\r
+#define DANUBE_CGU                      (KSEG1 + 0x1F103000)\r
+#define DANUBE_CGU_DIV                  ((volatile u32*)(DANUBE_CGU + 0x0000))\r
+#define DANUBE_CGU_PLL_NMK0             ((volatile u32*)(DANUBE_CGU + 0x0004))\r
+#define DANUBE_CGU_PLL_SR0              ((volatile u32*)(DANUBE_CGU + 0x0008))\r
+#define DANUBE_CGU_PLL_NMK1             ((volatile u32*)(DANUBE_CGU + 0x000C))\r
+#define DANUBE_CGU_PLL_SR1              ((volatile u32*)(DANUBE_CGU + 0x0010))\r
+#define DANUBE_CGU_PLL_SR2              ((volatile u32*)(DANUBE_CGU + 0x0014))\r
+#define DANUBE_CGU_IF_CLK               ((volatile u32*)(DANUBE_CGU + 0x0018))\r
+#define DANUBE_CGU_OSC_CTRL             ((volatile u32*)(DANUBE_CGU + 0x001C))\r
+#define DANUBE_CGU_SMD                  ((volatile u32*)(DANUBE_CGU + 0x0020))\r
+#define DANUBE_CGU_CRD                  ((volatile u32*)(DANUBE_CGU + 0x0024))\r
+#define DANUBE_CGU_CT1SR                ((volatile u32*)(DANUBE_CGU + 0x0028))\r
+#define DANUBE_CGU_CT2SR                ((volatile u32*)(DANUBE_CGU + 0x002C))\r
+#define DANUBE_CGU_PCMCR                ((volatile u32*)(DANUBE_CGU + 0x0030))\r
+#define DANUBE_CGU_MUX                  ((volatile u32*)(DANUBE_CGU + 0x0034))\r
+\r
+/*\r
+ *  CGU Divider Register\r
+ */\r
+#define CGU_DIV_SFTR                    (*DANUBE_CGU_DIV & (1 << 31))\r
+#define CGU_DIV_DIVE                    (*DANUBE_CGU_DIV & (1 << 16))\r
+#define CGU_DIV_IOR                     GET_BITS(*DANUBE_CGU_DIV, 5, 4)\r
+#define CGU_DIV_FKS                     GET_BITS(*DANUBE_CGU_DIV, 3, 2)\r
+#define CGU_DIV_FBS                     GET_BITS(*DANUBE_CGU_DIV, 1, 0)\r
+\r
+/*\r
+ *  CGU PLL0 NMK Register\r
+ */\r
+#define CGU_PLL_NMK0_PLLN               ((*DANUBE_CGU_PLL_NMK0 & (0xFFFFFFFF ^ ((1 << 24) - 1))) >> 24)\r
+#define CGU_PLL_NMK0_PLLM               GET_BITS(*DANUBE_CGU_PLL_NMK0, 23, 20)\r
+#define CGU_PLL_NMK0_PLLK               GET_BITS(*DANUBE_CGU_PLL_NMK0, 19, 0)\r
+\r
+/*\r
+ *  CGU PLL0 Status Register\r
+ */\r
+#define CGU_PLL_SR0_PLLDIV              ((*DANUBE_CGU_PLL_SR0 & (0xFFFFFFFF ^ ((1 << 28) - 1))) >> 28)\r
+#define CGU_PLL_SR0_PLLDEN              (*DANUBE_CGU_PLL_SR0 & (1 << 26))\r
+#define CGU_PLL_SR0_PLLPSE              GET_BITS(*DANUBE_CGU_PLL_SR0, 5, 4)\r
+#define CGU_PLL_SR0_PLLB                (*DANUBE_CGU_PLL_SR0 & (1 << 2))\r
+#define CGU_PLL_SR0_PLLL                (*DANUBE_CGU_PLL_SR0 & (1 << 1))\r
+#define CGU_PLL_SR0_PLLEN               (*DANUBE_CGU_PLL_SR0 & (1 << 0))\r
+\r
+#define CGU_PLL_SR0_DSMSEL              1\r
+#define CGU_PLL_SR0_PHASE_DIV_EN        1\r
+\r
+/*\r
+ *  CGU PLL1 NMK Register\r
+ */\r
+#define CGU_PLL_NMK1_PLLN               ((*DANUBE_CGU_PLL_NMK1 & (0xFFFFFFFF ^ ((1 << 24) - 1))) >> 24)\r
+#define CGU_PLL_NMK1_PLLM               GET_BITS(*DANUBE_CGU_PLL_NMK1, 23, 20)\r
+#define CGU_PLL_NMK1_PLLK               GET_BITS(*DANUBE_CGU_PLL_NMK1, 19, 0)\r
+\r
+/*\r
+ *  CGU PLL1 Status Register\r
+ */\r
+#define CGU_PLL_SR1_PLLDIV              ((*DANUBE_CGU_PLL_SR1 & (0xFFFFFFFF ^ ((1 << 28) - 1))) >> 28)\r
+#define CGU_PLL_SR1_PLLDEN              (*DANUBE_CGU_PLL_SR1 & (1 << 26))\r
+#define CGU_PLL_SR1_PLLPSE              GET_BITS(*DANUBE_CGU_PLL_SR1, 5, 4)\r
+#define CGU_PLL_SR1_PLLB                (*DANUBE_CGU_PLL_SR1 & (1 << 2))\r
+#define CGU_PLL_SR1_PLLL                (*DANUBE_CGU_PLL_SR1 & (1 << 1))\r
+#define CGU_PLL_SR1_PLLEN               (*DANUBE_CGU_PLL_SR1 & (1 << 0))\r
+\r
+#define CGU_PLL_SR1_DSMSEL              1\r
+#define CGU_PLL_SR1_PHASE_DIV_EN        1\r
+\r
+/*\r
+ *  CGU PLL2 Status Register\r
+ */\r
+#define CGU_PLL_SR2_PLLDIV              ((*DANUBE_CGU_PLL_SR2 & (0xFFFFFFFF ^ ((1 << 28) - 1))) >> 28)\r
+#define CGU_PLL_SR2_PLLDEN              (*DANUBE_CGU_PLL_SR2 & (1 << 27))\r
+#define CGU_PLL_SR2_PLLN                GET_BITS(*DANUBE_CGU_PLL_SR2, 25, 20)\r
+#define CGU_PLL_SR2_PLLM                GET_BITS(*DANUBE_CGU_PLL_SR2, 19, 16)\r
+#define CGU_PLL_SR2_PLLPS               (*DANUBE_CGU_PLL_SR2 & (1 << 5))\r
+#define CGU_PLL_SR2_PLLPE               (*DANUBE_CGU_PLL_SR2 & (1 << 4))\r
+#define CGU_PLL_SR2_PLLB                (*DANUBE_CGU_PLL_SR2 & (1 << 2))\r
+#define CGU_PLL_SR2_PLLL                (*DANUBE_CGU_PLL_SR2 & (1 << 1))\r
+#define CGU_PLL_SR2_PLLEN               (*DANUBE_CGU_PLL_SR2 & (1 << 0))\r
+\r
+/*\r
+ *  CGU Interface Clock Register\r
+ */\r
+#define CGU_IF_CLK_CLKOD0               GET_BITS(*DANUBE_CGU_IF_CLK, 27, 26)\r
+#define CGU_IF_CLK_CLKOD1               GET_BITS(*DANUBE_CGU_IF_CLK, 25, 24)\r
+#define CGU_IF_CLK_CLKOD2               GET_BITS(*DANUBE_CGU_IF_CLK, 23, 22)\r
+#define CGU_IF_CLK_CLKOD3               GET_BITS(*DANUBE_CGU_IF_CLK, 21, 20)\r
+#define CGU_IF_CLK_PDA                  (*DANUBE_CGU_IF_CLK & (1 << 18))\r
+#define CGU_IF_CLK_PCI_B                (*DANUBE_CGU_IF_CLK & (1 << 17))\r
+#define CGU_IF_CLK_PCIBM                (*DANUBE_CGU_IF_CLK & (1 << 16))\r
+#define CGU_IF_CLK_MIICS                (*DANUBE_CGU_IF_CLK & (1 << 3))\r
+#define CGU_IF_CLK_USBCS                (*DANUBE_CGU_IF_CLK & (1 << 2))\r
+#define CGU_IF_CLK_PCIF                 (*DANUBE_CGU_IF_CLK & (1 << 1))\r
+#define CGU_IF_CLK_PCIS                 (*DANUBE_CGU_IF_CLK & (1 << 0))\r
+\r
+/*\r
+ *  CGU Oscillator Control Register\r
+ */\r
+#define CGU_OSC_CTRL                    GET_BITS(*DANUBE_CGU_OSC_CTRL, 1, 0)\r
+\r
+/*\r
+ *  CGU SDRAM Memory Delay Register\r
+ */\r
+#define CGU_SMD_CLKI                    (*DANUBE_CGU_SMD & (1 << 31))\r
+#define CGU_SMD_MIDS                    GET_BITS(*DANUBE_CGU_SMD, 17, 12)\r
+#define CGU_SMD_MODS                    GET_BITS(*DANUBE_CGU_SMD, 11, 6)\r
+#define CGU_SMD_MDSEL                   GET_BITS(*DANUBE_CGU_SMD, 5, 0)\r
+\r
+/*\r
+ *  CGU CPU Clock Reduction Register\r
+ */\r
+#define CGU_CRD_SFTR                    (*DANUBE_CGU_CRD & (1 << 31))\r
+#define CGU_CRD_DIVE                    (*DANUBE_CGU_CRD & (1 << 16))\r
+#define CGU_CRD_CRD1                    GET_BITS(*DANUBE_CGU_CRD, 3, 2)\r
+#define CGU_CRD_CRD                     GET_BITS(*DANUBE_CGU_CRD, 1, 0)\r
+\r
+/*\r
+ *  CGU CT Status Register 1\r
+ */\r
+#define CGU_CT1SR_PDOUT                 GET_BITS(*DANUBE_CGU_CT1SR, 13, 0)\r
+\r
+/*\r
+ *  CGU CT Status Register 2\r
+ */\r
+#define CGU_CT2SR_PLL1K                 GET_BITS(*DANUBE_CGU_CT2SR, 9, 0)\r
+\r
+/*\r
+ *  CGU PCM Control Register\r
+ */\r
+#define CGU_PCMCR_DCL1                  GET_BITS(*DANUBE_CGU_PCMCR, 27, 25)\r
+#define CGU_PCMCR_MUXDCL                (*DANUBE_CGU_PCMCR & (1 << 22))\r
+#define CGU_PCMCR_MUXFSC                (*DANUBE_CGU_PCMCR & (1 << 18))\r
+#define CGU_PCMCR_PCM_SL                (*DANUBE_CGU_PCMCR & (1 << 13))\r
+#define CGU_PCMCR_DNTR                  (*DANUBE_CGU_PCMCR & (1 << 12))\r
+\r
+/*\r
+ *  CGU Clock Mux Register\r
+ */\r
+#define CGU_MUX_MII_CLK                 (*DANUBE_CGU_MUX & (1 << 6))\r
+#define CGU_MUX_SUB_SYS                 GET_BITS(*DANUBE_CGU_MUX, 5, 3)\r
+#define CGU_MUX_PP32                    GET_BITS(*DANUBE_CGU_MUX, 1, 0)\r
+\r
+\r
+/*\r
+ * ####################################\r
+ * Preparation of Debug on Amazon Chip\r
+ * ####################################\r
+ */\r
+\r
+/*\r
+ *  If try module on Amazon chip, prepare some tricks to prevent invalid memory write.\r
+ */\r
+#if defined(DEBUG_ON_AMAZON) && DEBUG_ON_AMAZON\r
+    u32 g_pFakeRegisters[0x0100];\r
+\r
+    #undef  DANUBE_CGU\r
+    #define DANUBE_CGU                  ((u32)g_pFakeRegisters)\r
+#endif  //  defined(DEBUG_ON_AMAZON) && DEBUG_ON_AMAZON\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *              Data Type\r
+ * ####################################\r
+ */\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *             Declaration\r
+ * ####################################\r
+ */\r
+\r
+/*\r
+ *  Pre-declaration of File Operations\r
+ */\r
+static ssize_t cgu_read(struct file *, char *, size_t, loff_t *);\r
+static ssize_t cgu_write(struct file *, const char *, size_t, loff_t *);\r
+static int cgu_ioctl(struct inode *, struct file *, unsigned int, unsigned long);\r
+static int cgu_open(struct inode *, struct file *);\r
+static int cgu_release(struct inode *, struct file *);\r
+\r
+/*\r
+ *  Pre-declaration of 64-bit Unsigned Integer Operation\r
+ */\r
+static inline void uint64_multiply(unsigned int, unsigned int, unsigned int *);\r
+static inline void uint64_divide(unsigned int *, unsigned int, unsigned int *, unsigned int *);\r
+\r
+/*\r
+ *  Calculate PLL Frequency\r
+ */\r
+static inline u32 cal_dsm(u32, u32);\r
+static inline u32 mash_dsm(u32, u32, u32);\r
+static inline u32 ssff_dsm_1(u32, u32, u32);\r
+static inline u32 ssff_dsm_2(u32, u32, u32);\r
+static inline u32 dsm(u32 M, u32, u32, int, int);\r
+static inline u32 cgu_get_pll0_fosc(void);\r
+static inline u32 cgu_get_pll0_fps(void);\r
+static inline u32 cgu_get_pll0_fdiv(void);\r
+static inline u32 cgu_get_pll1_fosc(void);\r
+static inline u32 cgu_get_pll1_fps(void);\r
+static inline u32 cgu_get_pll1_fdiv(void);\r
+static inline u32 cgu_get_pll2_fosc(void);\r
+static inline u32 cgu_get_pll2_fps(void);\r
+\r
+/*\r
+ *  Export Functions\r
+ */\r
+u32 cgu_get_mips_clock(int);\r
+u32 cgu_get_cpu_clock(void);\r
+u32 cgu_get_io_region_clock(void);\r
+u32 cgu_get_fpi_bus_clock(int);\r
+u32 cgu_get_pp32_clock(void);\r
+u32 cgu_get_pci_clock(void);\r
+u32 cgu_get_ethernet_clock(void);\r
+u32 cgu_get_usb_clock(void);\r
+u32 cgu_get_clockout(int);\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *            Local Variable\r
+ * ####################################\r
+ */\r
+\r
+static struct file_operations cgu_fops = {\r
+    owner:      THIS_MODULE,\r
+    llseek:     no_llseek,\r
+    read:       cgu_read,\r
+    write:      cgu_write,\r
+    ioctl:      cgu_ioctl,\r
+    open:       cgu_open,\r
+    release:    cgu_release\r
+};\r
+\r
+static struct miscdevice cgu_miscdev = {\r
+    MISC_DYNAMIC_MINOR,\r
+    "danube_cgu_dev",\r
+    &cgu_fops\r
+};\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *           Global Variable\r
+ * ####################################\r
+ */\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *            Local Function\r
+ * ####################################\r
+ */\r
+\r
+static ssize_t cgu_read(struct file *file, char *buf, size_t count, loff_t *ppos)\r
+{\r
+    return -EPERM;\r
+}\r
+\r
+static ssize_t cgu_write(struct file *file, const char *buf, size_t count, loff_t *ppos)\r
+{\r
+    return -EPERM;\r
+}\r
+\r
+static int cgu_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)\r
+{\r
+    int ret = 0;\r
+    struct cgu_clock_rates rates;\r
+\r
+    if ( _IOC_TYPE(cmd) != CGU_IOC_MAGIC\r
+        || _IOC_NR(cmd) >= CGU_IOC_MAXNR )\r
+        return -ENOTTY;\r
+\r
+    if ( _IOC_DIR(cmd) & _IOC_READ )\r
+        ret = !access_ok(VERIFY_WRITE, arg, _IOC_SIZE(cmd));\r
+    else if ( _IOC_DIR(cmd) & _IOC_WRITE )\r
+        ret = !access_ok(VERIFY_READ, arg, _IOC_SIZE(cmd));\r
+    if ( ret )\r
+        return -EFAULT;\r
+\r
+    switch ( cmd )\r
+    {\r
+    case CGU_GET_CLOCK_RATES:\r
+        /*  Calculate Clock Rates   */\r
+        rates.mips0     = cgu_get_mips_clock(0);\r
+        rates.mips1     = cgu_get_mips_clock(1);\r
+        rates.cpu       = cgu_get_cpu_clock();\r
+        rates.io_region = cgu_get_io_region_clock();\r
+        rates.fpi_bus1  = cgu_get_fpi_bus_clock(1);\r
+        rates.fpi_bus2  = cgu_get_fpi_bus_clock(2);\r
+        rates.pp32      = cgu_get_pp32_clock();\r
+        rates.pci       = cgu_get_pci_clock();\r
+        rates.ethernet  = cgu_get_ethernet_clock();\r
+        rates.usb       = cgu_get_usb_clock();\r
+        rates.clockout0 = cgu_get_clockout(0);\r
+        rates.clockout1 = cgu_get_clockout(1);\r
+        rates.clockout2 = cgu_get_clockout(2);\r
+        rates.clockout3 = cgu_get_clockout(3);\r
+        /*  Copy to User Space      */\r
+        copy_to_user((char*)arg, (char*)&rates, sizeof(rates));\r
+\r
+        ret = 0;\r
+        break;\r
+    default:\r
+        ret = -ENOTTY;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+static int cgu_open(struct inode *inode, struct file *file)\r
+{\r
+    return 0;\r
+}\r
+\r
+static int cgu_release(struct inode *inode, struct file *file)\r
+{\r
+    return 0;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    calculate 64-bit multiplication result of two 32-bit unsigned integer\r
+ *  Input:\r
+ *    u32Multiplier1 --- u32 (32-bit), one of the multipliers\r
+ *    u32Multiplier2 --- u32 (32-bit), the other multiplier\r
+ *    u32Result      --- u32[2], array to retrieve the multiplication result,\r
+ *                       index 0 is high word, index 1 is low word\r
+ *  Output:\r
+*    none\r
+ */\r
+static inline void uint64_multiply(u32 u32Multiplier1, u32 u32Multiplier2, u32 u32Result[2])\r
+{\r
+       u32 u32Multiplier1LowWord = u32Multiplier1 & 0xFFFF;\r
+       u32 u32Multiplier1HighWord = u32Multiplier1 >> 16;\r
+       u32 u32Multiplier2LowWord = u32Multiplier2 & 0xFFFF;\r
+       u32 u32Multiplier2HighWord = u32Multiplier2 >> 16;\r
+       u32 u32Combo1, u32Combo2, u32Combo3, u32Combo4;\r
+       u32 u32Word1, u32Word2, u32Word3, u32Word4;\r
+\r
+       u32Combo1 = u32Multiplier1LowWord * u32Multiplier2LowWord;\r
+       u32Combo2 = u32Multiplier1HighWord * u32Multiplier2LowWord;\r
+       u32Combo3 = u32Multiplier1LowWord * u32Multiplier2HighWord;\r
+       u32Combo4 = u32Multiplier1HighWord * u32Multiplier2HighWord;\r
+\r
+       u32Word1 = u32Combo1 & 0xFFFF;\r
+       u32Word2 = (u32Combo1 >> 16) + (u32Combo2 & 0xFFFF) + (u32Combo3 & 0xFFFF);\r
+       u32Word3 = (u32Combo2 >> 16) + (u32Combo3 >> 16) + (u32Combo4 & 0xFFFF) + (u32Word2 >> 16);\r
+       u32Word4 = (u32Combo4 >> 16) + (u32Word3 >> 16);\r
+\r
+       u32Result[0] = (u32Word4 << 16) | u32Word3;\r
+       u32Result[1] = (u32Word2 << 16) | u32Word1;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    divide 64-bit unsigned integer with 32-bit unsigned integer\r
+ *  Input:\r
+ *    u32Numerator   --- u32[2], index 0 is high word of numerator, while\r
+ *                       index 1 is low word of numerator\r
+ *    u32Denominator --- u32 (32-bit), the denominator in division, this\r
+ *                       parameter can not be zero, or lead to unpredictable\r
+ *                       result\r
+ *    pu32Quotient   --- u32 *, the pointer to retrieve 32-bit quotient, null\r
+ *                       pointer means ignore quotient\r
+ *    pu32Residue    --- u32 *, the pointer to retrieve 32-bit residue null\r
+ *                       pointer means ignore residue\r
+ *  Output:\r
+ *    none\r
+ */\r
+static inline void uint64_divide(u32 u32Numerator[2], u32 u32Denominator, u32 *pu32Quotient, u32 *pu32Residue)\r
+{\r
+       u32 u32DWord1, u32DWord2, u32DWord3;\r
+       u32 u32Quotient;\r
+       int i;\r
+\r
+       u32DWord3 = 0;\r
+       u32DWord2 = u32Numerator[0];\r
+       u32DWord1 = u32Numerator[1];\r
+\r
+       u32Quotient = 0;\r
+\r
+       for ( i = 0; i < 64; i++ )\r
+       {\r
+               u32DWord3 = (u32DWord3 << 1) | (u32DWord2 >> 31);\r
+               u32DWord2 = (u32DWord2 << 1) | (u32DWord1 >> 31);\r
+               u32DWord1 <<= 1;\r
+               u32Quotient <<= 1;\r
+               if ( u32DWord3 >= u32Denominator )\r
+               {\r
+                       u32DWord3 -= u32Denominator;\r
+                       u32Quotient |= 1;\r
+               }\r
+       }\r
+       if ( pu32Quotient )\r
+           *pu32Quotient = u32Quotient;\r
+       if ( pu32Residue )\r
+           *pu32Residue = u32DWord3;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    common routine to calculate PLL frequency\r
+ *  Input:\r
+ *    num --- u32, numerator\r
+ *    den --- u32, denominator\r
+ *  Output:\r
+ *    u32 --- frequency the PLL output\r
+ */\r
+static inline u32 cal_dsm(u32 num, u32 den)\r
+{\r
+    u32 ret;\r
+    u32 temp[2];\r
+    u32 residue;\r
+\r
+    uint64_multiply(num, BASIC_INPUT_CLOCK_FREQUENCY, temp);\r
+    uint64_divide(temp, den, &ret, &residue);\r
+    if ( (residue << 1) >= den )\r
+        ret++;\r
+\r
+    return ret;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    calculate PLL frequency following MASH-DSM\r
+ *  Input:\r
+ *    M   --- u32, denominator coefficient\r
+ *    N   --- u32, numerator integer coefficient\r
+ *    K   --- u32, numerator fraction coefficient\r
+ *  Output:\r
+ *    u32 --- frequency the PLL output\r
+ */\r
+static inline u32 mash_dsm(u32 M, u32 N, u32 K)\r
+{\r
+    u32 num = ((N + 1) << 10) + K;\r
+    u32 den = (M + 1) << 10;\r
+\r
+    return cal_dsm(num, den);\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    calculate PLL frequency following SSFF-DSM (0.25 < fraction < 0.75)\r
+ *  Input:\r
+ *    M   --- u32, denominator coefficient\r
+ *    N   --- u32, numerator integer coefficient\r
+ *    K   --- u32, numerator fraction coefficient\r
+ *  Output:\r
+ *    u32 --- frequency the PLL output\r
+ */\r
+static inline u32 ssff_dsm_1(u32 M, u32 N, u32 K)\r
+{\r
+    u32 num = ((N + 1) << 11) + K + 512;\r
+    u32 den = (M + 1) << 11;\r
+\r
+    return cal_dsm(num, den);\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    calculate PLL frequency following SSFF-DSM\r
+ *    (fraction < 0.125 || fraction > 0.875)\r
+ *  Input:\r
+ *    M   --- u32, denominator coefficient\r
+ *    N   --- u32, numerator integer coefficient\r
+ *    K   --- u32, numerator fraction coefficient\r
+ *  Output:\r
+ *    u32 --- frequency the PLL output\r
+ */\r
+static inline u32 ssff_dsm_2(u32 M, u32 N, u32 K)\r
+{\r
+    u32 num = K >= 512 ? ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;\r
+    u32 den = (M + 1) << 12;\r
+\r
+    return cal_dsm(num, den);\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    calculate PLL frequency\r
+ *  Input:\r
+ *    M            --- u32, denominator coefficient\r
+ *    N            --- u32, numerator integer coefficient\r
+ *    K            --- u32, numerator fraction coefficient\r
+ *    dsmsel       --- int, 0: MASH-DSM, 1: SSFF-DSM\r
+ *    phase_div_en --- int, 0: 0.25 < fraction < 0.75\r
+ *                          1: fraction < 0.125 || fraction > 0.875\r
+ *  Output:\r
+ *    u32          --- frequency the PLL output\r
+ */\r
+static inline u32 dsm(u32 M, u32 N, u32 K, int dsmsel, int phase_div_en)\r
+{\r
+    if ( !dsmsel )\r
+        return mash_dsm(M, N, K);\r
+    else\r
+        if ( !phase_div_en )\r
+            return ssff_dsm_1(M, N, K);\r
+        else\r
+            return ssff_dsm_2(M, N, K);\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get oscillate frequency of PLL0\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PLL0 Fosc\r
+ */\r
+static inline u32 cgu_get_pll0_fosc(void)\r
+{\r
+    return CGU_PLL_SR0_PLLB ? BASIC_INPUT_CLOCK_FREQUENCY : dsm(CGU_PLL_NMK0_PLLM, CGU_PLL_NMK0_PLLN, CGU_PLL_NMK0_PLLK, CGU_PLL_SR0_DSMSEL, CGU_PLL_SR0_PHASE_DIV_EN);\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get output frequency of PLL0 phase shifter\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PLL0 Fps\r
+ */\r
+static inline u32 cgu_get_pll0_fps(void)\r
+{\r
+    register u32 fps = cgu_get_pll0_fosc();\r
+\r
+    switch ( CGU_PLL_SR0_PLLPSE )\r
+    {\r
+    case 1:\r
+        /*  1.5     */\r
+        fps = ((fps << 1) + 1) / 3; break;\r
+    case 2:\r
+        /*  1.25    */\r
+        fps = ((fps << 2) + 2) / 5; break;\r
+    case 3:\r
+        /*  3.5     */\r
+        fps = ((fps << 1) + 3) / 7;\r
+    }\r
+    return fps;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get output frequency of PLL0 output divider\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PLL0 Fdiv\r
+ */\r
+static inline u32 cgu_get_pll0_fdiv(void)\r
+{\r
+    register u32 fdiv = cgu_get_pll0_fosc();\r
+\r
+    if ( CGU_PLL_SR0_PLLDEN )\r
+        fdiv = (fdiv + (CGU_PLL_SR0_PLLDIV + 1) / 2) / (CGU_PLL_SR0_PLLDIV + 1);\r
+    return fdiv;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get oscillate frequency of PLL1\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PLL1 Fosc\r
+ */\r
+static inline u32 cgu_get_pll1_fosc(void)\r
+{\r
+    return CGU_PLL_SR1_PLLB ? BASIC_INPUT_CLOCK_FREQUENCY : dsm(CGU_PLL_NMK1_PLLM, CGU_PLL_NMK1_PLLN, CGU_PLL_NMK1_PLLK, CGU_PLL_SR1_DSMSEL, CGU_PLL_SR1_PHASE_DIV_EN);\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get output frequency of PLL1 phase shifter\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PLL1 Fps\r
+ */\r
+static inline u32 cgu_get_pll1_fps(void)\r
+{\r
+    register u32 fps = cgu_get_pll1_fosc();\r
+\r
+    switch ( CGU_PLL_SR1_PLLPSE )\r
+    {\r
+    case 1:\r
+        /*  1.5     */\r
+        fps = ((fps << 1) + 1) / 3; break;\r
+    case 2:\r
+        /*  1.25    */\r
+        fps = ((fps << 2) + 2) / 5; break;\r
+    case 3:\r
+        /*  3.5     */\r
+        fps = ((fps << 1) + 3) / 7;\r
+    }\r
+    return fps;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get output frequency of PLL1 output divider\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PLL1 Fdiv\r
+ */\r
+static inline u32 cgu_get_pll1_fdiv(void)\r
+{\r
+    register u32 fdiv = cgu_get_pll1_fosc();\r
+\r
+    if ( CGU_PLL_SR1_PLLDEN )\r
+        fdiv = (fdiv + (CGU_PLL_SR1_PLLDIV + 1) / 2) / (CGU_PLL_SR1_PLLDIV + 1);\r
+    return fdiv;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get oscillate frequency of PLL2\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PLL2 Fosc\r
+ */\r
+static inline u32 cgu_get_pll2_fosc(void)\r
+{\r
+    u32 ret;\r
+    u32 temp[2];\r
+    u32 residue;\r
+\r
+    uint64_multiply((CGU_PLL_SR2_PLLN + 1) * 8, cgu_get_pll0_fdiv(), temp);\r
+    uint64_divide(temp, CGU_PLL_SR2_PLLM + 1, &ret, &residue);\r
+    if ( (residue << 1) >= CGU_PLL_SR2_PLLM )\r
+        ret++;\r
+\r
+    return ret;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get output frequency of PLL2 phase shifter\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PLL2 Fps\r
+ */\r
+static inline u32 cgu_get_pll2_fps(void)\r
+{\r
+    register u32 fps = cgu_get_pll2_fosc();\r
+\r
+    if ( CGU_PLL_SR2_PLLPE )\r
+    {\r
+        if ( CGU_PLL_SR2_PLLPS )\r
+            /*  1.25    */\r
+            fps = ((fps << 3) + 4) / 9;\r
+        else\r
+            /*  1.125   */\r
+            fps = ((fps << 2) + 2) / 5;\r
+    }\r
+\r
+    return fps;\r
+}\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *           Global Function\r
+ * ####################################\r
+ */\r
+\r
+/*\r
+ *  Description:\r
+ *    get frequency of MIPS (0: core, 1: DSP)\r
+ *  Input:\r
+ *    cpu --- int, 0: core, 1: DSP\r
+ *  Output:\r
+ *    u32 --- frequency of MIPS coprocessor (0: core, 1: DSP)\r
+ */\r
+u32 cgu_get_mips_clock(int cpu)\r
+{\r
+    register u32 ret = cgu_get_pll0_fosc();\r
+\r
+    if ( CGU_CRD_CRD )\r
+        ret = (ret + (CGU_CRD_CRD >> 1)) / (CGU_CRD_CRD + 1);\r
+    if ( cpu == 0 && CGU_CRD_CRD1 )\r
+        ret >>= CGU_CRD_CRD1;\r
+    return ret;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get frequency of MIPS core\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of MIPS core\r
+ */\r
+u32 cgu_get_cpu_clock(void)\r
+{\r
+    return cgu_get_mips_clock(0);\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get frequency of sub-system and memory controller\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of sub-system and memory controller\r
+ */\r
+u32 cgu_get_io_region_clock(void)\r
+{\r
+    register u32 ret = (CGU_MUX_SUB_SYS > 4) ? cgu_get_pll0_fosc() : cgu_get_mips_clock(1);\r
+\r
+    switch ( CGU_MUX_SUB_SYS )\r
+    {\r
+    case 0:\r
+        break;\r
+    case 1:\r
+    default:\r
+        ret = (ret + 1) >> 1; break;\r
+    case 2:\r
+        ret = (ret + 1) / 3; break;\r
+    case 3:\r
+        ret = (ret + 2) >> 2; break;\r
+    case 5:\r
+        ret = ((ret << 1) + 1) / 3; break;\r
+    case 6:\r
+        ret = ((ret << 1) + 2) / 5;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get frequency of FPI bus\r
+ *  Input:\r
+ *    fpi --- int, 1: FPI bus 1 (FBS1/Fast FPI Bus), 2: FPI bus 2 (FBS2)\r
+ *  Output:\r
+ *    u32 --- frequency of FPI bus\r
+ */\r
+u32 cgu_get_fpi_bus_clock(int fpi)\r
+{\r
+    register u32 ret = cgu_get_io_region_clock();\r
+\r
+    if ( fpi == 2 )\r
+        ret >>= 1;\r
+    return ret;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get frequency of PP32 processor\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PP32 processor\r
+ */\r
+u32 cgu_get_pp32_clock(void)\r
+{\r
+    register u32 ret;\r
+\r
+    switch ( CGU_MUX_PP32 )\r
+    {\r
+    case 0:\r
+    default:\r
+        ret = ((cgu_get_pll2_fosc() << 2) + 2) / 5; break;\r
+    case 1:\r
+        ret = ((cgu_get_pll2_fosc() << 3) + 4) / 9; break;\r
+    case 2:\r
+        ret = cgu_get_fpi_bus_clock(1); break;\r
+    case 3:\r
+        ret = cgu_get_mips_clock(1);\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get frequency of PCI bus\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of PCI bus\r
+ */\r
+u32 cgu_get_pci_clock(void)\r
+{\r
+    register u32 ret = 0;\r
+\r
+    if ( !CGU_IF_CLK_PCIS )\r
+    {\r
+        ret = cgu_get_pll2_fosc();\r
+        if ( CGU_IF_CLK_PCIF )\r
+            ret = (ret + 2) / 5;\r
+        else\r
+            ret = (ret + 4) / 9;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get frequency of ethernet module (MII)\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of ethernet module\r
+ */\r
+u32 cgu_get_ethernet_clock(void)\r
+{\r
+    register u32 ret = 0;\r
+\r
+    if ( !CGU_IF_CLK_MIICS )\r
+    {\r
+        ret = cgu_get_pll2_fosc();\r
+        if ( CGU_MUX_MII_CLK )\r
+            ret = (ret + 3) / 6;\r
+        else\r
+            ret = (ret + 6) / 12;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get frequency of USB\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    u32 --- frequency of USB\r
+ */\r
+u32 cgu_get_usb_clock(void)\r
+{\r
+    return CGU_IF_CLK_USBCS ? 12000000 : (cgu_get_pll2_fosc() + 12) / 25;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    get frequency of CLK_OUT pin\r
+ *  Input:\r
+ *    clkout --- int, clock out pin number\r
+ *  Output:\r
+ *    u32    --- frequency of CLK_OUT pin\r
+ */\r
+u32 cgu_get_clockout(int clkout)\r
+{\r
+    u32 fosc1 = cgu_get_pll1_fosc();\r
+    u32 fosc2 = cgu_get_pll2_fosc();\r
+\r
+    if ( clkout > 3 || clkout < 0 )\r
+        return 0;\r
+\r
+    switch ( ((u32)clkout << 2) | GET_BITS(*DANUBE_CGU_IF_CLK, 21 + clkout * 2, 20 + clkout * 2) )\r
+    {\r
+    case 0: /*  32.768KHz   */\r
+    case 14:\r
+        return (fosc1 + 6000) / 12000;\r
+    case 1: /*  1.536MHz    */\r
+        return (fosc1 + 128) / 256;\r
+    case 2: /*  2.5MHz      */\r
+        return (fosc2 + 60) / 120;\r
+    case 3: /*  12MHz       */\r
+    case 5:\r
+    case 12:\r
+        return (fosc2 + 12) / 25;\r
+    case 4: /*  40MHz       */\r
+        return (fosc2 * 2 + 7) / 15;\r
+    case 6: /*  24MHz       */\r
+        return (fosc2 * 2 + 12) / 25;\r
+    case 7: /*  48MHz       */\r
+        return (fosc2 * 4 + 12) / 25;\r
+    case 8: /*  25MHz       */\r
+    case 15:\r
+        return (fosc2 + 6) / 12;\r
+    case 9: /*  50MHz       */\r
+    case 13:\r
+        return (fosc2 + 3) / 6;\r
+    case 10:/*  30MHz       */\r
+        return (fosc2 + 5) / 10;\r
+    case 11:/*  60MHz       */\r
+        return (fosc2 + 2) / 5;\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *           Init/Cleanup API\r
+ * ####################################\r
+ */\r
+\r
+/*\r
+ *  Description:\r
+ *    register device\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    0    --- successful\r
+ *    else --- failure, usually it is negative value of error code\r
+ */\r
+int __init danube_cgu_init(void)\r
+{\r
+    int ret;\r
+\r
+    ret = misc_register(&cgu_miscdev);\r
+    if ( ret )\r
+    {\r
+        printk(KERN_ERR "cgu: can't misc_register\n");\r
+        return ret;\r
+    }\r
+    else\r
+        printk(KERN_INFO "cgu: misc_register on minor = %d\n", cgu_miscdev.minor);\r
+\r
+    /*\r
+     *  initialize fake registers to do testing on Amazon\r
+     */\r
+#if defined(DEBUG_ON_AMAZON) && DEBUG_ON_AMAZON\r
+    #ifdef  DEBUG_PRINT_INFO\r
+    #undef  DEBUG_PRINT_INFO\r
+    #endif\r
+    #define DEBUG_PRINT_INFO    1\r
+\r
+    *DANUBE_CGU_DIV         = 0x00010019;\r
+    *DANUBE_CGU_PLL_NMK0    = 0x416002C3;\r
+    *DANUBE_CGU_PLL_SR0     = 0x74000013;\r
+    *DANUBE_CGU_PLL_NMK1    = 0x4C60009C;\r
+    *DANUBE_CGU_PLL_SR1     = 0x54000013;\r
+    *DANUBE_CGU_PLL_SR2     = 0x58890013;\r
+    *DANUBE_CGU_IF_CLK      = 0x00000000;\r
+    *DANUBE_CGU_OSC_CTRL    = 0x00000000;\r
+    *DANUBE_CGU_SMD         = 0x00000000;\r
+    *DANUBE_CGU_CRD         = 0x00010000;\r
+    *DANUBE_CGU_CT1SR       = 0x00000000;\r
+    *DANUBE_CGU_CT2SR       = CGU_PLL_NMK1_PLLK;\r
+    *DANUBE_CGU_PCMCR       = 0x00000000;\r
+    *DANUBE_CGU_MUX         = 0x00000008;\r
+#endif  //  defined(DEBUG_ON_AMAZON) && DEBUG_ON_AMAZON\r
+\r
+    /*\r
+     *  for testing only\r
+     */\r
+#if defined(DEBUG_PRINT_INFO) && DEBUG_PRINT_INFO\r
+    printk("pll0 N = %d, M = %d, K = %d, DIV = %d\n", CGU_PLL_NMK0_PLLN, CGU_PLL_NMK0_PLLM, CGU_PLL_NMK0_PLLK, CGU_PLL_SR0_PLLDIV);\r
+    printk("pll1 N = %d, M = %d, K = %d, DIV = %d\n", CGU_PLL_NMK1_PLLN, CGU_PLL_NMK1_PLLM, CGU_PLL_NMK1_PLLK, CGU_PLL_SR1_PLLDIV);\r
+    printk("pll2 N = %d, M = %d, DIV = %d\n", CGU_PLL_SR2_PLLN, CGU_PLL_SR2_PLLM, CGU_PLL_SR2_PLLDIV);\r
+    printk("pll0_fosc    = %d\n", cgu_get_pll0_fosc());\r
+    printk("pll0_fps     = %d\n", cgu_get_pll0_fps());\r
+    printk("pll0_fdiv    = %d\n", cgu_get_pll0_fdiv());\r
+    printk("pll1_fosc    = %d\n", cgu_get_pll1_fosc());\r
+    printk("pll1_fps     = %d\n", cgu_get_pll1_fps());\r
+    printk("pll1_fdiv    = %d\n", cgu_get_pll1_fdiv());\r
+    printk("pll2_fosc    = %d\n", cgu_get_pll2_fosc());\r
+    printk("pll2_fps     = %d\n", cgu_get_pll2_fps());\r
+    printk("mips0 clock  = %d\n", cgu_get_mips_clock(0));\r
+    printk("mips1 clock  = %d\n", cgu_get_mips_clock(1));\r
+    printk("cpu clock    = %d\n", cgu_get_cpu_clock());\r
+    printk("IO region    = %d\n", cgu_get_io_region_clock());\r
+    printk("FPI bus 1    = %d\n", cgu_get_fpi_bus_clock(1));\r
+    printk("FPI bus 2    = %d\n", cgu_get_fpi_bus_clock(2));\r
+    printk("PP32 clock   = %d\n", cgu_get_pp32_clock());\r
+    printk("PCI clock    = %d\n", cgu_get_pci_clock());\r
+    printk("Ethernet     = %d\n", cgu_get_ethernet_clock());\r
+    printk("USB clock    = %d\n", cgu_get_usb_clock());\r
+    printk("Clockout0    = %d\n", cgu_get_clockout(0));\r
+    printk("Clockout1    = %d\n", cgu_get_clockout(1));\r
+    printk("Clockout2    = %d\n", cgu_get_clockout(2));\r
+    printk("Clockout3    = %d\n", cgu_get_clockout(3));\r
+#endif  //  defined(DEBUG_PRINT_INFO) && DEBUG_PRINT_INFO\r
+\r
+    return 0;\r
+}\r
+\r
+/*\r
+ *  Description:\r
+ *    deregister device\r
+ *  Input:\r
+ *    none\r
+ *  Output:\r
+ *    none\r
+ */\r
+void __exit danube_cgu_exit(void)\r
+{\r
+    int ret;\r
+\r
+    ret = misc_deregister(&cgu_miscdev);\r
+    if ( ret )\r
+        printk(KERN_ERR "cgu: can't misc_deregister, get error number %d\n", -ret);\r
+    else\r
+        printk(KERN_INFO "cgu: misc_deregister successfully\n");\r
+}\r
+\r
+module_init(danube_cgu_init);\r
+module_exit(danube_cgu_exit);\r
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/ifx_cgu.h b/package/uboot-ifxmips/files/cpu/mips/danube/ifx_cgu.h
new file mode 100644 (file)
index 0000000..78fe21d
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef __DANUBE_CGU_DEV_H__2005_07_20__14_26__\r
+#define __DANUBE_CGU_DEV_H__2005_07_20__14_26__\r
+\r
+\r
+/******************************************************************************\r
+       Copyright (c) 2002, Infineon Technologies.  All rights reserved.\r
+\r
+                               No Warranty\r
+   Because the program is licensed free of charge, there is no warranty for\r
+   the program, to the extent permitted by applicable law.  Except when\r
+   otherwise stated in writing the copyright holders and/or other parties\r
+   provide the program "as is" without warranty of any kind, either\r
+   expressed or implied, including, but not limited to, the implied\r
+   warranties of merchantability and fitness for a particular purpose. The\r
+   entire risk as to the quality and performance of the program is with\r
+   you.  should the program prove defective, you assume the cost of all\r
+   necessary servicing, repair or correction.\r
+\r
+   In no event unless required by applicable law or agreed to in writing\r
+   will any copyright holder, or any other party who may modify and/or\r
+   redistribute the program as permitted above, be liable to you for\r
+   damages, including any general, special, incidental or consequential\r
+   damages arising out of the use or inability to use the program\r
+   (including but not limited to loss of data or data being rendered\r
+   inaccurate or losses sustained by you or third parties or a failure of\r
+   the program to operate with any other programs), even if such holder or\r
+   other party has been advised of the possibility of such damages.\r
+******************************************************************************/\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *              Definition\r
+ * ####################################\r
+ */\r
+\r
+/*\r
+ *  ioctl Command\r
+ */\r
+#define CGU_IOC_MAGIC                   'u'\r
+#define CGU_GET_CLOCK_RATES             _IOW(CGU_IOC_MAGIC, 0, struct cgu_clock_rates)\r
+#define CGU_IOC_MAXNR                   1\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *              Data Type\r
+ * ####################################\r
+ */\r
+\r
+/*\r
+ *  Data Type Used to Call ioctl(GET_CLOCK_RATES)\r
+ */\r
+struct cgu_clock_rates {\r
+    u32     mips0;\r
+    u32     mips1;\r
+    u32     cpu;\r
+    u32     io_region;\r
+    u32     fpi_bus1;\r
+    u32     fpi_bus2;\r
+    u32     pp32;\r
+    u32     pci;\r
+    u32     ethernet;\r
+    u32     usb;\r
+    u32     clockout0;\r
+    u32     clockout1;\r
+    u32     clockout2;\r
+    u32     clockout3;\r
+};\r
+\r
+\r
+/*\r
+ * ####################################\r
+ *             Declaration\r
+ * ####################################\r
+ */\r
+\r
+#if defined(__KERNEL__)\r
+    extern u32 cgu_get_mips_clock(int);\r
+    extern u32 cgu_get_cpu_clock(void);\r
+    extern u32 cgu_get_io_region_clock(void);\r
+    extern u32 cgu_get_fpi_bus_clock(int);\r
+    extern u32 cgu_get_pp32_clock(void);\r
+    extern u32 cgu_get_pci_clock(void);\r
+    extern u32 cgu_get_ethernet_clock(void);\r
+    extern u32 cgu_get_usb_clock(void);\r
+    extern u32 cgu_get_clockout(int);\r
+#endif  //  defined(__KERNEL__)\r
+\r
+\r
+#endif  //  __DANUBE_CGU_DEV_H__2005_07_20__14_26__\r
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/ifx_clock.c b/package/uboot-ifxmips/files/cpu/mips/danube/ifx_clock.c
new file mode 100644 (file)
index 0000000..0a1cdac
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm-mips/danube.h>
+
+
+
+/*******************************************************************************
+*
+* get_cpuclk - returns the frequency of the CPU. 
+*
+* NOTE:
+*   This functions should be used by the hardware driver to get the correct
+*   frequency of the CPU. 
+*/
+
+unsigned int danube_get_ddr_hz(void)
+{
+        switch((*DANUBE_CGU_SYS) & 0x3){
+                case 0:
+                        return 166666667;
+                case 1:
+                        return 133333333;
+                case 2:
+                        return 111111111;
+                case 3:
+                        return 83333333;
+        }
+}
+
+
+uint danube_get_cpuclk(void)
+{
+#ifdef CONFIG_USE_EMULATOR
+        return EMULATOR_CPU_SPEED;
+#else //NOT CONFIG_USE_EMULATOR
+        unsigned int ddr_clock=danube_get_ddr_hz();
+        switch((*DANUBE_CGU_SYS) & 0xc){
+                case 0:
+                        return 333333333;
+                case 4:
+                        return ddr_clock;
+                case 8:
+                        return ddr_clock << 1;
+                default:
+                       break;
+                        /*reserved*/
+        }
+#endif
+
+}
+
+
+uint danube_get_fpiclk(void)
+{
+#ifdef CONFIG_USE_EMULATOR
+        unsigned int  clkCPU;
+        clkCPU = danube_get_cpu_hz();
+        return clkCPU >> 2;
+#else //NOT CONFIG_USE_EMULATOR
+        unsigned int ddr_clock=danube_get_ddr_hz();
+        if ((*DANUBE_CGU_SYS) & 0x40){
+                return ddr_clock >> 1;
+        }
+        return ddr_clock;
+#endif
+
+}
+
+
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/ifx_cpu.c b/package/uboot-ifxmips/files/cpu/mips/danube/ifx_cpu.c
new file mode 100644 (file)
index 0000000..49355de
--- /dev/null
@@ -0,0 +1,5 @@
+
+#define IFX_CPU_RESET                                  \
+{      *DANUBE_RCU_RST_REQ |=1<<30;                    \
+}
+
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/ifx_start.S b/package/uboot-ifxmips/files/cpu/mips/danube/ifx_start.S
new file mode 100644 (file)
index 0000000..17c0b0a
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * IFX Platform Dependent CPU Initializations
+ * - for Danube
+ */
+
+#define IFX_EBU_BOOTCFG_DWORD                                                  \
+       .word INFINEON_EBU_BOOTCFG; /* EBU init code, fetched during booting */ \
+       .word 0x00000000;           /* phases of the flash */
+
+#define IFX_MORE_RESERVED_VECTORS                                              \
+       XVECENT(romExcHandle,0x400);    /* Int, CauseIV=1 */                    \
+       RVECENT(romReserved,129);                                               \
+       RVECENT(romReserved,130);                                               \
+       RVECENT(romReserved,131);                                               \
+       RVECENT(romReserved,132);                                               \
+       RVECENT(romReserved,133);                                               \
+       RVECENT(romReserved,134);                                               \
+       RVECENT(romReserved,135);                                               \
+       RVECENT(romReserved,136);                                               \
+       RVECENT(romReserved,137);                                               \
+       RVECENT(romReserved,138);                                               \
+       RVECENT(romReserved,139);                                               \
+       RVECENT(romReserved,140);                                               \
+       RVECENT(romReserved,141);                                               \
+       RVECENT(romReserved,142);                                               \
+       RVECENT(romReserved,143);                                               \
+       RVECENT(romExcHandle,0x480);    /* EJTAG debug exception */
+
+#define IFX_RESET_PRECHECK                                                     \
+       mfc0    k0, CP0_EBASE;                                                  \
+       and     k0, EBASEF_CPUNUM;                                              \
+       bne     k0, zero, ifx_mips_handler_1;                                   \
+       nop;
+
+#define IFX_CPU_EXTRA_INIT                                                     \
+       mfc0    k0, CP0_CONFIG, 7;                                              \
+       li      k1, 0x04;                                                       \
+       or      k0, k1;                                                         \
+       mtc0    k0, CP0_CONFIG, 7;
+
+#define IFX_CACHE_OPER_MODE                                                    \
+       li      t0, CONF_CM_CACHABLE_NO_WA;
+
+/*
+ * Stop VCPU
+ */
+#define IFX_MIPS_HANDLER_1                                                     \
+       wait;                                                                   \
+       b ifx_mips_handler_1;                                                   \
+       nop;
+
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/incaip_clock.c b/package/uboot-ifxmips/files/cpu/mips/danube/incaip_clock.c
new file mode 100644 (file)
index 0000000..1b0a0fd
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifdef CONFIG_INCA_IP
+
+#include <common.h>
+#include <asm/inca-ip.h>
+
+
+/*******************************************************************************
+*
+* get_cpuclk - returns the frequency of the CPU.
+*
+* Gets the value directly from the INCA-IP hardware.
+*
+* RETURNS:
+*          150.000.000 for 150 MHz
+*          133.333.333 for 133 Mhz (= 400MHz/3)
+*          100.000.000 for 100 Mhz (= 400MHz/4)
+* NOTE:
+*   This functions should be used by the hardware driver to get the correct
+*   frequency of the CPU. Don't use the macros, which are set to init the CPU
+*   frequency in the ROM code.
+*/
+uint incaip_get_cpuclk (void)
+{
+       /*-------------------------------------------------------------------------*/
+       /* CPU Clock Input Multiplexer (MUX I)                                     */
+       /* Multiplexer MUX I selects the maximum input clock to the CPU.           */
+       /*-------------------------------------------------------------------------*/
+       if (*((volatile ulong *) INCA_IP_CGU_CGU_MUXCR) &
+           INCA_IP_CGU_CGU_MUXCR_MUXI) {
+               /* MUX I set to 150 MHz clock */
+               return 150000000;
+       } else {
+               /* MUX I set to 100/133 MHz clock */
+               if (*((volatile ulong *) INCA_IP_CGU_CGU_DIVCR) & 0x40) {
+                       /* Division value is 1/3, maximum CPU operating */
+                       /* frequency is 133.3 MHz                       */
+                       return 133333333;
+               } else {
+                       /* Division value is 1/4, maximum CPU operating */
+                       /* frequency is 100 MHz                         */
+                       return 100000000;
+               }
+       }
+}
+
+/*******************************************************************************
+*
+* get_fpiclk - returns the frequency of the FPI bus.
+*
+* Gets the value directly from the INCA-IP hardware.
+*
+* RETURNS: Frquency in Hz
+*
+* NOTE:
+*   This functions should be used by the hardware driver to get the correct
+*   frequency of the CPU. Don't use the macros, which are set to init the CPU
+*   frequency in the ROM code.
+*   The calculation for the
+*/
+uint incaip_get_fpiclk (void)
+{
+       uint clkCPU;
+
+       clkCPU = incaip_get_cpuclk ();
+
+       switch (*((volatile ulong *) INCA_IP_CGU_CGU_DIVCR) & 0xC) {
+       case 0x4:
+               return clkCPU >> 1;     /* devided by 2 */
+               break;
+       case 0x8:
+               return clkCPU >> 2;     /* devided by 4 */
+               break;
+       default:
+               return clkCPU;
+               break;
+       }
+}
+
+int incaip_set_cpuclk (void)
+{
+       extern void ebu_init(long);
+       extern void cgu_init(long);
+       extern void sdram_init(long);
+       char tmp[64];
+       ulong cpuclk;
+
+       if (getenv_r ("cpuclk", tmp, sizeof (tmp)) > 0) {
+               cpuclk = simple_strtoul (tmp, NULL, 10) * 1000000;
+               cgu_init (cpuclk);
+               ebu_init (cpuclk);
+               sdram_init (cpuclk);
+       }
+
+       return 0;
+}
+
+#endif /* CONFIG_INCA_IP */
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/incaip_wdt.S b/package/uboot-ifxmips/files/cpu/mips/danube/incaip_wdt.S
new file mode 100644 (file)
index 0000000..0c6b5e2
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  INCA-IP Watchdog timer management code.
+ *
+ *  Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+
+#ifdef CONFIG_INCA_IP
+
+#define WD_BASE            0xb8000000
+#define WD_CON0(value)     0x0020(value)
+#define WD_CON1(value)     0x0024(value)
+#define WD_DISABLE         0x00000008
+#define WD_ENABLE          0x00000000
+#define WD_WRITE_PW        0xFFFC00F8
+#define WD_WRITE_ENDINIT   0xFFFC00F3
+#define WD_WRITE_INIT      0xFFFC00F2
+
+
+       .globl  disable_incaip_wdt
+disable_incaip_wdt:
+       li      t0, WD_BASE
+
+       /* Calculate password.
+        */
+       lw      t2, WD_CON1(t0)
+       and     t2, 0xC
+
+       lw      t3, WD_CON0(t0)
+       and     t3, 0xFFFFFF01
+
+       or      t3, t2
+       or      t3, 0xF0
+
+       sw      t3, WD_CON0(t0)         /* write password */
+
+       /* Clear ENDINIT.
+        */
+       li      t1, WD_WRITE_INIT
+       sw      t1, WD_CON0(t0)
+
+
+       li      t1, WD_DISABLE
+       sw      t1, WD_CON1(t0)         /* disable watchdog */
+       li      t1, WD_WRITE_PW
+       sw      t1, WD_CON0(t0)         /* write password */
+       li      t1, WD_WRITE_ENDINIT
+       sw      t1, WD_CON0(t0)         /* end command */
+
+       j       ra
+       nop
+
+#endif /* CONFIG_INCA_IP */
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/interrupts.c b/package/uboot-ifxmips/files/cpu/mips/danube/interrupts.c
new file mode 100644 (file)
index 0000000..87f7a9f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+void enable_interrupts(void)
+{
+}
+
+int disable_interrupts(void)
+{
+       return 0;
+}
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/start.S b/package/uboot-ifxmips/files/cpu/mips/danube/start.S
new file mode 100644 (file)
index 0000000..b1ee491
--- /dev/null
@@ -0,0 +1,442 @@
+/*
+ *  Startup Code for MIPS32 CPU-core
+ *
+ *  Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#if defined(CONFIG_IFX_MIPS)
+#include "ifx_start.S"
+#endif
+
+#define RVECENT(f,n) \
+   b f; nop
+#define XVECENT(f,bev) \
+   b f     ;           \
+   li k0,bev
+
+       .set noreorder
+
+       .globl _start
+       .text
+_start:
+       RVECENT(reset,0)        /* U-boot entry point */
+       RVECENT(reset,1)        /* software reboot */
+#if defined(CONFIG_INCA_IP)
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+       .word 0x00000000           /* phase of the flash                    */
+#elif defined(CONFIG_IFX_MIPS) && defined(IFX_EBU_BOOTCFG_DWORD)
+       IFX_EBU_BOOTCFG_DWORD
+#elif defined(CONFIG_PURPLE)
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+#else
+       RVECENT(romReserved,2)
+#endif
+       RVECENT(romReserved,3)
+       RVECENT(romReserved,4)
+       RVECENT(romReserved,5)
+       RVECENT(romReserved,6)
+       RVECENT(romReserved,7)
+       RVECENT(romReserved,8)
+       RVECENT(romReserved,9)
+       RVECENT(romReserved,10)
+       RVECENT(romReserved,11)
+       RVECENT(romReserved,12)
+       RVECENT(romReserved,13)
+       RVECENT(romReserved,14)
+       RVECENT(romReserved,15)
+       RVECENT(romReserved,16)
+       RVECENT(romReserved,17)
+       RVECENT(romReserved,18)
+       RVECENT(romReserved,19)
+       RVECENT(romReserved,20)
+       RVECENT(romReserved,21)
+       RVECENT(romReserved,22)
+       RVECENT(romReserved,23)
+       RVECENT(romReserved,24)
+       RVECENT(romReserved,25)
+       RVECENT(romReserved,26)
+       RVECENT(romReserved,27)
+       RVECENT(romReserved,28)
+       RVECENT(romReserved,29)
+       RVECENT(romReserved,30)
+       RVECENT(romReserved,31)
+       RVECENT(romReserved,32)
+       RVECENT(romReserved,33)
+       RVECENT(romReserved,34)
+       RVECENT(romReserved,35)
+       RVECENT(romReserved,36)
+       RVECENT(romReserved,37)
+       RVECENT(romReserved,38)
+       RVECENT(romReserved,39)
+       RVECENT(romReserved,40)
+       RVECENT(romReserved,41)
+       RVECENT(romReserved,42)
+       RVECENT(romReserved,43)
+       RVECENT(romReserved,44)
+       RVECENT(romReserved,45)
+       RVECENT(romReserved,46)
+       RVECENT(romReserved,47)
+       RVECENT(romReserved,48)
+       RVECENT(romReserved,49)
+       RVECENT(romReserved,50)
+       RVECENT(romReserved,51)
+       RVECENT(romReserved,52)
+       RVECENT(romReserved,53)
+       RVECENT(romReserved,54)
+       RVECENT(romReserved,55)
+       RVECENT(romReserved,56)
+       RVECENT(romReserved,57)
+       RVECENT(romReserved,58)
+       RVECENT(romReserved,59)
+       RVECENT(romReserved,60)
+       RVECENT(romReserved,61)
+       RVECENT(romReserved,62)
+       RVECENT(romReserved,63)
+       XVECENT(romExcHandle,0x200)     /* bfc00200: R4000 tlbmiss vector */
+       RVECENT(romReserved,65)
+       RVECENT(romReserved,66)
+       RVECENT(romReserved,67)
+       RVECENT(romReserved,68)
+       RVECENT(romReserved,69)
+       RVECENT(romReserved,70)
+       RVECENT(romReserved,71)
+       RVECENT(romReserved,72)
+       RVECENT(romReserved,73)
+       RVECENT(romReserved,74)
+       RVECENT(romReserved,75)
+       RVECENT(romReserved,76)
+       RVECENT(romReserved,77)
+       RVECENT(romReserved,78)
+       RVECENT(romReserved,79)
+       XVECENT(romExcHandle,0x280)     /* bfc00280: R4000 xtlbmiss vector */
+       RVECENT(romReserved,81)
+       RVECENT(romReserved,82)
+       RVECENT(romReserved,83)
+       RVECENT(romReserved,84)
+       RVECENT(romReserved,85)
+       RVECENT(romReserved,86)
+       RVECENT(romReserved,87)
+       RVECENT(romReserved,88)
+       RVECENT(romReserved,89)
+       RVECENT(romReserved,90)
+       RVECENT(romReserved,91)
+       RVECENT(romReserved,92)
+       RVECENT(romReserved,93)
+       RVECENT(romReserved,94)
+       RVECENT(romReserved,95)
+       XVECENT(romExcHandle,0x300)     /* bfc00300: R4000 cache vector */
+       RVECENT(romReserved,97)
+       RVECENT(romReserved,98)
+       RVECENT(romReserved,99)
+       RVECENT(romReserved,100)
+       RVECENT(romReserved,101)
+       RVECENT(romReserved,102)
+       RVECENT(romReserved,103)
+       RVECENT(romReserved,104)
+       RVECENT(romReserved,105)
+       RVECENT(romReserved,106)
+       RVECENT(romReserved,107)
+       RVECENT(romReserved,108)
+       RVECENT(romReserved,109)
+       RVECENT(romReserved,110)
+       RVECENT(romReserved,111)
+       XVECENT(romExcHandle,0x380)     /* bfc00380: R4000 general vector */
+       RVECENT(romReserved,113)
+       RVECENT(romReserved,114)
+       RVECENT(romReserved,115)
+       RVECENT(romReserved,116)
+       RVECENT(romReserved,116)
+       RVECENT(romReserved,118)
+       RVECENT(romReserved,119)
+       RVECENT(romReserved,120)
+       RVECENT(romReserved,121)
+       RVECENT(romReserved,122)
+       RVECENT(romReserved,123)
+       RVECENT(romReserved,124)
+       RVECENT(romReserved,125)
+       RVECENT(romReserved,126)
+       RVECENT(romReserved,127)
+
+       /* We hope there are no more reserved vectors!
+        * 128 * 8 == 1024 == 0x400
+        * so this is address R_VEC+0x400 == 0xbfc00400
+        */
+#if defined(CONFIG_IFX_MIPS) && defined(IFX_MORE_RESERVED_VECTORS)
+       IFX_MORE_RESERVED_VECTORS
+#else
+#ifdef CONFIG_PURPLE
+/* 0xbfc00400 */
+       .word   0xdc870000
+       .word   0xfca70000
+       .word   0x20840008
+       .word   0x20a50008
+       .word   0x20c6ffff
+       .word   0x14c0fffa
+       .word   0x00000000
+       .word   0x03e00008
+       .word   0x00000000
+       .word   0x00000000
+/* 0xbfc00428 */
+       .word   0xdc870000
+       .word   0xfca70000
+       .word   0x20840008
+       .word   0x20a50008
+       .word   0x20c6ffff
+       .word   0x14c0fffa
+       .word   0x00000000
+       .word   0x03e00008
+       .word   0x00000000
+       .word   0x00000000
+#endif /* CONFIG_PURPLE */
+#endif /* CONFIG_IFX_MIPS */
+       .align 4
+reset:
+#if defined(CONFIG_IFX_MIPS) && defined(IFX_RESET_PRECHECK)
+       IFX_RESET_PRECHECK
+#endif
+       /* Clear watch registers.
+        */
+       mtc0    zero, CP0_WATCHLO
+       mtc0    zero, CP0_WATCHHI
+
+       /* STATUS register */
+#ifdef  CONFIG_TB0229
+       li      k0, ST0_CU0
+#else
+       mfc0    k0, CP0_STATUS
+#endif
+       li      k1, ~ST0_IE
+       and     k0, k1
+       mtc0    k0, CP0_STATUS
+
+       /* CAUSE register */
+       mtc0    zero, CP0_CAUSE
+
+#if defined(CONFIG_IFX_MIPS) && defined(IFX_CPU_EXTRA_INIT)
+       IFX_CPU_EXTRA_INIT
+#endif
+
+       /* Init Timer */
+       mtc0    zero, CP0_COUNT
+       mtc0    zero, CP0_COMPARE
+
+       /* CONFIG0 register */
+       li      t0, CONF_CM_UNCACHED
+       mtc0    t0, CP0_CONFIG
+
+       /* Initialize GOT pointer.
+       */
+       bal     1f
+       nop
+       .word   _GLOBAL_OFFSET_TABLE_
+       1:
+       move    gp, ra
+       lw      t1, 0(ra)
+       move    gp, t1
+
+#ifdef CONFIG_INCA_IP
+       /* Disable INCA-IP Watchdog.
+        */
+       la      t9, disable_incaip_wdt
+       jalr    t9
+       nop
+#endif
+
+       /* Initialize any external memory.
+        */
+       la      t9, lowlevel_init
+       jalr    t9
+       nop
+
+       /* Initialize caches...
+        */
+       la      t9, mips_cache_reset
+       jalr    t9
+       nop
+
+       /* ... and enable them.
+        */
+#if defined(CONFIG_IFX_MIPS) && defined(IFX_CACHE_OPER_MODE)
+       IFX_CACHE_OPER_MODE
+#else
+       li      t0, CONF_CM_CACHABLE_NONCOHERENT
+#endif
+       mtc0    t0, CP0_CONFIG
+
+
+       /* Set up temporary stack.
+        */
+       li      a0, CFG_INIT_SP_OFFSET
+       la      t9, mips_cache_lock
+       jalr    t9
+       nop
+
+       li      t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
+       la      sp, 0(t0)
+
+       la      t9, board_init_f
+       j       t9
+       nop
+
+#ifdef CFG_HEAD_CODE
+/*
+ * void jump_unconditional (addr)
+ * This function simply jumps to the location pointed by a0.
+ * a0 = target_location
+ *
+ */
+       .globl  jump_unconditional
+       .ent    jump_unconditional
+jump_unconditional:
+       move t9, a0
+       j       t9
+       nop
+       .end    jump_unconditional
+
+#endif
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * a0 = addr_sp
+ * a1 = gd
+ * a2 = destination address
+ */
+       .globl  relocate_code
+       .ent    relocate_code
+relocate_code:
+       move    sp, a0          /* Set new stack pointer                */
+
+#ifdef CFG_HEAD_CODE
+       li      t0, CFG_HEAD_BASE
+#else
+       li      t0, CFG_MONITOR_BASE
+#endif
+       la      t3, in_ram
+       lw      t2, -12(t3)     /* t2 <-- uboot_end_data        */
+       move    t1, a2
+
+       /*
+        * Fix GOT pointer:
+        *
+        * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+        */
+       move    t6, gp
+#ifdef CFG_HEAD_CODE
+       sub     gp, CFG_HEAD_BASE
+#else
+       sub     gp, CFG_MONITOR_BASE
+#endif
+       add     gp, a2                  /* gp now adjusted              */
+       sub     t6, gp, t6              /* t6 <-- relocation offset     */
+
+       /*
+        * t0 = source address
+        * t1 = target address
+        * t2 = source end address
+        */
+       /* On the purple board we copy the code earlier in a special way
+        * in order to solve flash problems
+        */
+#ifndef CONFIG_PURPLE
+1:
+       lw      t3, 0(t0)
+       sw      t3, 0(t1)
+       addu    t0, 4
+       ble     t0, t2, 1b
+       addu    t1, 4                   /* delay slot                   */
+#endif
+
+       /* If caches were enabled, we would have to flush them here.
+        */
+
+       /* Jump to where we've relocated ourselves.
+        */
+       addi    t0, a2, in_ram - _start
+       j       t0
+       nop
+
+       .word   uboot_end_data
+       .word   uboot_end
+       .word   num_got_entries
+
+in_ram:
+       /* Now we want to update GOT.
+        */
+       lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
+       addi    t4, gp, 8       /* Skipping first two entries.  */
+       li      t2, 2
+1:
+       lw      t1, 0(t4)
+       beqz    t1, 2f
+       add     t1, t6
+       sw      t1, 0(t4)
+2:
+       addi    t2, 1
+       blt     t2, t3, 1b
+       addi    t4, 4           /* delay slot                   */
+
+       /* Clear BSS.
+        */
+       lw      t1, -12(t0)     /* t1 <-- uboot_end_data        */
+       lw      t2, -8(t0)      /* t2 <-- uboot_end             */
+       add     t1, t6          /* adjust pointers              */
+       add     t2, t6
+
+       sub     t1, 4
+1:     addi    t1, 4
+       bltl    t1, t2, 1b
+       sw      zero, 0(t1)     /* delay slot                   */
+
+       move    a0, a1
+       la      t9, board_init_r
+       j       t9
+       move    a1, a2          /* delay slot                   */
+
+       .end    relocate_code
+
+
+       /* Exception handlers.
+        */
+romReserved:
+       b romReserved
+
+romExcHandle:
+       b romExcHandle
+
+       /* Additional handlers.
+        */
+#if defined(CONFIG_IFX_MIPS)
+#if defined(IFX_MIPS_HANDLER_1)
+ifx_mips_handler_1:
+       IFX_MIPS_HANDLER_1
+#endif
+#endif
+
diff --git a/package/uboot-ifxmips/files/cpu/mips/danube/start_bootstrap.S b/package/uboot-ifxmips/files/cpu/mips/danube/start_bootstrap.S
new file mode 100644 (file)
index 0000000..cd7a13f
--- /dev/null
@@ -0,0 +1,428 @@
+/*
+ *  Startup Code for MIPS32 CPU-core
+ *
+ *  Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+
+#define RVECENT(f,n) \
+   b f; nop
+#define XVECENT(f,bev) \
+   b f     ;           \
+   li k0,bev
+
+       .set noreorder
+
+       .globl _start_bootstrap
+       .text
+_start_bootstrap:
+       RVECENT(reset,0)        /* U-boot entry point */
+       RVECENT(reset,1)        /* software reboot */
+#if defined(CONFIG_INCA_IP) || defined(CONFIG_INCA_IP2)
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+       .word 0x00000000           /* phase of the flash                    */
+#elif defined(CONFIG_PURPLE)
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+#elif defined(CONFIG_DANUBE)
+
+       .org 0x10
+       .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
+       .word 0x00000000           /* phase of the flash                    */
+
+       .org 0x18
+       .word 0x312E3000           /* version x.x                           */
+       .word 0x00000000           /* phase of the flash                    */
+#else
+       RVECENT(romReserved,2)
+#endif
+       RVECENT(romReserved,3)
+       RVECENT(romReserved,4)
+       RVECENT(romReserved,5)
+       RVECENT(romReserved,6)
+       RVECENT(romReserved,7)
+       RVECENT(romReserved,8)
+       RVECENT(romReserved,9)
+       RVECENT(romReserved,10)
+       RVECENT(romReserved,11)
+       RVECENT(romReserved,12)
+       RVECENT(romReserved,13)
+       RVECENT(romReserved,14)
+       RVECENT(romReserved,15)
+       RVECENT(romReserved,16)
+       RVECENT(romReserved,17)
+       RVECENT(romReserved,18)
+       RVECENT(romReserved,19)
+       RVECENT(romReserved,20)
+       RVECENT(romReserved,21)
+       RVECENT(romReserved,22)
+       RVECENT(romReserved,23)
+       RVECENT(romReserved,24)
+       RVECENT(romReserved,25)
+       RVECENT(romReserved,26)
+       RVECENT(romReserved,27)
+       RVECENT(romReserved,28)
+       RVECENT(romReserved,29)
+       RVECENT(romReserved,30)
+       RVECENT(romReserved,31)
+       RVECENT(romReserved,32)
+       RVECENT(romReserved,33)
+       RVECENT(romReserved,34)
+       RVECENT(romReserved,35)
+       RVECENT(romReserved,36)
+       RVECENT(romReserved,37)
+       RVECENT(romReserved,38)
+       RVECENT(romReserved,39)
+       RVECENT(romReserved,40)
+       RVECENT(romReserved,41)
+       RVECENT(romReserved,42)
+       RVECENT(romReserved,43)
+       RVECENT(romReserved,44)
+       RVECENT(romReserved,45)
+       RVECENT(romReserved,46)
+       RVECENT(romReserved,47)
+       RVECENT(romReserved,48)
+       RVECENT(romReserved,49)
+       RVECENT(romReserved,50)
+       RVECENT(romReserved,51)
+       RVECENT(romReserved,52)
+       RVECENT(romReserved,53)
+       RVECENT(romReserved,54)
+       RVECENT(romReserved,55)
+       RVECENT(romReserved,56)
+       RVECENT(romReserved,57)
+       RVECENT(romReserved,58)
+       RVECENT(romReserved,59)
+       RVECENT(romReserved,60)
+       RVECENT(romReserved,61)
+       RVECENT(romReserved,62)
+       RVECENT(romReserved,63)
+       XVECENT(romExcHandle,0x200)     /* bfc00200: R4000 tlbmiss vector */
+       RVECENT(romReserved,65)
+       RVECENT(romReserved,66)
+       RVECENT(romReserved,67)
+       RVECENT(romReserved,68)
+       RVECENT(romReserved,69)
+       RVECENT(romReserved,70)
+       RVECENT(romReserved,71)
+       RVECENT(romReserved,72)
+       RVECENT(romReserved,73)
+       RVECENT(romReserved,74)
+       RVECENT(romReserved,75)
+       RVECENT(romReserved,76)
+       RVECENT(romReserved,77)
+       RVECENT(romReserved,78)
+       RVECENT(romReserved,79)
+       XVECENT(romExcHandle,0x280)     /* bfc00280: R4000 xtlbmiss vector */
+       RVECENT(romReserved,81)
+       RVECENT(romReserved,82)
+       RVECENT(romReserved,83)
+       RVECENT(romReserved,84)
+       RVECENT(romReserved,85)
+       RVECENT(romReserved,86)
+       RVECENT(romReserved,87)
+       RVECENT(romReserved,88)
+       RVECENT(romReserved,89)
+       RVECENT(romReserved,90)
+       RVECENT(romReserved,91)
+       RVECENT(romReserved,92)
+       RVECENT(romReserved,93)
+       RVECENT(romReserved,94)
+       RVECENT(romReserved,95)
+       XVECENT(romExcHandle,0x300)     /* bfc00300: R4000 cache vector */
+       RVECENT(romReserved,97)
+       RVECENT(romReserved,98)
+       RVECENT(romReserved,99)
+       RVECENT(romReserved,100)
+       RVECENT(romReserved,101)
+       RVECENT(romReserved,102)
+       RVECENT(romReserved,103)
+       RVECENT(romReserved,104)
+       RVECENT(romReserved,105)
+       RVECENT(romReserved,106)
+       RVECENT(romReserved,107)
+       RVECENT(romReserved,108)
+       RVECENT(romReserved,109)
+       RVECENT(romReserved,110)
+       RVECENT(romReserved,111)
+       XVECENT(romExcHandle,0x380)     /* bfc00380: R4000 general vector */
+       RVECENT(romReserved,113)
+       RVECENT(romReserved,114)
+       RVECENT(romReserved,115)
+       RVECENT(romReserved,116)
+       RVECENT(romReserved,116)
+       RVECENT(romReserved,118)
+       RVECENT(romReserved,119)
+       RVECENT(romReserved,120)
+       RVECENT(romReserved,121)
+       RVECENT(romReserved,122)
+       RVECENT(romReserved,123)
+       RVECENT(romReserved,124)
+       RVECENT(romReserved,125)
+       RVECENT(romReserved,126)
+       RVECENT(romReserved,127)
+
+       /* We hope there are no more reserved vectors!
+        * 128 * 8 == 1024 == 0x400
+        * so this is address R_VEC+0x400 == 0xbfc00400
+        */
+#ifdef CONFIG_PURPLE
+/* 0xbfc00400 */
+       .word   0xdc870000
+       .word   0xfca70000
+       .word   0x20840008
+       .word   0x20a50008
+       .word   0x20c6ffff
+       .word   0x14c0fffa
+       .word   0x00000000
+       .word   0x03e00008
+       .word   0x00000000
+       .word   0x00000000
+/* 0xbfc00428 */
+       .word   0xdc870000
+       .word   0xfca70000
+       .word   0x20840008
+       .word   0x20a50008
+       .word   0x20c6ffff
+       .word   0x14c0fffa
+       .word   0x00000000
+       .word   0x03e00008
+       .word   0x00000000
+       .word   0x00000000
+#endif /* CONFIG_PURPLE */
+       .align 4
+reset:
+#ifdef CONFIG_INCA_IP2
+       /* Check for Host or Voice CPU */
+
+       mfc0    k0, CP0_EBASE 
+       and     k0, EBASEF_CPUNUM
+       srl     k0, EBASEB_CPUNUM
+       subu    k0, EBASE_CPU_HOST
+       bne     k0, zero, voice_reset_handler
+       nop
+       
+#endif
+
+       /* Clear watch registers.
+        */
+       mtc0    zero, CP0_WATCHLO
+       mtc0    zero, CP0_WATCHHI
+
+       /* STATUS register */
+#ifdef  CONFIG_TB0229
+       li      k0, ST0_CU0
+#else
+       mfc0    k0, CP0_STATUS
+#endif
+       li      k1, ~ST0_IE
+       and     k0, k1
+       mtc0    k0, CP0_STATUS
+
+       /* CAUSE register */
+       mtc0    zero, CP0_CAUSE
+
+#ifdef CONFIG_INCA_IP2
+       /* CONFIG7 register */
+       mfc0    k0, CP0_CONFIG, 7
+       li      k1, 4 /* Disable RPS due to E83 bug of 24KEC */
+       or      k0, k1
+       mtc0    k0, CP0_CONFIG, 7
+#endif 
+       /* Init Timer */
+       mtc0    zero, CP0_COUNT
+       mtc0    zero, CP0_COMPARE
+
+       /* CONFIG0 register */
+       li      t0, CONF_CM_UNCACHED
+       mtc0    t0, CP0_CONFIG
+
+       /* Initialize GOT pointer.
+       */
+       bal     1f
+       nop
+       .word   _GLOBAL_OFFSET_TABLE_
+       1:
+       move    gp, ra
+       lw      t1, 0(ra)
+       move    gp, t1
+
+#ifdef CONFIG_INCA_IP
+       /* Disable INCA-IP Watchdog.
+        */
+       la      t9, disable_incaip_wdt
+       jalr    t9
+       nop
+#endif
+
+       /* Initialize any external memory.
+        */
+       la      t9, lowlevel_init
+       jalr    t9
+       nop
+
+       /* Initialize caches...
+        */
+       la      t9, mips_cache_reset
+       jalr    t9
+       nop
+
+       /* ... and enable them.
+        */
+#ifdef CONFIG_MIPS_FORCE_CACHE_WRITE_THROUGH
+       li      t0, CONF_CM_CACHABLE_NO_WA
+#else    
+       li      t0, CONF_CM_CACHABLE_NONCOHERENT
+#endif
+       mtc0    t0, CP0_CONFIG
+
+
+       /* Set up temporary stack.
+        */
+       li      a0, CFG_INIT_SP_OFFSET
+       la      t9, mips_cache_lock
+       jalr    t9
+       nop
+
+       li      t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
+       la      sp, 0(t0)
+
+       la      t9, bootstrap_board_init_f
+       j       t9
+       nop
+
+
+/*
+ * void bootstrap_relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * a0 = addr_sp
+ * a1 = gd
+ * a2 = destination address
+ */
+       .globl  bootstrap_relocate_code
+       .ent    bootstrap_relocate_code
+bootstrap_relocate_code:
+       move    sp, a0          /* Set new stack pointer                */
+
+       li      t0, BOOTSTRAP_CFG_MONITOR_BASE
+       la      t3, in_ram
+       lw      t2, -12(t3)     /* t2 <-- uboot_end_data_bootsrap       */
+       move    t1, a2
+
+       /*
+        * Fix GOT pointer:
+        *
+        * New GOT-PTR = (old GOT-PTR - BOOTSTRAP_CFG_MONITOR_BASE) + Destination Address
+        */
+       move    t6, gp
+       sub     gp, BOOTSTRAP_CFG_MONITOR_BASE
+       add     gp, a2                  /* gp now adjusted              */
+       sub     t6, gp, t6              /* t6 <-- relocation offset     */
+
+       /*
+        * t0 = source address
+        * t1 = target address
+        * t2 = source end address
+        */
+       /* On the purple board we copy the code earlier in a special way
+        * in order to solve flash problems
+        */
+#ifndef CONFIG_PURPLE
+1:
+       lw      t3, 0(t0)
+       sw      t3, 0(t1)
+       addu    t0, 4
+       ble     t0, t2, 1b
+       addu    t1, 4                   /* delay slot                   */
+#endif
+
+       /* If caches were enabled, we would have to flush them here.
+        */
+
+       /* Jump to where we've relocated ourselves.
+        */
+       addi    t0, a2, in_ram - _start_bootstrap
+       j       t0
+       nop
+
+       .word   uboot_end_data_bootstrap
+       .word   uboot_end_bootstrap
+       .word   num_got_entries
+
+in_ram:
+       /* Now we want to update GOT.
+        */
+       lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
+       addi    t4, gp, 8       /* Skipping first two entries.  */
+       li      t2, 2
+1:
+       lw      t1, 0(t4)
+       beqz    t1, 2f
+       add     t1, t6
+       sw      t1, 0(t4)
+2:
+       addi    t2, 1
+       blt     t2, t3, 1b
+       addi    t4, 4           /* delay slot                   */
+
+       /* Clear BSS.
+        */
+       lw      t1, -12(t0)     /* t1 <-- uboot_end_data_bootstrap      */
+       lw      t2, -8(t0)      /* t2 <-- uboot_end_bootstrap           */
+       add     t1, t6          /* adjust pointers              */
+       add     t2, t6
+
+       sub     t1, 4
+1:     addi    t1, 4
+       bltl    t1, t2, 1b
+       sw      zero, 0(t1)     /* delay slot                   */
+
+       move    a0, a1
+       la      t9, bootstrap_board_init_r
+       j       t9
+       move    a1, a2          /* delay slot                   */
+
+       .end    bootstrap_relocate_code
+
+
+       /* Exception handlers.
+        */
+romReserved:
+       b romReserved
+
+romExcHandle:
+       b romExcHandle
+
+#ifdef CONFIG_INCA_IP2
+voice_reset_handler:
+       wait
+       b voice_reset_handler
+       nop
+#endif
diff --git a/package/uboot-ifxmips/files/drivers/ifx_sw.c b/package/uboot-ifxmips/files/drivers/ifx_sw.c
new file mode 100644 (file)
index 0000000..ac8f1c8
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * DANUBE internal switch ethernet driver.
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) \
+    && defined(CONFIG_DANUBE_SWITCH)
+
+#include <malloc.h>
+#include <net.h>
+#include <asm/danube.h>
+#include <asm/addrspace.h>
+#include <asm/pinstrap.h>
+
+#define MII_MODE 1
+#define REV_MII_MODE 2
+
+#define TX_CHAN_NO   7
+#define RX_CHAN_NO   6
+
+#define NUM_RX_DESC    PKTBUFSRX                  
+#define NUM_TX_DESC    8
+#define MAX_PACKET_SIZE        1536
+#define TOUT_LOOP      100
+#define PHY0_ADDR       1 /*fixme: set the correct value here*/ 
+
+#define DMA_WRITE_REG(reg, value) *((volatile u32 *)reg) = (u32)value
+#define DMA_READ_REG(reg, value)    value = (u32)*((volatile u32*)reg)
+
+#define SW_WRITE_REG(reg, value)  *((volatile u32*)reg) = (u32)value   
+#define SW_READ_REG(reg, value)   value = (u32)*((volatile u32*)reg)
+
+typedef struct
+{
+       union
+       {
+               struct
+               {
+                       volatile u32 OWN                 :1;
+                       volatile u32 C                   :1;
+                       volatile u32 Sop                 :1;
+                       volatile u32 Eop                 :1;
+                       volatile u32 reserved            :3;
+                       volatile u32 Byteoffset          :2; 
+                       volatile u32 reserve             :7;
+                       volatile u32 DataLen             :16;
+               }field;
+
+               volatile u32 word;
+       }status;
+       
+       volatile u32 DataPtr;
+} danube_rx_descriptor_t;
+
+typedef struct
+{
+       union
+       {
+               struct
+               {
+                       volatile u32 OWN                 :1;
+                       volatile u32 C                   :1;
+                       volatile u32 Sop                 :1;
+                       volatile u32 Eop                 :1;
+                       volatile u32 Byteoffset          :5; 
+                       volatile u32 reserved            :7;
+                       volatile u32 DataLen             :16;
+               }field;
+
+               volatile u32 word;
+       }status;
+       
+       volatile u32 DataPtr;
+} danube_tx_descriptor_t;
+
+
+
+
+static danube_rx_descriptor_t rx_des_ring[NUM_RX_DESC] __attribute__ ((aligned(8)));
+static danube_tx_descriptor_t tx_des_ring[NUM_TX_DESC] __attribute__ ((aligned(8)));
+static int tx_num, rx_num;
+
+int danube_switch_init(struct eth_device *dev, bd_t * bis);
+int danube_switch_send(struct eth_device *dev, volatile void *packet,int length);
+int danube_switch_recv(struct eth_device *dev);
+void danube_switch_halt(struct eth_device *dev);
+static void danube_init_switch_chip(int mode);
+static void danube_dma_init(void);
+
+
+
+int danube_switch_initialize(bd_t * bis)
+{
+       struct eth_device *dev;
+      
+#if 0
+       printf("Entered danube_switch_initialize()\n");
+#endif
+
+       if (!(dev = (struct eth_device *) malloc (sizeof *dev)))
+       {
+               printf("Failed to allocate memory\n");
+               return 0;
+       }
+       memset(dev, 0, sizeof(*dev));
+
+       danube_dma_init();
+       danube_init_switch_chip(REV_MII_MODE);
+        
+#ifdef CLK_OUT2_25MHZ
+       *DANUBE_GPIO_P0_DIR=0x0000ae78;
+       *DANUBE_GPIO_P0_ALTSEL0=0x00008078; 
+       //joelin for Mii-1       *DANUBE_GPIO_P0_ALTSEL1=0x80000080;
+       *DANUBE_GPIO_P0_ALTSEL1=0x80000000; //joelin for Mii-1 
+       *DANUBE_CGU_IFCCR=0x00400010;
+       *DANUBE_GPIO_P0_OD=0x0000ae78;
+#endif        
+       
+        /*patch for 6996*/
+       
+       *DANUBE_RCU_RST_REQ |=1;
+        mdelay(200);
+       *DANUBE_RCU_RST_REQ &=(unsigned long)~1; 
+       mdelay(1);
+       /*while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+       *DANUBE_PPE_ETOP_MDIO_ACC =0x80123602;
+       */
+       /*while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+       *DANUBE_PPE_ETOP_MDIO_ACC =0x80123602;
+       */
+       /***************/
+       sprintf(dev->name, "danube Switch");
+       dev->init = danube_switch_init;
+       dev->halt = danube_switch_halt;
+       dev->send = danube_switch_send;
+       dev->recv = danube_switch_recv;
+
+       eth_register(dev);
+
+#if 0
+       printf("Leaving danube_switch_initialize()\n");
+#endif
+       while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+       *DANUBE_PPE_ETOP_MDIO_ACC =0x8001840F;
+       while((*DANUBE_PPE_ETOP_MDIO_ACC)&0x80000000);
+       *DANUBE_PPE_ETOP_MDIO_ACC =0x8003840F;
+       while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+       *DANUBE_PPE_ETOP_MDIO_ACC =0x8005840F;
+       //while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+       //*DANUBE_PPE_ETOP_MDIO_ACC =0x8006840F;
+       while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+       *DANUBE_PPE_ETOP_MDIO_ACC =0x8007840F;
+       while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+       *DANUBE_PPE_ETOP_MDIO_ACC =0x8008840F;
+       while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+       *DANUBE_PPE_ETOP_MDIO_ACC =0x8001840F;
+        while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+       *DANUBE_PPE_ETOP_MDIO_ACC =0x80123602; 
+#ifdef CLK_OUT2_25MHZ         
+        while(*DANUBE_PPE_ETOP_MDIO_ACC&0x80000000);
+        *DANUBE_PPE_ETOP_MDIO_ACC =0x80334000;
+#endif
+
+       return 1;
+}
+
+int danube_switch_init(struct eth_device *dev, bd_t * bis)
+{
+       int i;
+
+       tx_num=0;
+       rx_num=0;
+       
+               /* Reset DMA 
+                */
+//     serial_puts("i \n\0");
+
+       *DANUBE_DMA_CS=RX_CHAN_NO;
+       *DANUBE_DMA_CCTRL=0x2;/*fix me, need to reset this channel first?*/
+       *DANUBE_DMA_CPOLL= 0x80000040;
+       /*set descriptor base*/
+       *DANUBE_DMA_CDBA=(u32)rx_des_ring;
+       *DANUBE_DMA_CDLEN=NUM_RX_DESC;
+       *DANUBE_DMA_CIE = 0;
+       *DANUBE_DMA_CCTRL=0x30000;
+               
+       *DANUBE_DMA_CS=TX_CHAN_NO;
+       *DANUBE_DMA_CCTRL=0x2;/*fix me, need to reset this channel first?*/
+       *DANUBE_DMA_CPOLL= 0x80000040;
+       *DANUBE_DMA_CDBA=(u32)tx_des_ring;
+       *DANUBE_DMA_CDLEN=NUM_TX_DESC;  
+       *DANUBE_DMA_CIE = 0;
+       *DANUBE_DMA_CCTRL=0x30100;
+       
+       for(i=0;i < NUM_RX_DESC; i++)
+       {
+               danube_rx_descriptor_t * rx_desc = KSEG1ADDR(&rx_des_ring[i]);
+               rx_desc->status.word=0; 
+               rx_desc->status.field.OWN=1;
+               rx_desc->status.field.DataLen=PKTSIZE_ALIGN;   /* 1536  */      
+               rx_desc->DataPtr=(u32)KSEG1ADDR(NetRxPackets[i]);
+       }
+
+       for(i=0;i < NUM_TX_DESC; i++)
+       {
+               danube_tx_descriptor_t * tx_desc = KSEG1ADDR(&tx_des_ring[i]);
+               memset(tx_desc, 0, sizeof(tx_des_ring[0]));
+       }
+               /* turn on DMA rx & tx channel
+                */
+        *DANUBE_DMA_CS=RX_CHAN_NO;
+        *DANUBE_DMA_CCTRL|=1;/*reset and turn on the channel*/
+       
+       return 0;
+}
+
+void danube_switch_halt(struct eth_device *dev)
+{
+        int i; 
+               for(i=0;i<8;i++)
+       {
+          *DANUBE_DMA_CS=i;
+          *DANUBE_DMA_CCTRL&=~1;/*stop the dma channel*/
+       }
+//     udelay(1000000);
+}
+
+int danube_switch_send(struct eth_device *dev, volatile void *packet,int length)
+{
+
+       int                     i;
+       int                     res = -1;
+
+       danube_tx_descriptor_t * tx_desc= KSEG1ADDR(&tx_des_ring[tx_num]);
+       
+       if (length <= 0)
+       {
+               printf ("%s: bad packet size: %d\n", dev->name, length);
+               goto Done;
+       }
+       
+       for(i=0; tx_desc->status.field.OWN==1; i++)
+       {
+               if(i>=TOUT_LOOP)
+               {
+                       printf("NO Tx Descriptor...");
+                       goto Done;
+               }
+       }
+
+       //serial_putc('s');
+
+       tx_desc->status.field.Sop=1;
+       tx_desc->status.field.Eop=1;
+       tx_desc->status.field.C=0;
+       tx_desc->DataPtr = (u32)KSEG1ADDR(packet);
+       if(length<60)
+               tx_desc->status.field.DataLen = 60;
+       else
+               tx_desc->status.field.DataLen = (u32)length;    
+       
+       asm("SYNC");
+       tx_desc->status.field.OWN=1;
+                               
+       res=length;
+       tx_num++;
+        if(tx_num==NUM_TX_DESC) tx_num=0;
+       *DANUBE_DMA_CS=TX_CHAN_NO;
+         
+       if(!(*DANUBE_DMA_CCTRL & 1))
+       *DANUBE_DMA_CCTRL|=1;
+        
+Done:
+       return res;
+}
+
+int danube_switch_recv(struct eth_device *dev)
+{
+
+       int                    length  = 0;
+
+       danube_rx_descriptor_t * rx_desc;
+        int anchor_num=0;
+       int i;
+       for (;;)
+       {
+               rx_desc = KSEG1ADDR(&rx_des_ring[rx_num]);
+
+               if ((rx_desc->status.field.C == 0) || (rx_desc->status.field.OWN == 1))
+               {
+                  break;
+               }
+                
+                
+               length = rx_desc->status.field.DataLen;
+               if (length)
+               {               
+                       NetReceive((void*)KSEG1ADDR(NetRxPackets[rx_num]), length - 4);
+               //      serial_putc('*');
+               }
+               else
+               {
+                       printf("Zero length!!!\n");
+               }
+
+               rx_desc->status.field.Sop=0;
+               rx_desc->status.field.Eop=0;
+               rx_desc->status.field.C=0;
+               rx_desc->status.field.DataLen=PKTSIZE_ALIGN;
+               rx_desc->status.field.OWN=1;
+               rx_num++;
+               if(rx_num==NUM_RX_DESC) rx_num=0;
+
+       }
+
+       return length;
+}
+
+
+static void danube_init_switch_chip(int mode)
+{
+        int i;
+        /*get and set mac address for MAC*/
+        static unsigned char addr[6];
+        char *tmp,*end; 
+       tmp = getenv ("ethaddr");
+       if (NULL == tmp) {
+               printf("Can't get environment ethaddr!!!\n");
+       //      return NULL;
+       } else {
+               printf("ethaddr=%s\n", tmp);
+       }
+        *DANUBE_PMU_PWDCR = *DANUBE_PMU_PWDCR & 0xFFFFEFDF;
+        *DANUBE_PPE32_ETOP_MDIO_CFG &= ~0x6;
+        *DANUBE_PPE32_ENET_MAC_CFG = 0x187;
+  
+  // turn on port0, set to rmii and turn off port1.
+       if(mode==REV_MII_MODE)
+               {
+                *DANUBE_PPE32_ETOP_CFG = (*DANUBE_PPE32_ETOP_CFG & 0xfffffffc) | 0x0000000a;
+                } 
+       else if (mode == MII_MODE)
+               {
+               *DANUBE_PPE32_ETOP_CFG = (*DANUBE_PPE32_ETOP_CFG & 0xfffffffc) | 0x00000008;
+                }        
+
+       *DANUBE_PPE32_ETOP_IG_PLEN_CTRL = 0x4005ee; // set packetlen.
+        *ENET_MAC_CFG|=1<<11;/*enable the crc*/
+       return;
+}
+
+
+static void danube_dma_init(void)
+{
+        int i;
+//     serial_puts("d \n\0");
+
+        *DANUBE_PMU_PWDCR &=~(1<<DANUBE_PMU_DMA_SHIFT);/*enable DMA from PMU*/
+               /* Reset DMA 
+                */
+       *DANUBE_DMA_CTRL|=1; 
+        *DANUBE_DMA_IRNEN=0;/*disable all the interrupts first*/
+
+       /* Clear Interrupt Status Register               
+       */
+       *DANUBE_DMA_IRNCR=0xfffff;
+       /*disable all the dma interrupts*/
+       *DANUBE_DMA_IRNEN=0;
+       /*disable channel 0 and channel 1 interrupts*/
+       
+         *DANUBE_DMA_CS=RX_CHAN_NO;
+         *DANUBE_DMA_CCTRL=0x2;/*fix me, need to reset this channel first?*/
+          *DANUBE_DMA_CPOLL= 0x80000040;
+          /*set descriptor base*/
+          *DANUBE_DMA_CDBA=(u32)rx_des_ring;
+          *DANUBE_DMA_CDLEN=NUM_RX_DESC;
+          *DANUBE_DMA_CIE = 0;
+          *DANUBE_DMA_CCTRL=0x30000;
+               
+       *DANUBE_DMA_CS=TX_CHAN_NO;
+       *DANUBE_DMA_CCTRL=0x2;/*fix me, need to reset this channel first?*/
+        *DANUBE_DMA_CPOLL= 0x80000040;
+       *DANUBE_DMA_CDBA=(u32)tx_des_ring;
+        *DANUBE_DMA_CDLEN=NUM_TX_DESC;  
+       *DANUBE_DMA_CIE = 0;
+       *DANUBE_DMA_CCTRL=0x30100;
+       /*enable the poll function and set the poll counter*/
+       //*DANUBE_DMA_CPOLL=DANUBE_DMA_POLL_EN | (DANUBE_DMA_POLL_COUNT<<4);
+       /*set port properties, enable endian conversion for switch*/
+       *DANUBE_DMA_PS=0;
+       *DANUBE_DMA_PCTRL|=0xf<<8;/*enable 32 bit endian conversion*/
+
+       return;
+}
+
+
+
+
+
+#endif
diff --git a/package/uboot-ifxmips/files/include/LzmaWrapper.h b/package/uboot-ifxmips/files/include/LzmaWrapper.h
new file mode 100644 (file)
index 0000000..2f9a3ff
--- /dev/null
@@ -0,0 +1,36 @@
+/******************************************************************************
+**
+** FILE NAME    : LzmaWrapper.h
+** PROJECT      : bootloader
+** MODULES      : U-boot
+**
+** DATE         : 2 Nov 2006
+** AUTHOR       : Lin Mars
+** DESCRIPTION  : LZMA decoder support for U-boot 1.1.5
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author         $Comment
+** 2 Nov 2006   Lin Mars        init version which derived from LzmaTest.c from
+**                              LZMA v4.43 SDK
+*******************************************************************************/
+#ifndef  __LZMA_WRAPPER_H__
+#define  __LZMA_WRAPPER_H__
+
+#ifndef LZMA_RESULT_OK
+#define LZMA_RESULT_OK 0
+#endif
+#ifndef LZMA_RESULT_DATA_ERROR
+#define LZMA_RESULT_DATA_ERROR 1
+#endif
+
+extern int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len);
+
+#endif /*__LZMA_WRAPPER_H__*/
diff --git a/package/uboot-ifxmips/files/include/asm-mips/danube.h b/package/uboot-ifxmips/files/include/asm-mips/danube.h
new file mode 100644 (file)
index 0000000..c0be9fb
--- /dev/null
@@ -0,0 +1,2033 @@
+#ifndef DANUBE_H
+#define DANUBE_H
+/******************************************************************************
+       Copyright (c) 2002, Infineon Technologies.  All rights reserved.
+
+                               No Warranty
+   Because the program is licensed free of charge, there is no warranty for 
+   the program, to the extent permitted by applicable law.  Except when     
+   otherwise stated in writing the copyright holders and/or other parties   
+   provide the program "as is" without warranty of any kind, either         
+   expressed or implied, including, but not limited to, the implied         
+   warranties of merchantability and fitness for a particular purpose. The  
+   entire risk as to the quality and performance of the program is with     
+   you.  should the program prove defective, you assume the cost of all     
+   necessary servicing, repair or correction.                               
+                                                                            
+   In no event unless required by applicable law or agreed to in writing    
+   will any copyright holder, or any other party who may modify and/or      
+   redistribute the program as permitted above, be liable to you for        
+   damages, including any general, special, incidental or consequential     
+   damages arising out of the use or inability to use the program           
+   (including but not limited to loss of data or data being rendered        
+   inaccurate or losses sustained by you or third parties or a failure of   
+   the program to operate with any other programs), even if such holder or  
+   other party has been advised of the possibility of such damages. 
+******************************************************************************/
+
+/***********************************************************************/
+/*  Module      :  MEI register address and bits                       */
+/***********************************************************************/
+#define MEI_SPACE_ACCESS       0xB0100C00
+#define MEI_DATA_XFR                           (0x0000 + MEI_SPACE_ACCESS)
+#define        MEI_VERSION                             (0x0200 + MEI_SPACE_ACCESS)     
+#define        ARC_GP_STAT                             (0x0204 + MEI_SPACE_ACCESS)     
+#define        MEI_XFR_ADDR                            (0x020C + MEI_SPACE_ACCESS)     
+#define        MEI_TO_ARC_INT                          (0x021C + MEI_SPACE_ACCESS)
+#define        ARC_TO_MEI_INT                          (0x0220 + MEI_SPACE_ACCESS)     
+#define        ARC_TO_MEI_INT_MASK                     (0x0224 + MEI_SPACE_ACCESS)     
+#define        MEI_DEBUG_WAD                           (0x0228 + MEI_SPACE_ACCESS)     
+#define MEI_DEBUG_RAD                          (0x022C + MEI_SPACE_ACCESS)     
+#define        MEI_DEBUG_DATA                          (0x0230 + MEI_SPACE_ACCESS)     
+#define        MEI_DEBUG_DEC                           (0x0234 + MEI_SPACE_ACCESS)     
+#define        MEI_CONTROL                             (0x0238 + MEI_SPACE_ACCESS)     
+#define        AT_CELLRDY_BC0                          (0x023C + MEI_SPACE_ACCESS)
+#define        AT_CELLRDY_BC1                          (0x0240 + MEI_SPACE_ACCESS)     
+#define        AR_CELLRDY_BC0                          (0x0244 + MEI_SPACE_ACCESS)     
+#define        AR_CELLRDY_BC1                          (0x0248 + MEI_SPACE_ACCESS)     
+#define        AAI_ACCESS                              (0x024C + MEI_SPACE_ACCESS)     
+#define        AAITXCB0                                (0x0300 + MEI_SPACE_ACCESS)     
+#define        AAITXCB1                                (0x0304 + MEI_SPACE_ACCESS)     
+#define        AAIRXCB0                                (0x0308 + MEI_SPACE_ACCESS)     
+#define        AAIRXCB1                                (0x030C + MEI_SPACE_ACCESS)     
+
+
+/***********************************************************************/
+/*  Module      :  WDT register address and bits                       */
+/***********************************************************************/
+#define DANUBE_BIU_WDT_BASE             (0xBf8803F0)
+#define DANUBE_BIU_WDT_CR              (0x0000 + DANUBE_BIU_WDT_BASE)
+#define DANUBE_BIU_WDT_SR              (0x0008 + DANUBE_BIU_WDT_BASE)
+
+
+/***********************************************************************/
+/*  Module      :  PMU register address and bits                       */
+/***********************************************************************/
+#define DANUBE_PMU_BASE_ADDR                           (KSEG1+0x1F102000)
+
+/***PM Control Register***/
+#define DANUBE_PMU_CR                                  ((volatile u32*)(0x001C + DANUBE_PMU_BASE_ADDR))
+#define DANUBE_PMU_PWDCR                               DANUBE_PMU_CR
+#define DANUBE_PMU_SR                                  ((volatile u32*)(0x0020 + DANUBE_PMU_BASE_ADDR))
+
+#define DANUBE_PMU_DMA_SHIFT                    5
+#define DANUBE_PMU_PPE_SHIFT                    13
+#define DANUBE_PMU_ETOP_SHIFT                   22                                             
+#define DANUBE_PMU_ENET0_SHIFT                  24
+#define DANUBE_PMU_ENET1_SHIFT                  25
+
+
+#define DANUBE_PMU                                     DANUBE_PMU_BASE_ADDR
+/***PM Global Enable Register***/
+#define DANUBE_PMU_PM_GEN                       ((volatile u32*)(DANUBE_PMU+ 0x0000))
+#define DANUBE_PMU_PM_GEN_EN16                            (1 << 16)
+#define DANUBE_PMU_PM_GEN_EN15                            (1 << 15)
+#define DANUBE_PMU_PM_GEN_EN14                            (1 << 14)
+#define DANUBE_PMU_PM_GEN_EN13                            (1 << 13)
+#define DANUBE_PMU_PM_GEN_EN12                            (1 << 12)
+#define DANUBE_PMU_PM_GEN_EN11                            (1 << 11)
+#define DANUBE_PMU_PM_GEN_EN10                            (1 << 10)
+#define DANUBE_PMU_PM_GEN_EN9                              (1 << 9)
+#define DANUBE_PMU_PM_GEN_EN8                              (1 << 8)
+#define DANUBE_PMU_PM_GEN_EN7                              (1 << 7)
+#define DANUBE_PMU_PM_GEN_EN6                              (1 << 6)
+#define DANUBE_PMU_PM_GEN_EN5                              (1 << 5)
+#define DANUBE_PMU_PM_GEN_EN4                              (1 << 4)
+#define DANUBE_PMU_PM_GEN_EN3                              (1 << 3)
+#define DANUBE_PMU_PM_GEN_EN2                              (1 << 2)
+#define DANUBE_PMU_PM_GEN_EN0                              (1 << 0)
+                                                                                                                                                             
+/***PM Power Down Enable Register***/
+#define DANUBE_PMU_PM_PDEN                      ((volatile u32*)(DANUBE_PMU+ 0x0008))
+#define DANUBE_PMU_PM_PDEN_EN16                            (1 << 16)
+#define DANUBE_PMU_PM_PDEN_EN15                            (1 << 15)
+#define DANUBE_PMU_PM_PDEN_EN14                            (1 << 14)
+#define DANUBE_PMU_PM_PDEN_EN13                            (1 << 13)
+#define DANUBE_PMU_PM_PDEN_EN12                            (1 << 12)
+#define DANUBE_PMU_PM_PDEN_EN11                            (1 << 11)
+#define DANUBE_PMU_PM_PDEN_EN10                            (1 << 10)
+#define DANUBE_PMU_PM_PDEN_EN9                              (1 << 9)
+#define DANUBE_PMU_PM_PDEN_EN8                              (1 << 8)
+#define DANUBE_PMU_PM_PDEN_EN7                              (1 << 7)
+#define DANUBE_PMU_PM_PDEN_EN5                              (1 << 5)
+#define DANUBE_PMU_PM_PDEN_EN4                              (1 << 4)
+#define DANUBE_PMU_PM_PDEN_EN3                              (1 << 3)
+#define DANUBE_PMU_PM_PDEN_EN2                              (1 << 2)
+#define DANUBE_PMU_PM_PDEN_EN0                              (1 << 0)
+                                                                                                                                                             
+/***PM Wake-Up from Power Down Register***/
+#define DANUBE_PMU_PM_WUP                       ((volatile u32*)(DANUBE_PMU+ 0x0010))
+#define DANUBE_PMU_PM_WUP_WUP16                          (1 << 16)
+#define DANUBE_PMU_PM_WUP_WUP15                          (1 << 15)
+#define DANUBE_PMU_PM_WUP_WUP14                          (1 << 14)
+#define DANUBE_PMU_PM_WUP_WUP13                          (1 << 13)
+#define DANUBE_PMU_PM_WUP_WUP12                          (1 << 12)
+#define DANUBE_PMU_PM_WUP_WUP11                          (1 << 11)
+#define DANUBE_PMU_PM_WUP_WUP10                          (1 << 10)
+#define DANUBE_PMU_PM_WUP_WUP9                            (1 << 9)
+#define DANUBE_PMU_PM_WUP_WUP8                            (1 << 8)
+#define DANUBE_PMU_PM_PDEN_EN7                              (1 << 7)
+#define DANUBE_PMU_PM_PDEN_EN5                              (1 << 5)
+#define DANUBE_PMU_PM_PDEN_EN4                              (1 << 4)
+#define DANUBE_PMU_PM_PDEN_EN3                              (1 << 3)
+#define DANUBE_PMU_PM_PDEN_EN2                              (1 << 2)
+#define DANUBE_PMU_PM_PDEN_EN0                              (1 << 0)
+                                                                                                                                                             
+/***PM Wake-Up from Power Down Register***/
+#define DANUBE_PMU_PM_WUP                       ((volatile u32*)(DANUBE_PMU+ 0x0010))
+#define DANUBE_PMU_PM_WUP_WUP16                          (1 << 16)
+#define DANUBE_PMU_PM_WUP_WUP15                          (1 << 15)
+#define DANUBE_PMU_PM_WUP_WUP14                          (1 << 14)
+#define DANUBE_PMU_PM_WUP_WUP13                          (1 << 13)
+#define DANUBE_PMU_PM_WUP_WUP12                          (1 << 12)
+#define DANUBE_PMU_PM_WUP_WUP11                          (1 << 11)
+#define DANUBE_PMU_PM_WUP_WUP10                          (1 << 10)
+#define DANUBE_PMU_PM_WUP_WUP9                            (1 << 9)
+#define DANUBE_PMU_PM_WUP_WUP8                            (1 << 8)
+#define DANUBE_PMU_PM_WUP_WUP7                            (1 << 7)
+#define DANUBE_PMU_PM_WUP_WUP5                            (1 << 5)
+#define DANUBE_PMU_PM_WUP_WUP4                            (1 << 4)
+#define DANUBE_PMU_PM_WUP_WUP3                            (1 << 3)
+#define DANUBE_PMU_PM_WUP_WUP2                            (1 << 2)
+#define DANUBE_PMU_PM_WUP_WUP0                            (1 << 0)
+                                                                                                                                                             
+/***PM Control Register***/
+#define DANUBE_PMU_PM_CR                        ((volatile u32*)(DANUBE_PMU+ 0x0014))
+#define DANUBE_PMU_PM_CR_AWEN                            (1 << 31)
+#define DANUBE_PMU_PM_CR_SWRST                          (1 << 30)
+#define DANUBE_PMU_PM_CR_SWCR                            (1 << 2)
+#define DANUBE_PMU_PM_CR_CRD (value)                (((( 1 << 2) - 1) & (value)) << 0)
+                                                                                                                                                             
+/***********************************************************************/
+/*  Module      :  RCU register address and bits                       */
+/***********************************************************************/
+#define DANUBE_RCU_BASE_ADDR           (0xBF203000)
+
+#define DANUBE_RCU_REQ                         (0x0010 + DANUBE_RCU_BASE_ADDR)
+#define DANUBE_RCU_RST_REQ                      ((volatile u32*)(DANUBE_RCU_REQ))
+#define DANUBE_RCU_STAT                        (0x0014 + DANUBE_RCU_BASE_ADDR)
+#define DANUBE_RCU_RST_SR              ( (volatile u32 *)(DANUBE_RCU_STAT))
+#define DANUBE_RCU_PCI_RDY             ( (volatile u32 *)(DANUBE_RCU_BASE_ADDR+0x28))
+#define DANUBE_RCU_MON                  (0x0030 + DANUBE_RCU_BASE_ADDR)
+
+
+/***********************************************************************/
+/*  Module      :  BCU  register address and bits                       */
+/***********************************************************************/
+#define DANUBE_BCU_BASE_ADDR   (0xB0100000)
+/***BCU Control Register (0010H)***/
+#define DANUBE_BCU_CON                 (0x0010 + DANUBE_BCU_BASE_ADDR)
+#define DANUBE_BCU_BCU_CON_SPC (value)                (((( 1 << 8) - 1) & (value)) << 24)
+#define DANUBE_BCU_BCU_CON_SPE                              (1 << 19)
+#define DANUBE_BCU_BCU_CON_PSE                              (1 << 18)
+#define DANUBE_BCU_BCU_CON_DBG                              (1 << 16)
+#define DANUBE_BCU_BCU_CON_TOUT (value)               (((( 1 << 16) - 1) & (value)) << 0)
+
+
+/***BCU Error Control Capture Register (0020H)***/
+#define DANUBE_BCU_ECON        (0x0020 + DANUBE_BCU_BASE_ADDR)
+#define DANUBE_BCU_BCU_ECON_TAG (value)                (((( 1 << 4) - 1) & (value)) << 24)
+#define DANUBE_BCU_BCU_ECON_RDN                              (1 << 23)
+#define DANUBE_BCU_BCU_ECON_WRN                              (1 << 22)
+#define DANUBE_BCU_BCU_ECON_SVM                              (1 << 21)
+#define DANUBE_BCU_BCU_ECON_ACK (value)                (((( 1 << 2) - 1) & (value)) << 19)
+#define DANUBE_BCU_BCU_ECON_ABT                              (1 << 18)
+#define DANUBE_BCU_BCU_ECON_RDY                              (1 << 17)
+#define DANUBE_BCU_BCU_ECON_TOUT                            (1 << 16)
+#define DANUBE_BCU_BCU_ECON_ERRCNT (value)             (((( 1 << 16) - 1) & (value)) << 0)
+#define DANUBE_BCU_BCU_ECON_OPC (value)                (((( 1 << 4) - 1) & (value)) << 28)
+
+/***BCU Error Address Capture Register (0024 H)***/
+#define DANUBE_BCU_EADD        (0x0024 + DANUBE_BCU_BASE_ADDR)
+
+/***BCU Error Data Capture Register (0028H)***/
+#define DANUBE_BCU_EDAT        (0x0028 + DANUBE_BCU_BASE_ADDR)
+
+#define DANUBE_BCU_IRNEN       (0x00F4 + DANUBE_BCU_BASE_ADDR)
+#define DANUBE_BCU_IRNICR      (0x00F8 + DANUBE_BCU_BASE_ADDR)
+#define DANUBE_BCU_IRNCR       (0x00FC + DANUBE_BCU_BASE_ADDR)
+
+
+/***********************************************************************/
+/*  Module      :  MBC register address and bits                       */
+/***********************************************************************/
+
+#define DANUBE_MBC                          (0xBF103000)
+/***********************************************************************/
+
+
+/***Mailbox CPU Configuration Register***/
+#define DANUBE_MBC_MBC_CFG                      ((volatile u32*)(DANUBE_MBC+ 0x0080))
+#define DANUBE_MBC_MBC_CFG_SWAP (value)               (((( 1 << 2) - 1) & (value)) << 6)
+#define DANUBE_MBC_MBC_CFG_RES                              (1 << 5)
+#define DANUBE_MBC_MBC_CFG_FWID (value)               (((( 1 << 4) - 1) & (value)) << 1)
+#define DANUBE_MBC_MBC_CFG_SIZE                            (1 << 0)
+
+/***Mailbox CPU Interrupt Status Register***/
+#define DANUBE_MBC_MBC_ISR                      ((volatile u32*)(DANUBE_MBC+ 0x0084))
+#define DANUBE_MBC_MBC_ISR_B3DA                            (1 << 31)
+#define DANUBE_MBC_MBC_ISR_B2DA                            (1 << 30)
+#define DANUBE_MBC_MBC_ISR_B1E                              (1 << 29)
+#define DANUBE_MBC_MBC_ISR_B0E                              (1 << 28)
+#define DANUBE_MBC_MBC_ISR_WDT                              (1 << 27)
+#define DANUBE_MBC_MBC_ISR_DS260 (value)             (((( 1 << 27) - 1) & (value)) << 0)
+
+/***Mailbox CPU Mask Register***/
+#define DANUBE_MBC_MBC_MSK                      ((volatile u32*)(DANUBE_MBC+ 0x0088))
+#define DANUBE_MBC_MBC_MSK_B3DA                            (1 << 31)
+#define DANUBE_MBC_MBC_MSK_B2DA                            (1 << 30)
+#define DANUBE_MBC_MBC_MSK_B1E                              (1 << 29)
+#define DANUBE_MBC_MBC_MSK_B0E                              (1 << 28)
+#define DANUBE_MBC_MBC_MSK_WDT                              (1 << 27)
+#define DANUBE_MBC_MBC_MSK_DS260 (value)             (((( 1 << 27) - 1) & (value)) << 0)
+
+/***Mailbox CPU Mask 01 Register***/
+#define DANUBE_MBC_MBC_MSK01                    ((volatile u32*)(DANUBE_MBC+ 0x008C))
+#define DANUBE_MBC_MBC_MSK01_B3DA                            (1 << 31)
+#define DANUBE_MBC_MBC_MSK01_B2DA                            (1 << 30)
+#define DANUBE_MBC_MBC_MSK01_B1E                              (1 << 29)
+#define DANUBE_MBC_MBC_MSK01_B0E                              (1 << 28)
+#define DANUBE_MBC_MBC_MSK01_WDT                              (1 << 27)
+#define DANUBE_MBC_MBC_MSK01_DS260 (value)             (((( 1 << 27) - 1) & (value)) << 0)
+
+/***Mailbox CPU Mask 10 Register***/
+#define DANUBE_MBC_MBC_MSK10                    ((volatile u32*)(DANUBE_MBC+ 0x0090))
+#define DANUBE_MBC_MBC_MSK10_B3DA                            (1 << 31)
+#define DANUBE_MBC_MBC_MSK10_B2DA                            (1 << 30)
+#define DANUBE_MBC_MBC_MSK10_B1E                              (1 << 29)
+#define DANUBE_MBC_MBC_MSK10_B0E                              (1 << 28)
+#define DANUBE_MBC_MBC_MSK10_WDT                              (1 << 27)
+#define DANUBE_MBC_MBC_MSK10_DS260 (value)             (((( 1 << 27) - 1) & (value)) << 0)
+
+/***Mailbox CPU Short Command Register***/
+#define DANUBE_MBC_MBC_CMD                      ((volatile u32*)(DANUBE_MBC+ 0x0094))
+#define DANUBE_MBC_MBC_CMD_CS270 (value)             (((( 1 << 28) - 1) & (value)) << 0)
+
+/***Mailbox CPU Input Data of Buffer 0***/
+#define DANUBE_MBC_MBC_ID0                      ((volatile u32*)(DANUBE_MBC+ 0x0000))
+#define DANUBE_MBC_MBC_ID0_INDATA
+
+/***Mailbox CPU Input Data of Buffer 1***/
+#define DANUBE_MBC_MBC_ID1                      ((volatile u32*)(DANUBE_MBC+ 0x0020))
+#define DANUBE_MBC_MBC_ID1_INDATA
+
+/***Mailbox CPU Output Data of Buffer 2***/
+#define DANUBE_MBC_MBC_OD2                      ((volatile u32*)(DANUBE_MBC+ 0x0040))
+#define DANUBE_MBC_MBC_OD2_OUTDATA
+
+/***Mailbox CPU Output Data of Buffer 3***/
+#define DANUBE_MBC_MBC_OD3                      ((volatile u32*)(DANUBE_MBC+ 0x0060))
+#define DANUBE_MBC_MBC_OD3_OUTDATA
+
+/***Mailbox CPU Control Register of Buffer 0***/
+#define DANUBE_MBC_MBC_CR0                      ((volatile u32*)(DANUBE_MBC+ 0x0004))
+#define DANUBE_MBC_MBC_CR0_RDYABTFLS (value)          (((( 1 << 3) - 1) & (value)) << 0)
+
+/***Mailbox CPU Control Register of Buffer 1***/
+#define DANUBE_MBC_MBC_CR1                      ((volatile u32*)(DANUBE_MBC+ 0x0024))
+#define DANUBE_MBC_MBC_CR1_RDYABTFLS (value)          (((( 1 << 3) - 1) & (value)) << 0)
+
+/***Mailbox CPU Control Register of Buffer 2***/
+#define DANUBE_MBC_MBC_CR2                      ((volatile u32*)(DANUBE_MBC+ 0x0044))
+#define DANUBE_MBC_MBC_CR2_RDYABTFLS (value)          (((( 1 << 3) - 1) & (value)) << 0)
+
+/***Mailbox CPU Control Register of Buffer 3***/
+#define DANUBE_MBC_MBC_CR3                      ((volatile u32*)(DANUBE_MBC+ 0x0064))
+#define DANUBE_MBC_MBC_CR3_RDYABTFLS (value)          (((( 1 << 3) - 1) & (value)) << 0)
+
+/***Mailbox CPU Free Space of Buffer 0***/
+#define DANUBE_MBC_MBC_FS0                      ((volatile u32*)(DANUBE_MBC+ 0x0008))
+#define DANUBE_MBC_MBC_FS0_FS
+
+/***Mailbox CPU Free Space of Buffer 1***/
+#define DANUBE_MBC_MBC_FS1                      ((volatile u32*)(DANUBE_MBC+ 0x0028))
+#define DANUBE_MBC_MBC_FS1_FS
+
+/***Mailbox CPU Free Space of Buffer 2***/
+#define DANUBE_MBC_MBC_FS2                      ((volatile u32*)(DANUBE_MBC+ 0x0048))
+#define DANUBE_MBC_MBC_FS2_FS
+
+/***Mailbox CPU Free Space of Buffer 3***/
+#define DANUBE_MBC_MBC_FS3                      ((volatile u32*)(DANUBE_MBC+ 0x0068))
+#define DANUBE_MBC_MBC_FS3_FS
+
+/***Mailbox CPU Data Available in Buffer 0***/
+#define DANUBE_MBC_MBC_DA0                      ((volatile u32*)(DANUBE_MBC+ 0x000C))
+#define DANUBE_MBC_MBC_DA0_DA
+
+/***Mailbox CPU Data Available in Buffer 1***/
+#define DANUBE_MBC_MBC_DA1                      ((volatile u32*)(DANUBE_MBC+ 0x002C))
+#define DANUBE_MBC_MBC_DA1_DA
+
+/***Mailbox CPU Data Available in Buffer 2***/
+#define DANUBE_MBC_MBC_DA2                      ((volatile u32*)(DANUBE_MBC+ 0x004C))
+#define DANUBE_MBC_MBC_DA2_DA
+
+/***Mailbox CPU Data Available in Buffer 3***/
+#define DANUBE_MBC_MBC_DA3                      ((volatile u32*)(DANUBE_MBC+ 0x006C))
+#define DANUBE_MBC_MBC_DA3_DA
+
+/***Mailbox CPU Input Absolute Pointer of Buffer 0***/
+#define DANUBE_MBC_MBC_IABS0                    ((volatile u32*)(DANUBE_MBC+ 0x0010))
+#define DANUBE_MBC_MBC_IABS0_IABS
+
+/***Mailbox CPU Input Absolute Pointer of Buffer 1***/
+#define DANUBE_MBC_MBC_IABS1                    ((volatile u32*)(DANUBE_MBC+ 0x0030))
+#define DANUBE_MBC_MBC_IABS1_IABS
+
+/***Mailbox CPU Input Absolute Pointer of Buffer 2***/
+#define DANUBE_MBC_MBC_IABS2                    ((volatile u32*)(DANUBE_MBC+ 0x0050))
+#define DANUBE_MBC_MBC_IABS2_IABS
+
+/***Mailbox CPU Input Absolute Pointer of Buffer 3***/
+#define DANUBE_MBC_MBC_IABS3                    ((volatile u32*)(DANUBE_MBC+ 0x0070))
+#define DANUBE_MBC_MBC_IABS3_IABS
+
+/***Mailbox CPU Input Temporary Pointer of Buffer 0***/
+#define DANUBE_MBC_MBC_ITMP0                    ((volatile u32*)(DANUBE_MBC+ 0x0014))
+#define DANUBE_MBC_MBC_ITMP0_ITMP
+
+/***Mailbox CPU Input Temporary Pointer of Buffer 1***/
+#define DANUBE_MBC_MBC_ITMP1                    ((volatile u32*)(DANUBE_MBC+ 0x0034))
+#define DANUBE_MBC_MBC_ITMP1_ITMP
+
+/***Mailbox CPU Input Temporary Pointer of Buffer 2***/
+#define DANUBE_MBC_MBC_ITMP2                    ((volatile u32*)(DANUBE_MBC+ 0x0054))
+#define DANUBE_MBC_MBC_ITMP2_ITMP
+
+/***Mailbox CPU Input Temporary Pointer of Buffer 3***/
+#define DANUBE_MBC_MBC_ITMP3                    ((volatile u32*)(DANUBE_MBC+ 0x0074))
+#define DANUBE_MBC_MBC_ITMP3_ITMP
+
+/***Mailbox CPU Output Absolute Pointer of Buffer 0***/
+#define DANUBE_MBC_MBC_OABS0                    ((volatile u32*)(DANUBE_MBC+ 0x0018))
+#define DANUBE_MBC_MBC_OABS0_OABS
+
+/***Mailbox CPU Output Absolute Pointer of Buffer 1***/
+#define DANUBE_MBC_MBC_OABS1                    ((volatile u32*)(DANUBE_MBC+ 0x0038))
+#define DANUBE_MBC_MBC_OABS1_OABS
+
+/***Mailbox CPU Output Absolute Pointer of Buffer 2***/
+#define DANUBE_MBC_MBC_OABS2                    ((volatile u32*)(DANUBE_MBC+ 0x0058))
+#define DANUBE_MBC_MBC_OABS2_OABS
+
+/***Mailbox CPU Output Absolute Pointer of Buffer 3***/
+#define DANUBE_MBC_MBC_OABS3                    ((volatile u32*)(DANUBE_MBC+ 0x0078))
+#define DANUBE_MBC_MBC_OABS3_OABS
+
+/***Mailbox CPU Output Temporary Pointer of Buffer 0***/
+#define DANUBE_MBC_MBC_OTMP0                    ((volatile u32*)(DANUBE_MBC+ 0x001C))
+#define DANUBE_MBC_MBC_OTMP0_OTMP
+
+/***Mailbox CPU Output Temporary Pointer of Buffer 1***/
+#define DANUBE_MBC_MBC_OTMP1                    ((volatile u32*)(DANUBE_MBC+ 0x003C))
+#define DANUBE_MBC_MBC_OTMP1_OTMP
+
+/***Mailbox CPU Output Temporary Pointer of Buffer 2***/
+#define DANUBE_MBC_MBC_OTMP2                    ((volatile u32*)(DANUBE_MBC+ 0x005C))
+#define DANUBE_MBC_MBC_OTMP2_OTMP
+
+/***Mailbox CPU Output Temporary Pointer of Buffer 3***/
+#define DANUBE_MBC_MBC_OTMP3                    ((volatile u32*)(DANUBE_MBC+ 0x007C))
+#define DANUBE_MBC_MBC_OTMP3_OTMP
+
+/***DSP Control Register***/
+#define DANUBE_MBC_DCTRL                        ((volatile u32*)(DANUBE_MBC+ 0x00A0))
+#define DANUBE_MBC_DCTRL_BA                              (1 << 0)
+#define DANUBE_MBC_DCTRL_BMOD (value)               (((( 1 << 3) - 1) & (value)) << 1)
+#define DANUBE_MBC_DCTRL_IDL                              (1 << 4)
+#define DANUBE_MBC_DCTRL_RES                              (1 << 15)
+
+/***DSP Status Register***/
+#define DANUBE_MBC_DSTA                         ((volatile u32*)(DANUBE_MBC+ 0x00A4))
+#define DANUBE_MBC_DSTA_IDLE                            (1 << 0)
+#define DANUBE_MBC_DSTA_PD                              (1 << 1)
+
+/***DSP Test 1 Register***/
+#define DANUBE_MBC_DTST1                        ((volatile u32*)(DANUBE_MBC+ 0x00A8))
+#define DANUBE_MBC_DTST1_ABORT                          (1 << 0)
+#define DANUBE_MBC_DTST1_HWF32                          (1 << 1)
+#define DANUBE_MBC_DTST1_HWF4M                          (1 << 2)
+#define DANUBE_MBC_DTST1_HWFOP                          (1 << 3)
+
+
+/***********************************************************************/
+/*  Module      :  SSC1 register address and bits                      */
+/***********************************************************************/
+#define DANUBE_SSC1                            (KSEG1+0x1e100800) 
+/***********************************************************************/
+/***SSC Clock Control Register***/
+#define DANUBE_SSC_CLC                         (0x0000)
+#define DANUBE_SSC_CLC_RMC(value)               (((( 1 << 8) - 1) & (value)) << 8)
+#define DANUBE_SSC_CLC_DISS                     (1 << 1)
+#define DANUBE_SSC_CLC_DISR                     (1 << 0)
+/***SSC Port Input Selection Register***/
+#define DANUBE_SSC_PISEL                        (0x0004)
+/***SSC Identification Register***/
+#define DANUBE_SSC_ID                           (0x0008)
+/***Control Register (Programming Mode)***/
+#define DANUBE_SSC_CON                                 (0x0010)
+#define DANUBE_SSC_CON_RUEN                            (1 << 12)
+#define DANUBE_SSC_CON_TUEN                              (1 << 11)
+#define DANUBE_SSC_CON_AEN                              (1 << 10)
+#define DANUBE_SSC_CON_REN                              (1 << 9)
+#define DANUBE_SSC_CON_TEN                              (1 << 8)
+#define DANUBE_SSC_CON_LB                              (1 << 7)
+#define DANUBE_SSC_CON_PO                              (1 << 6)
+#define DANUBE_SSC_CON_PH                              (1 << 5)
+#define DANUBE_SSC_CON_HB                              (1 << 4)
+#define DANUBE_SSC_CON_BM(value)                       (((( 1 << 5) - 1) & (value)) << 16)
+#define DANUBE_SSC_CON_RX_OFF                          (1 << 1)
+#define DANUBE_SSC_CON_TX_OFF                          (1 << 0)
+/***SCC Status Register***/
+#define DANUBE_SSC_STATE                  (0x0014)
+#define DANUBE_SSC_STATE_EN                              (1 << 0)
+#define DANUBE_SSC_STATE_MS                              (1 << 1)
+#define DANUBE_SSC_STATE_BSY                              (1 << 13)
+#define DANUBE_SSC_STATE_RUE                              (1 << 12)
+#define DANUBE_SSC_STATE_TUE                              (1 << 11)
+#define DANUBE_SSC_STATE_AE                              (1 << 10)
+#define DANUBE_SSC_STATE_RE                              (1 << 9)
+#define DANUBE_SSC_STATE_TE                              (1 << 8)
+#define DANUBE_SSC_STATE_BC(value)                (((( 1 << 5) - 1) & (value)) << 16)
+/***SSC Write Hardware Modified Control Register***/
+#define DANUBE_SSC_WHBSTATE                   ( 0x0018)
+#define DANUBE_SSC_WHBSTATE_SETBE                          (1 << 15)
+#define DANUBE_SSC_WHBSTATE_SETPE                          (1 << 14)
+#define DANUBE_SSC_WHBSTATE_SETRE                          (1 << 13)
+#define DANUBE_SSC_WHBSTATE_SETTE                          (1 << 12)
+#define DANUBE_SSC_WHBSTATE_CLRBE                          (1 << 11)
+#define DANUBE_SSC_WHBSTATE_CLRPE                          (1 << 10)
+#define DANUBE_SSC_WHBSTATE_CLRRE                          (1 << 9)
+#define DANUBE_SSC_WHBSTATE_CLRTE                          (1 << 8)
+/***SSC Transmitter Buffer Register***/
+#define DANUBE_SSC_TB                       (0x0020)
+#define DANUBE_SSC_TB_TB_VALUE(value)          (((( 1 << 16) - 1) & (value)) << 0)
+/***SSC Receiver Buffer Register***/
+#define DANUBE_SSC_RB                       (0x0024)
+#define DANUBE_SSC_RB_RB_VALUE(value)          (((( 1 << 16) - 1) & (value)) << 0)
+/***SSC Receive FIFO Control Register***/
+#define DANUBE_SSC_RXFCON                   (0x0030)
+#define DANUBE_SSC_RXFCON_RXFITL(value)             (((( 1 << 6) - 1) & (value)) << 8)
+#define DANUBE_SSC_RXFCON_RXTMEN                        (1 << 2)
+#define DANUBE_SSC_RXFCON_RXFLU                          (1 << 1)
+#define DANUBE_SSC_RXFCON_RXFEN                          (1 << 0)
+/***SSC Transmit FIFO Control Register***/
+#define DANUBE_SSC_TXFCON                   ( 0x0034)
+#define DANUBE_SSC_TXFCON_RXFITL(value)             (((( 1 << 6) - 1) & (value)) << 8)
+#define DANUBE_SSC_TXFCON_TXTMEN                        (1 << 2)
+#define DANUBE_SSC_TXFCON_TXFLU                          (1 << 1)
+#define DANUBE_SSC_TXFCON_TXFEN                          (1 << 0)
+/***SSC FIFO Status Register***/
+#define DANUBE_SSC_FSTAT                    (0x0038)
+#define DANUBE_SSC_FSTAT_TXFFL(value)              (((( 1 << 6) - 1) & (value)) << 8)
+#define DANUBE_SSC_FSTAT_RXFFL(value)              (((( 1 << 6) - 1) & (value)) << 0)
+/***SSC Baudrate Timer Reload Register***/
+#define DANUBE_SSC_BR                       (0x0040)
+#define DANUBE_SSC_BR_BR_VALUE(value)          (((( 1 << 16) - 1) & (value)) << 0)
+#define DANUBE_SSC_BRSTAT                       (0x0044)
+#define DANUBE_SSC_SFCON                        (0x0060)
+#define DANUBE_SSC_SFSTAT                       (0x0064)
+#define DANUBE_SSC_GPOCON                       (0x0070)
+#define DANUBE_SSC_GPOSTAT                      (0x0074)
+#define DANUBE_SSC_WHBGPOSTAT                   (0x0078)
+#define DANUBE_SSC_RXREQ                        (0x0080)
+#define DANUBE_SSC_RXCNT                        (0x0084) 
+/*DMA Registers in Bus Clock Domain*/ 
+#define DANUBE_SSC_DMA_CON                      (0x00EC)
+/*interrupt Node Registers in Bus Clock Domain*/
+#define DANUBE_SSC_IRNEN                        (0x00F4)
+#define DANUBE_SSC_IRNCR                        (0x00F8)
+#define DANUBE_SSC_IRNICR                       (0x00FC)
+#define DANUBE_SSC_IRN_FIR                     0x8
+#define DANUBE_SSC_IRN_EIR                     0x4
+#define DANUBE_SSC_IRN_RIR                     0x2
+#define DANUBE_SSC_IRN_TIR                     0x1
+
+
+#define        DANUBE_SSC1_CLC                 ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_CLC))
+#define        DANUBE_SSC1_ID                  ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_ID))
+#define        DANUBE_SSC1_CON                 ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_CON))
+#define        DANUBE_SSC1_STATE                       ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_STATE))
+#define        DANUBE_SSC1_WHBSTATE                    ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_WHBSTATE))
+#define        DANUBE_SSC1_TB                  ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_TB))
+#define        DANUBE_SSC1_RB                  ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_RB))
+#define        DANUBE_SSC1_FSTAT                       ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_FSTAT))
+#define        DANUBE_SSC1_PISEL                       ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_PISEL))
+#define        DANUBE_SSC1_RXFCON                      ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_RXFCON))
+#define        DANUBE_SSC1_TXFCON                      ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_TXFCON))
+#define        DANUBE_SSC1_BR                  ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_BR))
+#define        DANUBE_SSC1_BRSTAT                      ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_BRSTAT))
+#define        DANUBE_SSC1_SFCON                       ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_SFCON))
+#define        DANUBE_SSC1_SFSTAT                      ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_SFSTAT))
+#define        DANUBE_SSC1_GPOCON                      ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_GPOCON))
+#define        DANUBE_SSC1_GPOSTAT                     ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_GPOSTAT))
+#define        DANUBE_SSC1_WHBGPOSTAT                  ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_WHBGPOSTAT))
+#define        DANUBE_SSC1_RXREQ                       ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_RXREQ))
+#define        DANUBE_SSC1_RXCNT                       ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_RXCNT))
+#define        DANUBE_SSC1_DMA_CON                     ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_DMA_CON))
+#define        DANUBE_SSC1_IRNEN                       ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_IRNEN))
+#define        DANUBE_SSC1_IRNICR                      ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_IRNICR))
+#define        DANUBE_SSC1_IRNCR                       ((volatile u32*)(DANUBE_SSC1+DANUBE_SSC_IRNCR))
+
+/***********************************************************************/
+/*  Module      :  GPIO register address and bits                       */
+/***********************************************************************/
+#define DANUBE_GPIO                     (0xBE100B00)
+/***Port 0 Data Output Register (0010H)***/
+#define DANUBE_GPIO_P0_OUT              ((volatile u32 *)(DANUBE_GPIO+ 0x0010))
+/***Port 1 Data Output Register (0040H)***/
+#define DANUBE_GPIO_P1_OUT              ((volatile u32 *)(DANUBE_GPIO+ 0x0040))
+/***Port 0 Data Input Register (0014H)***/
+#define DANUBE_GPIO_P0_IN               ((volatile u32 *)(DANUBE_GPIO+ 0x0014))
+/***Port 1 Data Input Register (0044H)***/
+#define DANUBE_GPIO_P1_IN               ((volatile u32 *)(DANUBE_GPIO+ 0x0044))
+/***Port 0 Direction Register (0018H)***/
+#define DANUBE_GPIO_P0_DIR              ((volatile u32 *)(DANUBE_GPIO+ 0x0018))
+/***Port 1 Direction Register (0048H)***/
+#define DANUBE_GPIO_P1_DIR              ((volatile u32 *)(DANUBE_GPIO+ 0x0048))
+/***Port 0 Alternate Function Select Register 0 (001C H) ***/
+#define DANUBE_GPIO_P0_ALTSEL0          ((volatile u32 *)(DANUBE_GPIO+ 0x001C))
+/***Port 1 Alternate Function Select Register 0 (004C H) ***/
+#define DANUBE_GPIO_P1_ALTSEL0          ((volatile u32 *)(DANUBE_GPIO+ 0x004C))
+/***Port 0 Alternate Function Select Register 1 (0020 H) ***/
+#define DANUBE_GPIO_P0_ALTSEL1          ((volatile u32 *)(DANUBE_GPIO+ 0x0020))
+/***Port 1 Alternate Function Select Register 0 (0050 H) ***/
+#define DANUBE_GPIO_P1_ALTSEL1          ((volatile u32 *)(DANUBE_GPIO+ 0x0050))
+/***Port 0 Open Drain Control Register (0024H)***/
+#define DANUBE_GPIO_P0_OD               ((volatile u32 *)(DANUBE_GPIO+ 0x0024))
+/***Port 1 Open Drain Control Register (0054H)***/
+#define DANUBE_GPIO_P1_OD               ((volatile u32 *)(DANUBE_GPIO+ 0x0054))
+/***Port 0 Input Schmitt-Trigger Off Register (0028 H) ***/
+#define DANUBE_GPIO_P0_STOFF            ((volatile u32 *)(DANUBE_GPIO+ 0x0028))
+/***Port 1 Input Schmitt-Trigger Off Register (0058 H) ***/
+#define DANUBE_GPIO_P1_STOFF            ((volatile u32 *)(DANUBE_GPIO+ 0x0058))
+/***Port 0 Pull Up/Pull Down Select Register (002C H)***/
+#define DANUBE_GPIO_P0_PUDSEL           ((volatile u32 *)(DANUBE_GPIO+ 0x002C))
+/***Port 1 Pull Up/Pull Down Select Register (005C H)***/
+#define DANUBE_GPIO_P1_PUDSEL           ((volatile u32 *)(DANUBE_GPIO+ 0x005C))
+/***Port 0 Pull Up Device Enable Register (0030 H)***/
+#define DANUBE_GPIO_P0_PUDEN            ((volatile u32 *)(DANUBE_GPIO+ 0x0030))
+/***Port 1 Pull Up Device Enable Register (0060 H)***/
+#define DANUBE_GPIO_P1_PUDEN            ((volatile u32 *)(DANUBE_GPIO+ 0x0060))
+/***********************************************************************/
+/*  Module      :  CGU register address and bits                       */
+/***********************************************************************/
+
+#define DANUBE_CGU                          (0xBF103000)
+/***********************************************************************/
+
+/***CGU Clock PLL0 ***/
+#define DANUBE_CGU_PLL0_CFG                    ((volatile u32*)(DANUBE_CGU+ 0x0004))
+/***CGU Clock PLL1 ***/
+#define DANUBE_CGU_PLL1_CFG                    ((volatile u32*)(DANUBE_CGU+ 0x0008))
+/***CGU Clock SYS Mux Register***/
+#define DANUBE_CGU_SYS                         ((volatile u32*)(DANUBE_CGU+ 0x0010))
+/***CGU Interface Clock Control Register***/
+#define DANUBE_CGU_IFCCR                        ((volatile u32*)(DANUBE_CGU+ 0x0018))
+/***CGU PCI Clock Control Register**/
+#define DANUBE_CGU_PCICR                          ((volatile u32*)(DANUBE_CGU+ 0x0034))
+
+
+/***********************************************************************/
+/*  Module      :  PCI register address and bits                       */
+/***********************************************************************/
+#define PCI_CR_PR_OFFSET  0xBE105400
+#define PCI_CR_CLK_CTRL_REG         (PCI_CR_PR_OFFSET + 0x0000)
+
+#define PCI_CR_PCI_ID_REG           (PCI_CR_PR_OFFSET + 0x0004)
+#define PCI_CR_SFT_RST_REG          (PCI_CR_PR_OFFSET + 0x0010)
+#define PCI_CR_PCI_FPI_ERR_ADDR_REG (PCI_CR_PR_OFFSET + 0x0014)
+#define PCI_CR_FCI_PCI_ERR_ADDR_REG (PCI_CR_PR_OFFSET + 0x0018)
+#define PCI_CR_FPI_ERR_TAG_REG      (PCI_CR_PR_OFFSET + 0x001C)
+#define PCI_CR_PCI_IRR_REG          (PCI_CR_PR_OFFSET + 0x0020)
+#define PCI_CR_PCI_IRA_REG          (PCI_CR_PR_OFFSET + 0x0024)
+#define PCI_CR_PCI_IRM_REG          (PCI_CR_PR_OFFSET + 0x0028)
+#define PCI_CR_PCI_EOI_REG          (PCI_CR_PR_OFFSET + 0x002C)
+#define PCI_CR_PCI_MOD_REG          (PCI_CR_PR_OFFSET + 0x0030)
+#define PCI_CR_DV_ID_REG            (PCI_CR_PR_OFFSET + 0x0034)
+#define PCI_CR_SUBSYS_ID_REG        (PCI_CR_PR_OFFSET + 0x0038)
+#define PCI_CR_PCI_PM_REG           (PCI_CR_PR_OFFSET + 0x003C)
+#define PCI_CR_CLASS_CODE1_REG      (PCI_CR_PR_OFFSET + 0x0040)
+#define PCI_CR_BAR11MASK_REG        (PCI_CR_PR_OFFSET + 0x0044)
+#define PCI_CR_BAR12MASK_REG        (PCI_CR_PR_OFFSET + 0x0048)
+#define PCI_CR_BAR13MASK_REG        (PCI_CR_PR_OFFSET + 0x004C)
+#define PCI_CR_BAR14MASK_REG        (PCI_CR_PR_OFFSET + 0x0050)
+#define PCI_CR_BAR15MASK_REG        (PCI_CR_PR_OFFSET + 0x0054)
+#define PCI_CR_BAR16MASK_REG        (PCI_CR_PR_OFFSET + 0x0058)
+#define PCI_CR_CIS_PT1_REG          (PCI_CR_PR_OFFSET + 0x005C)
+#define PCI_CR_SUBSYS_ID1_REG       (PCI_CR_PR_OFFSET + 0x0060)
+#define PCI_CR_PCI_ADDR_MAP11_REG   (PCI_CR_PR_OFFSET + 0x0064)
+#define PCI_CR_PCI_ADDR_MAP12_REG   (PCI_CR_PR_OFFSET + 0x0068)
+#define PCI_CR_PCI_ADDR_MAP13_REG   (PCI_CR_PR_OFFSET + 0x006C)
+#define PCI_CR_PCI_ADDR_MAP14_REG   (PCI_CR_PR_OFFSET + 0x0070)
+#define PCI_CR_PCI_ADDR_MAP15_REG   (PCI_CR_PR_OFFSET + 0x0074)
+#define PCI_CR_PCI_ADDR_MAP16_REG   (PCI_CR_PR_OFFSET + 0x0078)
+#define PCI_CR_FPI_SEG_EN_REG       (PCI_CR_PR_OFFSET + 0x007C)
+#define PCI_CR_PC_ARB_REG           (PCI_CR_PR_OFFSET + 0x0080)
+#define PCI_CR_BAR21MASK_REG        (PCI_CR_PR_OFFSET + 0x0084)
+#define PCI_CR_BAR22MASK_REG        (PCI_CR_PR_OFFSET + 0x0088)
+#define PCI_CR_BAR23MASK_REG        (PCI_CR_PR_OFFSET + 0x008C)
+#define PCI_CR_BAR24MASK_REG        (PCI_CR_PR_OFFSET + 0x0090)
+#define PCI_CR_BAR25MASK_REG        (PCI_CR_PR_OFFSET + 0x0094)
+#define PCI_CR_BAR26MASK_REG        (PCI_CR_PR_OFFSET + 0x0098)
+#define PCI_CR_CIS_PT2_REG          (PCI_CR_PR_OFFSET + 0x009C)
+#define PCI_CR_SUBSYS_ID2_REG       (PCI_CR_PR_OFFSET + 0x00A0)
+#define PCI_CR_PCI_ADDR_MAP21_REG   (PCI_CR_PR_OFFSET + 0x00A4)
+#define PCI_CR_PCI_ADDR_MAP22_REG   (PCI_CR_PR_OFFSET + 0x00A8)
+#define PCI_CR_PCI_ADDR_MAP23_REG   (PCI_CR_PR_OFFSET + 0x00AC)
+
+
+/***********************************************************************/
+/*  Module      :  MCD register address and bits                       */
+/***********************************************************************/
+#define DANUBE_MCD                                     (KSEG1+0x1F106000)
+
+/***Manufacturer Identification Register***/ 
+#define DANUBE_MCD_MANID                               ((volatile u32*)(DANUBE_MCD+ 0x0024))
+#define DANUBE_MCD_MANID_MANUF(value)                  (((( 1 << 11) - 1) & (value)) << 5)
+
+/***Chip Identification Register***/ 
+#define DANUBE_MCD_CHIPID                              ((volatile u32*)(DANUBE_MCD+ 0x0028))
+#define DANUBE_MCD_CHIPID_VERSION_GET(value)             (((value) >> 28) & ((1 << 4) - 1))
+#define DANUBE_MCD_CHIPID_VERSION_SET(value)             (((( 1 << 4) - 1) & (value)) << 28)
+#define DANUBE_MCD_CHIPID_PART_NUMBER_GET(value)         (((value) >> 12) & ((1 << 16) - 1))
+#define DANUBE_MCD_CHIPID_PART_NUMBER_SET(value)         (((( 1 << 16) - 1) & (value)) << 12)
+#define DANUBE_MCD_CHIPID_MANID_GET(value)               (((value) >> 1) & ((1 << 11) - 1))
+#define DANUBE_MCD_CHIPID_MANID_SET(value)               (((( 1 << 11) - 1) & (value)) << 1)
+
+#define DANUBE_CHIPID_STANDARD                         0x00EB
+#define DANUBE_CHIPID_YANGTSE                          0x00ED
+
+/***Redesign Tracing Identification Register***/ 
+#define DANUBE_MCD_RTID                                ((volatile u32*)(DANUBE_MCD+ 0x002C))
+#define DANUBE_MCD_RTID_LC                              (1 << 15)
+#define DANUBE_MCD_RTID_RIX(value)                     (((( 1 << 3) - 1) & (value)) << 0)
+
+                
+/***********************************************************************/
+/*  Module      :  EBU register address and bits                       */
+/***********************************************************************/
+
+#define DANUBE_EBU                          (0xBE105300)
+#define EBU_ADDR_SEL_0     (volatile u32*)(DANUBE_EBU + 0x20)
+#define EBU_ADDR_SEL_1     (volatile u32*)(DANUBE_EBU + 0x24)
+#define EBU_CON_0          (volatile u32*)(DANUBE_EBU + 0x60)
+#define EBU_CON_1          (volatile u32*)(DANUBE_EBU + 0x64)
+#define EBU_NAND_CON       (volatile u32*)(DANUBE_EBU + 0xB0)
+#define EBU_NAND_WAIT      (volatile u32*)(DANUBE_EBU + 0xB4)
+#define EBU_NAND_ECC0      (volatile u32*)(DANUBE_EBU + 0xB8)
+#define EBU_NAND_ECC_AC    (volatile u32*)(DANUBE_EBU + 0xBC)
+
+/***********************************************************************/
+
+
+/***EBU Clock Control Register***/
+#define DANUBE_EBU_CLC                      ((volatile u32*)(DANUBE_EBU+ 0x0000))
+#define DANUBE_EBU_CLC_DISS                            (1 << 1)
+#define DANUBE_EBU_CLC_DISR                            (1 << 0)
+
+/***EBU Global Control Register***/
+#define DANUBE_EBU_CON                      ((volatile u32*)(DANUBE_EBU+ 0x0010))
+#define DANUBE_EBU_CON_DTACS (value)              (((( 1 << 3) - 1) & (value)) << 20)
+#define DANUBE_EBU_CON_DTARW (value)              (((( 1 << 3) - 1) & (value)) << 16)
+#define DANUBE_EBU_CON_TOUTC (value)              (((( 1 << 8) - 1) & (value)) << 8)
+#define DANUBE_EBU_CON_ARBMODE (value)            (((( 1 << 2) - 1) & (value)) << 6)
+#define DANUBE_EBU_CON_ARBSYNC                      (1 << 5)
+#define DANUBE_EBU_CON_1                              (1 << 3)
+
+/***EBU Address Select Register 0***/
+#define DANUBE_EBU_ADDSEL0                  ((volatile u32*)(DANUBE_EBU+ 0x0020))
+#define DANUBE_EBU_ADDSEL0_BASE (value)               (((( 1 << 20) - 1) & (value)) << 12)
+#define DANUBE_EBU_ADDSEL0_MASK (value)               (((( 1 << 4) - 1) & (value)) << 4)
+#define DANUBE_EBU_ADDSEL0_MIRRORE                      (1 << 1)
+#define DANUBE_EBU_ADDSEL0_REGEN                          (1 << 0)
+
+/***EBU Address Select Register 1***/
+#define DANUBE_EBU_ADDSEL1                  ((volatile u32*)(DANUBE_EBU+ 0x0024))
+#define DANUBE_EBU_ADDSEL1_BASE (value)               (((( 1 << 20) - 1) & (value)) << 12)
+#define DANUBE_EBU_ADDSEL1_MASK (value)               (((( 1 << 4) - 1) & (value)) << 4)
+#define DANUBE_EBU_ADDSEL1_MIRRORE                      (1 << 1)
+#define DANUBE_EBU_ADDSEL1_REGEN                          (1 << 0)
+
+/***EBU Address Select Register 2***/
+#define DANUBE_EBU_ADDSEL2                  ((volatile u32*)(DANUBE_EBU+ 0x0028))
+#define DANUBE_EBU_ADDSEL2_BASE (value)               (((( 1 << 20) - 1) & (value)) << 12)
+#define DANUBE_EBU_ADDSEL2_MASK (value)               (((( 1 << 4) - 1) & (value)) << 4)
+#define DANUBE_EBU_ADDSEL2_MIRRORE                      (1 << 1)
+#define DANUBE_EBU_ADDSEL2_REGEN                          (1 << 0)
+
+/***EBU Address Select Register 3***/
+#define DANUBE_EBU_ADDSEL3                  ((volatile u32*)(DANUBE_EBU+ 0x0028))
+#define DANUBE_EBU_ADDSEL3_BASE (value)               (((( 1 << 20) - 1) & (value)) << 12)
+#define DANUBE_EBU_ADDSEL3_MASK (value)               (((( 1 << 4) - 1) & (value)) << 4)
+#define DANUBE_EBU_ADDSEL3_MIRRORE                      (1 << 1)
+#define DANUBE_EBU_ADDSEL3_REGEN                          (1 << 0)
+
+/***EBU Bus Configuration Register 0***/
+#define DANUBE_EBU_BUSCON0                  ((volatile u32*)(DANUBE_EBU+ 0x0060))
+#define DANUBE_EBU_BUSCON0_WRDIS                          (1 << 31)
+#define DANUBE_EBU_BUSCON0_ALEC (value)               (((( 1 << 2) - 1) & (value)) << 29)
+#define DANUBE_EBU_BUSCON0_BCGEN (value)              (((( 1 << 2) - 1) & (value)) << 27)
+#define DANUBE_EBU_BUSCON0_AGEN (value)               (((( 1 << 2) - 1) & (value)) << 24)
+#define DANUBE_EBU_BUSCON0_CMULTR (value)             (((( 1 << 2) - 1) & (value)) << 22)
+#define DANUBE_EBU_BUSCON0_WAIT (value)               (((( 1 << 2) - 1) & (value)) << 20)
+#define DANUBE_EBU_BUSCON0_WAITINV                      (1 << 19)
+#define DANUBE_EBU_BUSCON0_SETUP                          (1 << 18)
+#define DANUBE_EBU_BUSCON0_PORTW (value)              (((( 1 << 2) - 1) & (value)) << 16)
+#define DANUBE_EBU_BUSCON0_WAITRDC (value)            (((( 1 << 7) - 1) & (value)) << 9)
+#define DANUBE_EBU_BUSCON0_WAITWRC (value)            (((( 1 << 3) - 1) & (value)) << 6)
+#define DANUBE_EBU_BUSCON0_HOLDC (value)              (((( 1 << 2) - 1) & (value)) << 4)
+#define DANUBE_EBU_BUSCON0_RECOVC (value)             (((( 1 << 2) - 1) & (value)) << 2)
+#define DANUBE_EBU_BUSCON0_CMULT (value)              (((( 1 << 2) - 1) & (value)) << 0)
+
+/***EBU Bus Configuration Register 1***/
+#define DANUBE_EBU_BUSCON1                  ((volatile u32*)(DANUBE_EBU+ 0x0064))
+#define DANUBE_EBU_BUSCON1_WRDIS                          (1 << 31)
+#define DANUBE_EBU_BUSCON1_ALEC (value)               (((( 1 << 2) - 1) & (value)) << 29)
+#define DANUBE_EBU_BUSCON1_BCGEN (value)              (((( 1 << 2) - 1) & (value)) << 27)
+#define DANUBE_EBU_BUSCON1_AGEN (value)               (((( 1 << 2) - 1) & (value)) << 24)
+#define DANUBE_EBU_BUSCON1_CMULTR (value)             (((( 1 << 2) - 1) & (value)) << 22)
+#define DANUBE_EBU_BUSCON1_WAIT (value)               (((( 1 << 2) - 1) & (value)) << 20)
+#define DANUBE_EBU_BUSCON1_WAITINV                      (1 << 19)
+#define DANUBE_EBU_BUSCON1_SETUP                          (1 << 18)
+#define DANUBE_EBU_BUSCON1_PORTW (value)              (((( 1 << 2) - 1) & (value)) << 16)
+#define DANUBE_EBU_BUSCON1_WAITRDC (value)            (((( 1 << 7) - 1) & (value)) << 9)
+#define DANUBE_EBU_BUSCON1_WAITWRC (value)            (((( 1 << 3) - 1) & (value)) << 6)
+#define DANUBE_EBU_BUSCON1_HOLDC (value)              (((( 1 << 2) - 1) & (value)) << 4)
+#define DANUBE_EBU_BUSCON1_RECOVC (value)             (((( 1 << 2) - 1) & (value)) << 2)
+#define DANUBE_EBU_BUSCON1_CMULT (value)              (((( 1 << 2) - 1) & (value)) << 0)
+
+/***EBU Bus Configuration Register 2***/
+#define DANUBE_EBU_BUSCON2                  ((volatile u32*)(DANUBE_EBU+ 0x0068))
+#define DANUBE_EBU_BUSCON2_WRDIS                          (1 << 31)
+#define DANUBE_EBU_BUSCON2_ALEC (value)               (((( 1 << 2) - 1) & (value)) << 29)
+#define DANUBE_EBU_BUSCON2_BCGEN (value)              (((( 1 << 2) - 1) & (value)) << 27)
+#define DANUBE_EBU_BUSCON2_AGEN (value)               (((( 1 << 2) - 1) & (value)) << 24)
+#define DANUBE_EBU_BUSCON2_CMULTR (value)             (((( 1 << 2) - 1) & (value)) << 22)
+#define DANUBE_EBU_BUSCON2_WAIT (value)               (((( 1 << 2) - 1) & (value)) << 20)
+#define DANUBE_EBU_BUSCON2_WAITINV                      (1 << 19)
+#define DANUBE_EBU_BUSCON2_SETUP                          (1 << 18)
+#define DANUBE_EBU_BUSCON2_PORTW (value)              (((( 1 << 2) - 1) & (value)) << 16)
+#define DANUBE_EBU_BUSCON2_WAITRDC (value)            (((( 1 << 7) - 1) & (value)) << 9)
+#define DANUBE_EBU_BUSCON2_WAITWRC (value)            (((( 1 << 3) - 1) & (value)) << 6)
+#define DANUBE_EBU_BUSCON2_HOLDC (value)              (((( 1 << 2) - 1) & (value)) << 4)
+#define DANUBE_EBU_BUSCON2_RECOVC (value)             (((( 1 << 2) - 1) & (value)) << 2)
+#define DANUBE_EBU_BUSCON2_CMULT (value)              (((( 1 << 2) - 1) & (value)) << 0)
+
+/***********************************************************************/
+/*  Module      :  SDRAM register address and bits                     */
+/***********************************************************************/
+
+#define DANUBE_SDRAM                        (0xBF800000)
+/***********************************************************************/
+
+
+/***MC Access Error Cause Register***/
+#define DANUBE_SDRAM_MC_ERRCAUSE                  ((volatile u32*)(DANUBE_SDRAM+ 0x0100))
+#define DANUBE_SDRAM_MC_ERRCAUSE_ERR                              (1 << 31)
+#define DANUBE_SDRAM_MC_ERRCAUSE_PORT (value)               (((( 1 << 4) - 1) & (value)) << 16)
+#define DANUBE_SDRAM_MC_ERRCAUSE_CAUSE (value)              (((( 1 << 2) - 1) & (value)) << 0)
+#define DANUBE_SDRAM_MC_ERRCAUSE_Res (value)                (((( 1 << NaN) - 1) & (value)) << NaN)
+
+/***MC Access Error Address Register***/
+#define DANUBE_SDRAM_MC_ERRADDR                   ((volatile u32*)(DANUBE_SDRAM+ 0x0108))
+#define DANUBE_SDRAM_MC_ERRADDR_ADDR
+
+/***MC I/O General Purpose Register***/
+#define DANUBE_SDRAM_MC_IOGP                      ((volatile u32*)(DANUBE_SDRAM+ 0x0800))
+#define DANUBE_SDRAM_MC_IOGP_GPR6 (value)               (((( 1 << 4) - 1) & (value)) << 28)
+#define DANUBE_SDRAM_MC_IOGP_GPR5 (value)               (((( 1 << 4) - 1) & (value)) << 24)
+#define DANUBE_SDRAM_MC_IOGP_GPR4 (value)               (((( 1 << 4) - 1) & (value)) << 20)
+#define DANUBE_SDRAM_MC_IOGP_GPR3 (value)               (((( 1 << 4) - 1) & (value)) << 16)
+#define DANUBE_SDRAM_MC_IOGP_GPR2 (value)               (((( 1 << 4) - 1) & (value)) << 12)
+#define DANUBE_SDRAM_MC_IOGP_CPS                              (1 << 11)
+#define DANUBE_SDRAM_MC_IOGP_CLKDELAY (value)          (((( 1 << 3) - 1) & (value)) << 8)
+#define DANUBE_SDRAM_MC_IOGP_CLKRAT (value)             (((( 1 << 4) - 1) & (value)) << 4)
+#define DANUBE_SDRAM_MC_IOGP_RDDEL (value)              (((( 1 << 4) - 1) & (value)) << 0)
+
+/***MC Self Refresh Register***/
+#define DANUBE_SDRAM_MC_SELFRFSH                  ((volatile u32*)(DANUBE_SDRAM+ 0x0A00))
+#define DANUBE_SDRAM_MC_SELFRFSH_PWDS                            (1 << 1)
+#define DANUBE_SDRAM_MC_SELFRFSH_PWD                              (1 << 0)
+#define DANUBE_SDRAM_MC_SELFRFSH_Res (value)                (((( 1 << 30) - 1) & (value)) << 2)
+
+/***MC Enable Register***/
+#define DANUBE_SDRAM_MC_CTRLENA                   ((volatile u32*)(DANUBE_SDRAM+ 0x1000))
+#define DANUBE_SDRAM_MC_CTRLENA_ENA                              (1 << 0)
+#define DANUBE_SDRAM_MC_CTRLENA_Res (value)                (((( 1 << 31) - 1) & (value)) << 1)
+
+/***MC Mode Register Setup Code***/
+#define DANUBE_SDRAM_MC_MRSCODE                   ((volatile u32*)(DANUBE_SDRAM+ 0x1008))
+#define DANUBE_SDRAM_MC_MRSCODE_UMC (value)                (((( 1 << 5) - 1) & (value)) << 7)
+#define DANUBE_SDRAM_MC_MRSCODE_CL (value)                (((( 1 << 3) - 1) & (value)) << 4)
+#define DANUBE_SDRAM_MC_MRSCODE_WT                              (1 << 3)
+#define DANUBE_SDRAM_MC_MRSCODE_BL (value)                (((( 1 << 3) - 1) & (value)) << 0)
+
+/***MC Configuration Data-word Width Register***/
+#define DANUBE_SDRAM_MC_CFGDW                    ((volatile u32*)(DANUBE_SDRAM+ 0x1010))
+#define DANUBE_SDRAM_MC_CFGDW_DW (value)                (((( 1 << 4) - 1) & (value)) << 0)
+#define DANUBE_SDRAM_MC_CFGDW_Res (value)                (((( 1 << 28) - 1) & (value)) << 4)
+
+/***MC Configuration Physical Bank 0 Register***/
+#define DANUBE_SDRAM_MC_CFGPB0                    ((volatile u32*)(DANUBE_SDRAM+ 0x1018))
+#define DANUBE_SDRAM_MC_CFGPB0_MCSEN0 (value)             (((( 1 << 4) - 1) & (value)) << 12)
+#define DANUBE_SDRAM_MC_CFGPB0_BANKN0 (value)             (((( 1 << 4) - 1) & (value)) << 8)
+#define DANUBE_SDRAM_MC_CFGPB0_ROWW0 (value)              (((( 1 << 4) - 1) & (value)) << 4)
+#define DANUBE_SDRAM_MC_CFGPB0_COLW0 (value)              (((( 1 << 4) - 1) & (value)) << 0)
+#define DANUBE_SDRAM_MC_CFGPB0_Res (value)                (((( 1 << 16) - 1) & (value)) << 16)
+
+/***MC Latency Register***/
+#define DANUBE_SDRAM_MC_LATENCY                   ((volatile u32*)(DANUBE_SDRAM+ 0x1038))
+#define DANUBE_SDRAM_MC_LATENCY_TRP (value)                (((( 1 << 4) - 1) & (value)) << 16)
+#define DANUBE_SDRAM_MC_LATENCY_TRAS (value)               (((( 1 << 4) - 1) & (value)) << 12)
+#define DANUBE_SDRAM_MC_LATENCY_TRCD (value)               (((( 1 << 4) - 1) & (value)) << 8)
+#define DANUBE_SDRAM_MC_LATENCY_TDPL (value)               (((( 1 << 4) - 1) & (value)) << 4)
+#define DANUBE_SDRAM_MC_LATENCY_TDAL (value)               (((( 1 << 4) - 1) & (value)) << 0)
+#define DANUBE_SDRAM_MC_LATENCY_Res (value)                (((( 1 << 12) - 1) & (value)) << 20)
+
+/***MC Refresh Cycle Time Register***/
+#define DANUBE_SDRAM_MC_TREFRESH                  ((volatile u32*)(DANUBE_SDRAM+ 0x1040))
+#define DANUBE_SDRAM_MC_TREFRESH_TREF (value)               (((( 1 << 13) - 1) & (value)) << 0)
+#define DANUBE_SDRAM_MC_TREFRESH_Res (value)                (((( 1 << 19) - 1) & (value)) << 13)
+
+
+/***********************************************************************/
+/*  Module      :  GPTU register address and bits                      */
+/***********************************************************************/
+
+#define DANUBE_GPTU                         (0xB8000300)
+/***********************************************************************/
+
+
+/***GPT Clock Control Register***/
+#define DANUBE_GPTU_GPT_CLC                      ((volatile u32*)(DANUBE_GPTU+ 0x0000))
+#define DANUBE_GPTU_GPT_CLC_RMC (value)                (((( 1 << 8) - 1) & (value)) << 8)
+#define DANUBE_GPTU_GPT_CLC_DISS                            (1 << 1)
+#define DANUBE_GPTU_GPT_CLC_DISR                            (1 << 0)
+
+/***GPT Timer 3 Control Register***/
+#define DANUBE_GPTU_GPT_T3CON                    ((volatile u32*)(DANUBE_GPTU+ 0x0014))
+#define DANUBE_GPTU_GPT_T3CON_T3RDIR                        (1 << 15)
+#define DANUBE_GPTU_GPT_T3CON_T3CHDIR                      (1 << 14)
+#define DANUBE_GPTU_GPT_T3CON_T3EDGE                        (1 << 13)
+#define DANUBE_GPTU_GPT_T3CON_BPS1 (value)               (((( 1 << 2) - 1) & (value)) << 11)
+#define DANUBE_GPTU_GPT_T3CON_T3OTL                          (1 << 10)
+#define DANUBE_GPTU_GPT_T3CON_T3UD                            (1 << 7)
+#define DANUBE_GPTU_GPT_T3CON_T3R                              (1 << 6)
+#define DANUBE_GPTU_GPT_T3CON_T3M (value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define DANUBE_GPTU_GPT_T3CON_T3I (value)                (((( 1 << 3) - 1) & (value)) << 0)
+
+/***GPT Write Hardware Modified Timer 3 Control Register
+If set and clear bit are written concurrently with 1, the associated bit is not changed.***/
+#define DANUBE_GPTU_GPT_WHBT3CON                 ((volatile u32*)(DANUBE_GPTU+ 0x004C))
+#define DANUBE_GPTU_GPT_WHBT3CON_SETT3CHDIR                (1 << 15)
+#define DANUBE_GPTU_GPT_WHBT3CON_CLRT3CHDIR                (1 << 14)
+#define DANUBE_GPTU_GPT_WHBT3CON_SETT3EDGE                  (1 << 13)
+#define DANUBE_GPTU_GPT_WHBT3CON_CLRT3EDGE                  (1 << 12)
+#define DANUBE_GPTU_GPT_WHBT3CON_SETT3OTL                  (1 << 11)
+#define DANUBE_GPTU_GPT_WHBT3CON_CLRT3OTL                  (1 << 10)
+
+/***GPT Timer 2 Control Register***/
+#define DANUBE_GPTU_GPT_T2CON                    ((volatile u32*)(DANUBE_GPTU+ 0x0010))
+#define DANUBE_GPTU_GPT_T2CON_TxRDIR                        (1 << 15)
+#define DANUBE_GPTU_GPT_T2CON_TxCHDIR                      (1 << 14)
+#define DANUBE_GPTU_GPT_T2CON_TxEDGE                        (1 << 13)
+#define DANUBE_GPTU_GPT_T2CON_TxIRDIS                      (1 << 12)
+#define DANUBE_GPTU_GPT_T2CON_TxRC                            (1 << 9)
+#define DANUBE_GPTU_GPT_T2CON_TxUD                            (1 << 7)
+#define DANUBE_GPTU_GPT_T2CON_TxR                              (1 << 6)
+#define DANUBE_GPTU_GPT_T2CON_TxM (value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define DANUBE_GPTU_GPT_T2CON_TxI (value)                (((( 1 << 3) - 1) & (value)) << 0)
+
+/***GPT Timer 4 Control Register***/
+#define DANUBE_GPTU_GPT_T4CON                    ((volatile u32*)(DANUBE_GPTU+ 0x0018))
+#define DANUBE_GPTU_GPT_T4CON_TxRDIR                        (1 << 15)
+#define DANUBE_GPTU_GPT_T4CON_TxCHDIR                      (1 << 14)
+#define DANUBE_GPTU_GPT_T4CON_TxEDGE                        (1 << 13)
+#define DANUBE_GPTU_GPT_T4CON_TxIRDIS                      (1 << 12)
+#define DANUBE_GPTU_GPT_T4CON_TxRC                            (1 << 9)
+#define DANUBE_GPTU_GPT_T4CON_TxUD                            (1 << 7)
+#define DANUBE_GPTU_GPT_T4CON_TxR                              (1 << 6)
+#define DANUBE_GPTU_GPT_T4CON_TxM (value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define DANUBE_GPTU_GPT_T4CON_TxI (value)                (((( 1 << 3) - 1) & (value)) << 0)
+
+/***GPT Write HW Modified Timer 2 Control Register If set
+ and clear bit are written concurrently with 1, the associated bit is not changed.***/
+#define DANUBE_GPTU_GPT_WHBT2CON                 ((volatile u32*)(DANUBE_GPTU+ 0x0048))
+#define DANUBE_GPTU_GPT_WHBT2CON_SETTxCHDIR                (1 << 15)
+#define DANUBE_GPTU_GPT_WHBT2CON_CLRTxCHDIR                (1 << 14)
+#define DANUBE_GPTU_GPT_WHBT2CON_SETTxEDGE                  (1 << 13)
+#define DANUBE_GPTU_GPT_WHBT2CON_CLRTxEDGE                  (1 << 12)
+
+/***GPT Write HW Modified Timer 4 Control Register If set
+ and clear bit are written concurrently with 1, the associated bit is not changed.***/
+#define DANUBE_GPTU_GPT_WHBT4CON                 ((volatile u32*)(DANUBE_GPTU+ 0x0050))
+#define DANUBE_GPTU_GPT_WHBT4CON_SETTxCHDIR                (1 << 15)
+#define DANUBE_GPTU_GPT_WHBT4CON_CLRTxCHDIR                (1 << 14)
+#define DANUBE_GPTU_GPT_WHBT4CON_SETTxEDGE                  (1 << 13)
+#define DANUBE_GPTU_GPT_WHBT4CON_CLRTxEDGE                  (1 << 12)
+
+/***GPT Capture Reload Register***/
+#define DANUBE_GPTU_GPT_CAPREL                   ((volatile u32*)(DANUBE_GPTU+ 0x0030))
+#define DANUBE_GPTU_GPT_CAPREL_CAPREL (value)             (((( 1 << 16) - 1) & (value)) << 0)
+
+/***GPT Timer 2 Register***/
+#define DANUBE_GPTU_GPT_T2                       ((volatile u32*)(DANUBE_GPTU+ 0x0034))
+#define DANUBE_GPTU_GPT_T2_TVAL (value)               (((( 1 << 16) - 1) & (value)) << 0)
+
+/***GPT Timer 3 Register***/
+#define DANUBE_GPTU_GPT_T3                       ((volatile u32*)(DANUBE_GPTU+ 0x0038))
+#define DANUBE_GPTU_GPT_T3_TVAL (value)               (((( 1 << 16) - 1) & (value)) << 0)
+
+/***GPT Timer 4 Register***/
+#define DANUBE_GPTU_GPT_T4                       ((volatile u32*)(DANUBE_GPTU+ 0x003C))
+#define DANUBE_GPTU_GPT_T4_TVAL (value)               (((( 1 << 16) - 1) & (value)) << 0)
+
+/***GPT Timer 5 Register***/
+#define DANUBE_GPTU_GPT_T5                       ((volatile u32*)(DANUBE_GPTU+ 0x0040))
+#define DANUBE_GPTU_GPT_T5_TVAL (value)               (((( 1 << 16) - 1) & (value)) << 0)
+
+/***GPT Timer 6 Register***/
+#define DANUBE_GPTU_GPT_T6                       ((volatile u32*)(DANUBE_GPTU+ 0x0044))
+#define DANUBE_GPTU_GPT_T6_TVAL (value)               (((( 1 << 16) - 1) & (value)) << 0)
+
+/***GPT Timer 6 Control Register***/
+#define DANUBE_GPTU_GPT_T6CON                    ((volatile u32*)(DANUBE_GPTU+ 0x0020))
+#define DANUBE_GPTU_GPT_T6CON_T6SR                            (1 << 15)
+#define DANUBE_GPTU_GPT_T6CON_T6CLR                          (1 << 14)
+#define DANUBE_GPTU_GPT_T6CON_BPS2 (value)               (((( 1 << 2) - 1) & (value)) << 11)
+#define DANUBE_GPTU_GPT_T6CON_T6OTL                          (1 << 10)
+#define DANUBE_GPTU_GPT_T6CON_T6UD                            (1 << 7)
+#define DANUBE_GPTU_GPT_T6CON_T6R                              (1 << 6)
+#define DANUBE_GPTU_GPT_T6CON_T6M (value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define DANUBE_GPTU_GPT_T6CON_T6I (value)                (((( 1 << 3) - 1) & (value)) << 0)
+
+/***GPT Write HW Modified Timer 6 Control Register If set
+ and clear bit are written concurrently with 1, the associated bit is not changed.***/
+#define DANUBE_GPTU_GPT_WHBT6CON                 ((volatile u32*)(DANUBE_GPTU+ 0x0054))
+#define DANUBE_GPTU_GPT_WHBT6CON_SETT6OTL                  (1 << 11)
+#define DANUBE_GPTU_GPT_WHBT6CON_CLRT6OTL                  (1 << 10)
+
+/***GPT Timer 5 Control Register***/
+#define DANUBE_GPTU_GPT_T5CON                    ((volatile u32*)(DANUBE_GPTU+ 0x001C))
+#define DANUBE_GPTU_GPT_T5CON_T5SC                            (1 << 15)
+#define DANUBE_GPTU_GPT_T5CON_T5CLR                          (1 << 14)
+#define DANUBE_GPTU_GPT_T5CON_CI (value)                (((( 1 << 2) - 1) & (value)) << 12)
+#define DANUBE_GPTU_GPT_T5CON_T5CC                            (1 << 11)
+#define DANUBE_GPTU_GPT_T5CON_CT3                              (1 << 10)
+#define DANUBE_GPTU_GPT_T5CON_T5RC                            (1 << 9)
+#define DANUBE_GPTU_GPT_T5CON_T5UDE                          (1 << 8)
+#define DANUBE_GPTU_GPT_T5CON_T5UD                            (1 << 7)
+#define DANUBE_GPTU_GPT_T5CON_T5R                              (1 << 6)
+#define DANUBE_GPTU_GPT_T5CON_T5M (value)                (((( 1 << 3) - 1) & (value)) << 3)
+#define DANUBE_GPTU_GPT_T5CON_T5I (value)                (((( 1 << 3) - 1) & (value)) << 0)
+
+
+/***********************************************************************/
+/*  Module      :  IOM register address and bits                       */
+/***********************************************************************/
+
+#define DANUBE_IOM                          (0xBF105000)
+/***********************************************************************/
+
+
+/***Receive FIFO***/
+#define DANUBE_IOM_RFIFO                        ((volatile u32*)(DANUBE_IOM+ 0x0000))
+#define DANUBE_IOM_RFIFO_RXD (value)                (((( 1 << 8) - 1) & (value)) << 0)
+
+/***Transmit FIFO***/
+#define DANUBE_IOM_XFIFO                        ((volatile u32*)(DANUBE_IOM+ 0x0000))
+#define DANUBE_IOM_XFIFO_TXD (value)                (((( 1 << 8) - 1) & (value)) << 0)
+
+/***Interrupt Status Register HDLC***/
+#define DANUBE_IOM_ISTAH                        ((volatile u32*)(DANUBE_IOM+ 0x0080))
+#define DANUBE_IOM_ISTAH_RME                              (1 << 7)
+#define DANUBE_IOM_ISTAH_RPF                              (1 << 6)
+#define DANUBE_IOM_ISTAH_RFO                              (1 << 5)
+#define DANUBE_IOM_ISTAH_XPR                              (1 << 4)
+#define DANUBE_IOM_ISTAH_XMR                              (1 << 3)
+#define DANUBE_IOM_ISTAH_XDU                              (1 << 2)
+
+/***Interrupt Mask Register HDLC***/
+#define DANUBE_IOM_MASKH                        ((volatile u32*)(DANUBE_IOM+ 0x0080))
+#define DANUBE_IOM_MASKH_RME                              (1 << 7)
+#define DANUBE_IOM_MASKH_RPF                              (1 << 6)
+#define DANUBE_IOM_MASKH_RFO                              (1 << 5)
+#define DANUBE_IOM_MASKH_XPR                              (1 << 4)
+#define DANUBE_IOM_MASKH_XMR                              (1 << 3)
+#define DANUBE_IOM_MASKH_XDU                              (1 << 2)
+
+/***Status Register***/
+#define DANUBE_IOM_STAR                         ((volatile u32*)(DANUBE_IOM+ 0x0084))
+#define DANUBE_IOM_STAR_XDOV                            (1 << 7)
+#define DANUBE_IOM_STAR_XFW                              (1 << 6)
+#define DANUBE_IOM_STAR_RACI                            (1 << 3)
+#define DANUBE_IOM_STAR_XACI                            (1 << 1)
+
+/***Command Register***/
+#define DANUBE_IOM_CMDR                         ((volatile u32*)(DANUBE_IOM+ 0x0084))
+#define DANUBE_IOM_CMDR_RMC                              (1 << 7)
+#define DANUBE_IOM_CMDR_RRES                            (1 << 6)
+#define DANUBE_IOM_CMDR_XTF                              (1 << 3)
+#define DANUBE_IOM_CMDR_XME                              (1 << 1)
+#define DANUBE_IOM_CMDR_XRES                            (1 << 0)
+
+/***Mode Register***/
+#define DANUBE_IOM_MODEH                        ((volatile u32*)(DANUBE_IOM+ 0x0088))
+#define DANUBE_IOM_MODEH_MDS2                            (1 << 7)
+#define DANUBE_IOM_MODEH_MDS1                            (1 << 6)
+#define DANUBE_IOM_MODEH_MDS0                            (1 << 5)
+#define DANUBE_IOM_MODEH_RAC                              (1 << 3)
+#define DANUBE_IOM_MODEH_DIM2                            (1 << 2)
+#define DANUBE_IOM_MODEH_DIM1                            (1 << 1)
+#define DANUBE_IOM_MODEH_DIM0                            (1 << 0)
+
+/***Extended Mode Register***/
+#define DANUBE_IOM_EXMR                         ((volatile u32*)(DANUBE_IOM+ 0x008C))
+#define DANUBE_IOM_EXMR_XFBS                            (1 << 7)
+#define DANUBE_IOM_EXMR_RFBS (value)               (((( 1 << 2) - 1) & (value)) << 5)
+#define DANUBE_IOM_EXMR_SRA                              (1 << 4)
+#define DANUBE_IOM_EXMR_XCRC                            (1 << 3)
+#define DANUBE_IOM_EXMR_RCRC                            (1 << 2)
+#define DANUBE_IOM_EXMR_ITF                              (1 << 0)
+
+/***SAPI1 Register***/
+#define DANUBE_IOM_SAP1                         ((volatile u32*)(DANUBE_IOM+ 0x0094))
+#define DANUBE_IOM_SAP1_SAPI1 (value)              (((( 1 << 6) - 1) & (value)) << 2)
+#define DANUBE_IOM_SAP1_MHA                              (1 << 0)
+
+/***Receive Frame Byte Count Low***/
+#define DANUBE_IOM_RBCL                         ((volatile u32*)(DANUBE_IOM+ 0x0098))
+#define DANUBE_IOM_RBCL_RBC(value)              (1 << value)
+
+
+/***SAPI2 Register***/
+#define DANUBE_IOM_SAP2                         ((volatile u32*)(DANUBE_IOM+ 0x0098))
+#define DANUBE_IOM_SAP2_SAPI2 (value)              (((( 1 << 6) - 1) & (value)) << 2)
+#define DANUBE_IOM_SAP2_MLA                              (1 << 0)
+
+/***Receive Frame Byte Count High***/
+#define DANUBE_IOM_RBCH                         ((volatile u32*)(DANUBE_IOM+ 0x009C))
+#define DANUBE_IOM_RBCH_OV                              (1 << 4)
+#define DANUBE_IOM_RBCH_RBC11                          (1 << 3)
+#define DANUBE_IOM_RBCH_RBC10                          (1 << 2)
+#define DANUBE_IOM_RBCH_RBC9                            (1 << 1)
+#define DANUBE_IOM_RBCH_RBC8                            (1 << 0)
+
+/***TEI1 Register 1***/
+#define DANUBE_IOM_TEI1                         ((volatile u32*)(DANUBE_IOM+ 0x009C))
+#define DANUBE_IOM_TEI1_TEI1 (value)               (((( 1 << 7) - 1) & (value)) << 1)
+#define DANUBE_IOM_TEI1_EA                              (1 << 0)
+
+/***Receive Status Register***/
+#define DANUBE_IOM_RSTA                         ((volatile u32*)(DANUBE_IOM+ 0x00A0))
+#define DANUBE_IOM_RSTA_VFR                              (1 << 7)
+#define DANUBE_IOM_RSTA_RDO                              (1 << 6)
+#define DANUBE_IOM_RSTA_CRC                              (1 << 5)
+#define DANUBE_IOM_RSTA_RAB                              (1 << 4)
+#define DANUBE_IOM_RSTA_SA1                              (1 << 3)
+#define DANUBE_IOM_RSTA_SA0                              (1 << 2)
+#define DANUBE_IOM_RSTA_TA                              (1 << 0)
+#define DANUBE_IOM_RSTA_CR                              (1 << 1)
+
+/***TEI2 Register***/
+#define DANUBE_IOM_TEI2                         ((volatile u32*)(DANUBE_IOM+ 0x00A0))
+#define DANUBE_IOM_TEI2_TEI2 (value)               (((( 1 << 7) - 1) & (value)) << 1)
+#define DANUBE_IOM_TEI2_EA                              (1 << 0)
+
+/***Test Mode Register HDLC***/
+#define DANUBE_IOM_TMH                          ((volatile u32*)(DANUBE_IOM+ 0x00A4))
+#define DANUBE_IOM_TMH_TLP                              (1 << 0)
+
+/***Command/Indication Receive 0***/
+#define DANUBE_IOM_CIR0                         ((volatile u32*)(DANUBE_IOM+ 0x00B8))
+#define DANUBE_IOM_CIR0_CODR0 (value)              (((( 1 << 4) - 1) & (value)) << 4)
+#define DANUBE_IOM_CIR0_CIC0                            (1 << 3)
+#define DANUBE_IOM_CIR0_CIC1                            (1 << 2)
+#define DANUBE_IOM_CIR0_SG                              (1 << 1)
+#define DANUBE_IOM_CIR0_BAS                              (1 << 0)
+
+/***Command/Indication Transmit 0***/
+#define DANUBE_IOM_CIX0                         ((volatile u32*)(DANUBE_IOM+ 0x00B8))
+#define DANUBE_IOM_CIX0_CODX0 (value)              (((( 1 << 4) - 1) & (value)) << 4)
+#define DANUBE_IOM_CIX0_TBA2                            (1 << 3)
+#define DANUBE_IOM_CIX0_TBA1                            (1 << 2)
+#define DANUBE_IOM_CIX0_TBA0                            (1 << 1)
+#define DANUBE_IOM_CIX0_BAC                              (1 << 0)
+
+/***Command/Indication Receive 1***/
+#define DANUBE_IOM_CIR1                         ((volatile u32*)(DANUBE_IOM+ 0x00BC))
+#define DANUBE_IOM_CIR1_CODR1 (value)              (((( 1 << 6) - 1) & (value)) << 2)
+
+/***Command/Indication Transmit 1***/
+#define DANUBE_IOM_CIX1                         ((volatile u32*)(DANUBE_IOM+ 0x00BC))
+#define DANUBE_IOM_CIX1_CODX1 (value)              (((( 1 << 6) - 1) & (value)) << 2)
+#define DANUBE_IOM_CIX1_CICW                            (1 << 1)
+#define DANUBE_IOM_CIX1_CI1E                            (1 << 0)
+
+/***Controller Data Access Reg. (CH10)***/
+#define DANUBE_IOM_CDA10                        ((volatile u32*)(DANUBE_IOM+ 0x0100))
+#define DANUBE_IOM_CDA10_CDA (value)                (((( 1 << 8) - 1) & (value)) << 0)
+
+/***Controller Data Access Reg. (CH11)***/
+#define DANUBE_IOM_CDA11                        ((volatile u32*)(DANUBE_IOM+ 0x0104))
+#define DANUBE_IOM_CDA11_CDA (value)                (((( 1 << 8) - 1) & (value)) << 0)
+
+/***Controller Data Access Reg. (CH20)***/
+#define DANUBE_IOM_CDA20                        ((volatile u32*)(DANUBE_IOM+ 0x0108))
+#define DANUBE_IOM_CDA20_CDA (value)                (((( 1 << 8) - 1) & (value)) << 0)
+
+/***Controller Data Access Reg. (CH21)***/
+#define DANUBE_IOM_CDA21                        ((volatile u32*)(DANUBE_IOM+ 0x010C))
+#define DANUBE_IOM_CDA21_CDA (value)                (((( 1 << 8) - 1) & (value)) << 0)
+
+/***Time Slot and Data Port Sel. (CH10)***/
+#define DANUBE_IOM_CDA_TSDP10                   ((volatile u32*)(DANUBE_IOM+ 0x0110))
+#define DANUBE_IOM_CDA_TSDP10_DPS                              (1 << 7)
+#define DANUBE_IOM_CDA_TSDP10_TSS (value)                (((( 1 << 4) - 1) & (value)) << 0)
+
+/***Time Slot and Data Port Sel. (CH11)***/
+#define DANUBE_IOM_CDA_TSDP11                   ((volatile u32*)(DANUBE_IOM+ 0x0114))
+#define DANUBE_IOM_CDA_TSDP11_DPS                              (1 << 7)
+#define DANUBE_IOM_CDA_TSDP11_TSS (value)                (((( 1 << 4) - 1) & (value)) << 0)
+
+/***Time Slot and Data Port Sel. (CH20)***/
+#define DANUBE_IOM_CDA_TSDP20                   ((volatile u32*)(DANUBE_IOM+ 0x0118))
+#define DANUBE_IOM_CDA_TSDP20_DPS                              (1 << 7)
+#define DANUBE_IOM_CDA_TSDP20_TSS (value)                (((( 1 << 4) - 1) & (value)) << 0)
+
+/***Time Slot and Data Port Sel. (CH21)***/
+#define DANUBE_IOM_CDA_TSDP21                   ((volatile u32*)(DANUBE_IOM+ 0x011C))
+#define DANUBE_IOM_CDA_TSDP21_DPS                              (1 << 7)
+#define DANUBE_IOM_CDA_TSDP21_TSS (value)                (((( 1 << 4) - 1) & (value)) << 0)
+
+/***Time Slot and Data Port Sel. (CH10)***/
+#define DANUBE_IOM_CO_TSDP10                    ((volatile u32*)(DANUBE_IOM+ 0x0120))
+#define DANUBE_IOM_CO_TSDP10_DPS                              (1 << 7)
+#define DANUBE_IOM_CO_TSDP10_TSS (value)                (((( 1 << 4) - 1) & (value)) << 0)
+
+/***Time Slot and Data Port Sel. (CH11)***/
+#define DANUBE_IOM_CO_TSDP11                    ((volatile u32*)(DANUBE_IOM+ 0x0124))
+#define DANUBE_IOM_CO_TSDP11_DPS                              (1 << 7)
+#define DANUBE_IOM_CO_TSDP11_TSS (value)                (((( 1 << 4) - 1) & (value)) << 0)
+
+/***Time Slot and Data Port Sel. (CH20)***/
+#define DANUBE_IOM_CO_TSDP20                    ((volatile u32*)(DANUBE_IOM+ 0x0128))
+#define DANUBE_IOM_CO_TSDP20_DPS                              (1 << 7)
+#define DANUBE_IOM_CO_TSDP20_TSS (value)                (((( 1 << 4) - 1) & (value)) << 0)
+
+/***Time Slot and Data Port Sel. (CH21)***/
+#define DANUBE_IOM_CO_TSDP21                    ((volatile u32*)(DANUBE_IOM+ 0x012C))
+#define DANUBE_IOM_CO_TSDP21_DPS                              (1 << 7)
+#define DANUBE_IOM_CO_TSDP21_TSS (value)                (((( 1 << 4) - 1) & (value)) << 0)
+
+/***Ctrl. Reg. Contr. Data Access CH1x***/
+#define DANUBE_IOM_CDA1_CR                      ((volatile u32*)(DANUBE_IOM+ 0x0138))
+#define DANUBE_IOM_CDA1_CR_EN_TBM                        (1 << 5)
+#define DANUBE_IOM_CDA1_CR_EN_I1                          (1 << 4)
+#define DANUBE_IOM_CDA1_CR_EN_I0                          (1 << 3)
+#define DANUBE_IOM_CDA1_CR_EN_O1                          (1 << 2)
+#define DANUBE_IOM_CDA1_CR_EN_O0                          (1 << 1)
+#define DANUBE_IOM_CDA1_CR_SWAP                            (1 << 0)
+
+/***Ctrl. Reg. Contr. Data Access CH1x***/
+#define DANUBE_IOM_CDA2_CR                      ((volatile u32*)(DANUBE_IOM+ 0x013C))
+#define DANUBE_IOM_CDA2_CR_EN_TBM                        (1 << 5)
+#define DANUBE_IOM_CDA2_CR_EN_I1                          (1 << 4)
+#define DANUBE_IOM_CDA2_CR_EN_I0                          (1 << 3)
+#define DANUBE_IOM_CDA2_CR_EN_O1                          (1 << 2)
+#define DANUBE_IOM_CDA2_CR_EN_O0                          (1 << 1)
+#define DANUBE_IOM_CDA2_CR_SWAP                            (1 << 0)
+
+/***Control Register B-Channel Data***/
+#define DANUBE_IOM_BCHA_CR                      ((volatile u32*)(DANUBE_IOM+ 0x0144))
+#define DANUBE_IOM_BCHA_CR_EN_BC2                        (1 << 4)
+#define DANUBE_IOM_BCHA_CR_EN_BC1                        (1 << 3)
+
+/***Control Register B-Channel Data***/
+#define DANUBE_IOM_BCHB_CR                      ((volatile u32*)(DANUBE_IOM+ 0x0148))
+#define DANUBE_IOM_BCHB_CR_EN_BC2                        (1 << 4)
+#define DANUBE_IOM_BCHB_CR_EN_BC1                        (1 << 3)
+
+/***Control Reg. for HDLC and CI1 Data***/
+#define DANUBE_IOM_DCI_CR                       ((volatile u32*)(DANUBE_IOM+ 0x014C))
+#define DANUBE_IOM_DCI_CR_DPS_CI1                      (1 << 7)
+#define DANUBE_IOM_DCI_CR_EN_CI1                        (1 << 6)
+#define DANUBE_IOM_DCI_CR_EN_D                            (1 << 5)
+
+/***Control Reg. for HDLC and CI1 Data***/
+#define DANUBE_IOM_DCIC_CR                      ((volatile u32*)(DANUBE_IOM+ 0x014C))
+#define DANUBE_IOM_DCIC_CR_DPS_CI0                      (1 << 7)
+#define DANUBE_IOM_DCIC_CR_EN_CI0                        (1 << 6)
+#define DANUBE_IOM_DCIC_CR_DPS_D                          (1 << 5)
+
+/***Control Reg. Serial Data Strobe x***/
+#define DANUBE_IOM_SDS_CR                       ((volatile u32*)(DANUBE_IOM+ 0x0154))
+#define DANUBE_IOM_SDS_CR_ENS_TSS                      (1 << 7)
+#define DANUBE_IOM_SDS_CR_ENS_TSS_1                  (1 << 6)
+#define DANUBE_IOM_SDS_CR_ENS_TSS_3                  (1 << 5)
+#define DANUBE_IOM_SDS_CR_TSS (value)                (((( 1 << 4) - 1) & (value)) << 0)
+
+/***Control Register IOM Data***/
+#define DANUBE_IOM_IOM_CR                       ((volatile u32*)(DANUBE_IOM+ 0x015C))
+#define DANUBE_IOM_IOM_CR_SPU                              (1 << 7)
+#define DANUBE_IOM_IOM_CR_CI_CS                          (1 << 5)
+#define DANUBE_IOM_IOM_CR_TIC_DIS                      (1 << 4)
+#define DANUBE_IOM_IOM_CR_EN_BCL                        (1 << 3)
+#define DANUBE_IOM_IOM_CR_CLKM                            (1 << 2)
+#define DANUBE_IOM_IOM_CR_Res                              (1 << 1)
+#define DANUBE_IOM_IOM_CR_DIS_IOM                      (1 << 0)
+
+/***Synchronous Transfer Interrupt***/
+#define DANUBE_IOM_STI                          ((volatile u32*)(DANUBE_IOM+ 0x0160))
+#define DANUBE_IOM_STI_STOV21                        (1 << 7)
+#define DANUBE_IOM_STI_STOV20                        (1 << 6)
+#define DANUBE_IOM_STI_STOV11                        (1 << 5)
+#define DANUBE_IOM_STI_STOV10                        (1 << 4)
+#define DANUBE_IOM_STI_STI21                          (1 << 3)
+#define DANUBE_IOM_STI_STI20                          (1 << 2)
+#define DANUBE_IOM_STI_STI11                          (1 << 1)
+#define DANUBE_IOM_STI_STI10                          (1 << 0)
+
+/***Acknowledge Synchronous Transfer Interrupt***/
+#define DANUBE_IOM_ASTI                         ((volatile u32*)(DANUBE_IOM+ 0x0160))
+#define DANUBE_IOM_ASTI_ACK21                          (1 << 3)
+#define DANUBE_IOM_ASTI_ACK20                          (1 << 2)
+#define DANUBE_IOM_ASTI_ACK11                          (1 << 1)
+#define DANUBE_IOM_ASTI_ACK10                          (1 << 0)
+
+/***Mask Synchronous Transfer Interrupt***/
+#define DANUBE_IOM_MSTI                         ((volatile u32*)(DANUBE_IOM+ 0x0164))
+#define DANUBE_IOM_MSTI_STOV21                        (1 << 7)
+#define DANUBE_IOM_MSTI_STOV20                        (1 << 6)
+#define DANUBE_IOM_MSTI_STOV11                        (1 << 5)
+#define DANUBE_IOM_MSTI_STOV10                        (1 << 4)
+#define DANUBE_IOM_MSTI_STI21                          (1 << 3)
+#define DANUBE_IOM_MSTI_STI20                          (1 << 2)
+#define DANUBE_IOM_MSTI_STI11                          (1 << 1)
+#define DANUBE_IOM_MSTI_STI10                          (1 << 0)
+
+/***Configuration Register for Serial Data Strobes***/
+#define DANUBE_IOM_SDS_CONF                    ((volatile u32*)(DANUBE_IOM+ 0x0168))
+#define DANUBE_IOM_SDS_CONF_SDS_BCL                      (1 << 0)
+
+/***Monitoring CDA Bits***/
+#define DANUBE_IOM_MCDA                         ((volatile u32*)(DANUBE_IOM+ 0x016C))
+#define DANUBE_IOM_MCDA_MCDA21 (value)             (((( 1 << 2) - 1) & (value)) << 6)
+#define DANUBE_IOM_MCDA_MCDA20 (value)             (((( 1 << 2) - 1) & (value)) << 4)
+#define DANUBE_IOM_MCDA_MCDA11 (value)             (((( 1 << 2) - 1) & (value)) << 2)
+#define DANUBE_IOM_MCDA_MCDA10 (value)             (((( 1 << 2) - 1) & (value)) << 0)
+
+/***********************************************************************/
+/*  Module      :  ASC0 register address and bits                      */
+/***********************************************************************/
+#define DANUBE_ASC0                          (KSEG1+0x1E100400)
+/***********************************************************************/
+#define DANUBE_ASC0_TBUF                        ((volatile u32*)(DANUBE_ASC0 + 0x0020))
+#define DANUBE_ASC0_RBUF                        ((volatile u32*)(DANUBE_ASC0 + 0x0024))
+#define DANUBE_ASC0_FSTAT                       ((volatile u32*)(DANUBE_ASC0 + 0x0048))
+#define DANUBE_ASC0_FSTAT_TXFREE_GET(value)     (((value) >> 24) & ((1 << 6) - 1))
+#define DANUBE_ASC0_FSTAT_TXFREE_SET(value)     (((( 1 << 6) - 1) & (value)) << 24)
+#define DANUBE_ASC0_FSTAT_RXFREE_GET(value)     (((value) >> 16) & ((1 << 6) - 1))
+#define DANUBE_ASC0_FSTAT_RXFREE_SET(value)     (((( 1 << 6) - 1) & (value)) << 16)
+#define DANUBE_ASC0_FSTAT_TXFFL_GET(value)      (((value) >> 8) & ((1 << 6) - 1))
+#define DANUBE_ASC0_FSTAT_TXFFL_SET(value)      (((( 1 << 6) - 1) & (value)) << 8)
+#define DANUBE_ASC0_FSTAT_RXFFL_GET(value)      (((value) >> 0) & ((1 << 6) - 1))
+#define DANUBE_ASC0_FSTAT_RXFFL_SET(value)      (((( 1 << 6) - 1) & (value)) << 0)
+
+
+/***********************************************************************/
+/*  Module      :  ASC1 register address and bits                      */
+/***********************************************************************/
+
+#define DANUBE_ASC1                          (KSEG1+0x1E100C00)
+       /***********************************************************************/
+
+#define DANUBE_ASC1_TBUF                        ((volatile u32*)(DANUBE_ASC1 + 0x0020))
+#define DANUBE_ASC1_RBUF                        ((volatile u32*)(DANUBE_ASC1 + 0x0024))
+#define DANUBE_ASC1_FSTAT                       ((volatile u32*)(DANUBE_ASC1 + 0x0048))
+#define DANUBE_ASC1_FSTAT_TXFREE_GET(value)     (((value) >> 24) & ((1 << 6) - 1))
+#define DANUBE_ASC1_FSTAT_TXFREE_SET(value)     (((( 1 << 6) - 1) & (value)) << 24)
+#define DANUBE_ASC1_FSTAT_RXFREE_GET(value)     (((value) >> 16) & ((1 << 6) - 1))
+#define DANUBE_ASC1_FSTAT_RXFREE_SET(value)     (((( 1 << 6) - 1) & (value)) << 16)
+#define DANUBE_ASC1_FSTAT_TXFFL_GET(value)      (((value) >> 8) & ((1 << 6) - 1))
+#define DANUBE_ASC1_FSTAT_TXFFL_SET(value)      (((( 1 << 6) - 1) & (value)) << 8)
+#define DANUBE_ASC1_FSTAT_RXFFL_GET(value)      (((value) >> 0) & ((1 << 6) - 1))
+#define DANUBE_ASC1_FSTAT_RXFFL_SET(value)      (((( 1 << 6) - 1) & (value)) << 0)
+
+/***********************************************************************/
+/*  Module      :  DMA register address and bits                       */
+/***********************************************************************/
+/***********************************************************************/
+/*  Module      :  DMA register address and bits                       */
+/***********************************************************************/
+
+#define DANUBE_DMA                          (0xBE104100)
+/***********************************************************************/
+
+#define DANUBE_DMA_BASE                 DANUBE_DMA 
+#define DANUBE_DMA_CLC                  (volatile u32*)DANUBE_DMA_BASE
+#define DANUBE_DMA_ID                   (volatile u32*)(DANUBE_DMA_BASE+0x08)       
+#define DANUBE_DMA_CTRL                 (volatile u32*)(DANUBE_DMA_BASE+0x10)
+#define DANUBE_DMA_CPOLL                (volatile u32*)(DANUBE_DMA_BASE+0x14)  
+#define DANUBE_DMA_CS                   (volatile u32*)(DANUBE_DMA_BASE+0x18)
+#define DANUBE_DMA_CCTRL                (volatile u32*)(DANUBE_DMA_BASE+0x1C) 
+#define DANUBE_DMA_CDBA                 (volatile u32*)(DANUBE_DMA_BASE+0x20)
+#define DANUBE_DMA_CDLEN                (volatile u32*)(DANUBE_DMA_BASE+0x24) 
+#define DANUBE_DMA_CIS                  (volatile u32*)(DANUBE_DMA_BASE+0x28) 
+#define DANUBE_DMA_CIE                  (volatile u32*)(DANUBE_DMA_BASE+0x2C) 
+
+#define DANUBE_DMA_PS                   (volatile u32*)(DANUBE_DMA_BASE+0x40)
+#define DANUBE_DMA_PCTRL                (volatile u32*)(DANUBE_DMA_BASE+0x44) 
+
+#define DANUBE_DMA_IRNEN                (volatile u32*)(DANUBE_DMA_BASE+0xf4)  
+#define DANUBE_DMA_IRNCR                (volatile u32*)(DANUBE_DMA_BASE+0xf8) 
+#define DANUBE_DMA_IRNICR               (volatile u32*)(DANUBE_DMA_BASE+0xfc)
+/***********************************************************************/
+/*  Module      :  Debug register address and bits                     */
+/***********************************************************************/
+
+#define DANUBE_Debug                        (0xBF106000)
+/***********************************************************************/
+
+
+/***MCD Break Bus Switch Register***/
+#define DANUBE_Debug_MCD_BBS                      ((volatile u32*)(DANUBE_Debug+ 0x0000))
+#define DANUBE_Debug_MCD_BBS_BTP1                            (1 << 19)
+#define DANUBE_Debug_MCD_BBS_BTP0                            (1 << 18)
+#define DANUBE_Debug_MCD_BBS_BSP1                            (1 << 17)
+#define DANUBE_Debug_MCD_BBS_BSP0                            (1 << 16)
+#define DANUBE_Debug_MCD_BBS_BT5EN                          (1 << 15)
+#define DANUBE_Debug_MCD_BBS_BT4EN                          (1 << 14)
+#define DANUBE_Debug_MCD_BBS_BT5                              (1 << 13)
+#define DANUBE_Debug_MCD_BBS_BT4                              (1 << 12)
+#define DANUBE_Debug_MCD_BBS_BS5EN                          (1 << 7)
+#define DANUBE_Debug_MCD_BBS_BS4EN                          (1 << 6)
+#define DANUBE_Debug_MCD_BBS_BS5                              (1 << 5)
+#define DANUBE_Debug_MCD_BBS_BS4                              (1 << 4)
+
+/***MCD Multiplexer Control Register***/
+#define DANUBE_Debug_MCD_MCR                      ((volatile u32*)(DANUBE_Debug+ 0x0008))
+#define DANUBE_Debug_MCD_MCR_MUX5                            (1 << 4)
+#define DANUBE_Debug_MCD_MCR_MUX4                            (1 << 3)
+#define DANUBE_Debug_MCD_MCR_MUX1                            (1 << 0)
+
+
+/***********************************************************************/
+/*  Module      :  SRAM register address and bits                      */
+/***********************************************************************/
+
+#define DANUBE_SRAM                         (0xBF980000)
+/***********************************************************************/
+
+
+/***SRAM Size Register***/
+#define DANUBE_SRAM_SRAM_SIZE                    ((volatile u32*)(DANUBE_SRAM+ 0x0800))
+#define DANUBE_SRAM_SRAM_SIZE_SIZE (value)               (((( 1 << 23) - 1) & (value)) << 0)
+
+/***********************************************************************/
+/*  Module      :  BIU register address and bits                       */
+/***********************************************************************/
+
+#define DANUBE_BIU                          (0xBFA80000)
+/***********************************************************************/
+
+
+/***BIU Identification Register***/
+#define DANUBE_BIU_BIU_ID                       ((volatile u32*)(DANUBE_BIU+ 0x0000))
+#define DANUBE_BIU_BIU_ID_ARCH                            (1 << 16)
+#define DANUBE_BIU_BIU_ID_ID (value)                (((( 1 << 8) - 1) & (value)) << 8)
+#define DANUBE_BIU_BIU_ID_REV (value)                (((( 1 << 8) - 1) & (value)) << 0)
+
+/***BIU Access Error Cause Register***/
+#define DANUBE_BIU_BIU_ERRCAUSE                 ((volatile u32*)(DANUBE_BIU+ 0x0100))
+#define DANUBE_BIU_BIU_ERRCAUSE_ERR                              (1 << 31)
+#define DANUBE_BIU_BIU_ERRCAUSE_PORT (value)               (((( 1 << 4) - 1) & (value)) << 16)
+#define DANUBE_BIU_BIU_ERRCAUSE_CAUSE (value)              (((( 1 << 2) - 1) & (value)) << 0)
+
+/***BIU Access Error Address Register***/
+#define DANUBE_BIU_BIU_ERRADDR                  ((volatile u32*)(DANUBE_BIU+ 0x0108))
+#define DANUBE_BIU_BIU_ERRADDR_ADDR
+
+
+/***********************************************************************/
+/*  Module      :  ICU register address and bits                       */
+/***********************************************************************/
+
+#define DANUBE_ICU                          (0xBF880200)
+#define DANUBE_ICU                          (0xBF880200)
+#define DANUBE_ICU_EXI                      (0xBF101000)
+/***********************************************************************/
+
+      
+/***IM0 Interrupt Status Register***/ 
+#define DANUBE_ICU_IM0_ISR                      ((volatile u32*)(DANUBE_ICU+ 0x0000))
+#define DANUBE_ICU_IM0_ISR_IR(value)               (1 << (value))
+                      
+      
+/***IM1 Interrupt Status Register***/ 
+#define DANUBE_ICU_IM1_ISR                      ((volatile u32*)(DANUBE_ICU+ 0x0020))
+#define DANUBE_ICU_IM1_ISR_IR(value)               (1 << (value))
+                      
+      
+/***IM2 Interrupt Status Register***/ 
+#define DANUBE_ICU_IM2_ISR                      ((volatile u32*)(DANUBE_ICU+ 0x0040))
+#define DANUBE_ICU_IM2_ISR_IR(value)               (1 << (value))
+                      
+/***IM3 Interrupt Status Register***/
+#define DANUBE_ICU_IM3_ISR                      ((volatile u32*)(DANUBE_ICU+ 0x0060))
+#define DANUBE_ICU_IM3_ISR_IR(value)               (1 << (value))
+                                                                                       
+/***IM4 Interrupt Status Register***/
+#define DANUBE_ICU_IM4_ISR                      ((volatile u32*)(DANUBE_ICU+ 0x0080))
+#define DANUBE_ICU_IM4_ISR_IR(value)               (1 << (value))
+
+                       
+/***IM0 Interrupt Enable Register***/ 
+#define DANUBE_ICU_IM0_IER                      ((volatile u32*)(DANUBE_ICU+ 0x0008))
+#define DANUBE_ICU_IM0_IER_IR(value)               (1 << (value))
+                      
+      
+/***IM1 Interrupt Enable Register***/ 
+#define DANUBE_ICU_IM1_IER                      ((volatile u32*)(DANUBE_ICU+ 0x0028))
+#define DANUBE_ICU_IM1_IER_IR(value)               (1 << (value))
+                      
+      
+/***IM2 Interrupt Enable Register***/ 
+#define DANUBE_ICU_IM2_IER                      ((volatile u32*)(DANUBE_ICU+ 0x0048))
+#define DANUBE_ICU_IM2_IER_IR(value)               (1 << (value)8
+                      
+/***IM3 Interrupt Enable Register***/
+#define DANUBE_ICU_IM3_IER                      ((volatile u32*)(DANUBE_ICU+ 0x0068))
+#define DANUBE_ICU_IM3_IER_IR(value)               (1 << (value))
+                                                                                       
+/***IM4 Interrupt Enable Register***/
+#define DANUBE_ICU_IM4_IER                      ((volatile u32*)(DANUBE_ICU+ 0x0088))
+#define DANUBE_ICU_IM4_IER_IR(value)               (1 << (value))
+
+            
+/***IM0 Interrupt Output Status Register***/ 
+#define DANUBE_ICU_IM0_IOSR                    ((volatile u32*)(DANUBE_ICU+ 0x0010))
+#define DANUBE_ICU_IM0_IOSR_IR(value)               (1 << (value))
+                      
+      
+/***IM1 Interrupt Output Status Register***/ 
+#define DANUBE_ICU_IM1_IOSR                    ((volatile u32*)(DANUBE_ICU+ 0x0030))
+#define DANUBE_ICU_IM1_IOSR_IR(value)               (1 << (value))
+                      
+      
+/***IM2 Interrupt Output Status Register***/ 
+#define DANUBE_ICU_IM2_IOSR                    ((volatile u32*)(DANUBE_ICU+ 0x0050))
+#define DANUBE_ICU_IM2_IOSR_IR(value)               (1 << (value))
+                      
+/***IM3 Interrupt Output Status Register***/
+#define DANUBE_ICU_IM3_IOSR                    ((volatile u32*)(DANUBE_ICU+ 0x0070))
+#define DANUBE_ICU_IM3_IOSR_IR(value)               (1 << (value))
+                                                                                       
+/***IM4 Interrupt Output Status Register***/
+#define DANUBE_ICU_IM4_IOSR                    ((volatile u32*)(DANUBE_ICU+ 0x0090))
+#define DANUBE_ICU_IM4_IOSR_IR(value)               (1 << (value))
+
+            
+/***IM0 Interrupt Request Set Register***/ 
+#define DANUBE_ICU_IM0_IRSR                    ((volatile u32*)(DANUBE_ICU+ 0x0018))
+#define DANUBE_ICU_IM0_IRSR_IR(value)               (1 << (value))
+                      
+      
+/***IM1 Interrupt Request Set Register***/ 
+#define DANUBE_ICU_IM1_IRSR                    ((volatile u32*)(DANUBE_ICU+ 0x0038))
+#define DANUBE_ICU_IM1_IRSR_IR(value)               (1 << (value))
+                      
+      
+/***IM2 Interrupt Request Set Register***/ 
+#define DANUBE_ICU_IM2_IRSR                    ((volatile u32*)(DANUBE_ICU+ 0x0058))
+#define DANUBE_ICU_IM2_IRSR_IR(value)               (1 << (value))
+                      
+/***IM3 Interrupt Request Set Register***/
+#define DANUBE_ICU_IM3_IRSR                    ((volatile u32*)(DANUBE_ICU+ 0x0078))
+#define DANUBE_ICU_IM3_IRSR_IR(value)               (1 << (value))
+                                                                                       
+/***IM4 Interrupt Request Set Register***/
+#define DANUBE_ICU_IM4_IRSR                    ((volatile u32*)(DANUBE_ICU+ 0x0098))
+#define DANUBE_ICU_IM4_IRSR_IR(value)               (1 << (value))
+
+/***Interrupt Vector Value Register***/
+#define DANUBE_ICU_IM_VEC                      ((volatile u32*)(DANUBE_ICU+ 0x0060))
+
+/***Interrupt Vector Value Mask***/
+#define DANUBE_ICU_IM0_VEC_MASK                0x0000001f
+#define DANUBE_ICU_IM1_VEC_MASK                0x000003e0
+#define DANUBE_ICU_IM2_VEC_MASK                0x00007c00
+#define DANUBE_ICU_IM3_VEC_MASK                0x000f8000
+#define DANUBE_ICU_IM4_VEC_MASK                0x01f00000
+
+/***DMA Interrupt Mask Value***/
+#define DANUBE_DMA_H_MASK                      0x00000fff
+                                                                                       
+/***External Interrupt Control Register***/
+#define DANUBE_ICU_EXTINTCR                ((volatile u32*)(DANUBE_ICU_EXI+ 0x0000))                                                                                    
+#define DANUBE_ICU_IRNICR                  ((volatile u32*)(DANUBE_ICU_EXI+ 0x0004))                                                                                       
+#define DANUBE_ICU_IRNCR                   ((volatile u32*)(DANUBE_ICU_EXI+ 0x0008))                                                                                       
+#define DANUBE_ICU_IRNEN                   ((volatile u32*)(DANUBE_ICU_EXI+ 0x000c))
+#define DANUBE_ICU_NMI_CR                   ((volatile u32*)(DANUBE_ICU_EXI+ 0x00f0))
+#define DANUBE_ICU_NMI_SR                   ((volatile u32*)(DANUBE_ICU_EXI+ 0x00f4))
+
+/***********************************************************************/
+/*  Module      :  MPS register address and bits                       */
+/***********************************************************************/
+
+#define DANUBE_MPS                          (KSEG1+0x1F107000)
+/***********************************************************************/
+
+#define DANUBE_MPS_CHIPID                       ((volatile u32*)(DANUBE_MPS + 0x0344))
+#define DANUBE_MPS_CHIPID_VERSION_GET(value)    (((value) >> 28) & ((1 << 4) - 1))
+#define DANUBE_MPS_CHIPID_VERSION_SET(value)    (((( 1 << 4) - 1) & (value)) << 28)
+#define DANUBE_MPS_CHIPID_PARTNUM_GET(value)    (((value) >> 12) & ((1 << 16) - 1))
+#define DANUBE_MPS_CHIPID_PARTNUM_SET(value)    (((( 1 << 16) - 1) & (value)) << 12)
+#define DANUBE_MPS_CHIPID_MANID_GET(value)      (((value) >> 1) & ((1 << 10) - 1))
+#define DANUBE_MPS_CHIPID_MANID_SET(value)      (((( 1 << 10) - 1) & (value)) << 1)
+
+
+/* voice channel 0 ... 3 interrupt enable register */
+#define DANUBE_MPS_VC0ENR ((volatile u32*)(DANUBE_MPS + 0x0000))
+#define DANUBE_MPS_VC1ENR ((volatile u32*)(DANUBE_MPS + 0x0004))
+#define DANUBE_MPS_VC2ENR ((volatile u32*)(DANUBE_MPS + 0x0008))
+#define DANUBE_MPS_VC3ENR ((volatile u32*)(DANUBE_MPS + 0x000C))
+/* voice channel 0 ... 3 interrupt status read register */
+#define DANUBE_MPS_RVC0SR ((volatile u32*)(DANUBE_MPS + 0x0010))
+#define DANUBE_MPS_RVC1SR ((volatile u32*)(DANUBE_MPS + 0x0014))
+#define DANUBE_MPS_RVC2SR ((volatile u32*)(DANUBE_MPS + 0x0018))
+#define DANUBE_MPS_RVC3SR ((volatile u32*)(DANUBE_MPS + 0x001C))
+/* voice channel 0 ... 3 interrupt status set register */
+#define DANUBE_MPS_SVC0SR ((volatile u32*)(DANUBE_MPS + 0x0020))
+#define DANUBE_MPS_SVC1SR ((volatile u32*)(DANUBE_MPS + 0x0024))
+#define DANUBE_MPS_SVC2SR ((volatile u32*)(DANUBE_MPS + 0x0028))
+#define DANUBE_MPS_SVC3SR ((volatile u32*)(DANUBE_MPS + 0x002C))
+/* voice channel 0 ... 3 interrupt status clear register */
+#define DANUBE_MPS_CVC0SR ((volatile u32*)(DANUBE_MPS + 0x0030))
+#define DANUBE_MPS_CVC1SR ((volatile u32*)(DANUBE_MPS + 0x0034))
+#define DANUBE_MPS_CVC2SR ((volatile u32*)(DANUBE_MPS + 0x0038))
+#define DANUBE_MPS_CVC3SR ((volatile u32*)(DANUBE_MPS + 0x003C))
+/* common status 0 and 1 read register */
+#define DANUBE_MPS_RAD0SR ((volatile u32*)(DANUBE_MPS + 0x0040))
+#define DANUBE_MPS_RAD1SR ((volatile u32*)(DANUBE_MPS + 0x0044))
+/* common status 0 and 1 set register */
+#define DANUBE_MPS_SAD0SR ((volatile u32*)(DANUBE_MPS + 0x0048))
+#define DANUBE_MPS_SAD1SR ((volatile u32*)(DANUBE_MPS + 0x004C))
+/* common status 0 and 1 clear register */
+#define DANUBE_MPS_CAD0SR ((volatile u32*)(DANUBE_MPS + 0x0050))
+#define DANUBE_MPS_CAD1SR ((volatile u32*)(DANUBE_MPS + 0x0054))
+/* common status 0 and 1 enable register */
+#define DANUBE_MPS_AD0ENR ((volatile u32*)(DANUBE_MPS + 0x0058))
+#define DANUBE_MPS_AD1ENR ((volatile u32*)(DANUBE_MPS + 0x005C))
+/* notification enable register */
+#define DANUBE_MPS_CPU0_NFER ((volatile u32*)(DANUBE_MPS + 0x0060))
+#define DANUBE_MPS_CPU1_NFER ((volatile u32*)(DANUBE_MPS + 0x0064))
+/* CPU to CPU interrup request register */
+#define DANUBE_MPS_CPU0_2_CPU1_IRR ((volatile u32*)(DANUBE_MPS + 0x0070))
+#define DANUBE_MPS_CPU0_2_CPU1_IER ((volatile u32*)(DANUBE_MPS + 0x0074))
+/* Global interrupt request and request enable register */
+#define DANUBE_MPS_GIRR ((volatile u32*)(DANUBE_MPS + 0x0078))
+#define DANUBE_MPS_GIER ((volatile u32*)(DANUBE_MPS + 0x007C))
+
+
+#define DANUBE_MPS_CPU0_SMP0 ((volatile u32*)(DANUBE_MPS + 0x00100))
+
+#define DANUBE_MPS_CPU1_SMP0 ((volatile u32*)(DANUBE_MPS + 0x00200))
+/************************************************************************/
+/*   Module       :   DEU register address and bits                    */
+/************************************************************************/
+#define DANUBE_DEU_BASE_ADDR               (0xBE102000)
+/*   DEU Control Register */
+#define DANUBE_DEU_CLK                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0000))
+#define DANUBE_DEU_ID                      ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0008))
+
+/*   DEU control register */
+#define DANUBE_DEU_CON                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0010))
+#define DANUBE_DEU_IHR                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0014))
+#define DANUBE_DEU_ILR                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0018))
+#define DANUBE_DEU_K1HR                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x001C))
+#define DANUBE_DEU_K1LR                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0020))
+#define DANUBE_DEU_K3HR                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0024))
+#define DANUBE_DEU_K3LR                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0028))
+#define DANUBE_DEU_IVHR                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x002C))
+#define DANUBE_DEU_IVLR                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0030))
+#define DANUBE_DEU_OHR                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0040))
+#define DANUBE_DEU_OLR                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0050))
+
+/* AES DEU register */
+#define DANUBE_AES_CON                            ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0050))
+#define DANUBE_AES_ID3R                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0054))
+#define DANUBE_AES_ID2R                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0058))
+#define DANUBE_AES_ID1R                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x005C))
+#define DANUBE_AES_ID0R                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0060))
+
+/* AES Key register */
+#define DANUBE_AES_K7R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0064))
+#define DANUBE_AES_K6R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0068))
+#define DANUBE_AES_K5R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x006C))
+#define DANUBE_AES_K4R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0070))
+#define DANUBE_AES_K3R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0074))
+#define DANUBE_AES_K2R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0078))
+#define DANUBE_AES_K1R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x007C))
+#define DANUBE_AES_K0R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0080))
+
+/* AES vector register */
+#define DANUBE_AES_IV3R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0084))
+#define DANUBE_AES_IV2R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0088))
+#define DANUBE_AES_IV1R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x008C))
+#define DANUBE_AES_IV0R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0090))
+#define DANUBE_AES_0D3R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0094))
+#define DANUBE_AES_0D2R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x0098))
+#define DANUBE_AES_OD1R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x009C))
+#define DANUBE_AES_OD0R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x00A0))
+
+/* hash control registe */
+#define DANUBE_HASH_CON                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x00B0))
+#define DANUBE_HASH_MR                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x00B4))
+#define DANUBE_HASH_D1R                    ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x00B8 ))
+#define DANUBE_HASH_D2R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x00BC ))
+#define DANUBE_HASH_D3R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x00C0 ))
+#define DANUBE_HASH_D4R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x00C4))
+#define DANUBE_HASH_D5R                     ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x00C8))
+
+#define DANUBE_CON                         ((volatile u32 *)(DANUBE_DEU_BASE_ADDR + 0x00EC))
+
+
+
+/************************************************************************/
+/*   Module       :   PPE register address and bits                    */
+/************************************************************************/
+#define DANUBE_PPE_BASE_ADDR                (KSEG1 + 0x1E180000)
+#define DANUBE_PPE_PP32_DEBUG_REG_ADDR(x)          ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x0000) << 2)))
+#define DANUBE_PPE_PPM_INT_REG_ADDR(x)             ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x0030) << 2)))
+#define DANUBE_PPE_PP32_INTERNAL_RES_ADDR(x)       ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x0040) << 2)))
+#define DANUBE_PPE_PPE_CLOCK_CONTROL_ADDR(x)       ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x0100) << 2)))
+#define DANUBE_PPE_CDM_CODE_MEMORY_RAM0_ADDR(x)    ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x1000) << 2)))
+#define DANUBE_PPE_CDM_CODE_MEMORY_RAM1_ADDR(x)    ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x2000) << 2)))
+#define DANUBE_PPE_REG_ADDR(x)                 ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x4000) << 2)))
+#define DANUBE_PPE_PP32_DATA_MEMORY_RAM1_ADDR(x)   ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x5000) << 2)))
+#define DANUBE_PPE_PPM_INT_UNIT_ADDR(x)            ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x6000) << 2)))
+#define DANUBE_PPE_PPM_TIMER0_ADDR(x)              ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x6100) << 2)))
+#define DANUBE_PPE_PPM_TASK_IND_REG_ADDR(x)        ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x6200) << 2)))
+#define DANUBE_PPE_PPS_BRK_ADDR(x)                 ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x6300) << 2)))
+#define DANUBE_PPE_PPM_TIMER1_ADDR(x)              ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x6400) << 2)))
+#define DANUBE_PPE_SB_RAM0_ADDR(x)                 ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x8000) << 2)))
+#define DANUBE_PPE_SB_RAM1_ADDR(x)                 ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x8400) << 2)))
+#define DANUBE_PPE_SB_RAM2_ADDR(x)                 ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x8C00) << 2)))
+#define DANUBE_PPE_SB_RAM3_ADDR(x)                 ((volatile u32*)(DANUBE_PPE_BASE_ADDR + (((x) + 0x9600) << 2)))
+
+#define DANUBE_PPE_PP32_SLEEP                      DANUBE_PPE_REG_ADDR(0x0010) /* PP32 Power Saving Register */
+#define DANUBE_PPE_CDM_CFG                         DANUBE_PPE_REG_ADDR(0x0100) /* Code/Data Memory (CDM) Register */
+
+/* Mailbox Registers */
+#define DANUBE_PPE_MBOX_IGU0_ISRS                  DANUBE_PPE_REG_ADDR(0x0200)
+#define DANUBE_PPE_MBOX_IGU0_ISRC                  DANUBE_PPE_REG_ADDR(0x0201)
+#define DANUBE_PPE_MBOX_IGU0_ISR                   DANUBE_PPE_REG_ADDR(0x0202)
+#define DANUBE_PPE_MBOX_IGU0_IER                   DANUBE_PPE_REG_ADDR(0x0203)
+#define DANUBE_PPE_MBOX_IGU1_ISRS0                 DANUBE_PPE_REG_ADDR(0x0204)
+#define DANUBE_PPE_MBOX_IGU1_ISRC0                 DANUBE_PPE_REG_ADDR(0x0205)
+#define DANUBE_PPE_MBOX_IGU1_ISR0                  DANUBE_PPE_REG_ADDR(0x0206)
+#define DANUBE_PPE_MBOX_IGU1_IER0                  DANUBE_PPE_REG_ADDR(0x0207)
+#define DANUBE_PPE_MBOX_IGU1_ISRS1                 DANUBE_PPE_REG_ADDR(0x0208)
+#define DANUBE_PPE_MBOX_IGU1_ISRC1                 DANUBE_PPE_REG_ADDR(0x0209)
+#define DANUBE_PPE_MBOX_IGU1_ISR1                  DANUBE_PPE_REG_ADDR(0x020A)
+#define DANUBE_PPE_MBOX_IGU1_IER1                  DANUBE_PPE_REG_ADDR(0x020B)
+#define DANUBE_PPE_MBOX_IGU1_ISRS2                 DANUBE_PPE_REG_ADDR(0x020C)
+#define DANUBE_PPE_MBOX_IGU1_ISRC2                 DANUBE_PPE_REG_ADDR(0x020D)
+#define DANUBE_PPE_MBOX_IGU1_ISR2                  DANUBE_PPE_REG_ADDR(0x020E)
+#define DANUBE_PPE_MBOX_IGU1_IER2                  DANUBE_PPE_REG_ADDR(0x020F)
+#define DANUBE_PPE_MBOX_IGU2_ISRS                  DANUBE_PPE_REG_ADDR(0x0210)
+#define DANUBE_PPE_MBOX_IGU2_ISRC                  DANUBE_PPE_REG_ADDR(0x0211)
+#define DANUBE_PPE_MBOX_IGU2_ISR                   DANUBE_PPE_REG_ADDR(0x0212)
+#define DANUBE_PPE_MBOX_IGU2_IER                   DANUBE_PPE_REG_ADDR(0x0213)
+#define DANUBE_PPE_MBOX_IGU3_ISRS                  DANUBE_PPE_REG_ADDR(0x0214)
+#define DANUBE_PPE_MBOX_IGU3_ISRC                  DANUBE_PPE_REG_ADDR(0x0215)
+#define DANUBE_PPE_MBOX_IGU3_ISR                   DANUBE_PPE_REG_ADDR(0x0216)
+#define DANUBE_PPE_MBOX_IGU3_IER                   DANUBE_PPE_REG_ADDR(0x0217)
+#define DANUBE_PPE_MBOX_IGU4_ISRS                  DANUBE_PPE_REG_ADDR(0x0218)
+#define DANUBE_PPE_MBOX_IGU4_ISRC                  DANUBE_PPE_REG_ADDR(0x0219)
+#define DANUBE_PPE_MBOX_IGU4_ISR                   DANUBE_PPE_REG_ADDR(0x021A)
+#define DANUBE_PPE_MBOX_IGU4_IER                   DANUBE_PPE_REG_ADDR(0x021B)
+/*
+ *    Shared Buffer (SB) Registers
+ */
+#define DANUBE_PPE_SB_MST_PRI0                     DANUBE_PPE_REG_ADDR(0x0300)
+#define DANUBE_PPE_SB_MST_PRI1                     DANUBE_PPE_REG_ADDR(0x0301)
+#define DANUBE_PPE_SB_MST_PRI2                     DANUBE_PPE_REG_ADDR(0x0302)
+#define DANUBE_PPE_SB_MST_PRI3                     DANUBE_PPE_REG_ADDR(0x0303)
+#define DANUBE_PPE_SB_MST_PRI4                     DANUBE_PPE_REG_ADDR(0x0304)
+#define DANUBE_PPE_SB_MST_SEL                      DANUBE_PPE_REG_ADDR(0x0305)
+/*
+ *    RTHA Registers
+ */
+#define DANUBE_PPE_RFBI_CFG                        DANUBE_PPE_REG_ADDR(0x0400)
+#define DANUBE_PPE_RBA_CFG0                        DANUBE_PPE_REG_ADDR(0x0404)
+#define DANUBE_PPE_RBA_CFG1                        DANUBE_PPE_REG_ADDR(0x0405)
+#define DANUBE_PPE_RCA_CFG0                        DANUBE_PPE_REG_ADDR(0x0408)
+#define DANUBE_PPE_RCA_CFG1                        DANUBE_PPE_REG_ADDR(0x0409)
+#define DANUBE_PPE_RDES_CFG0                       DANUBE_PPE_REG_ADDR(0x040C)
+#define DANUBE_PPE_RDES_CFG1                       DANUBE_PPE_REG_ADDR(0x040D)
+#define DANUBE_PPE_SFSM_STATE0                     DANUBE_PPE_REG_ADDR(0x0410)
+#define DANUBE_PPE_SFSM_STATE1                     DANUBE_PPE_REG_ADDR(0x0411)
+#define DANUBE_PPE_SFSM_DBA0                       DANUBE_PPE_REG_ADDR(0x0412)
+#define DANUBE_PPE_SFSM_DBA1                       DANUBE_PPE_REG_ADDR(0x0413)
+#define DANUBE_PPE_SFSM_CBA0                       DANUBE_PPE_REG_ADDR(0x0414)
+#define DANUBE_PPE_SFSM_CBA1                       DANUBE_PPE_REG_ADDR(0x0415)
+#define DANUBE_PPE_SFSM_CFG0                       DANUBE_PPE_REG_ADDR(0x0416)
+#define DANUBE_PPE_SFSM_CFG1                       DANUBE_PPE_REG_ADDR(0x0417)
+#define DANUBE_PPE_SFSM_PGCNT0                     DANUBE_PPE_REG_ADDR(0x041C)
+#define DANUBE_PPE_SFSM_PGCNT1                     DANUBE_PPE_REG_ADDR(0x041D)
+/*
+ *    TTHA Registers
+ */
+#define DANUBE_PPE_FFSM_DBA0                       DANUBE_PPE_REG_ADDR(0x0508)
+#define DANUBE_PPE_FFSM_DBA1                       DANUBE_PPE_REG_ADDR(0x0509)
+#define DANUBE_PPE_FFSM_CFG0                       DANUBE_PPE_REG_ADDR(0x050A)
+#define DANUBE_PPE_FFSM_CFG1                       DANUBE_PPE_REG_ADDR(0x050B)
+#define DANUBE_PPE_FFSM_IDLE_HEAD_BC0              DANUBE_PPE_REG_ADDR(0x050E)
+#define DANUBE_PPE_FFSM_IDLE_HEAD_BC1              DANUBE_PPE_REG_ADDR(0x050F)
+#define DANUBE_PPE_FFSM_PGCNT0                     DANUBE_PPE_REG_ADDR(0x0514)
+#define DANUBE_PPE_FFSM_PGCNT1                     DANUBE_PPE_REG_ADDR(0x0515)
+/*
+ *    ETOP MDIO Registers
+ */
+#define DANUBE_PPE_ETOP_MDIO_CFG                   DANUBE_PPE_REG_ADDR(0x0600)
+#define DANUBE_PPE_ETOP_MDIO_ACC                   DANUBE_PPE_REG_ADDR(0x0601)
+#define DANUBE_PPE_ETOP_CFG                        DANUBE_PPE_REG_ADDR(0x0602)
+#define DANUBE_PPE_ETOP_IG_VLAN_COS                DANUBE_PPE_REG_ADDR(0x0603)
+#define DANUBE_PPE_ETOP_IG_DSCP_COS3               DANUBE_PPE_REG_ADDR(0x0604)
+#define DANUBE_PPE_ETOP_IG_DSCP_COS2               DANUBE_PPE_REG_ADDR(0x0605)
+#define DANUBE_PPE_ETOP_IG_DSCP_COS1               DANUBE_PPE_REG_ADDR(0x0606)
+#define DANUBE_PPE_ETOP_IG_DSCP_COS0               DANUBE_PPE_REG_ADDR(0x0607)
+#define DANUBE_PPE_ETOP_IG_PLEN_CTRL0              DANUBE_PPE_REG_ADDR(0x0608)
+#define DANUBE_PPE_ETOP_IG_PLEN_CTRL1              DANUBE_PPE_REG_ADDR(0x0609)
+#define DANUBE_PPE_ETOP_ISR                        DANUBE_PPE_REG_ADDR(0x060A)
+#define DANUBE_PPE_ETOP_IER                        DANUBE_PPE_REG_ADDR(0x060B)
+#define DANUBE_PPE_ETOP_VPID                       DANUBE_PPE_REG_ADDR(0x060C)
+#define DANUBE_PPE_ENET_MAC_CFG                    DANUBE_PPE_REG_ADDR(0x0610)
+#define DANUBE_PPE_ENETS_DBA                       DANUBE_PPE_REG_ADDR(0x0612)
+#define DANUBE_PPE_ENETS_CBA                       DANUBE_PPE_REG_ADDR(0x0613)
+#define DANUBE_PPE_ENETS_CFG                       DANUBE_PPE_REG_ADDR(0x0614)
+#define DANUBE_PPE_ENETS_PGCNT                     DANUBE_PPE_REG_ADDR(0x0615)
+#define DANUBE_PPE_ENETS_PGCNT_DSRC_PP32          (0x00020000)
+#define DANUBE_PPE_ENETS_PGCNT_DVAL_SHIFT         (9)
+#define DANUBE_PPE_ENETS_PGCNT_DCMD               (0x00000100) 
+#define DANUBE_PPE_ENETS_PKTCNT                    DANUBE_PPE_REG_ADDR(0x0616)
+#define DANUBE_PPE_ENETS_PKTCNT_DSRC_PP32         (0x00000200)
+#define DANUBE_PPE_ENETS_PKTCNT_DCMD              (0x00000100) 
+#define DANUBE_PPE_ENETS_PKTCNT_UPKT              (0x000000FF) 
+#define DANUBE_PPE_ENETS_BUF_CTRL                  DANUBE_PPE_REG_ADDR(0x0617)
+#define DANUBE_PPE_ENETS_COS_CFG                   DANUBE_PPE_REG_ADDR(0x0618)
+#define DANUBE_PPE_ENETS_IGDROP                    DANUBE_PPE_REG_ADDR(0x0619)
+#define DANUBE_PPE_ENETF_DBA                       DANUBE_PPE_REG_ADDR(0x0630)
+#define DANUBE_PPE_ENETF_CBA                       DANUBE_PPE_REG_ADDR(0x0631)
+#define DANUBE_PPE_ENETF_CFG                       DANUBE_PPE_REG_ADDR(0x0632)
+#define DANUBE_PPE_ENETF_PGCNT                     DANUBE_PPE_REG_ADDR(0x0633)
+#define DANUBE_PPE_ENETF_PGCNT_ISRC_PP32          (0x00020000)
+#define DANUBE_PPE_ENETF_PGCNT_IVAL_SHIFT         (9)
+#define DANUBE_PPE_ENETF_PGCNT_ICMD               (0x00000100) 
+#define DANUBE_PPE_ENETF_PKTCNT                    DANUBE_PPE_REG_ADDR(0x0634)
+#define DANUBE_PPE_ENETF_PKTCNT_ISRC_PP32         (0x00000200)
+#define DANUBE_PPE_ENETF_PKTCNT_ICMD              (0x00000100) 
+#define DANUBE_PPE_ENETF_PKTCNT_VPKT              (0x000000FF) 
+#define DANUBE_PPE_ENETF_HFCTRL                    DANUBE_PPE_REG_ADDR(0x0635)
+#define DANUBE_PPE_ENETF_TXCTRL                    DANUBE_PPE_REG_ADDR(0x0636)
+#define DANUBE_PPE_ENETF_VLCOS0                    DANUBE_PPE_REG_ADDR(0x0638)
+#define DANUBE_PPE_ENETF_VLCOS1                    DANUBE_PPE_REG_ADDR(0x0639)
+#define DANUBE_PPE_ENETF_VLCOS2                    DANUBE_PPE_REG_ADDR(0x063A)
+#define DANUBE_PPE_ENETF_VLCOS3                    DANUBE_PPE_REG_ADDR(0x063B)
+#define DANUBE_PPE_ENETF_EGERR                     DANUBE_PPE_REG_ADDR(0x063C)
+#define DANUBE_PPE_ENETF_EGDROP                    DANUBE_PPE_REG_ADDR(0x063D)
+/*
+ *    DPLUS Registers
+ */
+#define DANUBE_PPE_DPLUS_TXDB                      DANUBE_PPE_REG_ADDR(0x0700)
+#define DANUBE_PPE_DPLUS_TXCB                      DANUBE_PPE_REG_ADDR(0x0701)
+#define DANUBE_PPE_DPLUS_TXCFG                     DANUBE_PPE_REG_ADDR(0x0702)
+#define DANUBE_PPE_DPLUS_TXPGCNT                   DANUBE_PPE_REG_ADDR(0x0703)
+#define DANUBE_PPE_DPLUS_RXDB                      DANUBE_PPE_REG_ADDR(0x0710)
+#define DANUBE_PPE_DPLUS_RXCB                      DANUBE_PPE_REG_ADDR(0x0711)
+#define DANUBE_PPE_DPLUS_RXCFG                     DANUBE_PPE_REG_ADDR(0x0712)
+#define DANUBE_PPE_DPLUS_RXPGCNT                   DANUBE_PPE_REG_ADDR(0x0713)
+/*
+ *    BMC Registers
+ */
+#define DANUBE_PPE_BMC_CMD3                        DANUBE_PPE_REG_ADDR(0x0800)
+#define DANUBE_PPE_BMC_CMD2                        DANUBE_PPE_REG_ADDR(0x0801)
+#define DANUBE_PPE_BMC_CMD1                        DANUBE_PPE_REG_ADDR(0x0802)
+#define DANUBE_PPE_BMC_CMD0                        DANUBE_PPE_REG_ADDR(0x0803)
+#define DANUBE_PPE_BMC_CFG0                        DANUBE_PPE_REG_ADDR(0x0804)
+#define DANUBE_PPE_BMC_CFG1                        DANUBE_PPE_REG_ADDR(0x0805)
+#define DANUBE_PPE_BMC_POLY0                       DANUBE_PPE_REG_ADDR(0x0806)
+#define DANUBE_PPE_BMC_POLY1                       DANUBE_PPE_REG_ADDR(0x0807)
+#define DANUBE_PPE_BMC_CRC0                        DANUBE_PPE_REG_ADDR(0x0808)
+#define DANUBE_PPE_BMC_CRC1                        DANUBE_PPE_REG_ADDR(0x0809)
+/*
+ *    SLL Registers
+ */
+#define DANUBE_PPE_SLL_CMD1                        DANUBE_PPE_REG_ADDR(0x0900)
+#define DANUBE_PPE_SLL_CMD0                        DANUBE_PPE_REG_ADDR(0x0901)
+#define DANUBE_PPE_SLL_KEY0                        DANUBE_PPE_REG_ADDR(0x0910)
+#define DANUBE_PPE_SLL_KEY1                        DANUBE_PPE_REG_ADDR(0x0911)
+#define DANUBE_PPE_SLL_KEY2                        DANUBE_PPE_REG_ADDR(0x0912)
+#define DANUBE_PPE_SLL_KEY3                        DANUBE_PPE_REG_ADDR(0x0913)
+#define DANUBE_PPE_SLL_KEY4                        DANUBE_PPE_REG_ADDR(0x0914)
+#define DANUBE_PPE_SLL_KEY5                        DANUBE_PPE_REG_ADDR(0x0915)
+#define DANUBE_PPE_SLL_RESULT                      DANUBE_PPE_REG_ADDR(0x0920)
+/*
+ *    EMA Registers
+ */
+#define DANUBE_PPE_EMA_CMD2                        DANUBE_PPE_REG_ADDR(0x0A00)
+#define DANUBE_PPE_EMA_CMD1                        DANUBE_PPE_REG_ADDR(0x0A01)
+#define DANUBE_PPE_EMA_CMD0                        DANUBE_PPE_REG_ADDR(0x0A02)
+#define DANUBE_PPE_EMA_ISR                         DANUBE_PPE_REG_ADDR(0x0A04)
+#define DANUBE_PPE_EMA_IER                         DANUBE_PPE_REG_ADDR(0x0A05)
+#define DANUBE_PPE_EMA_CFG                         DANUBE_PPE_REG_ADDR(0x0A06)
+/*
+ *    UTPS Registers
+ */
+#define DANUBE_PPE_UTP_TXCA0                       DANUBE_PPE_REG_ADDR(0x0B00)
+#define DANUBE_PPE_UTP_TXNA0                       DANUBE_PPE_REG_ADDR(0x0B01)
+#define DANUBE_PPE_UTP_TXCA1                       DANUBE_PPE_REG_ADDR(0x0B02)
+#define DANUBE_PPE_UTP_TXNA1                       DANUBE_PPE_REG_ADDR(0x0B03)
+#define DANUBE_PPE_UTP_RXCA0                       DANUBE_PPE_REG_ADDR(0x0B10)
+#define DANUBE_PPE_UTP_RXNA0                       DANUBE_PPE_REG_ADDR(0x0B11)
+#define DANUBE_PPE_UTP_RXCA1                       DANUBE_PPE_REG_ADDR(0x0B12)
+#define DANUBE_PPE_UTP_RXNA1                       DANUBE_PPE_REG_ADDR(0x0B13)
+#define DANUBE_PPE_UTP_CFG                         DANUBE_PPE_REG_ADDR(0x0B20)
+#define DANUBE_PPE_UTP_ISR                         DANUBE_PPE_REG_ADDR(0x0B30)
+#define DANUBE_PPE_UTP_IER                         DANUBE_PPE_REG_ADDR(0x0B31)
+/*
+ *    QSB Registers
+ */
+#define DANUBE_PPE_QSB_RELOG                       DANUBE_PPE_REG_ADDR(0x0C00)
+#define DANUBE_PPE_QSB_EMIT0                       DANUBE_PPE_REG_ADDR(0x0C01)
+#define DANUBE_PPE_QSB_EMIT1                       DANUBE_PPE_REG_ADDR(0x0C02)
+#define DANUBE_PPE_QSB_ICDV                        DANUBE_PPE_REG_ADDR(0x0C07)
+#define DANUBE_PPE_QSB_SBL                         DANUBE_PPE_REG_ADDR(0x0C09)
+#define DANUBE_PPE_QSB_CFG                         DANUBE_PPE_REG_ADDR(0x0C0A)
+#define DANUBE_PPE_QSB_RTM                         DANUBE_PPE_REG_ADDR(0x0C0B)
+#define DANUBE_PPE_QSB_RTD                         DANUBE_PPE_REG_ADDR(0x0C0C)
+#define DANUBE_PPE_QSB_RAMAC                       DANUBE_PPE_REG_ADDR(0x0C0D)
+#define DANUBE_PPE_QSB_ISTAT                       DANUBE_PPE_REG_ADDR(0x0C0E)
+#define DANUBE_PPE_QSB_IMR                         DANUBE_PPE_REG_ADDR(0x0C0F)
+#define DANUBE_PPE_QSB_SRC                         DANUBE_PPE_REG_ADDR(0x0C10)
+/*
+ *    DSP User Registers
+ */
+#define DANUBE_PPE_DREG_A_VERSION                  DANUBE_PPE_REG_ADDR(0x0D00)
+#define DANUBE_PPE_DREG_A_CFG                      DANUBE_PPE_REG_ADDR(0x0D01)
+#define DANUBE_PPE_DREG_AT_CTRL                    DANUBE_PPE_REG_ADDR(0x0D02)
+#define DANUBE_PPE_DREG_AR_CTRL                    DANUBE_PPE_REG_ADDR(0x0D08)
+#define DANUBE_PPE_DREG_A_UTPCFG                   DANUBE_PPE_REG_ADDR(0x0D0E)
+#define DANUBE_PPE_DREG_A_STATUS                   DANUBE_PPE_REG_ADDR(0x0D0F)
+#define DANUBE_PPE_DREG_AT_CFG0                    DANUBE_PPE_REG_ADDR(0x0D20)
+#define DANUBE_PPE_DREG_AT_CFG1                    DANUBE_PPE_REG_ADDR(0x0D21)
+#define DANUBE_PPE_DREG_FB_SIZE0                   DANUBE_PPE_REG_ADDR(0x0D22)
+#define DANUBE_PPE_DREG_FB_SIZE1                   DANUBE_PPE_REG_ADDR(0x0D23)
+#define DANUBE_PPE_DREG_AT_CELL0                   DANUBE_PPE_REG_ADDR(0x0D24)
+#define DANUBE_PPE_DREG_AT_CELL1                   DANUBE_PPE_REG_ADDR(0x0D25)
+#define DANUBE_PPE_DREG_AT_IDLE_CNT0               DANUBE_PPE_REG_ADDR(0x0D26)
+#define DANUBE_PPE_DREG_AT_IDLE_CNT1               DANUBE_PPE_REG_ADDR(0x0D27)
+#define DANUBE_PPE_DREG_AT_IDLE0                   DANUBE_PPE_REG_ADDR(0x0D28)
+#define DANUBE_PPE_DREG_AT_IDLE1                   DANUBE_PPE_REG_ADDR(0x0D29)
+#define DANUBE_PPE_DREG_AR_CFG0                    DANUBE_PPE_REG_ADDR(0x0D60)
+#define DANUBE_PPE_DREG_AR_CFG1                    DANUBE_PPE_REG_ADDR(0x0D61)
+#define DANUBE_PPE_DREG_AR_FB_START0               DANUBE_PPE_REG_ADDR(0x0D62)
+#define DANUBE_PPE_DREG_AR_FB_START1               DANUBE_PPE_REG_ADDR(0x0D63)
+#define DANUBE_PPE_DREG_AR_FB_END0                 DANUBE_PPE_REG_ADDR(0x0D64)
+#define DANUBE_PPE_DREG_AR_FB_END1                 DANUBE_PPE_REG_ADDR(0x0D65)
+#define DANUBE_PPE_DREG_AR_ATM_STAT0               DANUBE_PPE_REG_ADDR(0x0D66)
+#define DANUBE_PPE_DREG_AR_ATM_STAT1               DANUBE_PPE_REG_ADDR(0x0D67)
+#define DANUBE_PPE_DREG_AR_CELL0                   DANUBE_PPE_REG_ADDR(0x0D68)
+#define DANUBE_PPE_DREG_AR_CELL1                   DANUBE_PPE_REG_ADDR(0x0D69)
+#define DANUBE_PPE_DREG_AR_IDLE_CNT0               DANUBE_PPE_REG_ADDR(0x0D6A)
+#define DANUBE_PPE_DREG_AR_IDLE_CNT1               DANUBE_PPE_REG_ADDR(0x0D6B)
+#define DANUBE_PPE_DREG_AR_AIIDLE_CNT0             DANUBE_PPE_REG_ADDR(0x0D6C)
+#define DANUBE_PPE_DREG_AR_AIIDLE_CNT1             DANUBE_PPE_REG_ADDR(0x0D6D)
+#define DANUBE_PPE_DREG_AR_BE_CNT0                 DANUBE_PPE_REG_ADDR(0x0D6E)
+#define DANUBE_PPE_DREG_AR_BE_CNT1                 DANUBE_PPE_REG_ADDR(0x0D6F)
+#define DANUBE_PPE_DREG_AR_HEC_CNT0                DANUBE_PPE_REG_ADDR(0x0D70)
+#define DANUBE_PPE_DREG_AR_HEC_CNT1                DANUBE_PPE_REG_ADDR(0x0D71)
+#define DANUBE_PPE_DREG_AR_CD_CNT0                 DANUBE_PPE_REG_ADDR(0x0D72)
+#define DANUBE_PPE_DREG_AR_CD_CNT1                 DANUBE_PPE_REG_ADDR(0x0D73)
+#define DANUBE_PPE_DREG_AR_IDLE0                   DANUBE_PPE_REG_ADDR(0x0D74)
+#define DANUBE_PPE_DREG_AR_IDLE1                   DANUBE_PPE_REG_ADDR(0x0D75)
+#define DANUBE_PPE_DREG_AR_DELIN0                  DANUBE_PPE_REG_ADDR(0x0D76)
+#define DANUBE_PPE_DREG_AR_DELIN1                  DANUBE_PPE_REG_ADDR(0x0D77)
+#define DANUBE_PPE_DREG_RESV0                      DANUBE_PPE_REG_ADDR(0x0D78)
+#define DANUBE_PPE_DREG_RESV1                      DANUBE_PPE_REG_ADDR(0x0D79)
+#define DANUBE_PPE_DREG_RX_MIB_CMD0                DANUBE_PPE_REG_ADDR(0x0D80)
+#define DANUBE_PPE_DREG_RX_MIB_CMD1                DANUBE_PPE_REG_ADDR(0x0D81)
+#define DANUBE_PPE_DREG_AR_OVDROP_CNT0             DANUBE_PPE_REG_ADDR(0x0D98)
+#define DANUBE_PPE_DREG_AR_OVDROP_CNT1             DANUBE_PPE_REG_ADDR(0x0D99)
+
+
+/************************************************************************/
+/*   Module       :   PPE register address and bits                    */
+/************************************************************************/
+#define DANUBE_PPE32_BASE  0xBE180000
+#define DANUBE_PPE32_DEBUG_BREAK_TRACE_REG   (DANUBE_PPE32_BASE + (0x0000 * 4))
+#define DANUBE_PPE32_INT_MASK_STATUS_REG     (DANUBE_PPE32_BASE + (0x0030 * 4))
+#define DANUBE_PPE32_INT_RESOURCE_REG        (DANUBE_PPE32_BASE + (0x0040 * 4))
+#define DANUBE_PPE32_CDM_CODE_MEM_B0         (DANUBE_PPE32_BASE + (0x1000 * 4))
+#define DANUBE_PPE32_CDM_CODE_MEM_B1         (DANUBE_PPE32_BASE + (0x2000 * 4))
+#define DANUBE_PPE32_DATA_MEM_MAP_REG_BASE   (DANUBE_PPE32_BASE + (0x4000 * 4))
+
+/************************************************************************/
+/*   Module       :   PPE register address and bits                    */
+/************************************************************************/
+#define DANUBE_PPE32_BASE  0xBE180000
+#define DANUBE_PPE32_DEBUG_BREAK_TRACE_REG   (DANUBE_PPE32_BASE + (0x0000 * 4))
+#define DANUBE_PPE32_INT_MASK_STATUS_REG     (DANUBE_PPE32_BASE + (0x0030 * 4))
+#define DANUBE_PPE32_INT_RESOURCE_REG        (DANUBE_PPE32_BASE + (0x0040 * 4))
+#define DANUBE_PPE32_CDM_CODE_MEM_B0         (DANUBE_PPE32_BASE + (0x1000 * 4))
+#define DANUBE_PPE32_CDM_CODE_MEM_B1         (DANUBE_PPE32_BASE + (0x2000 * 4))
+#define DANUBE_PPE32_DATA_MEM_MAP_REG_BASE   (DANUBE_PPE32_BASE + (0x4000 * 4))
+
+/*
+ *    ETOP MDIO Registers
+ */
+#define ETOP_MDIO_CFG           ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0600 * 4)))
+#define ETOP_MDIO_ACC           ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0601 * 4)))
+#define ETOP_CFG                ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0602 * 4)))
+#define ETOP_IG_VLAN_COS        ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0603 * 4)))
+#define ETOP_IG_DSCP_COS3       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0604 * 4)))
+#define ETOP_IG_DSCP_COS2       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0605 * 4)))
+#define ETOP_IG_DSCP_COS1       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0606 * 4)))
+#define ETOP_IG_DSCP_COS0       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0607 * 4)))
+#define ETOP_IG_PLEN_CTRL       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0608 * 4)))
+#define ETOP_ISR                ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x060A * 4)))
+#define ETOP_IER                ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x060B * 4)))
+#define ETOP_VPID               ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x060C * 4)))
+#define ENET_MAC_CFG            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0610 * 4)))  
+#define ENETS_DBA               ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0612 * 4)))       
+#define ENETS_CBA               ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0613 * 4)))        
+#define ENETS_CFG               ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0614 * 4))) 
+#define ENETS_PGCNT             ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0615 * 4)))
+#define ENETS_PKTCNT            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0616 * 4)))
+#define ENETS_BUF_CTRL          ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0617 * 4)))
+#define ENETS_COS_CFG           ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0618 * 4)))
+#define ENETS_IGDROP            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0619 * 4)))
+#define ENETS_IGERR             ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x061A * 4))) 
+#define ENET_MAC_DA0           ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x061B * 4))) 
+#define ENET_MAC_DA1           ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x061C * 4))) 
+
+#define ENETF_DBA               ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0630 * 4)))
+#define ENETF_CBA               ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0631 * 4)))
+#define ENETF_CFG               ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0632 * 4)))
+#define ENETF_PGCNT             ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0633 * 4)))
+#define ENETF_PKTCNT            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0634 * 4)))
+#define ENETF_HFCTRL            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0635 * 4)))
+#define ENETF_TXCTRL            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0636 * 4)))
+
+#define ENETF_VLCOS0            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0638 * 4)))
+#define ENETF_VLCOS1            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0639 * 4)))
+#define ENETF_VLCOS2            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x063A * 4)))
+#define ENETF_VLCOS3            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x063B * 4)))
+#define ENETF_EGERR             ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x063C * 4)))
+#define ENETF_EGDROP            ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x063D * 4)))
+
+
+/*
+ *    ETOP MDIO Registers
+ */
+#define DANUBE_PPE32_ETOP_MDIO_CFG           ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0600 * 4)))
+#define DANUBE_PPE32_ETOP_MDIO_ACC           ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0601 * 4)))
+#define DANUBE_PPE32_ETOP_CFG                ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0602 * 4)))
+#define DANUBE_PPE32_ETOP_IG_VLAN_COS        ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0603 * 4)))
+#define DANUBE_PPE32_ETOP_IG_DSCP_COS3       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0604 * 4)))
+#define DANUBE_PPE32_ETOP_IG_DSCP_COS2       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0605 * 4)))
+#define DANUBE_PPE32_ETOP_IG_DSCP_COS1       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0606 * 4)))
+#define DANUBE_PPE32_ETOP_IG_DSCP_COS0       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0607 * 4)))
+#define DANUBE_PPE32_ETOP_IG_PLEN_CTRL       ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0608 * 4)))
+#define DANUBE_PPE32_ETOP_ISR                ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x060A * 4)))
+#define DANUBE_PPE32_ETOP_IER                ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x060B * 4)))
+#define DANUBE_PPE32_ETOP_VPID               ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x060C * 4)))
+
+
+/* ENET Register */
+#define DANUBE_PPE32_ENET_MAC_CFG              ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0610 * 4)))
+#define DANUBE_PPE32_ENET_IG_PKTDROP           ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0619 * 4)))
+#define DANUBE_PPE32_ENET_CoS_CFG              ((volatile u32 *)(DANUBE_PPE32_DATA_MEM_MAP_REG_BASE + (0x0618 * 4)))
+
+/*********LED register definition****************/
+
+#define DANUBE_LED                      0xBE100BB0
+#define DANUBE_LED_CON0                 ((volatile u32*)(DANUBE_LED + 0x0000))
+#define DANUBE_LED_CON1                 ((volatile u32*)(DANUBE_LED + 0x0004))
+#define DANUBE_LED_CPU0                 ((volatile u32*)(DANUBE_LED + 0x0008))
+#define DANUBE_LED_CPU1                 ((volatile u32*)(DANUBE_LED + 0x000C))
+#define DANUBE_LED_AR                   ((volatile u32*)(DANUBE_LED + 0x0010))
+
+
+
+
+/***********************************************************************/
+#define DANUBE_REG32(addr)                *((volatile u32 *)(addr))
+/***********************************************************************/
+#endif //DANUBE_H 
diff --git a/package/uboot-ifxmips/files/include/asm-mips/errno.h b/package/uboot-ifxmips/files/include/asm-mips/errno.h
new file mode 100644 (file)
index 0000000..134a8fc
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef _ARM_ERRNO_H
+#define _ARM_ERRNO_H
+
+#define        EPERM            1      /* Operation not permitted */
+#define        ENOENT           2      /* No such file or directory */
+#define        ESRCH            3      /* No such process */
+#define        EINTR            4      /* Interrupted system call */
+#define        EIO              5      /* I/O error */
+#define        ENXIO            6      /* No such device or address */
+#define        E2BIG            7      /* Arg list too long */
+#define        ENOEXEC          8      /* Exec format error */
+#define        EBADF            9      /* Bad file number */
+#define        ECHILD          10      /* No child processes */
+#define        EAGAIN          11      /* Try again */
+#define        ENOMEM          12      /* Out of memory */
+#define        EACCES          13      /* Permission denied */
+#define        EFAULT          14      /* Bad address */
+#define        ENOTBLK         15      /* Block device required */
+#define        EBUSY           16      /* Device or resource busy */
+#define        EEXIST          17      /* File exists */
+#define        EXDEV           18      /* Cross-device link */
+#define        ENODEV          19      /* No such device */
+#define        ENOTDIR         20      /* Not a directory */
+#define        EISDIR          21      /* Is a directory */
+#define        EINVAL          22      /* Invalid argument */
+#define        ENFILE          23      /* File table overflow */
+#define        EMFILE          24      /* Too many open files */
+#define        ENOTTY          25      /* Not a typewriter */
+#define        ETXTBSY         26      /* Text file busy */
+#define        EFBIG           27      /* File too large */
+#define        ENOSPC          28      /* No space left on device */
+#define        ESPIPE          29      /* Illegal seek */
+#define        EROFS           30      /* Read-only file system */
+#define        EMLINK          31      /* Too many links */
+#define        EPIPE           32      /* Broken pipe */
+#define        EDOM            33      /* Math argument out of domain of func */
+#define        ERANGE          34      /* Math result not representable */
+#define        EDEADLK         35      /* Resource deadlock would occur */
+#define        ENAMETOOLONG    36      /* File name too long */
+#define        ENOLCK          37      /* No record locks available */
+#define        ENOSYS          38      /* Function not implemented */
+#define        ENOTEMPTY       39      /* Directory not empty */
+#define        ELOOP           40      /* Too many symbolic links encountered */
+#define        EWOULDBLOCK     EAGAIN  /* Operation would block */
+#define        ENOMSG          42      /* No message of desired type */
+#define        EIDRM           43      /* Identifier removed */
+#define        ECHRNG          44      /* Channel number out of range */
+#define        EL2NSYNC        45      /* Level 2 not synchronized */
+#define        EL3HLT          46      /* Level 3 halted */
+#define        EL3RST          47      /* Level 3 reset */
+#define        ELNRNG          48      /* Link number out of range */
+#define        EUNATCH         49      /* Protocol driver not attached */
+#define        ENOCSI          50      /* No CSI structure available */
+#define        EL2HLT          51      /* Level 2 halted */
+#define        EBADE           52      /* Invalid exchange */
+#define        EBADR           53      /* Invalid request descriptor */
+#define        EXFULL          54      /* Exchange full */
+#define        ENOANO          55      /* No anode */
+#define        EBADRQC         56      /* Invalid request code */
+#define        EBADSLT         57      /* Invalid slot */
+#define        EDEADLOCK       58      /* File locking deadlock error */
+#define        EBFONT          59      /* Bad font file format */
+#define        ENOSTR          60      /* Device not a stream */
+#define        ENODATA         61      /* No data available */
+#define        ETIME           62      /* Timer expired */
+#define        ENOSR           63      /* Out of streams resources */
+#define        ENONET          64      /* Machine is not on the network */
+#define        ENOPKG          65      /* Package not installed */
+#define        EREMOTE         66      /* Object is remote */
+#define        ENOLINK         67      /* Link has been severed */
+#define        EADV            68      /* Advertise error */
+#define        ESRMNT          69      /* Srmount error */
+#define        ECOMM           70      /* Communication error on send */
+#define        EPROTO          71      /* Protocol error */
+#define        EMULTIHOP       72      /* Multihop attempted */
+#define        EDOTDOT         73      /* RFS specific error */
+#define        EBADMSG         74      /* Not a data message */
+#define        EOVERFLOW       75      /* Value too large for defined data type */
+#define        ENOTUNIQ        76      /* Name not unique on network */
+#define        EBADFD          77      /* File descriptor in bad state */
+#define        EREMCHG         78      /* Remote address changed */
+#define        ELIBACC         79      /* Can not access a needed shared library */
+#define        ELIBBAD         80      /* Accessing a corrupted shared library */
+#define        ELIBSCN         81      /* .lib section in a.out corrupted */
+#define        ELIBMAX         82      /* Attempting to link in too many shared libraries */
+#define        ELIBEXEC        83      /* Cannot exec a shared library directly */
+#define        EILSEQ          84      /* Illegal byte sequence */
+#define        ERESTART        85      /* Interrupted system call should be restarted */
+#define        ESTRPIPE        86      /* Streams pipe error */
+#define        EUSERS          87      /* Too many users */
+#define        ENOTSOCK        88      /* Socket operation on non-socket */
+#define        EDESTADDRREQ    89      /* Destination address required */
+#define        EMSGSIZE        90      /* Message too long */
+#define        EPROTOTYPE      91      /* Protocol wrong type for socket */
+#define        ENOPROTOOPT     92      /* Protocol not available */
+#define        EPROTONOSUPPORT 93      /* Protocol not supported */
+#define        ESOCKTNOSUPPORT 94      /* Socket type not supported */
+#define        EOPNOTSUPP      95      /* Operation not supported on transport endpoint */
+#define        EPFNOSUPPORT    96      /* Protocol family not supported */
+#define        EAFNOSUPPORT    97      /* Address family not supported by protocol */
+#define        EADDRINUSE      98      /* Address already in use */
+#define        EADDRNOTAVAIL   99      /* Cannot assign requested address */
+#define        ENETDOWN        100     /* Network is down */
+#define        ENETUNREACH     101     /* Network is unreachable */
+#define        ENETRESET       102     /* Network dropped connection because of reset */
+#define        ECONNABORTED    103     /* Software caused connection abort */
+#define        ECONNRESET      104     /* Connection reset by peer */
+#define        ENOBUFS         105     /* No buffer space available */
+#define        EISCONN         106     /* Transport endpoint is already connected */
+#define        ENOTCONN        107     /* Transport endpoint is not connected */
+#define        ESHUTDOWN       108     /* Cannot send after transport endpoint shutdown */
+#define        ETOOMANYREFS    109     /* Too many references: cannot splice */
+#define        ETIMEDOUT       110     /* Connection timed out */
+#define        ECONNREFUSED    111     /* Connection refused */
+#define        EHOSTDOWN       112     /* Host is down */
+#define        EHOSTUNREACH    113     /* No route to host */
+#define        EALREADY        114     /* Operation already in progress */
+#define        EINPROGRESS     115     /* Operation now in progress */
+#define        ESTALE          116     /* Stale NFS file handle */
+#define        EUCLEAN         117     /* Structure needs cleaning */
+#define        ENOTNAM         118     /* Not a XENIX named type file */
+#define        ENAVAIL         119     /* No XENIX semaphores available */
+#define        EISNAM          120     /* Is a named type file */
+#define        EREMOTEIO       121     /* Remote I/O error */
+#define        EDQUOT          122     /* Quota exceeded */
+
+#define        ENOMEDIUM       123     /* No medium found */
+#define        EMEDIUMTYPE     124     /* Wrong medium type */
+
+/* Should never be seen by user programs */
+#define ERESTARTSYS    512
+#define ERESTARTNOINTR 513
+#define ERESTARTNOHAND 514     /* restart if no handler.. */
+#define ENOIOCTLCMD    515     /* No ioctl command */
+
+#define _LAST_ERRNO    515
+
+#endif
diff --git a/package/uboot-ifxmips/files/include/asm-mips/ifx_asc.h b/package/uboot-ifxmips/files/include/asm-mips/ifx_asc.h
new file mode 100644 (file)
index 0000000..51abc95
--- /dev/null
@@ -0,0 +1,220 @@
+/*****************************************************************************
+ * DANUBE BootROM
+ * Copyright (c) 2005, Infineon Technologies AG, All rights reserved
+ * IFAP DC COM SD
+ *****************************************************************************/
+#ifndef __ASC_H
+#define __ASC_H
+
+#define DANUBEASC_TXFIFO_FL                    1
+#define DANUBEASC_RXFIFO_FL                    1
+#define DANUBEASC_TXFIFO_FULL                  16
+
+/* channel operating modes */
+#define        ASCOPT_CSIZE    0x00000003
+#define        ASCOPT_CS7      0x00000001
+#define        ASCOPT_CS8      0x00000002
+#define        ASCOPT_PARENB   0x00000004
+#define        ASCOPT_STOPB    0x00000008
+#define        ASCOPT_PARODD   0x00000010
+#define        ASCOPT_CREAD    0x00000020
+
+#define ASC_OPTIONS            (ASCOPT_CREAD | ASCOPT_CS8)
+
+/* ASC input select (0 or 1) */
+#define CONSOLE_TTY    0
+
+#define DANUBEASC_TXFIFO_FL       1
+#define DANUBEASC_RXFIFO_FL       1
+#define DANUBEASC_TXFIFO_FULL     16
+
+/* interrupt lines masks for the ASC device interrupts*/
+/* change these macroses if it's necessary */
+#define DANUBEASC_IRQ_LINE_ALL        0x0000007f  /* all IRQs */
+
+#define DANUBEASC_IRQ_LINE_TIR            0x00000001      /* Tx Int */
+#define DANUBEASC_IRQ_LINE_TBIR           0x00000002      /* Tx Buffer Int */
+#define DANUBEASC_IRQ_LINE_RIR            0x00000004      /* Rx Int */
+#define DANUBEASC_IRQ_LINE_EIR            0x00000008      /* Error Int */
+#define DANUBEASC_IRQ_LINE_ABSTIR         0x00000010      /* Autobaud Start Int */
+#define DANUBEASC_IRQ_LINE_ABDETIP        0x00000020      /* Autobaud Detection Int */
+#define DANUBEASC_IRQ_LINE_SFCIR          0x00000040      /* Software Flow Control Int */
+
+/* interrupt controller access macros */
+#define ASC_INTERRUPTS_ENABLE(X)  \
+*((volatile unsigned int*) DANUBE_ICU_IM0_IER) |= X;
+#define ASC_INTERRUPTS_DISABLE(X) \
+*((volatile unsigned int*) DANUBE_ICU_IM0_IER) &= ~X;
+#define ASC_INTERRUPTS_CLEAR(X)   \
+*((volatile unsigned int*) DANUBE_ICU_IM0_ISR) = X;
+
+/* CLC register's bits and bitfields */
+#define ASCCLC_DISR        0x00000001
+#define ASCCLC_DISS        0x00000002
+#define ASCCLC_RMCMASK     0x0000FF00
+#define ASCCLC_RMCOFFSET   8
+
+/* CON register's bits and bitfields */
+#define ASCCON_MODEMASK        0x0000000f
+#define ASCCON_M_8ASYNC        0x0
+#define ASCCON_M_8IRDA         0x1
+#define ASCCON_M_7ASYNC        0x2
+#define ASCCON_M_7IRDA         0x3
+#define ASCCON_WLSMASK         0x0000000c
+#define ASCCON_WLSOFFSET       2
+#define ASCCON_WLS_8BIT        0x0
+#define ASCCON_WLS_7BIT        0x1
+#define ASCCON_PEN             0x00000010
+#define ASCCON_ODD             0x00000020
+#define ASCCON_SP              0x00000040
+#define ASCCON_STP             0x00000080
+#define ASCCON_BRS             0x00000100
+#define ASCCON_FDE             0x00000200
+#define ASCCON_ERRCLK          0x00000400
+#define ASCCON_EMMASK          0x00001800
+#define ASCCON_EMOFFSET        11
+#define ASCCON_EM_ECHO_OFF     0x0
+#define ASCCON_EM_ECHO_AB      0x1
+#define ASCCON_EM_ECHO_ON      0x2
+#define ASCCON_LB              0x00002000
+#define ASCCON_ACO             0x00004000
+#define ASCCON_R               0x00008000
+#define ASCCON_PAL             0x00010000
+#define ASCCON_FEN             0x00020000
+#define ASCCON_RUEN            0x00040000
+#define ASCCON_ROEN            0x00080000
+#define ASCCON_TOEN            0x00100000
+#define ASCCON_BEN             0x00200000
+#define ASCCON_TXINV           0x01000000
+#define ASCCON_RXINV           0x02000000
+#define ASCCON_TXMSB           0x04000000
+#define ASCCON_RXMSB           0x08000000
+
+/* STATE register's bits and bitfields */
+#define ASCSTATE_REN           0x00000001
+#define ASCSTATE_PE            0x00010000
+#define ASCSTATE_FE            0x00020000
+#define ASCSTATE_RUE           0x00040000
+#define ASCSTATE_ROE           0x00080000
+#define ASCSTATE_TOE           0x00100000
+#define ASCSTATE_BE            0x00200000
+#define ASCSTATE_TXBVMASK      0x07000000
+#define ASCSTATE_TXBVOFFSET    24
+#define ASCSTATE_TXEOM         0x08000000
+#define ASCSTATE_RXBVMASK      0x70000000
+#define ASCSTATE_RXBVOFFSET    28
+#define ASCSTATE_RXEOM         0x80000000
+
+/* WHBSTATE register's bits and bitfields */
+#define ASCWHBSTATE_CLRREN    0x00000001
+#define ASCWHBSTATE_SETREN    0x00000002
+#define ASCWHBSTATE_CLRPE     0x00000004
+#define ASCWHBSTATE_CLRFE     0x00000008
+#define ASCWHBSTATE_CLRRUE    0x00000010
+#define ASCWHBSTATE_CLRROE    0x00000020
+#define ASCWHBSTATE_CLRTOE    0x00000040
+#define ASCWHBSTATE_CLRBE     0x00000080
+#define ASCWHBSTATE_SETPE     0x00000100
+#define ASCWHBSTATE_SETFE     0x00000200
+#define ASCWHBSTATE_SETRUE    0x00000400
+#define ASCWHBSTATE_SETROE    0x00000800
+#define ASCWHBSTATE_SETTOE    0x00001000
+#define ASCWHBSTATE_SETBE     0x00002000
+
+/* ABCON register's bits and bitfields */
+#define ASCABCON_ABEN       0x0001
+#define ASCABCON_AUREN      0x0002
+#define ASCABCON_ABSTEN     0x0004
+#define ASCABCON_ABDETEN    0x0008
+#define ASCABCON_FCDETEN    0x0010
+
+/* FDV register mask, offset and bitfields*/
+#define ASCFDV_VALUE_MASK     0x000001FF
+
+/* WHBABCON register's bits and bitfields */
+#define ASCWHBABCON_CLRABEN     0x0001
+#define ASCWHBABCON_SETABEN     0x0002
+
+/* ABSTAT register's bits and bitfields */
+#define ASCABSTAT_FCSDET    0x0001
+#define ASCABSTAT_FCCDET    0x0002
+#define ASCABSTAT_SCSDET    0x0004
+#define ASCABSTAT_SCCDET    0x0008
+#define ASCABSTAT_DETWAIT   0x0010
+
+/* WHBABSTAT register's bits and bitfields */
+#define ASCWHBABSTAT_CLRFCSDET  0x0001
+#define ASCWHBABSTAT_SETFCSDET  0x0002
+#define ASCWHBABSTAT_CLRFCCDET  0x0004
+#define ASCWHBABSTAT_SETFCCDET  0x0008
+#define ASCWHBABSTAT_CLRSCSDET  0x0010
+#define ASCWHBABSTAT_SETSCSDET  0x0020
+#define ASCWHBABSTAT_CLRSCCDET  0x0040
+#define ASCWHBABSTAT_SETSCCDET  0x0080
+#define ASCWHBABSTAT_CLRDETWAIT 0x0100
+#define ASCWHBABSTAT_SETDETWAIT 0x0200
+
+/* TXFCON register's bits and bitfields */
+#define ASCTXFCON_TXFIFO1       0x00000400
+#define ASCTXFCON_TXFEN         0x0001
+#define ASCTXFCON_TXFFLU        0x0002
+#define ASCTXFCON_TXFITLMASK    0x3F00
+#define ASCTXFCON_TXFITLOFF     8
+
+/* RXFCON register's bits and bitfields */
+#define ASCRXFCON_RXFIFO1       0x00000400
+#define ASCRXFCON_RXFEN         0x0001
+#define ASCRXFCON_RXFFLU        0x0002
+#define ASCRXFCON_RXFITLMASK    0x3F00
+#define ASCRXFCON_RXFITLOFF     8
+
+/* FSTAT register's bits and bitfields */
+#define ASCFSTAT_RXFFLMASK      0x003F
+#define ASCFSTAT_TXFFLMASK      0x3F00
+#define ASCFSTAT_TXFFLOFF       8
+
+typedef  struct         /* DanubeAsc_t */
+{
+       volatile unsigned long  asc_clc;                            /*0x0000*/
+       volatile unsigned long  asc_pisel;                          /*0x0004*/
+       volatile unsigned long  asc_id;                             /*0x0008*/
+       volatile unsigned long  asc_rsvd1[1];   /* for mapping */   /*0x000C*/
+       volatile unsigned long  asc_con;                           /*0x0010*/
+       volatile unsigned long  asc_state;                          /*0x0014*/
+       volatile unsigned long  asc_whbstate;                       /*0x0018*/
+       volatile unsigned long  asc_rsvd2[1];   /* for mapping */   /*0x001C*/
+       volatile unsigned long  asc_tbuf;                           /*0x0020*/
+       volatile unsigned long  asc_rbuf;                           /*0x0024*/
+       volatile unsigned long  asc_rsvd3[2];   /* for mapping */   /*0x0028*/
+       volatile unsigned long  asc_abcon;                          /*0x0030*/
+       volatile unsigned long  asc_abstat;     /* not used */      /*0x0034*/
+       volatile unsigned long  asc_whbabcon;                       /*0x0038*/
+       volatile unsigned long  asc_whbabstat;  /* not used */      /*0x003C*/
+       volatile unsigned long  asc_rxfcon;                         /*0x0040*/
+       volatile unsigned long  asc_txfcon;                         /*0x0044*/
+       volatile unsigned long  asc_fstat;                          /*0x0048*/
+       volatile unsigned long  asc_rsvd4[1];   /* for mapping */   /*0x004C*/
+       volatile unsigned long  asc_bg;                             /*0x0050*/
+       volatile unsigned long  asc_bg_timer;                       /*0x0054*/
+       volatile unsigned long  asc_fdv;                            /*0x0058*/
+       volatile unsigned long  asc_pmw;                            /*0x005C*/
+       volatile unsigned long  asc_modcon;                         /*0x0060*/
+       volatile unsigned long  asc_modstat;                        /*0x0064*/
+       volatile unsigned long  asc_rsvd5[2];   /* for mapping */   /*0x0068*/
+       volatile unsigned long  asc_sfcc;                           /*0x0070*/
+       volatile unsigned long  asc_rsvd6[3];   /* for mapping */   /*0x0074*/
+       volatile unsigned long  asc_eomcon;                         /*0x0080*/
+       volatile unsigned long  asc_rsvd7[26];   /* for mapping */  /*0x0084*/
+       volatile unsigned long  asc_dmacon;                         /*0x00EC*/
+       volatile unsigned long  asc_rsvd8[1];   /* for mapping */   /*0x00F0*/
+       volatile unsigned long  asc_irnen;                          /*0x00F4*/
+       volatile unsigned long  asc_irnicr;                         /*0x00F8*/
+       volatile unsigned long  asc_irncr;                          /*0x00FC*/
+} DanubeAsc_t;
+
+int asc_init (void);
+void asc_puts (const char *s);
+void asc_putc (const char c);
+int asc_getc (void);
+
+#endif /* __ASC_H */
diff --git a/package/uboot-ifxmips/files/include/asm-mips/inca-ip2.h b/package/uboot-ifxmips/files/include/asm-mips/inca-ip2.h
new file mode 100644 (file)
index 0000000..19c8ceb
--- /dev/null
@@ -0,0 +1,634 @@
+/************************************************************************
+ *
+ * Copyright (c) 2005
+ * Infineon Technologies AG
+ * St. Martin Strasse 53; 81669 Muenchen; Germany
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+/***********************************************************************/
+/*  Module      :  DMA register address and bits                       */
+/***********************************************************************/
+         
+#define INCA_IP2_DMA                           (KSEG1+0x14101000)
+/***********************************************************************/
+#define CONFIGURATION_REGISTERS_CLC (INCA_IP2_DMA + 0x00)
+#define CONFIGURATION_REGISTERS_ID (INCA_IP2_DMA + 0x08)
+#define GENERAL_REGISTERS_DMA_CTRL (INCA_IP2_DMA + 0x10)
+#define CHANNEL_RELATED_REGISTERS_DMA_CS (INCA_IP2_DMA + 0x18)
+#define CHANNEL_RELATED_REGISTERS_DMA_CCTRL (INCA_IP2_DMA + 0x1C)
+#define CHANNEL_RELATED_REGISTERS_DMA_CDBA (INCA_IP2_DMA + 0x20)
+#define CHANNEL_RELATED_REGISTERS_DMA_CDLEN (INCA_IP2_DMA + 0x24)
+#define CHANNEL_RELATED_REGISTERS_DMA_CIE (INCA_IP2_DMA + 0x2C)
+#define CHANNEL_RELATED_REGISTERS_DMA_CIS (INCA_IP2_DMA + 0x28)
+#define CHANNEL_RELATED_REGISTERS_DMA_CPOLL (INCA_IP2_DMA + 0x14)
+       
+#define PORT_RELATED_REGISTERS_DMA_PS (INCA_IP2_DMA + 0x40)
+#define PORT_RELATED_REGISTERS_DMA_PCTRL (INCA_IP2_DMA + 0x44)
+       
+#define INTERRUPT_NODE_REGISTERS_DMA_IRNEN (INCA_IP2_DMA + 0xF4)
+#define INTERRUPT_NODE_REGISTERS_DMA_IRNCR (INCA_IP2_DMA + 0xF8)
+#define INTERRUPT_NODE_REGISTERS_DMA_IRNICR (INCA_IP2_DMA + 0xFC)
+
+#if 0
+/* ISR */
+#define DMA_ISR_RDERR          0x20
+#define DMA_ISR_CMDCPT         0x10
+#define DMA_ISR_CPT                    0x8
+#define DMA_ISR_DURR           0x4
+#define DMA_ISR_EOP                    0x2
+#endif
+#define DMA_RESET_CHANNEL       0x00000002
+#define DMA_ENABLE_CHANNEL       0x00000001
+#define DMA_DESC_BYTEOFF_SHIFT         22
+
+#define DMA_POLLING_ENABLE             0x80000000
+#define DMA_POLLING_CNT                        0x50    /*minimum 0x10, max 0xfff0*/
+
+/***********************************************************************/
+/*  Module      :  ICU register address and bits                       */
+/***********************************************************************/
+
+#define INCA_IP2_ICU                          (KSEG1+0x1F880200)
+/***********************************************************************/
+
+#define INCA_IP2_ICU_IM0_ISR                      ((volatile u32*)(INCA_IP2_ICU + 0x0000))
+#define INCA_IP2_ICU_IM0_IER                      ((volatile u32*)(INCA_IP2_ICU + 0x0008))
+#define INCA_IP2_ICU_IM0_IOSR                     ((volatile u32*)(INCA_IP2_ICU + 0x0010))
+#define INCA_IP2_ICU_IM0_IRSR                     ((volatile u32*)(INCA_IP2_ICU + 0x0018))
+#define INCA_IP2_ICU_IM0_IMR                      ((volatile u32*)(INCA_IP2_ICU + 0x0020))
+#define INCA_IP2_ICU_IM0_IMR_IID                  (1 << 31)
+#define INCA_IP2_ICU_IM0_IMR_IN_GET(value)        (((value) >> 0) & ((1 << 5) - 1))
+#define INCA_IP2_ICU_IM0_IMR_IN_SET(value)        (((( 1 << 5) - 1) & (value)) << 0)
+#define INCA_IP2_ICU_IM0_IR(value)                (1 << (value))
+
+#define INCA_IP2_ICU_IM1_ISR                      ((volatile u32*)(INCA_IP2_ICU + 0x0028))
+#define INCA_IP2_ICU_IM1_IER                      ((volatile u32*)(INCA_IP2_ICU + 0x0030))
+#define INCA_IP2_ICU_IM1_IOSR                     ((volatile u32*)(INCA_IP2_ICU + 0x0038))
+#define INCA_IP2_ICU_IM1_IRSR                     ((volatile u32*)(INCA_IP2_ICU + 0x0040))
+#define INCA_IP2_ICU_IM1_IMR                      ((volatile u32*)(INCA_IP2_ICU + 0x0048))
+#define INCA_IP2_ICU_IM1_IMR_IID                  (1 << 31)
+#define INCA_IP2_ICU_IM1_IMR_IN_GET(value)        (((value) >> 0) & ((1 << 5) - 1))
+#define INCA_IP2_ICU_IM1_IMR_IN_SET(value)        (((( 1 << 5) - 1) & (value)) << 0)
+#define INCA_IP2_ICU_IM1_IR(value)                (1 << (value))
+
+#define INCA_IP2_ICU_IM2_ISR                      ((volatile u32*)(INCA_IP2_ICU + 0x0050))
+#define INCA_IP2_ICU_IM2_IER                      ((volatile u32*)(INCA_IP2_ICU + 0x0058))
+#define INCA_IP2_ICU_IM2_IOSR                     ((volatile u32*)(INCA_IP2_ICU + 0x0060))
+#define INCA_IP2_ICU_IM2_IRSR                     ((volatile u32*)(INCA_IP2_ICU + 0x0068))
+#define INCA_IP2_ICU_IM2_IMR                      ((volatile u32*)(INCA_IP2_ICU + 0x0070))
+#define INCA_IP2_ICU_IM2_IMR_IID                  (1 << 31)
+#define INCA_IP2_ICU_IM2_IMR_IN_GET(value)        (((value) >> 0) & ((1 << 5) - 1))
+#define INCA_IP2_ICU_IM2_IMR_IN_SET(value)        (((( 1 << 5) - 1) & (value)) << 0)
+#define INCA_IP2_ICU_IM2_IR(value)                (1 << (value))
+
+#define INCA_IP2_ICU_IM3_ISR                      ((volatile u32*)(INCA_IP2_ICU + 0x0078))
+#define INCA_IP2_ICU_IM3_IER                      ((volatile u32*)(INCA_IP2_ICU + 0x0080))
+#define INCA_IP2_ICU_IM3_IOSR                     ((volatile u32*)(INCA_IP2_ICU + 0x0088))
+#define INCA_IP2_ICU_IM3_IRSR                     ((volatile u32*)(INCA_IP2_ICU + 0x0090))
+#define INCA_IP2_ICU_IM3_IMR                      ((volatile u32*)(INCA_IP2_ICU + 0x0098))
+#define INCA_IP2_ICU_IM3_IMR_IID                  (1 << 31)
+#define INCA_IP2_ICU_IM3_IMR_IN_GET(value)        (((value) >> 0) & ((1 << 5) - 1))
+#define INCA_IP2_ICU_IM3_IMR_IN_SET(value)        (((( 1 << 5) - 1) & (value)) << 0)
+#define INCA_IP2_ICU_IM3_IR(value)                (1 << (value))
+
+#define INCA_IP2_ICU_IM4_ISR                      ((volatile u32*)(INCA_IP2_ICU + 0x00A0))
+#define INCA_IP2_ICU_IM4_IER                      ((volatile u32*)(INCA_IP2_ICU + 0x00A8))
+#define INCA_IP2_ICU_IM4_IOSR                     ((volatile u32*)(INCA_IP2_ICU + 0x00B0))
+#define INCA_IP2_ICU_IM4_IRSR                     ((volatile u32*)(INCA_IP2_ICU + 0x00B8))
+#define INCA_IP2_ICU_IM4_IMR                      ((volatile u32*)(INCA_IP2_ICU + 0x00C0))
+#define INCA_IP2_ICU_IM4_IMR_IID                  (1 << 31)
+#define INCA_IP2_ICU_IM4_IMR_IN_GET(value)        (((value) >> 0) & ((1 << 5) - 1))
+#define INCA_IP2_ICU_IM4_IMR_IN_SET(value)        (((( 1 << 5) - 1) & (value)) << 0)
+#define INCA_IP2_ICU_IM4_IR(value)                (1 << (value))
+
+#define INCA_IP2_ICU_IM5_ISR                      ((volatile u32*)(INCA_IP2_ICU + 0x00C8))
+#define INCA_IP2_ICU_IM5_IER                      ((volatile u32*)(INCA_IP2_ICU + 0x00D0))
+#define INCA_IP2_ICU_IM5_IOSR                     ((volatile u32*)(INCA_IP2_ICU + 0x00D8))
+#define INCA_IP2_ICU_IM5_IRSR                     ((volatile u32*)(INCA_IP2_ICU + 0x00E0))
+#define INCA_IP2_ICU_IM5_IMR                      ((volatile u32*)(INCA_IP2_ICU + 0x00E8))
+#define INCA_IP2_ICU_IM5_IMR_IID                  (1 << 31)
+#define INCA_IP2_ICU_IM5_IMR_IN_GET(value)        (((value) >> 0) & ((1 << 5) - 1))
+#define INCA_IP2_ICU_IM5_IMR_IN_SET(value)        (((( 1 << 5) - 1) & (value)) << 0)
+#define INCA_IP2_ICU_IM5_IR(value)                (1 << (value))
+
+
+/***********************************************************************/
+/*  Module      :  CGU register address and bits                       */
+/***********************************************************************/
+
+#define INCA_IP2_CGU                          (KSEG1+0x1F100800)
+/***********************************************************************/
+
+#define INCA_IP2_CGU_PLL2CR                       ((volatile u32*)(INCA_IP2_CGU + 0x0008))
+#define INCA_IP2_CGU_FBSCR                        ((volatile u32*)(INCA_IP2_CGU + 0x0018))
+#define INCA_IP2_CGU_FBSCR_LPBSDIV_GET(value)     (((value) >> 6) & ((1 << 2) - 1))
+#define INCA_IP2_CGU_FBSCR_DIV0_GET(value)        (((value) >> 0) & ((1 << 3) - 1))
+#define INCA_IP2_CGU_FBSCR_DIV1_GET(value)        (((value) >> 4) & ((1 << 2) - 1))
+
+/***********************************************************************/
+/*  Module      :  MPS register address and bits                       */
+/***********************************************************************/
+
+#define INCA_IP2_MPS                          (KSEG1+0x1F101400)
+/***********************************************************************/
+
+#define INCA_IP2_MPS_CHIPID                       ((volatile u32*)(INCA_IP2_MPS + 0x0344))
+#define INCA_IP2_MPS_CHIPID_VERSION_GET(value)    (((value) >> 28) & ((1 << 4) - 1))
+#define INCA_IP2_MPS_CHIPID_VERSION_SET(value)    (((( 1 << 4) - 1) & (value)) << 28)
+#define INCA_IP2_MPS_CHIPID_PARTNUM_GET(value)    (((value) >> 12) & ((1 << 16) - 1))
+#define INCA_IP2_MPS_CHIPID_PARTNUM_SET(value)    (((( 1 << 16) - 1) & (value)) << 12)
+#define INCA_IP2_MPS_CHIPID_MANID_GET(value)      (((value) >> 1) & ((1 << 10) - 1))
+#define INCA_IP2_MPS_CHIPID_MANID_SET(value)      (((( 1 << 10) - 1) & (value)) << 1)
+
+
+/* voice channel 0 ... 3 interrupt enable register */
+#define INCA_IP2_MPS_VC0ENR ((volatile u32*)(INCA_IP2_MPS + 0x0000))
+#define INCA_IP2_MPS_VC1ENR ((volatile u32*)(INCA_IP2_MPS + 0x0004))
+#define INCA_IP2_MPS_VC2ENR ((volatile u32*)(INCA_IP2_MPS + 0x0008))
+#define INCA_IP2_MPS_VC3ENR ((volatile u32*)(INCA_IP2_MPS + 0x000C))
+/* voice channel 0 ... 3 interrupt status read register */
+#define INCA_IP2_MPS_RVC0SR ((volatile u32*)(INCA_IP2_MPS + 0x0010))
+#define INCA_IP2_MPS_RVC1SR ((volatile u32*)(INCA_IP2_MPS + 0x0014))
+#define INCA_IP2_MPS_RVC2SR ((volatile u32*)(INCA_IP2_MPS + 0x0018))
+#define INCA_IP2_MPS_RVC3SR ((volatile u32*)(INCA_IP2_MPS + 0x001C))
+/* voice channel 0 ... 3 interrupt status set register */
+#define INCA_IP2_MPS_SVC0SR ((volatile u32*)(INCA_IP2_MPS + 0x0020))
+#define INCA_IP2_MPS_SVC1SR ((volatile u32*)(INCA_IP2_MPS + 0x0024))
+#define INCA_IP2_MPS_SVC2SR ((volatile u32*)(INCA_IP2_MPS + 0x0028))
+#define INCA_IP2_MPS_SVC3SR ((volatile u32*)(INCA_IP2_MPS + 0x002C))
+/* voice channel 0 ... 3 interrupt status clear register */
+#define INCA_IP2_MPS_CVC0SR ((volatile u32*)(INCA_IP2_MPS + 0x0030))
+#define INCA_IP2_MPS_CVC1SR ((volatile u32*)(INCA_IP2_MPS + 0x0034))
+#define INCA_IP2_MPS_CVC2SR ((volatile u32*)(INCA_IP2_MPS + 0x0038))
+#define INCA_IP2_MPS_CVC3SR ((volatile u32*)(INCA_IP2_MPS + 0x003C))
+/* common status 0 and 1 read register */
+#define INCA_IP2_MPS_RAD0SR ((volatile u32*)(INCA_IP2_MPS + 0x0040))
+#define INCA_IP2_MPS_RAD1SR ((volatile u32*)(INCA_IP2_MPS + 0x0044))
+/* common status 0 and 1 set register */
+#define INCA_IP2_MPS_SAD0SR ((volatile u32*)(INCA_IP2_MPS + 0x0048))
+#define INCA_IP2_MPS_SAD1SR ((volatile u32*)(INCA_IP2_MPS + 0x004C))
+/* common status 0 and 1 clear register */
+#define INCA_IP2_MPS_CAD0SR ((volatile u32*)(INCA_IP2_MPS + 0x0050))
+#define INCA_IP2_MPS_CAD1SR ((volatile u32*)(INCA_IP2_MPS + 0x0054))
+/* notification enable register */
+#define INCA_IP2_MPS_CPU0_NFER ((volatile u32*)(INCA_IP2_MPS + 0x0060))
+#define INCA_IP2_MPS_CPU1_NFER ((volatile u32*)(INCA_IP2_MPS + 0x0064))
+/* CPU to CPU interrup request register */
+#define INCA_IP2_MPS_CPU0_2_CPU1_IRR ((volatile u32*)(INCA_IP2_MPS + 0x0070))
+#define INCA_IP2_MPS_CPU0_2_CPU1_IER ((volatile u32*)(INCA_IP2_MPS + 0x0074))
+/* Global interrupt request and request enable register */
+#define INCA_IP2_MPS_GIRR ((volatile u32*)(INCA_IP2_MPS + 0x0078))
+#define INCA_IP2_MPS_GIER ((volatile u32*)(INCA_IP2_MPS + 0x007C))
+
+/* Addresses of enable registers not yet defined 
+#define INCA_IP2_MPS_AD0ENR ((volatile u32*)(INCA_IP2_MPS + 0x????))
+#define INCA_IP2_MPS_AD1ENR ((volatile u32*)(INCA_IP2_MPS + 0x????))
+*/
+
+
+/***********************************************************************/
+/*  Module      :  ASC0 register address and bits                      */
+/***********************************************************************/
+
+#define INCA_IP2_ASC0                          (KSEG1+0x1E000400)
+/***********************************************************************/
+
+#define INCA_IP2_ASC0_TBUF                        ((volatile u32*)(INCA_IP2_ASC0 + 0x0020))
+#define INCA_IP2_ASC0_RBUF                        ((volatile u32*)(INCA_IP2_ASC0 + 0x0024))
+#define INCA_IP2_ASC0_FSTAT                       ((volatile u32*)(INCA_IP2_ASC0 + 0x0048))
+#define INCA_IP2_ASC0_FSTAT_TXFREE_GET(value)     (((value) >> 24) & ((1 << 6) - 1))
+#define INCA_IP2_ASC0_FSTAT_TXFREE_SET(value)     (((( 1 << 6) - 1) & (value)) << 24)
+#define INCA_IP2_ASC0_FSTAT_RXFREE_GET(value)     (((value) >> 16) & ((1 << 6) - 1))
+#define INCA_IP2_ASC0_FSTAT_RXFREE_SET(value)     (((( 1 << 6) - 1) & (value)) << 16)
+#define INCA_IP2_ASC0_FSTAT_TXFFL_GET(value)      (((value) >> 8) & ((1 << 6) - 1))
+#define INCA_IP2_ASC0_FSTAT_TXFFL_SET(value)      (((( 1 << 6) - 1) & (value)) << 8)
+#define INCA_IP2_ASC0_FSTAT_RXFFL_GET(value)      (((value) >> 0) & ((1 << 6) - 1))
+#define INCA_IP2_ASC0_FSTAT_RXFFL_SET(value)      (((( 1 << 6) - 1) & (value)) << 0)
+
+
+/***********************************************************************/
+/*  Module      :  ASC1 register address and bits                      */
+/***********************************************************************/
+
+#define INCA_IP2_ASC1                          (KSEG1+0x1E000800)
+/***********************************************************************/
+
+#define INCA_IP2_ASC1_TBUF                        ((volatile u32*)(INCA_IP2_ASC1 + 0x0020))
+#define INCA_IP2_ASC1_RBUF                        ((volatile u32*)(INCA_IP2_ASC1 + 0x0024))
+#define INCA_IP2_ASC1_FSTAT                       ((volatile u32*)(INCA_IP2_ASC1 + 0x0048))
+#define INCA_IP2_ASC1_FSTAT_TXFREE_GET(value)     (((value) >> 24) & ((1 << 6) - 1))
+#define INCA_IP2_ASC1_FSTAT_TXFREE_SET(value)     (((( 1 << 6) - 1) & (value)) << 24)
+#define INCA_IP2_ASC1_FSTAT_RXFREE_GET(value)     (((value) >> 16) & ((1 << 6) - 1))
+#define INCA_IP2_ASC1_FSTAT_RXFREE_SET(value)     (((( 1 << 6) - 1) & (value)) << 16)
+#define INCA_IP2_ASC1_FSTAT_TXFFL_GET(value)      (((value) >> 8) & ((1 << 6) - 1))
+#define INCA_IP2_ASC1_FSTAT_TXFFL_SET(value)      (((( 1 << 6) - 1) & (value)) << 8)
+#define INCA_IP2_ASC1_FSTAT_RXFFL_GET(value)      (((value) >> 0) & ((1 << 6) - 1))
+#define INCA_IP2_ASC1_FSTAT_RXFFL_SET(value)      (((( 1 << 6) - 1) & (value)) << 0)
+
+
+/***********************************************************************/
+/*  Module      :  RCU register address and bits                       */
+/***********************************************************************/
+
+#define INCA_IP2_RCU                          (KSEG1+0x1E001C00)
+/***********************************************************************/
+
+/***Reset Request Register***/ 
+#define INCA_IP2_RCU_RST_REQ                      ((volatile u32*)(INCA_IP2_RCU + 0x0000))
+#define INCA_IP2_RCU_RST_REQ_CPU0                 (1 << 31)
+#define INCA_IP2_RCU_RST_REQ_CPU1                 (1 << 30)
+#define INCA_IP2_RCU_RST_REQ_CPUSUB               (1 << 29)
+#define INCA_IP2_RCU_RST_REQ_HRST                 (1 << 28)
+#define INCA_IP2_RCU_RST_REQ_WDT0                 (1 << 27)
+#define INCA_IP2_RCU_RST_REQ_WDT1                 (1 << 26)
+#define INCA_IP2_RCU_RST_REQ_CFG_GET(value)       (((value) >> 23) & ((1 << 3) - 1))
+#define INCA_IP2_RCU_RST_REQ_CFG_SET(value)       (((( 1 << 3) - 1) & (value)) << 23)
+#define INCA_IP2_RCU_RST_REQ_SWTBOOT              (1 << 22)
+#define INCA_IP2_RCU_RST_REQ_DMA                  (1 << 21)
+#define INCA_IP2_RCU_RST_REQ_ETHPHY1              (1 << 20)
+#define INCA_IP2_RCU_RST_REQ_ETHPHY0              (1 << 19)
+#define INCA_IP2_RCU_RST_REQ_CPU0_BR              (1 << 18)
+
+/* CPU0, CPU1, CPUSUB, HRST, WDT0, WDT1, DMA, ETHPHY1, ETHPHY0 */
+#define INCA_IP2_RCU_RST_REQ_ALL                  0xFC380000 
+
+/***NMI Status Register***/ 
+#define INCA_IP2_RCU_NMISR                        ((volatile u32*)(INCA_IP2_RCU + 0x00F4))
+#define INCA_IP2_RCU_NMISR_NMIEXT                 (1 << 2)
+#define INCA_IP2_RCU_NMISR_NMIPLL2                (1 << 1)
+#define INCA_IP2_RCU_NMISR_NMIPLL1                (1 << 0)
+
+
+/***********************************************************************/
+/*  Module      :  WDT register address and bits                       */
+/***********************************************************************/
+         
+#define INCA_IP2_WDT                           (KSEG1+0x1F880000)
+/***********************************************************************/
+
+/***Watchdog Timer Control Register ***/ 
+#define INCA_IP2_WDT_BIU_WDT_CR                   ((volatile u32*)(INCA_IP2_WDT + 0x03F0))
+#define INCA_IP2_WDT_BIU_WDT_CR_GEN               (1 << 31)
+#define INCA_IP2_WDT_BIU_WDT_CR_DSEN              (1 << 30)
+#define INCA_IP2_WDT_BIU_WDT_CR_LPEN              (1 << 29)
+#define INCA_IP2_WDT_BIU_WDT_CR_PWL_GET(value)    (((value) >> 26) & ((1 << 2) - 1))
+#define INCA_IP2_WDT_BIU_WDT_CR_PWL_SET(value)    (((( 1 << 2) - 1) & (value)) << 26)
+#define INCA_IP2_WDT_BIU_WDT_CR_CLKDIV_GET(value) (((value) >> 24) & ((1 << 2) - 1))
+#define INCA_IP2_WDT_BIU_WDT_CR_CLKDIV_SET(value) (((( 1 << 2) - 1) & (value)) << 24)
+#define INCA_IP2_WDT_BIU_WDT_CR_PW_GET(value)     (((value) >> 16) & ((1 << 8) - 1))
+#define INCA_IP2_WDT_BIU_WDT_CR_PW_SET(value)     (((( 1 << 8) - 1) & (value)) << 16)
+#define INCA_IP2_WDT_BIU_WDT_CR_RELOAD_GET(value) (((value) >> 0) & ((1 << 16) - 1))
+#define INCA_IP2_WDT_BIU_WDT_CR_RELOAD_SET(value) (((( 1 << 16) - 1) & (value)) << 0)
+
+/***Watchdog Timer Status Register***/ 
+#define INCA_IP2_WDT_BIU_WDT_SR                   ((volatile u32*)(INCA_IP2_WDT + 0x03F8))
+#define INCA_IP2_WDT_BIU_WDT_SR_EN                (1 << 31)
+#define INCA_IP2_WDT_BIU_WDT_SR_AE                (1 << 30)
+#define INCA_IP2_WDT_BIU_WDT_SR_PRW               (1 << 29)
+#define INCA_IP2_WDT_BIU_WDT_SR_EXP               (1 << 28)
+#define INCA_IP2_WDT_BIU_WDT_SR_PWD               (1 << 27)
+#define INCA_IP2_WDT_BIU_WDT_SR_DS                (1 << 26)
+#define INCA_IP2_WDT_BIU_WDT_SR_VALUE_GET(value)  (((value) >> 0) & ((1 << 16) - 1))
+#define INCA_IP2_WDT_BIU_WDT_SR_VALUE_SET(value)  (((( 1 << 16) - 1) & (value)) << 0)
+
+
+/***********************************************************************/
+/*  Module      :  BCU0 register address and bits                      */
+/***********************************************************************/
+
+#define INCA_IP2_BCU0                           (KSEG1+0x14100000)
+/***********************************************************************/
+
+#define INCA_IP2_BCU0_CON                         ((volatile u32*)(INCA_IP2_BCU0 + 0x0010))
+#define INCA_IP2_BCU0_ECON                        ((volatile u32*)(INCA_IP2_BCU0 + 0x0020))
+#define INCA_IP2_BCU0_EADD                        ((volatile u32*)(INCA_IP2_BCU0 + 0x0024))
+#define INCA_IP2_BCU0_EDAT                        ((volatile u32*)(INCA_IP2_BCU0 + 0x0028))
+#define INCA_IP2_BCU0_IRNCR1                      ((volatile u32*)(INCA_IP2_BCU0 + 0x00F8))
+#define INCA_IP2_BCU0_IRNCR0                      ((volatile u32*)(INCA_IP2_BCU0 + 0x00FC))
+
+
+/***********************************************************************/
+/*  Module      :  BCU1 register address and bits                      */
+/***********************************************************************/
+
+#define INCA_IP2_BCU1                           (KSEG1+0x1E000000)
+/***********************************************************************/
+
+#define INCA_IP2_BCU1_CON                         ((volatile u32*)(INCA_IP2_BCU1 + 0x0010))
+#define INCA_IP2_BCU1_ECON                        ((volatile u32*)(INCA_IP2_BCU1 + 0x0020))
+#define INCA_IP2_BCU1_EADD                        ((volatile u32*)(INCA_IP2_BCU1 + 0x0024))
+#define INCA_IP2_BCU1_EDAT                        ((volatile u32*)(INCA_IP2_BCU1 + 0x0028))
+#define INCA_IP2_BCU1_IRNCR1                      ((volatile u32*)(INCA_IP2_BCU1 + 0x00F8))
+#define INCA_IP2_BCU1_IRNCR0                      ((volatile u32*)(INCA_IP2_BCU1 + 0x00FC))
+
+
+/***********************************************************************/
+/*  Module      :  MC register address and bits                        */
+/***********************************************************************/
+
+#define INCA_IP2_MC                             (KSEG1+0x1F800000)
+/***********************************************************************/
+
+#define INCA_IP2_MC_ERRCAUSE                      ((volatile u32*)(INCA_IP2_MC + 0x0010))
+#define INCA_IP2_MC_ERRADDR                       ((volatile u32*)(INCA_IP2_MC + 0x0020))
+#define INCA_IP2_MC_CON                           ((volatile u32*)(INCA_IP2_MC + 0x0060))
+
+/***********************************************************************/
+/*  Module      :  MC SDRAM register address and bits                        */
+/***********************************************************************/
+#define INCA_IP2_SDRAM                          (KSEG1+0x1F800200)
+/***********************************************************************/
+#define INCA_IP2_SDRAM_MC_CFGPB0                  ((volatile u32*)(INCA_IP2_SDRAM + 0x0040))
+
+/***********************************************************************/
+/*  Module      :  MC DDR register address and bits                        */
+/***********************************************************************/
+#define INCA_IP2_DDR                            (KSEG1+0x1F801000)
+/***********************************************************************/
+#define INCA_IP2_DDR_MC_DC19                      ((volatile u32*)(INCA_IP2_DDR + 0x0130))
+#define INCA_IP2_DDR_MC_DC20                      ((volatile u32*)(INCA_IP2_DDR + 0x0140))
+
+
+/***********************************************************************/
+/*  Module      :  PMS register address and bits                       */
+/***********************************************************************/
+
+#define INCA_IP2_PMS     (KSEG1 + 0x1F100C00)
+
+#define INCA_IP2_PMS_PMS_SR                            ((volatile u32*) (INCA_IP2_PMS + 0x0000))
+#define INCA_IP2_PMS_PMS_SR_ASC1                       (1 << 14)
+#define INCA_IP2_PMS_PMS_SR_ASC0                       (1 << 13)
+#define INCA_IP2_PMS_PMS_GEN                           ((volatile u32*) (INCA_IP2_PMS + 0x0004))
+#define INCA_IP2_PMS_PMS_GEN_DMA                       (1 << 16)
+#define INCA_IP2_PMS_PMS_GEN_ASC1                      (1 << 14)
+#define INCA_IP2_PMS_PMS_GEN_ASC0                      (1 << 13)
+#define INCA_IP2_PMS_PMS_GEN_SPI0                      (1 << 11)
+#define INCA_IP2_PMS_PMS_GEN_SPI1                      (1 << 12)
+#define INCA_IP2_PMS_PMS_CFG                           ((volatile u32*) (INCA_IP2_PMS + 0x0008))
+
+
+/***********************************************************************/
+/*  Module      :  GPIO register address and bits                       */
+/***********************************************************************/
+
+#define INCA_IP2_GPIO     (KSEG1 + 0x1F102600)
+
+#define INCA_IP2_GPIO_OUT              ((volatile u32*) (INCA_IP2_GPIO + 0x0000))
+#define INCA_IP2_GPIO_IN                       ((volatile u32*) (INCA_IP2_GPIO + 0x0004))
+#define INCA_IP2_GPIO_DIR              ((volatile u32*) (INCA_IP2_GPIO + 0x0008))
+#define INCA_IP2_GPIO_ALTSEL1          ((volatile u32*) (INCA_IP2_GPIO + 0x000C))
+#define INCA_IP2_GPIO_ALTSEL2          ((volatile u32*) (INCA_IP2_GPIO + 0x0010))
+#define INCA_IP2_GPIO_STOFF            ((volatile u32*) (INCA_IP2_GPIO + 0x0014))
+#define INCA_IP2_GPIO_OD                       ((volatile u32*) (INCA_IP2_GPIO + 0x0018))
+#define INCA_IP2_GPIO_PUDEB            ((volatile u32*) (INCA_IP2_GPIO + 0x001C))
+
+/***********************************************************************/
+/*  Module      :  RCU register address and bits                       */
+/***********************************************************************/
+
+#define INCA_IP2_RCU                          (KSEG1+0x1E001C00)
+/***********************************************************************/
+
+/***Reset Request Register***/ 
+#define INCA_IP2_RCU_RST_REQ                      ((volatile u32*)(INCA_IP2_RCU + 0x0000))
+#define INCA_IP2_RCU_RST_REQ_CPU0                 (1 << 31)
+#define INCA_IP2_RCU_RST_REQ_CPU1                 (1 << 30)
+#define INCA_IP2_RCU_RST_REQ_CPUSUB               (1 << 29)
+#define INCA_IP2_RCU_RST_REQ_HRST                 (1 << 28)
+#define INCA_IP2_RCU_RST_REQ_WDT0                 (1 << 27)
+#define INCA_IP2_RCU_RST_REQ_WDT1                 (1 << 26)
+#define INCA_IP2_RCU_RST_REQ_CFG_GET(value)       (((value) >> 23) & ((1 << 3) - 1))
+#define INCA_IP2_RCU_RST_REQ_CFG_SET(value)       (((( 1 << 3) - 1) & (value)) << 23)
+#define INCA_IP2_RCU_RST_REQ_SWTBOOT              (1 << 22)
+#define INCA_IP2_RCU_RST_REQ_DMA                  (1 << 21)
+#define INCA_IP2_RCU_RST_REQ_ETHPHY1              (1 << 20)
+#define INCA_IP2_RCU_RST_REQ_ETHPHY0              (1 << 19)
+#define INCA_IP2_RCU_RST_REQ_CPU0_BR              (1 << 18)
+
+/* CPU0, CPU1, CPUSUB, HRST, WDT0, WDT1, DMA, ETHPHY1, ETHPHY0 */
+#define INCA_IP2_RCU_RST_REQ_ALL                  0xFC380000 
+
+/***Reset Status Register***/ 
+#define INCA_IP2_RCU_SR                           ((volatile u32*)(INCA_IP2_RCU + 0x0008))
+
+/***NMI Status Register***/ 
+#define INCA_IP2_RCU_NMISR                        ((volatile u32*)(INCA_IP2_RCU + 0x00F4))
+#define INCA_IP2_RCU_NMISR_NMIEXT                 (1 << 2)
+#define INCA_IP2_RCU_NMISR_NMIPLL2                (1 << 1)
+#define INCA_IP2_RCU_NMISR_NMIPLL1                (1 << 0)
+
+/***********************************************************************/
+/*  Module      :  EBU register address and bits                       */
+/***********************************************************************/
+
+#define INCA_IP2_EBU                          (KSEG1+0x14102000)
+/***********************************************************************/
+
+#define INCA_IP2_EBU_ADDSEL0                      ((volatile u32*)(INCA_IP2_EBU + 0x0020))
+#define INCA_IP2_EBU_ADDSEL1                      ((volatile u32*)(INCA_IP2_EBU + 0x0024))
+#define INCA_IP2_EBU_ADDSEL2                      ((volatile u32*)(INCA_IP2_EBU + 0x0028))
+#define INCA_IP2_EBU_ADDSEL3                      ((volatile u32*)(INCA_IP2_EBU + 0x002C))
+#define INCA_IP2_EBU_CON0                      ((volatile u32*)(INCA_IP2_EBU + 0x0060))
+#define INCA_IP2_EBU_CON1                      ((volatile u32*)(INCA_IP2_EBU + 0x0064))
+#define INCA_IP2_EBU_CON2                      ((volatile u32*)(INCA_IP2_EBU + 0x0068))
+#define INCA_IP2_EBU_CON3                      ((volatile u32*)(INCA_IP2_EBU + 0x006C))
+#define INCA_IP2_EBU_CON_WRDIS                     (1 << 31)
+
+
+
+
+/***********************************************************************/
+/*  Module      :  SWITCH register address and bits                       */
+/***********************************************************************/
+
+#define INCA_IP2_SWITCH                                (KSEG1+0x18000000)
+/***********************************************************************/
+
+/* PR Base address */
+#define PR_BASE                (INCA_IP2_SWITCH + 0x00008000)
+
+/* SE Base Address */
+#define SE_BASE                (INCA_IP2_SWITCH + 0x00009000)
+
+#define PR_CTRL_REG                            (PR_BASE + 0x0000)      
+#define MA_LEARN_REG                   (PR_BASE + 0x0004)
+#define DST_LOOKUP_REG                 (PR_BASE + 0x0008)
+
+#define COS_SEL_REG                            (PR_BASE + 0x000c)
+#define PRI2_COS_REG                   (PR_BASE + 0x0010)              
+#define UNKNOWN_DEST_REG               (PR_BASE + 0x0014)
+       
+#define CPU_ACS_CTRL_REG               (PR_BASE + 0x0018)
+#define CPU_ACS_DATA_REG               (PR_BASE + 0x001c)
+
+#define MA_READ_REG                            (PR_BASE + 0x0020)
+#define TB_CTRL_REG                            (PR_BASE + 0x0024)
+#define RATE_REG                               (PR_BASE + 0x0028)
+#define BURST_REG                              (PR_BASE + 0x0048)
+#define EBURST_REG                             (PR_BASE + 0x0068)
+
+#define RULE_SEL_REG                   (PR_BASE + 0x0088)
+
+#define GEN_SFT_AGE_STB         (PR_BASE + 0x008C)
+#define PR_ISR_REG                             (PR_BASE + 0x0090)
+#define PR_IMR_REG                             (PR_BASE + 0x0094)
+#define PR_IPR_REG                             (PR_BASE + 0x0098)
+#define BPDU_REG                               (PR_BASE + 0x00A4)
+
+/*     Switching Engine Register Description   */
+#define QLL_CMD_REG                            (SE_BASE)
+#define QLL_DATA_REG0                  (SE_BASE + 0x0004)
+#define QLL_DATA_REG1                  (SE_BASE + 0x0008)
+
+#define VLAN_MIBS_CMD_REG              (SE_BASE + 0x000c)
+#define VLAN_MIBS_DATA_REG             (SE_BASE + 0x0010)
+
+#define SD_CMD_REG                             (SE_BASE + 0x0014)
+#define SD_DATA_REGS0                  (SE_BASE + 0x0018)
+#define SD_DATA_REGS1                  (SE_BASE + 0x001C)
+#define SD_DATA_REGS2                  (SE_BASE + 0x0020)
+
+#define VLAN_TBL_CMD_REG               (SE_BASE + 0x0024)
+#define VLAN_TBL_DATA_REG              (SE_BASE + 0x0028)
+
+#define FD_TBL_CMD_REG                 (SE_BASE + 0x002c)
+#define FD_TBL_DATA_REG                        (SE_BASE + 0x0030)
+
+#define SYMM_VLAN_REG                  (SE_BASE + 0x0038)
+#define PORT_AUTH                              (SE_BASE + 0x0048)
+#define CPU_LINK_OK_REG        (SE_BASE + 0x0050)
+/* #define TRUNK_CTRL_REGS                     (SE_BASE + 0x0054)  */
+#define MIRROR_PORT_REG                        (SE_BASE + 0x0064)
+
+#define ST_PT_REG                              (SE_BASE + 0x0068)
+#define JUMBO_ENABLE_REG               (SE_BASE + 0x006C)
+#define STACK_PORT_REG                 (SE_BASE + 0x0074)
+#define EG_MON_REG              (SE_BASE + 0x007C)
+#define VR_MIB_REG                     (SE_BASE + 0x0080)
+#define QUEUE_CMD_REGS                 (SE_BASE + 0x0090)
+
+#define GLOBAL_RX_WM_REG               (SE_BASE + 0x0200)
+#define PORT0_RX_WM_REG0               (SE_BASE + 0x0204)
+#define PORT1_RX_WM_REG0               (SE_BASE + 0x0208)
+#define PORT2_RX_WM_REG0               (SE_BASE + 0x020C)
+
+#define PORT_RX_WM_REGS                        (SE_BASE + 0x0200)
+#define PORT_TX_WM_REGS                        (SE_BASE + 0x0300)
+#define PORT0_TX_WM_REG0               (SE_BASE + 0x0330)
+#define PORT1_TX_WM_REG0               (SE_BASE + 0x0338)
+#define PORT2_TX_WM_REG0               (SE_BASE + 0x0340)
+#define PORT0_TX_WM_REG1               (SE_BASE + 0x0334)
+#define PORT1_TX_WM_REG1               (SE_BASE + 0x033C)
+#define PORT2_TX_WM_REG1               (SE_BASE + 0x0344)
+
+
+#define QUEUE_STATUS_REGS              (SE_BASE + 0x0400)
+
+#define SE_INT_STS_REG                 (SE_BASE + 0x08e0)
+#define SE_INT_MSK_REG_RD          (SE_BASE + 0x08e4)
+#define SE_INT_MSK_REG_WR              (SE_BASE + 0x08e8)
+#define SE_INT_PRI_REG_RD              (SE_BASE + 0x08ec)
+#define SE_INT_PRI_REG_WR              (SE_BASE + 0x08f0)  /* address too be defined*/
+
+/***********************************************************************/
+/*  Module      :  Ethernet Switch port related addresses and bits     */
+/***********************************************************************/
+#define GPORT0_BASE                            (KSEG1+0x18006000)
+#define GPORT1_BASE                            (KSEG1+0x18007000)
+#define GPORT2_BASE                            (KSEG1+0x1800C000)
+
+#define PORTREG_BASE GPORT0_BASE
+
+#define SWITCH_P0_GMAC_REG (GPORT0_BASE + 0x0004)
+#define SWITCH_P0_GMAC_CTRL (GPORT0_BASE + 0x000C)
+#define SWITCH_P0_RTX_INT_STATUS (GPORT0_BASE + 0x0010)
+#define SWITCH_P0_RTX_INT_MASK (GPORT0_BASE + 0x0014)
+#define SWITCH_P0_INT_PRIORITY (GPORT0_BASE + 0x0018)
+#define SWITCH_P0_RX_CONF (GPORT0_BASE + 0x0400)
+#define SWITCH_P0_OFFSET0_REG (GPORT0_BASE + 0x0404)
+#define SWITCH_P0_OFFSET1_REG (GPORT0_BASE + 0x0408)
+#define SWITCH_P0_PORT_MASK0_REG (GPORT0_BASE + 0x0420)
+#define SWITCH_P0_PORT_MASK1_REG (GPORT0_BASE + 0x0424)
+#define SWITCH_P0_PORT_MASK2_REG (GPORT0_BASE + 0x0428)
+#define SWITCH_P0_PORT_MASK3_REG (GPORT0_BASE + 0x042C)
+#define SWITCH_P0_PORT_RULE0_REG (GPORT0_BASE + 0x0430)
+#define SWITCH_P0_PORT_RULE1_REG (GPORT0_BASE + 0x0434)
+#define SWITCH_P0_PORT_RULE2_REG (GPORT0_BASE + 0x0438)
+#define SWITCH_P0_PORT_RULE3_REG (GPORT0_BASE + 0x043C)
+#define SWITCH_P0_PORT_IKEY_SEL (GPORT0_BASE + 0x0440)
+#define SWITCH_P0_PORT_RX_VLAN_ID (GPORT0_BASE + 0x0450)
+#define SWITCH_P0_TX_CONF (GPORT0_BASE + 0x0800)
+#define SWITCH_P0_PORT_TX_VLAN_ID (GPORT0_BASE + 0x0804)
+#define SWITCH_P0_PORT_MIB_REG_0 (GPORT0_BASE + 0x0C00)
+#define SWITCH_P0_GMAC_MIB_REG_0 (GPORT0_BASE + 0x0C54)
+
+#define SWITCH_P1_GMAC_REG (GPORT1_BASE + 0x0004)
+#define SWITCH_P1_GMAC_CTRL (GPORT1_BASE + 0x000C)
+#define SWITCH_P1_RTX_INT_STATUS (GPORT1_BASE + 0x0010)
+#define SWITCH_P1_RTX_INT_MASK (GPORT1_BASE + 0x0014)
+#define SWITCH_P1_INT_PRIORITY (GPORT1_BASE + 0x0018)
+#define SWITCH_P1_RX_CONF (GPORT1_BASE + 0x0400)
+#define SWITCH_P1_OFFSET0_REG (GPORT1_BASE + 0x0404)
+#define SWITCH_P1_OFFSET1_REG (GPORT1_BASE + 0x0408)
+#define SWITCH_P1_PORT_MASK0_REG (GPORT1_BASE + 0x0420)
+#define SWITCH_P1_PORT_MASK1_REG (GPORT1_BASE + 0x0424)
+#define SWITCH_P1_PORT_MASK2_REG (GPORT1_BASE + 0x0428)
+#define SWITCH_P1_PORT_MASK3_REG (GPORT1_BASE + 0x042C)
+#define SWITCH_P1_PORT_RULE0_REG (GPORT1_BASE + 0x0430)
+#define SWITCH_P1_PORT_RULE1_REG (GPORT1_BASE + 0x0434)
+#define SWITCH_P1_PORT_RULE2_REG (GPORT1_BASE + 0x0438)
+#define SWITCH_P1_PORT_RULE3_REG (GPORT1_BASE + 0x043C)
+#define SWITCH_P1_PORT_IKEY_SEL (GPORT1_BASE + 0x0440)
+#define SWITCH_P1_PORT_RX_VLAN_ID (GPORT1_BASE + 0x0450)
+#define SWITCH_P1_TX_CONF (GPORT1_BASE + 0x0800)
+#define SWITCH_P1_PORT_TX_VLAN_ID (GPORT1_BASE + 0x0804)
+#define SWITCH_P1_PORT_MIB_REG_0 (GPORT1_BASE + 0x0C00)
+#define SWITCH_P1_GMAC_MIB_REG_0 (GPORT1_BASE + 0x0C54)
+
+#define SWITCH_P2_GMAC_REG (GPORT2_BASE + 0x0004)
+#define SWITCH_P2_GMAC_CTRL (GPORT2_BASE + 0x000C)
+#define SWITCH_P2_RTX_INT_STATUS (GPORT2_BASE + 0x0010)
+#define SWITCH_P2_RTX_INT_MASK (GPORT2_BASE + 0x0014)
+#define SWITCH_P2_INT_PRIORITY (GPORT2_BASE + 0x0018)
+#define SWITCH_P2_MDIO_ID_1 (GPORT2_BASE + 0x00A8)
+#define SWITCH_P2_PAUSE_CTL_1 (GPORT2_BASE + 0x00B0)
+#define SWITCH_P2_MDIO_MOD_SEL (GPORT2_BASE + 0x00B4)
+#define SWITCH_P2_MDIO_ACC_0 (GPORT2_BASE + 0x00B8)
+#define SWITCH_P2_RX_CONF (GPORT2_BASE + 0x0400)
+#define SWITCH_P2_OFFSET0_REG (GPORT2_BASE + 0x0404)
+#define SWITCH_P2_OFFSET1_REG (GPORT2_BASE + 0x0408)
+#define SWITCH_P2_PORT_MASK0_REG (GPORT2_BASE + 0x0420)
+#define SWITCH_P2_PORT_MASK1_REG (GPORT2_BASE + 0x0424)
+#define SWITCH_P2_PORT_MASK2_REG (GPORT2_BASE + 0x0428)
+#define SWITCH_P2_PORT_MASK3_REG (GPORT2_BASE + 0x042C)
+#define SWITCH_P2_PORT_RULE0_REG (GPORT2_BASE + 0x0430)
+#define SWITCH_P2_PORT_RULE1_REG (GPORT2_BASE + 0x0434)
+#define SWITCH_P2_PORT_RULE2_REG (GPORT2_BASE + 0x0438)
+#define SWITCH_P2_PORT_RULE3_REG (GPORT2_BASE + 0x043C)
+#define SWITCH_P2_PORT_IKEY_SEL (GPORT2_BASE + 0x0440)
+#define SWITCH_P2_PORT_RX_VLAN_ID (GPORT2_BASE + 0x0450)
+#define SWITCH_P2_TX_CONF (GPORT2_BASE + 0x0800)
+#define SWITCH_P2_PORT_TX_VLAN_ID (GPORT2_BASE + 0x0804)
+#define SWITCH_P2_PORT_MIB_REG_0 (GPORT2_BASE + 0x0C00)
+#define SWITCH_P2_GMAC_MIB_REG_0 (GPORT2_BASE + 0x0C54)
+
+#define MDIO_MOD_SEL SWITCH_P2_MDIO_MOD_SEL
+#define SWITCH_MDIO_ACC SWITCH_P2_MDIO_ACC_0
+#define SWITCH_MDIO_ID SWITCH_P2_MDIO_ID_1
+/* #define TX_CONFIG_REG SWITCH_P0_TX_CONF  */
+
+#define SWITCH_PMAC_HD_CTL (GPORT2_BASE + 0x0070)
+#define SWITCH_PMAC_SA1 (GPORT2_BASE + 0x0074)
+#define SWITCH_PMAC_SA2 (GPORT2_BASE + 0x0078)
+#define SWITCH_PMAC_DA1 (GPORT2_BASE + 0x007C)
+#define SWITCH_PMAC_DA2 (GPORT2_BASE + 0x0080)
+#define SWITCH_PMAC_VLAN (GPORT2_BASE + 0x0084)
+#define SWITCH_PMAC_TX_IPG (GPORT2_BASE + 0x0088)
+#define SWITCH_PMAC_RX_IPG (GPORT2_BASE + 0x008C)
+
diff --git a/package/uboot-ifxmips/files/include/asm-mips/pinstrap.h b/package/uboot-ifxmips/files/include/asm-mips/pinstrap.h
new file mode 100644 (file)
index 0000000..1a446fa
--- /dev/null
@@ -0,0 +1,12 @@
+#define FLASH_STRAP            0x1             
+#define MII_0_STRAP            0x2
+#define MII_1_STRAP            0x3
+#define ASC_STRAP              0x4
+#define SFLASH_STRAP           0x5
+#define RESERVE_STRAP          0x6
+#define PRODUCT_TEST_STRAP     0x7
+#define PIN_STRAP_MASK         0x001C0000
+#define PIN_STRAP_SHIFT                18
+#define PIN_STRAP              0xB0100914
+#define SDRAM_WIDTH_MASK       0x400000
+#define SDRAM_WIDTH_SHIFT      22
diff --git a/package/uboot-ifxmips/files/include/asm-mips/romconfig.h b/package/uboot-ifxmips/files/include/asm-mips/romconfig.h
new file mode 100644 (file)
index 0000000..8951b3a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This file contains the configuration parameters for the DANUBE board.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+
+#define EXCEPTION_BASE 0x200
+
+/*****************************************************************************
+ * DANUBE
+ *****************************************************************************/
+/* lock cache for C program stack */
+/* points to ROM */
+/* stack size is 16K */
+#define LOCK_DCACHE_ADDR               0x9FC00000
+#define LOCK_DCACHE_SIZE               0x1000
+#define CFG_EBU_BOOTWORD             0x688c688c
+                                                                                                                                                             
+#define CFG_HZ       (danube_get_cpuclk() / 2)
+
+                                                                                                                                                             
+/*
+ * Memory layout
+ */
+//#define CFG_SDRAM_BASE       0x80080000
+#define CFG_CACHE_LOCK_SIZE  LOCK_DCACHE_SIZE
+#define CFG_INIT_SP_OFFSET   CFG_CACHE_LOCK_SIZE
+
+/*
+ * Cache settings
+ */
+#define CFG_CACHE_SIZE   16384
+#define CFG_CACHE_LINES  32
+#define CFG_CACHE_WAYS   4
+#define CFG_CACHE_SETS   128
+
+#define CFG_ICACHE_SIZE   CFG_CACHE_SIZE
+#define CFG_DCACHE_SIZE   CFG_CACHE_SIZE
+#define CFG_CACHELINE_SIZE  CFG_CACHE_LINES
+
+#endif /* __CONFIG_H */
diff --git a/package/uboot-ifxmips/files/include/boot.h b/package/uboot-ifxmips/files/include/boot.h
new file mode 100644 (file)
index 0000000..8f70ebb
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef _BOOT_H
+#define _BOOT_H
+
+/* All this should be defined somewhere in danube.h later... */
+
+#define MPS_SRAM_BASE_ADDRESS   0xBF200000
+#define MPS_SRAM_BOOT_OFFSET    0x1C0
+
+/* Offset for CPU1 (both CPUs have same register set) */
+#define BOOT_BASE_ADDRESS   (MPS_SRAM_BASE_ADDRESS + MPS_SRAM_BOOT_OFFSET)
+#define BOOT_CPU_OFFSET     0x20
+
+
+#ifdef __ASSEMBLY__
+#define BOOT_RVEC                    (BOOT_BASE_ADDRESS + 0x00)
+#define BOOT_NVEC                    (BOOT_BASE_ADDRESS + 0x04)
+#define BOOT_EVEC                    (BOOT_BASE_ADDRESS + 0x08)
+#define BOOT_CP0_CAUSE     (BOOT_BASE_ADDRESS + 0x0C)
+#define BOOT_CP0_EPC         (BOOT_BASE_ADDRESS + 0x10)
+#define BOOT_CP0_EEPC     (BOOT_BASE_ADDRESS + 0x14)
+#define BOOT_SIZE        (BOOT_BASE_ADDRESS + 0x18)   /* for CPU1 */
+#define BOOT_RCU_SR        (BOOT_BASE_ADDRESS + 0x18) /* for CPU0 */
+#define BOOT_CFG_STAT     (BOOT_BASE_ADDRESS + 0x1C)
+#else
+#define BOOT_RVEC(cpu)         (volatile u32*)(BOOT_BASE_ADDRESS + (cpu * BOOT_CPU_OFFSET) + 0x00)
+#define BOOT_NVEC(cpu)         (volatile u32*)(BOOT_BASE_ADDRESS + (cpu * BOOT_CPU_OFFSET) + 0x04)
+#define BOOT_EVEC(cpu)         (volatile u32*)(BOOT_BASE_ADDRESS + (cpu * BOOT_CPU_OFFSET) + 0x08)
+#define BOOT_CP0_STATUS(cpu)   (volatile u32*)(BOOT_BASE_ADDRESS + (cpu * BOOT_CPU_OFFSET) + 0x0C)
+#define BOOT_CP0_EPC(cpu)      (volatile u32*)(BOOT_BASE_ADDRESS + (cpu * BOOT_CPU_OFFSET) + 0x10)
+#define BOOT_CP0_EEPC(cpu)     (volatile u32*)(BOOT_BASE_ADDRESS + (cpu * BOOT_CPU_OFFSET) + 0x14)
+#define BOOT_SIZE(cpu)       (volatile u32*)(BOOT_BASE_ADDRESS + (cpu * BOOT_CPU_OFFSET) + 0x18)    /* for CPU1 */
+#define BOOT_RCU_SR(cpu)       (volatile u32*)(BOOT_BASE_ADDRESS + (cpu * BOOT_CPU_OFFSET) + 0x18)  /* for CPU0 */
+#define BOOT_CFG_STAT(cpu)     (volatile u32*)(BOOT_BASE_ADDRESS + (cpu * BOOT_CPU_OFFSET) + 0x1C)
+#endif
+
+#define BOOT_CFG_NOR                   0x01
+#define BOOT_CFG_MII                   0x02
+#define BOOT_CFG_PCI           0x03
+#define BOOT_CFG_ASC                   0x04
+#define BOOT_CFG_SFLASH                0x05
+#define BOOT_CFG_NAND                  0x06
+#define BOOT_CFG_RMII          0x07
+#define BOOT_CFG_TEST          0x00
+
+#define BOOT_NUM_RETRY  3
+
+#define BOOT_STAT_MASK_ALL     0x0000FFFF
+#define BOOT_STAT_MASK_STAT    0x0000F000
+#define BOOT_STAT_MASK_BERR    0x00000F00
+#define BOOT_STAT_MASK_BSTRAP  0x000000F0
+#define BOOT_STAT_MASK_BMODULE 0x0000000F
+
+#define BOOT_STAT_INIT         0x00000000
+#define BOOT_STAT_BSTRAP       0x00001000
+#define BOOT_STAT_RETRY        0x00002000
+#define BOOT_STAT_START        0x00003000
+#define BOOT_STAT_HALT         0x0000F000
+
+#define BOOT_ERR_NO_RVEC       0x00000100
+#define BOOT_ERR_NO_NVEC       0x00000200
+#define BOOT_ERR_NO_EVEC       0x00000300
+#define BOOT_ERR_BSTRAP        0x00000400
+#define BOOT_ERR_EXC           0x00000800
+
+#ifndef __ASSEMBLY__
+void boot_set_status( u32 status, u32 mask);
+void boot_set_config( u32 config);
+void boot_set_rvec( u32 vector);
+void boot_set_size( u32 size);
+void boot_sdbg( u8* string, u32 value);
+void boot_error( u32 berr);
+int boot_from_ebu(void);
+void _boot_rvec(void);
+typedef struct
+{
+       u32   cpu;              /** CPU number */
+       u32   config;           /** Boot configuration */
+   u32   endian;           /** CPU endianess */
+   u32   debug;            /** Debug mode */
+       u32     (*exit)(void);     /** application vector */
+} boot_data;
+
+extern boot_data bootrom;
+#endif
+
+#endif /* #ifdef _BOOT_H */
diff --git a/package/uboot-ifxmips/files/include/configs/danube.h b/package/uboot-ifxmips/files/include/configs/danube.h
new file mode 100644 (file)
index 0000000..12cca11
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This file contains the configuration parameters for the danube board.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/ifx_cfg.h>
+
+#define  USE_REFERENCE_BOARD
+//#define   USE_EVALUATION_BOARD
+
+#define   DANUBE_BOOT_FROM_EBU
+#define   DANUBE_USE_DDR_RAM
+
+#ifdef DANUBE_USE_DDR_RAM
+//#define  DANUBE_DDR_RAM_111M
+#define DANUBE_DDR_RAM_166M
+//#define PROMOSDDR400
+//#define DDR_SAMSUNG_166M
+//#define DDR_PSC_166M
+//#define DANUBE_DDR_RAM_133M
+#define DANUBE_DDR_RAM_SIZE    32      /* 32M DDR-DRAM for reference board */
+#endif
+#define CLK_OUT2_25MHZ
+#define CONFIG_MIPS32          1       /* MIPS 4Kc CPU core    */
+#define CONFIG_DANUBE          1       /* on a danube Board    */
+#define RAM_SIZE                0x2000000 /*32M ram*/
+
+#define CPU_CLOCK_RATE         235000000   /* 235 MHz clock for the MIPS core */
+
+#define INFINEON_EBU_BOOTCFG   0x688C688C      /* CMULT = 8 for 150 MHz */
+
+#define CONFIG_BOOTDELAY       3       /* autoboot after 3 seconds     */
+
+#define CONFIG_BAUDRATE                115200
+
+#define DEBUG_PARSER           2
+
+/* valid baudrates */
+#define CFG_BAUDRATE_TABLE     { 300, 9600, 19200, 38400, 57600, 115200 }
+
+#ifndef CFG_HEAD_CODE
+#define        CONFIG_TIMESTAMP                /* Print image info with timestamp */
+#endif
+
+#define CONFIG_PREBOOT "echo;" \
+       "echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \
+       "echo"
+
+#undef CONFIG_BOOTARGS
+/* by MarsLin 2005/05/10, to support different hardware configuations */
+//#define CONFIG_EXTRA_ENV_SETTINGS    <configs/ifx_extra_env.h>
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "ethaddr=11:22:33:44:55:66\0" \
+       "serverip=192.168.45.100\0" \
+       "ipaddr=192.168.45.108\0"  \
+       "update_uboot=tftp 0x80500000 u-boot.ifx;era 1:0-10; cp.b 0x80500000 0xb0000000 0x10000\0" \
+       "update_openwrt=tftp 0x80500000 openwrt-ifxmips-squashfs.image; era 1:10-120; cp.b 0x80500000 0xb0030000 0x300000\0" \
+       "bootargs=console=ttyS1,115200 rootfstype=squashfs,jffs2 init=/etc/preinit\0"
+
+#define CONFIG_BOOTCOMMAND     "bootm 0xb0030000"
+
+#define CONFIG_COMMANDS_YES    (CONFIG_CMD_DFL | \
+                                CFG_CMD_ASKENV         | \
+                                CFG_CMD_DHRYSTONE      | \
+                                CFG_CMD_NET    )
+
+#define CONFIG_COMMANDS_NO     (CFG_CMD_NFS            | \
+                                CFG_CMD_FPGA           | \
+                                CFG_CMD_IMLS           | \
+                                CFG_CMD_ITEST          | \
+                                CFG_CMD_XING           | \
+                                CFG_CMD_IMI            | \
+                                CFG_CMD_BMP            | \
+                                CFG_CMD_BOOTD          | \
+                                CFG_CMD_CONSOLE        | \
+                                CFG_CMD_LOADS          | \
+                                CFG_CMD_LOADB          )
+
+#define CONFIG_COMMANDS                (CONFIG_COMMANDS_YES & ~CONFIG_COMMANDS_NO)
+
+#if 0
+                                CFG_CMD_DHCP
+                                CFG_CMD_ELF
+                                CFG_CMD_NAND
+#endif
+
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define        CFG_LONGHELP                            /* undef to save memory      */
+#define        CFG_PROMPT              "DANUBE # "     /* Monitor Command Prompt    */
+#define        CFG_CBSIZE              256             /* Console I/O Buffer Size   */
+#define        CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)  /* Print Buffer Size */
+#define        CFG_MAXARGS             16              /* max number of command args*/
+
+#define CFG_MALLOC_LEN         128*1024
+
+#define CFG_BOOTPARAMS_LEN     128*1024
+
+#define CFG_HZ       (CPU_CLOCK_RATE / 2)
+
+#define        CFG_LOAD_ADDR           0x80100000      /* default load address */
+
+#define CFG_MEMTEST_START      0x80100000
+#define CFG_MEMTEST_END                0x80400000
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CFG_MAX_FLASH_BANKS    1       /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT     (135)   /* max number of sectors on one chip */
+
+#define PHYS_FLASH_1           0xB0000000 /* Flash Bank #1 */
+#define PHYS_FLASH_2           0xB4000000 /* Flash Bank #2 */
+
+#define BOOTSTRAP_TEXT_BASE 0xb0000000         
+
+/* The following #defines are needed to get flash environment right */
+#define        CFG_MONITOR_BASE        UBOOT_RAM_TEXT_BASE     /* board/danube/config.mk. = 0xA0800000 */
+#define        BOOTSTRAP_CFG_MONITOR_BASE      BOOTSTRAP_TEXT_BASE     /* board/danube/config.mk. = 0xA0800000 */
+#define        CFG_MONITOR_LEN         (256 << 10)
+
+#define CFG_INIT_SP_OFFSET     0x400000
+
+#define CFG_FLASH_BASE         PHYS_FLASH_1
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT   (20 * CFG_HZ) /* Timeout for Flash Erase */
+#define CFG_FLASH_WRITE_TOUT   (20 * CFG_HZ) /* Timeout for Flash Write */
+
+#define        CFG_ENV_IS_IN_FLASH     1
+//#define CFG_ENV_IS_NOWHERE   1
+//#define CFG_ENV_IS_IN_NVRAM  1
+/* Address and size of Primary Environment Sector      */
+#define CFG_ENV_ADDR           IFX_CFG_FLASH_UBOOT_CFG_START_ADDR
+#define CFG_ENV_SIZE           IFX_CFG_FLASH_UBOOT_CFG_SIZE
+
+#define CONFIG_FLASH_16BIT
+
+#define CONFIG_NR_DRAM_BANKS   1
+
+#define CONFIG_DANUBE_SWITCH
+#define CONFIG_NET_MULTI
+#define CONFIG_ENV_OVERWRITE
+
+#define EXCEPTION_BASE 0x200
+
+/**
+ *\brief definition for nand
+ *
+ */
+#define CFG_MAX_NAND_DEVICE    1       /* Max number of NAND devices           */
+#define NAND_ChipID_UNKNOWN    0x00
+#define SECTORSIZE 512
+#define NAND_MAX_FLOORS 1
+#define NAND_MAX_CHIPS 1
+
+
+#define ADDR_COLUMN 1
+#define ADDR_PAGE 2
+#define ADDR_COLUMN_PAGE 3
+
+
+#define AT91_SMART_MEDIA_ALE (1 << 22)  /* our ALE is AD22 */
+#define AT91_SMART_MEDIA_CLE (1 << 21)  /* our CLE is AD21 */
+
+#define NAND_DISABLE_CE(nand) 
+#define NAND_ENABLE_CE(nand)
+#define NAND_WAIT_READY(nand)
+#define WRITE_NAND_COMMAND(d, adr) 
+#define WRITE_NAND_ADDRESS(d, adr) 
+#define WRITE_NAND(d, adr) 
+#define READ_NAND(adr) 
+/* the following are NOP's in our implementation */
+#define NAND_CTL_CLRALE(nandptr)
+#define NAND_CTL_SETALE(nandptr)
+#define NAND_CTL_CLRCLE(nandptr)
+#define NAND_CTL_SETCLE(nandptr)
+
+
+
+#define NAND_BASE_ADDRESS  0xB4000000
+
+#define NAND_WRITE(addr, val)     *((u8*)(NAND_BASE_ADDRESS | (addr))) = val;while((*EBU_NAND_WAIT & 0x08) == 0);
+#define NAND_READ(addr, val)      val = *((u8*)(NAND_BASE_ADDRESS | (addr)))
+#define NAND_CE_SET 
+#define NAND_CE_CLEAR
+#define NAND_READY       ( ((*EBU_NAND_WAIT)&0x07) == 7)
+#define NAND_READY_CLEAR  *EBU_NAND_WAIT = 0;
+#define WRITE_CMD    0x18
+#define WRITE_ADDR   0x14
+#define WRITE_LADDR  0x10
+#define WRITE_DATA  0x10
+#define READ_DATA    0x10
+#define READ_LDATA   0x00
+#define ACCESS_WAIT
+#define IFX_ATC_NAND 0xc176
+#define IFX_BTC_NAND 0xc166
+#define ST_512WB2_NAND 0x2076
+
+#define NAND_OK              0x00000000    /* Bootstrap succesful, start address in BOOT_RVEC */
+#define NAND_ERR             0x80000000
+#define NAND_ACC_TIMEOUT     (NAND_ERR | 0x00000001)
+#define NAND_ACC_ERR         (NAND_ERR | 0x00000002)
+
+
+/*****************************************************************************
+ * DANUBE
+ *****************************************************************************/
+/* lock cache for C program stack */
+/* points to ROM */
+/* stack size is 16K */
+#define LOCK_DCACHE_ADDR               0x9FC00000
+#define LOCK_DCACHE_SIZE               0x1000
+
+/*
+ * Memory layout
+ */
+#define CFG_SDRAM_BASE         0x80000000
+#define CFG_SDRAM_BASE_UNCACHE 0xA0000000
+#define CFG_CACHE_LOCK_SIZE  LOCK_DCACHE_SIZE
+
+/*
+ * Cache settings
+ */
+#define CFG_CACHE_SIZE   16384
+#define CFG_CACHE_LINES  32
+#define CFG_CACHE_WAYS   4
+#define CFG_CACHE_SETS   128
+
+#define CFG_ICACHE_SIZE   CFG_CACHE_SIZE
+#define CFG_DCACHE_SIZE   CFG_CACHE_SIZE
+#define CFG_CACHELINE_SIZE  CFG_CACHE_LINES
+
+#endif /* __CONFIG_H */
diff --git a/package/uboot-ifxmips/files/include/configs/ifx_cfg.h b/package/uboot-ifxmips/files/include/configs/ifx_cfg.h
new file mode 100644 (file)
index 0000000..101f2ac
--- /dev/null
@@ -0,0 +1,249 @@
+/* ============================================================================
+ * Copyright (C) 2003[- 2004] ? Infineon Technologies AG.
+ *
+ * All rights reserved.
+ * ============================================================================
+ *
+ * ============================================================================
+ *
+ * This document contains proprietary information belonging to Infineon 
+ * Technologies AG. Passing on and copying of this document, and communication
+ * of its contents is not permitted without prior written authorisation.
+ * 
+ * ============================================================================
+ *
+ * File Name: ifx_cfg.h
+ * Author : Mars Lin (mars.lin@infineon.com)
+ * Date: 
+ *
+ * ===========================================================================
+ *
+ * Project:
+ * Block:
+ *
+ * ===========================================================================
+ * Contents:  This file contains the data structures and definitions used 
+ *           by the core iptables and the sip alg modules. 
+ * ===========================================================================
+ * References:
+ */
+
+/*
+ * This file contains the configuration parameters for the IFX board.
+ */
+#ifndef _DANUBE_CFG_H_
+#define _DANUBE_CFG_H_
+
+/*-----------------------------------------------------------------------
+ * U-Boot/Kernel configurations
+ */
+#define IFX_CFG_UBOOT_DEFAULT_CFG_IPADDR               "172.20.80.100"
+#define IFX_CFG_UBOOT_DEFAULT_CFG_SERVERIP             "172.20.80.2"
+#define IFX_CFG_UBOOT_DEFAULT_CFG_ETHADDR              "00:E0:92:00:01:40"
+#define IFX_CFG_UBOOT_DEFAULT_CFG_NETDEV               "eth1"
+#define IFX_CFG_UBOOT_DEFAULT_CFG_BAUDRATE             "115200"
+#define IFX_CFG_UBOOT_LOAD_ADDRESS                      "0x80800000"
+
+/* End of U-Boot/Kernel configurations
+ *-----------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------
+ * Board specific configurations
+ */
+#ifdef IFX_CONFIG_MEMORY_SIZE
+       #define IFX_CFG_MEM_SIZE        31
+#else
+       #error "ERROR!! Define memory size first!"
+#endif
+
+//2MB flash partition
+#if (IFX_CONFIG_FLASH_SIZE == 2)
+#define IFX_CFG_FLASH_PARTITIONS_INFO                                   \
+        "part0_begin=0xB0000000\0"                                      \
+        "part1_begin=0xB0010000\0"                                      \
+        "part2_begin=0xB0050000\0"                                      \
+        "total_part=3\0"
+
+#define IFX_CFG_FLASH_DATA_BLOCKS_INFO                                 \
+       "data_block0=" IFX_CFG_FLASH_UBOOT_IMAGE_BLOCK_NAME "\0"        \
+       "data_block1=" IFX_CFG_FLASH_FIRMWARE_IMAGE_BLOCK_NAME "\0"     \
+       "data_block2=" IFX_CFG_FLASH_ROOTFS_IMAGE_BLOCK_NAME "\0"       \
+       "data_block3=" IFX_CFG_FLASH_KERNEL_IMAGE_BLOCK_NAME "\0"       \
+       "data_block4=" IFX_CFG_FLASH_SYSTEM_CFG_BLOCK_NAME "\0"         \
+       "data_block5=" IFX_CFG_FLASH_UBOOT_CFG_BLOCK_NAME "\0"          \
+       "data_block6=" IFX_CFG_FLASH_FIRMWARE_DIAG_BLOCK_NAME "\0"      \
+       "data_block7=" IFX_CFG_FLASH_CALIBRATION_CFG_BLOCK_NAME "\0"    \
+       "total_db=8\0"
+
+       #define IFX_CFG_FLASH_UBOOT_IMAGE_BLOCK_NAME            "uboot"
+       #define IFX_CFG_FLASH_UBOOT_IMAGE_START_ADDR            0xB0000000
+       #define IFX_CFG_FLASH_UBOOT_IMAGE_SIZE                  0
+       #define IFX_CFG_FLASH_UBOOT_IMAGE_MTDBLOCK_NAME         "/dev/mtdblock0"
+
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_BLOCK_NAME         "firmware"
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_START_ADDR         0xB0010000
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_SIZE               0
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_MTDBLOCK_NAME      "/dev/mtdblock1"
+
+       #define IFX_CFG_FLASH_ROOTFS_IMAGE_BLOCK_NAME           "rootfs"
+       #define IFX_CFG_FLASH_ROOTFS_IMAGE_START_ADDR           0xB0050000
+       #define IFX_CFG_FLASH_ROOTFS_IMAGE_SIZE                 0
+       #define IFX_CFG_FLASH_ROOTFS_IMAGE_MTDBLOCK_NAME        "/dev/mtdblock2"
+
+       #define IFX_CFG_FLASH_KERNEL_IMAGE_BLOCK_NAME           "kernel"
+       #define IFX_CFG_FLASH_KERNEL_IMAGE_START_ADDR           0xB01FCFFF
+       #define IFX_CFG_FLASH_KERNEL_IMAGE_SIZE                 0
+
+       #define IFX_CFG_FLASH_SYSTEM_CFG_BLOCK_NAME             "sysconfig"
+       #define IFX_CFG_FLASH_SYSTEM_CFG_START_ADDR             0xB01FD000
+       #define IFX_CFG_FLASH_SYSTEM_CFG_SIZE                   0
+       #define IFX_CFG_FLASH_SYSTEM_CFG_END_ADDR               0xB01FEFFF
+
+       #define IFX_CFG_FLASH_UBOOT_CFG_BLOCK_NAME              "ubootconfig"
+       #define IFX_CFG_FLASH_UBOOT_CFG_START_ADDR              0xB01FF000
+       #define IFX_CFG_FLASH_UBOOT_CFG_SIZE                    0x0C00
+       #define IFX_CFG_FLASH_UBOOT_CFG_END_ADDR                0xB01FFBFF
+
+       #define IFX_CFG_FLASH_FIRMWARE_DIAG_BLOCK_NAME          "fwdiag"
+       #define IFX_CFG_FLASH_FIRMWARE_DIAG_START_ADDR          0xB31FFC00
+       #define IFX_CFG_FLASH_FIRMWARE_DIAG_SIZE                0x0200
+       #define IFX_CFG_FLASH_FIRMWARE_DIAG_END_ADDR            0xB01FFDFF
+
+       #define IFX_CFG_FLASH_CALIBRATION_CFG_BLOCK_NAME        "calibration"
+       #define IFX_CFG_FLASH_CALIBRATION_CFG_START_ADDR        0xB01FFE00
+       #define IFX_CFG_FLASH_CALIBRATION_CFG_SIZE              0x0200
+       #define IFX_CFG_FLASH_CALIBRATION_CFG_END_ADDR          0xB01FFFFF
+
+       #define IFX_CFG_FLASH_END_ADDR                          0xB01FFFFF
+
+//4MB flash partition
+#elif (IFX_CONFIG_FLASH_SIZE == 4)
+#define IFX_CFG_FLASH_PARTITIONS_INFO                                   \
+        "part0_begin=0xB0000000\0"                                      \
+        "part1_begin=0xB0020000\0"                                      \
+        "part2_begin=0xB0060000\0"                                      \
+        "total_part=3\0"
+
+#define IFX_CFG_FLASH_DATA_BLOCKS_INFO                                  \
+        "data_block0=" IFX_CFG_FLASH_UBOOT_IMAGE_BLOCK_NAME "\0"        \
+        "data_block1=" IFX_CFG_FLASH_FIRMWARE_IMAGE_BLOCK_NAME "\0"     \
+        "data_block2=" IFX_CFG_FLASH_ROOTFS_IMAGE_BLOCK_NAME "\0"       \
+        "data_block3=" IFX_CFG_FLASH_KERNEL_IMAGE_BLOCK_NAME "\0"       \
+        "data_block4=" IFX_CFG_FLASH_SYSTEM_CFG_BLOCK_NAME "\0"         \
+       "data_block5=" IFX_CFG_FLASH_UBOOT_CFG_BLOCK_NAME "\0"          \
+        "data_block6=" IFX_CFG_FLASH_VOIP_CFG_BLOCK_NAME "\0"           \
+        "data_block7=" IFX_CFG_FLASH_FIRMWARE_DIAG_BLOCK_NAME "\0"     \
+       "data_block8=" IFX_CFG_FLASH_CALIBRATION_CFG_BLOCK_NAME "\0"    \
+       "total_db=9\0"
+
+       #define IFX_CFG_FLASH_UBOOT_IMAGE_BLOCK_NAME            "uboot"
+       #define IFX_CFG_FLASH_UBOOT_IMAGE_START_ADDR            0xB0000000
+       #define IFX_CFG_FLASH_UBOOT_IMAGE_SIZE                  0
+       #define IFX_CFG_FLASH_UBOOT_IMAGE_MTDBLOCK_NAME         "/dev/mtdblock0"
+
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_BLOCK_NAME         "firmware"
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_START_ADDR         0xB0020000
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_SIZE               0
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_MTDBLOCK_NAME      "/dev/mtdblock1"
+
+       #define IFX_CFG_FLASH_ROOTFS_IMAGE_BLOCK_NAME           "rootfs"
+       #define IFX_CFG_FLASH_ROOTFS_IMAGE_START_ADDR           0xB0060000
+       #define IFX_CFG_FLASH_ROOTFS_IMAGE_SIZE                 0
+       #define IFX_CFG_FLASH_ROOTFS_IMAGE_MTDBLOCK_NAME        "/dev/mtdblock2"
+
+       #define IFX_CFG_FLASH_KERNEL_IMAGE_BLOCK_NAME           "kernel"
+       #define IFX_CFG_FLASH_KERNEL_IMAGE_START_ADDR           0xB03F4FFF
+       #define IFX_CFG_FLASH_KERNEL_IMAGE_SIZE                 0
+
+       #define IFX_CFG_FLASH_SYSTEM_CFG_BLOCK_NAME             "sysconfig"
+       #define IFX_CFG_FLASH_SYSTEM_CFG_START_ADDR             0xB03F5000
+       #define IFX_CFG_FLASH_SYSTEM_CFG_SIZE                   0x2000
+       #define IFX_CFG_FLASH_SYSTEM_CFG_END_ADDR               0xB03F6FFF
+
+       #define IFX_CFG_FLASH_UBOOT_CFG_BLOCK_NAME              "ubootconfig"
+       #define IFX_CFG_FLASH_UBOOT_CFG_START_ADDR              0xB03F7000
+       #define IFX_CFG_FLASH_UBOOT_CFG_SIZE                    0x0C00
+       #define IFX_CFG_FLASH_UBOOT_CFG_END_ADDR                0xB03F7BFF
+
+       #define IFX_CFG_FLASH_VOIP_CFG_BLOCK_NAME               "voip"
+       #define IFX_CFG_FLASH_VOIP_CFG_START_ADDR               0xB03F7C00
+       #define IFX_CFG_FLASH_VOIP_CFG_SIZE                     0x8000
+       #define IFX_CFG_FLASH_VOIP_CFG_END_ADDR                 0xB03FFBFF
+
+       #define IFX_CFG_FLASH_FIRMWARE_DIAG_BLOCK_NAME          "fwdiag"
+       #define IFX_CFG_FLASH_FIRMWARE_DIAG_START_ADDR          0xB03FFC00
+       #define IFX_CFG_FLASH_FIRMWARE_DIAG_SIZE                0x0200
+       #define IFX_CFG_FLASH_FIRMWARE_DIAG_END_ADDR            0xB03FFDFF
+
+       #define IFX_CFG_FLASH_CALIBRATION_CFG_BLOCK_NAME        "calibration"
+       #define IFX_CFG_FLASH_CALIBRATION_CFG_START_ADDR        0xB03FFE00
+       #define IFX_CFG_FLASH_CALIBRATION_CFG_SIZE              0x0200
+       #define IFX_CFG_FLASH_CALIBRATION_CFG_END_ADDR          0xB03FFFFF
+
+       #define IFX_CFG_FLASH_END_ADDR                          0xB03FFFFF
+//8MB flash definition
+#elif (IFX_CONFIG_FLASH_SIZE == 8)
+#define IFX_CFG_FLASH_PARTITIONS_INFO                                   \
+        "part0_begin=0xB0000000\0"                                      \
+        "part1_begin=0xB0080000\0"                                      \
+        "part2_begin=0xB0280000\0"                                      \
+        "part3_begin=0xB0790000\0"                                      \
+        "part4_begin=0xB07A0000\0"                                      \
+        "part5_begin=0xB07E0000\0"                                      \
+        "total_part=6\0"
+
+#define IFX_CFG_FLASH_DATA_BLOCKS_INFO                                  \
+        "data_block0=" IFX_CFG_FLASH_UBOOT_IMAGE_BLOCK_NAME "\0"        \
+        "data_block1=" IFX_CFG_FLASH_KERNEL_IMAGE_BLOCK_NAME "\0"       \
+        "data_block2=" IFX_CFG_FLASH_ROOTFS_IMAGE_BLOCK_NAME "\0"       \
+        "data_block3=" IFX_CFG_FLASH_SYSTEM_CFG_BLOCK_NAME "\0"         \
+        "data_block4=" IFX_CFG_FLASH_FIRMWARE_IMAGE_BLOCK_NAME "\0"     \
+       "data_block5=" IFX_CFG_FLASH_UBOOT_CFG_BLOCK_NAME "\0"          \
+        "total_db=6\0"
+
+        #define IFX_CFG_FLASH_UBOOT_IMAGE_BLOCK_NAME            "uboot"
+        #define IFX_CFG_FLASH_UBOOT_IMAGE_START_ADDR            0xB0000000
+        #define IFX_CFG_FLASH_UBOOT_IMAGE_END_ADDR              0xB007FFFF
+        #define IFX_CFG_FLASH_UBOOT_IMAGE_SIZE                  0x00080000
+        #define IFX_CFG_FLASH_UBOOT_IMAGE_MTDBLOCK_NAME         "/dev/mtdblock0"
+
+        #define IFX_CFG_FLASH_KERNEL_IMAGE_BLOCK_NAME           "kernel"
+        #define IFX_CFG_FLASH_KERNEL_IMAGE_START_ADDR           0xB0080000
+        #define IFX_CFG_FLASH_KERNEL_IMAGE_SIZE                 0x200000
+        #define IFX_CFG_FLASH_KERNEL_IMAGE_END_ADDR             0xB017FFFF
+        #define IFX_CFG_FLASH_KERNEL_IMAGE_MTDBLOCK_NAME        "/dev/mtdblock1"
+
+        #define IFX_CFG_FLASH_ROOTFS_IMAGE_BLOCK_NAME           "rootfs"
+        #define IFX_CFG_FLASH_ROOTFS_IMAGE_START_ADDR           0xB0280000
+        #define IFX_CFG_FLASH_ROOTFS_IMAGE_SIZE                 0x00510000
+        #define IFX_CFG_FLASH_ROOTFS_IMAGE_END_ADDR             0xB078FFFF
+        #define IFX_CFG_FLASH_ROOTFS_IMAGE_MTDBLOCK_NAME        "/dev/mtdblock2"
+
+       #define IFX_CFG_FLASH_SYSTEM_CFG_BLOCK_NAME             "sysconfig"
+       #define IFX_CFG_FLASH_SYSTEM_CFG_START_ADDR             0xB0790000
+       #define IFX_CFG_FLASH_SYSTEM_CFG_SIZE                   0x10000
+       #define IFX_CFG_FLASH_SYSTEM_CFG_END_ADDR               0xB079FFFF
+       #define IFX_CFG_FLASH_SYSTEM_CFG_MTDBLOCK_NAME          "/dev/mtdblock3"
+
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_BLOCK_NAME         "firmware"
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_START_ADDR         0xB07A0000
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_SIZE               0x40000
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_END_ADDR           0xB07DFFFF
+       #define IFX_CFG_FLASH_FIRMWARE_IMAGE_MTDBLOCK_NAME      "/dev/mtdblock4"
+
+        #define IFX_CFG_FLASH_UBOOT_CFG_BLOCK_NAME              "ubootconfig"
+        #define IFX_CFG_FLASH_UBOOT_CFG_START_ADDR              0xB0020000
+        #define IFX_CFG_FLASH_UBOOT_CFG_END_ADDR                0xB002FFFF
+        #define IFX_CFG_FLASH_UBOOT_CFG_SIZE                    0x10000
+        #define IFX_CFG_FLASH_UBOOT_CFG_MTDBLOCK_NAME           "/dev/mtdblock5"
+
+        #define IFX_CFG_FLASH_END_ADDR                          0xB07FFFFF
+#else
+       #error "ERROR!! Define flash size first!"
+#endif
+/* End of Board specific configurations
+ *-----------------------------------------------------------------------
+ */
+
+#endif
diff --git a/package/uboot-ifxmips/files/include/configs/ifx_extra_env.h b/package/uboot-ifxmips/files/include/configs/ifx_extra_env.h
new file mode 100644 (file)
index 0000000..a03d836
--- /dev/null
@@ -0,0 +1,94 @@
+/* ============================================================================
+ * Copyright (C) 2003[- 2004] ? Infineon Technologies AG.
+ *
+ * All rights reserved.
+ * ============================================================================
+ *
+ * ============================================================================
+ *
+ * This document contains proprietary information belonging to Infineon 
+ * Technologies AG. Passing on and copying of this document, and communication
+ * of its contents is not permitted without prior written authorisation.
+ * 
+ * ============================================================================
+ *
+ * File Name: ifx_extra_env.h
+ * Author : Mars Lin (mars.lin@infineon.com)
+ * Date: 
+ *
+ * ===========================================================================
+ *
+ * Project:
+ * Block:
+ *
+ * ===========================================================================
+ * Contents:  This file contains the data structures and definitions used 
+ *           by the core iptables and the sip alg modules.
+ * ===========================================================================
+ * References:
+ */
+       "mem=" MK_STR(IFX_CONFIG_MEMORY_SIZE) "M\0"
+       "ipaddr=" IFX_CFG_UBOOT_DEFAULT_CFG_IPADDR "\0"
+       "serverip=" IFX_CFG_UBOOT_DEFAULT_CFG_SERVERIP "\0"
+       "ethaddr=" IFX_CFG_UBOOT_DEFAULT_CFG_ETHADDR "\0"
+       "netdev=eth0\0"
+       "baudrate=" IFX_CFG_UBOOT_DEFAULT_CFG_BAUDRATE "\0"
+       "loadaddr=" IFX_CFG_UBOOT_LOAD_ADDRESS "\0"
+       "rootpath=/tftpboot/nfsrootfs\0"
+       "nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath)\0"
+       "ramargs=setenv bootargs root=/dev/ram rw\0"
+       "addip=setenv bootargs $(bootargs) ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname):$(netdev):on\0"
+       "addmisc=setenv bootargs $(bootargs) console=ttyS1,$(baudrate) ethaddr=$(ethaddr) mem=$(mem) panic=1\0"
+       "flash_nfs=run nfsargs addip addmisc;bootm $(kernel_addr)\0"
+       "ramdisk_addr=B0100000\0"
+       "flash_self=run ramargs addip addmisc;bootm $(kernel_addr) $(ramdisk_addr)\0"
+       "bootfile=uImage\0"
+       "net_nfs=tftp $(loadaddr) $(bootfile);run nfsargs addip addmisc;bootm\0"
+       "net_flash=tftp $(loadaddr) $(bootfile); run flashargs addip addmisc; bootm\0"
+       "u-boot=u-boot.ifx\0"
+       "jffs2fs=jffs2.img\0"
+        "rootfs=rootfs.img\0"
+       "firmware=firmware.img\0"
+       "load=tftp $(loadaddr) $(u-boot)\0"
+       "update=protect off 1:0-2;era 1:0-2;cp.b $(loadaddr) B0000000 $(filesize)\0"
+       "flashargs=setenv bootargs root=/dev/mtdblock2 ro rootfstype=squashfs\0"
+       "mtdargs=setenv bootargs root=/dev/mtdblock2 rw rootfstype=jffs2\0"
+       "flash_flash=run flashargs addip addmisc; bootm $(f_kernel_addr)\0"
+       "net_mtd=tftp $(loadaddr) $(bootfile); run mtdargs addip addmisc; bootm\0"
+       "flash_mtd=run mtdargs addip addmisc; bootm $(f_kernel_addr)\0"
+       "update_uboot=tftpboot $(loadaddr) $(u-boot);upgrade uboot $(loadaddr) $(filesize) 0\0"
+       "update_kernel=tftpboot $(loadaddr) $(bootfile);upgrade kernel $(loadaddr) $(filesize) 0\0"
+       "update_rootfs=tftpboot $(loadaddr) $(rootfs); upgrade rootfs $(loadaddr) $(filesize) 0\0"
+       "update_rootfs_1=tftpboot $(loadaddr) $(rootfs); erase 1:47-132; cp.b $(loadaddr) $(f_rootfs_addr) $(filesize)\0"
+       "update_jffs2=tftpboot $(loadaddr) $(rootfs); upgrade rootfs $(loadaddr) $(filesize) 0\0"
+       "update_jffs2_1=tftpboot $(loadaddr) $(jffs2fs); erase 1:47-132; cp.b $(loadaddr) $(f_rootfs_addr) $(filesize)\0"
+       "update_firmware=tftpboot $(loadaddr) $(firmware);upgrade firmware $(loadaddr) $(filesize) 0\0"
+       "reset_uboot_config=erase " MK_STR(IFX_CFG_FLASH_UBOOT_CFG_START_ADDR) " " MK_STR(IFX_CFG_FLASH_UBOOT_CFG_END_ADDR) "\0" 
+       IFX_CFG_FLASH_PARTITIONS_INFO
+       "flash_end=" MK_STR(IFX_CFG_FLASH_END_ADDR) "\0"
+       IFX_CFG_FLASH_DATA_BLOCKS_INFO
+       "f_uboot_addr=" MK_STR(IFX_CFG_FLASH_UBOOT_IMAGE_START_ADDR) "\0"
+       "f_uboot_size=" MK_STR(IFX_CFG_FLASH_UBOOT_IMAGE_SIZE) "\0"
+       "f_ubootconfig_addr=" MK_STR(IFX_CFG_FLASH_UBOOT_CFG_START_ADDR) "\0"
+       "f_ubootconfig_size=" MK_STR(IFX_CFG_FLASH_UBOOT_CFG_SIZE) "\0"
+       "f_ubootconfig_end=" MK_STR(IFX_CFG_FLASH_UBOOT_CFG_END_ADDR) "\0"
+       "f_kernel_addr=" MK_STR(IFX_CFG_FLASH_KERNEL_IMAGE_START_ADDR) "\0"
+       "f_kernel_size=" MK_STR(IFX_CFG_FLASH_KERNEL_IMAGE_SIZE) "\0"
+       "f_kernel_end=" MK_STR(IFX_CFG_FLASH_KERNEL_IMAGE_END_ADDR) "\0"
+       "f_rootfs_addr=" MK_STR(IFX_CFG_FLASH_ROOTFS_IMAGE_START_ADDR) "\0"
+       "f_rootfs_size=" MK_STR(IFX_CFG_FLASH_ROOTFS_IMAGE_SIZE) "\0"
+       "f_rootfs_end=" MK_STR(IFX_CFG_FLASH_ROOTFS_IMAGE_END_ADDR) "\0" 
+       "f_firmware_addr=" MK_STR(IFX_CFG_FLASH_FIRMWARE_IMAGE_START_ADDR) "\0"
+       "f_firmware_size=" MK_STR(IFX_CFG_FLASH_FIRMWARE_IMAGE_SIZE) "\0"
+       "f_sysconfig_addr=" MK_STR(IFX_CFG_FLASH_SYSTEM_CFG_START_ADDR) "\0"
+       "f_sysconfig_size=" MK_STR(IFX_CFG_FLASH_SYSTEM_CFG_SIZE) "\0"
+       /*
+       "f_fwdiag_addr=" MK_STR(IFX_CFG_FLASH_FIRMWARE_DIAG_START_ADDR) "\0"
+       "f_fwdiag_size=" MK_STR(IFX_CFG_FLASH_FIRMWARE_DIAG_SIZE) "\0"
+       "f_calibration_addr=" MK_STR(IFX_CFG_FLASH_CALIBRATION_CFG_START_ADDR) "\0"
+       "f_calibration_size=" MK_STR(IFX_CFG_FLASH_CALIBRATION_CFG_SIZE) "\0"
+#if (IFX_CONFIG_FLASH_SIZE == 4) || (IFX_CONFIG_FLASH_SIZE == 8) 
+       "f_voip_addr=" MK_STR(IFX_CFG_FLASH_VOIP_CFG_START_ADDR) "\0" 
+       "f_voip_size=" MK_STR(IFX_CFG_FLASH_VOIP_CFG_SIZE) "\0" 
+#endif
+       */
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/LzmaDecode.c b/package/uboot-ifxmips/files/lib_bootstrap/LzmaDecode.c
new file mode 100644 (file)
index 0000000..28263e6
--- /dev/null
@@ -0,0 +1,622 @@
+/*
+  LzmaDecode.c
+  LZMA Decoder (optimized for Speed version)
+  
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this Code, expressly permits you to 
+  statically or dynamically link your Code (or bind by name) to the 
+  interfaces of this file without subjecting your linked Code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifdef CONFIG_LZMA
+
+#include "LzmaDecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+
+#if 0
+#define RC_TEST { if (Buffer == BufferLim) \
+  { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) { printf("ERROR, %s, %d\n", __FILE__, __LINE__); return result; } \
+  BufferLim = Buffer + size; if (size == 0) { printf("ERROR, %s, %d\n", __FILE__, __LINE__); return LZMA_RESULT_DATA_ERROR; } }}
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) \
+  { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) { return result; } \
+  BufferLim = Buffer + size; if (size == 0) { return LZMA_RESULT_DATA_ERROR; } }}
+#endif
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#if 0
+#define RC_TEST { if (Buffer == BufferLim) { printf("ERROR, %s, %d\n", __FILE__, __LINE__); return LZMA_RESULT_DATA_ERROR; } }
+#else
+#define RC_TEST { if (Buffer == BufferLim) { return LZMA_RESULT_DATA_ERROR; } }
+#endif
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+  { UpdateBit0(p); mi <<= 1; A0; } else \
+  { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 
+  
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)               
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+  { int i = numLevels; res = 1; \
+  do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+  res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+  unsigned char prop0;
+  if (size < LZMA_PROPERTIES_SIZE)
+  {
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+    printf("ERROR: %s, %d\n", __FILE__, __LINE__);
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+  prop0 = propsData[0];
+  if (prop0 >= (9 * 5 * 5))
+  {
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+    printf("ERROR: %s, %d\n", __FILE__, __LINE__);
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+  {
+    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+    propsRes->lc = prop0;
+    /*
+    unsigned char remainder = (unsigned char)(prop0 / 9);
+    propsRes->lc = prop0 % 9;
+    propsRes->pb = remainder / 5;
+    propsRes->lp = remainder % 5;
+    */
+  }
+
+  #ifdef _LZMA_OUT_READ
+  {
+    int i;
+    propsRes->DictionarySize = 0;
+    for (i = 0; i < 4; i++)
+      propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+    if (propsRes->DictionarySize == 0)
+      propsRes->DictionarySize = 1;
+  }
+  #endif
+  return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *InCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+  CProb *p = vs->Probs;
+  SizeT nowPos = 0;
+  Byte previousByte = 0;
+  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+  int lc = vs->Properties.lc;
+
+  #ifdef _LZMA_OUT_READ
+  
+  UInt32 Range = vs->Range;
+  UInt32 Code = vs->Code;
+  #ifdef _LZMA_IN_CB
+  const Byte *Buffer = vs->Buffer;
+  const Byte *BufferLim = vs->BufferLim;
+  #else
+  const Byte *Buffer = inStream;
+  const Byte *BufferLim = inStream + inSize;
+  #endif
+  int state = vs->State;
+  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+  int len = vs->RemainLen;
+  UInt32 globalPos = vs->GlobalPos;
+  UInt32 distanceLimit = vs->DistanceLimit;
+
+  Byte *dictionary = vs->Dictionary;
+  UInt32 dictionarySize = vs->Properties.DictionarySize;
+  UInt32 dictionaryPos = vs->DictionaryPos;
+
+  Byte tempDictionary[4];
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+  if (len == kLzmaStreamWasFinishedId)
+    return LZMA_RESULT_OK;
+
+  if (dictionarySize == 0)
+  {
+    dictionary = tempDictionary;
+    dictionarySize = 1;
+    tempDictionary[0] = vs->TempDictionary[0];
+  }
+
+  if (len == kLzmaNeedInitId)
+  {
+    {
+      UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+      UInt32 i;
+      for (i = 0; i < numProbs; i++)
+        p[i] = kBitModelTotal >> 1; 
+      rep0 = rep1 = rep2 = rep3 = 1;
+      state = 0;
+      globalPos = 0;
+      distanceLimit = 0;
+      dictionaryPos = 0;
+      dictionary[dictionarySize - 1] = 0;
+      #ifdef _LZMA_IN_CB
+      RC_INIT;
+      #else
+      RC_INIT(inStream, inSize);
+      #endif
+    }
+    len = 0;
+  }
+  while(len != 0 && nowPos < outSize)
+  {
+    UInt32 pos = dictionaryPos - rep0;
+    if (pos >= dictionarySize)
+      pos += dictionarySize;
+    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+    if (++dictionaryPos == dictionarySize)
+      dictionaryPos = 0;
+    len--;
+  }
+  if (dictionaryPos == 0)
+    previousByte = dictionary[dictionarySize - 1];
+  else
+    previousByte = dictionary[dictionaryPos - 1];
+
+  #else /* if !_LZMA_OUT_READ */
+
+  int state = 0;
+  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+  int len = 0;
+  const Byte *Buffer;
+  const Byte *BufferLim;
+  UInt32 Range;
+  UInt32 Code;
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+
+  {
+    UInt32 i;
+    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+    for (i = 0; i < numProbs; i++)
+      p[i] = kBitModelTotal >> 1;
+  }
+  
+  #ifdef _LZMA_IN_CB
+  RC_INIT;
+  #else
+  RC_INIT(inStream, inSize);
+  #endif
+
+  #endif /* _LZMA_OUT_READ */
+
+  while(nowPos < outSize)
+  {
+    CProb *prob;
+    UInt32 bound;
+    int posState = (int)(
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & posStateMask);
+
+    prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+    IfBit0(prob)
+    {
+      int symbol = 1;
+      UpdateBit0(prob)
+      prob = p + Literal + (LZMA_LIT_SIZE * 
+        (((
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+      if (state >= kNumLitStates)
+      {
+        int matchByte;
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        matchByte = dictionary[pos];
+        #else
+        matchByte = outStream[nowPos - rep0];
+        #endif
+        do
+        {
+          int bit;
+          CProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & 0x100);
+          probLit = prob + 0x100 + bit + symbol;
+          RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+        }
+        while (symbol < 0x100);
+      }
+      while (symbol < 0x100)
+      {
+        CProb *probLit = prob + symbol;
+        RC_GET_BIT(probLit, symbol)
+      }
+      previousByte = (Byte)symbol;
+
+      outStream[nowPos++] = previousByte;
+      #ifdef _LZMA_OUT_READ
+      if (distanceLimit < dictionarySize)
+        distanceLimit++;
+
+      dictionary[dictionaryPos] = previousByte;
+      if (++dictionaryPos == dictionarySize)
+        dictionaryPos = 0;
+      #endif
+      if (state < 4) state = 0;
+      else if (state < 10) state -= 3;
+      else state -= 6;
+    }
+    else             
+    {
+      UpdateBit1(prob);
+      prob = p + IsRep + state;
+      IfBit0(prob)
+      {
+        UpdateBit0(prob);
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        state = state < kNumLitStates ? 0 : 3;
+        prob = p + LenCoder;
+      }
+      else
+      {
+        UpdateBit1(prob);
+        prob = p + IsRepG0 + state;
+        IfBit0(prob)
+        {
+          UpdateBit0(prob);
+          prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IfBit0(prob)
+          {
+            #ifdef _LZMA_OUT_READ
+            UInt32 pos;
+            #endif
+            UpdateBit0(prob);
+            
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit == 0)
+            #else
+            if (nowPos == 0)
+            #endif
+            {
+                         
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+              printf("ERROR: %s, %d\n", __FILE__, __LINE__);
+#endif
+              return LZMA_RESULT_DATA_ERROR;
+            }
+            
+            state = state < kNumLitStates ? 9 : 11;
+            #ifdef _LZMA_OUT_READ
+            pos = dictionaryPos - rep0;
+            if (pos >= dictionarySize)
+              pos += dictionarySize;
+            previousByte = dictionary[pos];
+            dictionary[dictionaryPos] = previousByte;
+            if (++dictionaryPos == dictionarySize)
+              dictionaryPos = 0;
+            #else
+            previousByte = outStream[nowPos - rep0];
+            #endif
+            outStream[nowPos++] = previousByte;
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit < dictionarySize)
+              distanceLimit++;
+            #endif
+
+            continue;
+          }
+          else
+          {
+            UpdateBit1(prob);
+          }
+        }
+        else
+        {
+          UInt32 distance;
+          UpdateBit1(prob);
+          prob = p + IsRepG1 + state;
+          IfBit0(prob)
+          {
+            UpdateBit0(prob);
+            distance = rep1;
+          }
+          else 
+          {
+            UpdateBit1(prob);
+            prob = p + IsRepG2 + state;
+            IfBit0(prob)
+            {
+              UpdateBit0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UpdateBit1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = p + RepLenCoder;
+      }
+      {
+        int numBits, offset;
+        CProb *probLen = prob + LenChoice;
+        IfBit0(probLen)
+        {
+          UpdateBit0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          numBits = kLenNumLowBits;
+        }
+        else
+        {
+          UpdateBit1(probLen);
+          probLen = prob + LenChoice2;
+          IfBit0(probLen)
+          {
+            UpdateBit0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            numBits = kLenNumMidBits;
+          }
+          else
+          {
+            UpdateBit1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            numBits = kLenNumHighBits;
+          }
+        }
+        RangeDecoderBitTreeDecode(probLen, numBits, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        int posSlot;
+        state += kNumLitStates;
+        prob = p + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
+            kNumPosSlotBits);
+        RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+          rep0 = (2 | ((UInt32)posSlot & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            rep0 <<= numDirectBits;
+            prob = p + SpecPos + rep0 - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              RC_NORMALIZE
+              Range >>= 1;
+              rep0 <<= 1;
+              if (Code >= Range)
+              {
+                Code -= Range;
+                rep0 |= 1;
+              }
+            }
+            while (--numDirectBits != 0);
+            prob = p + Align;
+            rep0 <<= kNumAlignBits;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            int i = 1;
+            int mi = 1;
+            do
+            {
+              CProb *prob3 = prob + mi;
+              RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+              i <<= 1;
+            }
+            while(--numDirectBits != 0);
+          }
+        }
+        else
+          rep0 = posSlot;
+        if (++rep0 == (UInt32)(0))
+        {
+          /* it's for stream version */
+          len = kLzmaStreamWasFinishedId;
+          break;
+        }
+      }
+
+      len += kMatchMinLen;
+      #ifdef _LZMA_OUT_READ
+      if (rep0 > distanceLimit) 
+      #else
+      if (rep0 > nowPos)
+      #endif
+      {
+               
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+        printf("ERROR: %s, %d\n", __FILE__, __LINE__);
+#endif
+        return LZMA_RESULT_DATA_ERROR;
+      }
+
+      #ifdef _LZMA_OUT_READ
+      if (dictionarySize - distanceLimit > (UInt32)len)
+        distanceLimit += len;
+      else
+        distanceLimit = dictionarySize;
+      #endif
+
+      do
+      {
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        previousByte = dictionary[pos];
+        dictionary[dictionaryPos] = previousByte;
+        if (++dictionaryPos == dictionarySize)
+          dictionaryPos = 0;
+        #else
+        previousByte = outStream[nowPos - rep0];
+        #endif
+        len--;
+        outStream[nowPos++] = previousByte;
+      }
+      while(len != 0 && nowPos < outSize);
+    }
+  }
+  RC_NORMALIZE;
+
+  #ifdef _LZMA_OUT_READ
+  vs->Range = Range;
+  vs->Code = Code;
+  vs->DictionaryPos = dictionaryPos;
+  vs->GlobalPos = globalPos + (UInt32)nowPos;
+  vs->DistanceLimit = distanceLimit;
+  vs->Reps[0] = rep0;
+  vs->Reps[1] = rep1;
+  vs->Reps[2] = rep2;
+  vs->Reps[3] = rep3;
+  vs->State = state;
+  vs->RemainLen = len;
+  vs->TempDictionary[0] = tempDictionary[0];
+  #endif
+
+  #ifdef _LZMA_IN_CB
+  vs->Buffer = Buffer;
+  vs->BufferLim = BufferLim;
+  #else
+  *inSizeProcessed = (SizeT)(Buffer - inStream);
+  #endif
+  *outSizeProcessed = nowPos;
+  return LZMA_RESULT_OK;
+}
+
+#endif /* CONFIG_LZMA */
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/LzmaDecode.h b/package/uboot-ifxmips/files/lib_bootstrap/LzmaDecode.h
new file mode 100644 (file)
index 0000000..2870eeb
--- /dev/null
@@ -0,0 +1,113 @@
+/* 
+  LzmaDecode.h
+  LZMA Decoder interface
+
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs, 
+   but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+  int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+  int lc;
+  int lp;
+  int pb;
+  #ifdef _LZMA_OUT_READ
+  UInt32 DictionarySize;
+  #endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+  CLzmaProperties Properties;
+  CProb *Probs;
+
+  #ifdef _LZMA_IN_CB
+  const unsigned char *Buffer;
+  const unsigned char *BufferLim;
+  #endif
+
+  #ifdef _LZMA_OUT_READ
+  unsigned char *Dictionary;
+  UInt32 Range;
+  UInt32 Code;
+  UInt32 DictionaryPos;
+  UInt32 GlobalPos;
+  UInt32 DistanceLimit;
+  UInt32 Reps[4];
+  int State;
+  int RemainLen;
+  unsigned char TempDictionary[4];
+  #endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/LzmaTypes.h b/package/uboot-ifxmips/files/lib_bootstrap/LzmaTypes.h
new file mode 100644 (file)
index 0000000..288c5e4
--- /dev/null
@@ -0,0 +1,45 @@
+/* 
+LzmaTypes.h 
+
+Types for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.40 (2006-05-01)
+*/
+
+#ifndef __LZMATYPES_H
+#define __LZMATYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif 
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif 
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif 
+
+/* #define _LZMA_SYSTEM_SIZE_T */
+/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_SYSTEM_SIZE_T
+#include <stddef.h>
+typedef size_t SizeT;
+#else
+typedef UInt32 SizeT;
+#endif
+#endif
+
+#endif
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/LzmaWrapper.c b/package/uboot-ifxmips/files/lib_bootstrap/LzmaWrapper.c
new file mode 100644 (file)
index 0000000..955b911
--- /dev/null
@@ -0,0 +1,223 @@
+/******************************************************************************
+**
+** FILE NAME    : LzmaWrapper.c
+** PROJECT      : bootloader
+** MODULES      : U-boot
+**
+** DATE         : 2 Nov 2006
+** AUTHOR       : Lin Mars
+** DESCRIPTION  : LZMA decoder support for U-boot 1.1.5
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author         $Comment
+** 2 Nov 2006   Lin Mars        init version which derived from LzmaTest.c from
+**                              LZMA v4.43 SDK
+*******************************************************************************/
+#define LZMA_NO_STDIO
+#ifndef LZMA_NO_STDIO
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include <config.h>
+#include <common.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <malloc.h>
+
+#ifdef CONFIG_LZMA
+
+#include "LzmaDecode.h"
+#include "LzmaWrapper.h"
+
+static const char *kCantReadMessage = "Can not read from source buffer";
+static const char *kCantAllocateMessage = "Not enough buffer for decompression";
+
+static size_t rpos=0, dpos=0;
+
+static int MyReadFileAndCheck(unsigned char *src, void *dest, size_t size)
+{
+  if (size == 0)
+    return 0;
+  memcpy(dest, src + rpos, size);
+  rpos += size;
+  return 1;
+}
+
+int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len)
+{
+  /* We use two 32-bit integers to construct 64-bit integer for file size.
+     You can remove outSizeHigh, if you don't need >= 4GB supporting,
+     or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+  UInt32 outSize = 0;
+  UInt32 outSizeHigh = 0;
+  SizeT outSizeFull;
+  unsigned char *outStream;
+  
+  int waitEOS = 1; 
+  /* waitEOS = 1, if there is no uncompressed size in headers, 
+   so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+  SizeT compressedSize;
+  unsigned char *inStream;
+
+  CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
+  unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+  int res;
+
+  if (sizeof(UInt32) < 4)
+  {
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+    printf("LZMA decoder needs correct UInt32\n");
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+
+  {
+    long length=s_len;
+    if ((long)(SizeT)length != length)
+    {
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+      printf("Too big compressed stream\n");
+#endif
+      return LZMA_RESULT_DATA_ERROR;
+    }
+    compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
+  }
+
+  /* Read LZMA properties for compressed stream */
+
+  if (!MyReadFileAndCheck(source, properties, sizeof(properties)))
+  {
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+    printf("%s\n", kCantReadMessage);
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+
+  /* Read uncompressed size */
+  {
+    int i;
+    for (i = 0; i < 8; i++)
+    {
+      unsigned char b;
+      if (!MyReadFileAndCheck(source, &b, 1))
+      {
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+        printf("%s\n", kCantReadMessage);
+#endif
+        return LZMA_RESULT_DATA_ERROR;
+      }
+      if (b != 0xFF)
+        waitEOS = 0;
+      if (i < 4)
+        outSize += (UInt32)(b) << (i * 8);
+      else
+        outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+    }
+    
+    if (waitEOS)
+    {
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+      printf("Stream with EOS marker is not supported");
+#endif
+      return LZMA_RESULT_DATA_ERROR;
+    }
+    outSizeFull = (SizeT)outSize;
+    if (sizeof(SizeT) >= 8)
+      outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
+    else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
+    {
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+      printf("Too big uncompressed stream");
+#endif
+      return LZMA_RESULT_DATA_ERROR;
+    }
+  }
+
+  /* Decode LZMA properties and allocate memory */
+  if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+  {
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+    printf("Incorrect stream properties");
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+  state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+
+  if (outSizeFull == 0)
+    outStream = 0;
+  else
+  {
+    if (outSizeFull > d_len)
+      outStream = 0;
+    else
+      outStream = dest;
+  }
+
+  if (compressedSize == 0)
+    inStream = 0;
+  else
+  {
+    if ((compressedSize+rpos) > s_len )
+      inStream = 0;
+    else
+      inStream = source + rpos;
+  }
+
+  if (state.Probs == 0 
+    || (outStream == 0 && outSizeFull != 0)
+    || (inStream == 0 && compressedSize != 0)
+    )
+  {
+    free(state.Probs);
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+    printf("%s\n", kCantAllocateMessage);
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+
+  /* Decompress */
+  {
+    SizeT inProcessed;
+    SizeT outProcessed;
+    res = LzmaDecode(&state,
+      inStream, compressedSize, &inProcessed,
+      outStream, outSizeFull, &outProcessed);
+    if (res != 0)
+    {
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+      printf("\nDecoding error = %d\n", res);
+#endif
+      res = 1;
+    }
+    else
+    {
+      *d_len = outProcessed;
+    }
+  }
+
+  free(state.Probs);
+  return res;
+}
+
+#endif /* CONFIG_LZMA */
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/Makefile b/package/uboot-ifxmips/files/lib_bootstrap/Makefile
new file mode 100644 (file)
index 0000000..e650be0
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    = libbootstrap.a
+
+#OBJS_PRINTF_ENABLED   = bootstrap_board.o time.o console.o LzmaWrapper.o LzmaDecode.o crc32.o ctype.o display_options.o string.o vsprintf.o lists.o devices.o
+#OBJS_PRINTF_DISBALED  = bootstrap_board.o LzmaDecode.o string.o crc32.o LzmaWrapper.o 
+
+OBJS   = bootstrap_board_$(BOARDDIR).o LzmaDecode.o string.o crc32.o LzmaWrapper.o 
+
+ifeq ($(BOOTSTRAP_PRINTF_STATUS), BOOTSTRAP_PRINTF_ENABLED)
+#overwrite objs
+OBJS   = bootstrap_board_$(BOARDDIR).o time.o console.o LzmaWrapper.o LzmaDecode.o crc32.o ctype.o display_options.o string.o vsprintf.o lists.o devices.o
+CFLAGS += -DDEBUG_ENABLE_BOOTSTRAP_PRINTF
+endif
+
+all:   .depend $(LIB)
+
+$(LIB):        $(OBJS)
+       $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend:       Makefile $(OBJS:.o=.c)
+               echo "make libbootstrap.a with HEAD_SIZE $(HEAD_SIZE)"
+               $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/bootstrap_board_danube.c b/package/uboot-ifxmips/files/lib_bootstrap/bootstrap_board_danube.c
new file mode 100644 (file)
index 0000000..22f0a5a
--- /dev/null
@@ -0,0 +1,501 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <devices.h>
+#include <version.h>
+#include <net.h>
+#include <environment.h>
+#ifdef CONFIG_DANUBE
+#include <asm-mips/danube.h>
+#include <configs/danube.h>
+#endif
+#include "LzmaWrapper.h"
+
+//#define DEBUG_ENABLE_BOOTSTRAP_PRINTF
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if ( ((CFG_ENV_ADDR+CFG_ENV_SIZE) < BOOTSTRAP_CFG_MONITOR_BASE) || \
+      (CFG_ENV_ADDR >= (BOOTSTRAP_CFG_MONITOR_BASE + CFG_MONITOR_LEN)) ) || \
+    defined(CFG_ENV_IS_IN_NVRAM)
+#define        TOTAL_MALLOC_LEN        (CFG_MALLOC_LEN + CFG_ENV_SIZE)
+#else
+#define        TOTAL_MALLOC_LEN        CFG_MALLOC_LEN
+#endif
+
+#undef DEBUG
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+extern unsigned long nand_init(void);
+#endif
+
+#ifdef CONFIG_SERIAL_FLASH
+extern int serial_flash_init (void);
+#endif
+
+extern int timer_init(void);
+
+extern int incaip_set_cpuclk(void);
+
+extern ulong uboot_end_data_bootstrap;
+extern ulong uboot_end_bootstrap;
+
+ulong monitor_flash_len;
+
+const char version_string[] =
+       U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")";
+
+static char *failed = "*** failed ***\n";
+
+/*
+ * Begin and End of memory area for malloc(), and current "brk"
+ */
+static ulong mem_malloc_start;
+static ulong mem_malloc_end;
+static ulong mem_malloc_brk;
+
+
+/*
+ * The Malloc area is immediately below the monitor copy in DRAM
+ */
+static void mem_malloc_init (ulong dest_addr)
+{
+//     ulong dest_addr = BOOTSTRAP_CFG_MONITOR_BASE + gd->reloc_off;
+
+       mem_malloc_end = dest_addr;
+       mem_malloc_start = dest_addr - TOTAL_MALLOC_LEN;
+       mem_malloc_brk = mem_malloc_start;
+
+       memset ((void *) mem_malloc_start,
+               0,
+               mem_malloc_end - mem_malloc_start);
+}
+
+void *malloc(unsigned int size)
+{
+       if(size < (mem_malloc_end - mem_malloc_start))
+       {
+               mem_malloc_start += size;
+               return (void *)(mem_malloc_start - size);
+       }
+       return NULL;
+}
+
+void *realloc(void *src,unsigned int size)
+{
+       return NULL;
+}
+
+void free(void *src)
+{
+       return;
+}
+
+
+void *sbrk (ptrdiff_t increment)
+{
+       ulong old = mem_malloc_brk;
+       ulong new = old + increment;
+
+       if ((new < mem_malloc_start) || (new > mem_malloc_end)) {
+               return (NULL);
+       }
+       mem_malloc_brk = new;
+       return ((void *) old);
+}
+
+
+static int init_func_ram (void)
+{
+#ifdef CONFIG_BOARD_TYPES
+       int board_type = gd->board_type;
+#else
+       int board_type = 0;     /* use dummy arg */
+#endif
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       puts ("DRAM:  ");
+#endif
+
+       if ((gd->ram_size = initdram (board_type)) > 0) {
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+               print_size (gd->ram_size, "\n");
+#endif
+               return (0);
+       }
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       puts (failed);
+#endif
+       return (1);
+}
+
+static int display_banner(void)
+{
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       printf ("\n\n%s\n\n", version_string);
+#endif
+       return (0);
+}
+
+static int init_baudrate (void)
+{
+#if 0
+       char tmp[64];   /* long enough for environment variables */
+       int i = getenv_r ("baudrate", tmp, sizeof (tmp));
+
+       gd->baudrate = (i > 0)
+                       ? (int) simple_strtoul (tmp, NULL, 10)
+                       : CONFIG_BAUDRATE;
+#endif
+
+       gd->baudrate = CONFIG_BAUDRATE;
+
+       return (0);
+}
+#ifdef CONFIG_DANUBE
+static void init_led(void)
+{
+
+  *(unsigned long *)0xBE100B18 |=  0x70;
+  *(unsigned long *)0xBE100B1C |=  0x70;
+  *(unsigned long *)0xBE100B20 &= ~0x70;
+  *(unsigned long *)0xBE100B24 |=  0x70;
+#ifdef USE_REFERENCE_BOARD
+
+  *DANUBE_LED_CON1 = 0x00000003;
+  *DANUBE_LED_CPU0 = 0x0000010;
+  *DANUBE_LED_CPU1 = 0x00000000;
+  *DANUBE_LED_AR   = 0x00000000;
+  *DANUBE_LED_CON0 = 0x84000000;
+
+#else
+
+  *DANUBE_LED_CON1 = 0x00000007;
+  *DANUBE_LED_CPU0 = 0x00001000;
+  *DANUBE_LED_CPU1 = 0x00000000;
+  *DANUBE_LED_AR   = 0x00000000;
+  *DANUBE_LED_CON0 = 0x84000000;
+
+#endif
+
+}
+#endif
+/*
+ * Breath some life into the board...
+ *
+ * The first part of initialization is running from Flash memory;
+ * its main purpose is to initialize the RAM so that we
+ * can relocate the monitor code to RAM.
+ */
+
+/*
+ * All attempts to come up with a "common" initialization sequence
+ * that works for all boards and architectures failed: some of the
+ * requirements are just _too_ different. To get rid of the resulting
+ * mess of board dependend #ifdef'ed code we now make the whole
+ * initialization sequence configurable to the user.
+ *
+ * The requirements for any new initalization function is simple: it
+ * receives a pointer to the "global data" structure as it's only
+ * argument, and returns an integer return code, where 0 means
+ * "continue" and != 0 means "fatal error, hang the system".
+ */
+typedef int (init_fnc_t) (void);
+
+init_fnc_t *init_sequence[] = {
+       //timer_init,
+       //env_init,             /* initialize environment */
+#ifdef CONFIG_INCA_IP
+       incaip_set_cpuclk,      /* set cpu clock according to environment variable */
+#endif
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       init_baudrate,          /* initialze baudrate settings */
+       serial_init,            /* serial communications setup */
+       console_init_f,
+       display_banner,         /* say that we are here */
+#endif
+       init_func_ram,
+       //checkboard,
+       NULL,
+};
+
+
+void bootstrap_board_init_f(ulong bootflag)
+{
+       gd_t gd_data, *id;
+       bd_t *bd;
+       init_fnc_t **init_fnc_ptr;
+       ulong addr, addr_sp, len = (ulong)&uboot_end_bootstrap - BOOTSTRAP_CFG_MONITOR_BASE;
+       ulong *s;
+       ulong lzmaImageaddr  = 0;
+#ifdef CONFIG_PURPLE
+       void copy_code (ulong);
+#endif
+
+       /* Pointer is writable since we allocated a register for it.
+        */
+       gd = &gd_data;
+       /* compiler optimization barrier needed for GCC >= 3.4 */
+       __asm__ __volatile__("": : :"memory");
+
+       memset ((void *)gd, 0, sizeof (gd_t));
+
+       for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+               if ((*init_fnc_ptr)() != 0) {
+                       hang ();
+               }
+       }
+
+       /*
+        * Now that we have DRAM mapped and working, we can
+        * relocate the code and continue running from DRAM.
+        */
+       addr = CFG_SDRAM_BASE + gd->ram_size;
+
+       /* We can reserve some RAM "on top" here.
+        */
+
+       /* round down to next 4 kB limit.
+        */
+       addr &= ~(4096 - 1);
+       debug ("Top of RAM usable for U-Boot at: %08lx\n", addr);
+
+       /* Reserve memory for U-Boot code, data & bss
+        * round down to next 16 kB limit
+        */
+       addr -= len;
+       addr &= ~(16 * 1024 - 1);
+
+       debug ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
+
+        /* Reserve memory for malloc() arena.
+        */
+       addr_sp = addr - TOTAL_MALLOC_LEN;
+       debug ("Reserving %dk for malloc() at: %08lx\n",
+                       TOTAL_MALLOC_LEN >> 10, addr_sp);
+
+       /*
+        * (permanently) allocate a Board Info struct
+        * and a permanent copy of the "global" data
+        */
+       addr_sp -= sizeof(bd_t);
+       bd = (bd_t *)addr_sp;
+       gd->bd = bd;
+       debug ("Reserving %d Bytes for Board Info at: %08lx\n",
+                       sizeof(bd_t), addr_sp);
+
+       addr_sp -= sizeof(gd_t);
+       id = (gd_t *)addr_sp;
+       debug ("Reserving %d Bytes for Global Data at: %08lx\n",
+                       sizeof (gd_t), addr_sp);
+
+       /* Reserve memory for boot params.
+        */
+       addr_sp -= CFG_BOOTPARAMS_LEN;
+       bd->bi_boot_params = addr_sp;
+       debug ("Reserving %dk for boot params() at: %08lx\n",
+                       CFG_BOOTPARAMS_LEN >> 10, addr_sp);
+
+       /*
+        * Finally, we set up a new (bigger) stack.
+        *
+        * Leave some safety gap for SP, force alignment on 16 byte boundary
+        * Clear initial stack frame
+        */
+       addr_sp -= 16;
+       addr_sp &= ~0xF;
+       s = (ulong *)addr_sp;
+       *s-- = 0;
+       *s-- = 0;
+       addr_sp = (ulong)s;
+       debug ("Stack Pointer at: %08lx\n", addr_sp);
+
+       /*
+        * Save local variables to board info struct
+        */
+       bd->bi_memstart = CFG_SDRAM_BASE;       /* start of  DRAM memory */
+       bd->bi_memsize  = gd->ram_size;         /* size  of  DRAM memory in bytes */
+       bd->bi_baudrate = gd->baudrate;         /* Console Baudrate */
+
+       memcpy (id, (void *)gd, sizeof (gd_t));
+
+       /* On the purple board we copy the code in a special way
+        * in order to solve flash problems
+        */
+#ifdef CONFIG_PURPLE
+       copy_code(addr);
+#endif
+
+       lzmaImageaddr = (ulong)&uboot_end_data_bootstrap;
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       printf ("\n relocating to address %08x ", addr);
+#endif
+
+       bootstrap_relocate_code (addr_sp, id, addr);
+
+       /* NOTREACHED - relocate_code() does not return */
+}
+/************************************************************************
+ *
+ * This is the next part if the initialization sequence: we are now
+ * running from RAM and have a "normal" C environment, i. e. global
+ * data can be written, BSS has been cleared, the stack size in not
+ * that critical any more, etc.
+ *
+ ************************************************************************
+ */
+#define CONFIG_LZMA 
+
+void bootstrap_board_init_r (gd_t *id, ulong dest_addr)
+{
+       int i;
+
+       ulong   addr;
+       ulong   data, len, checksum;
+       ulong  *len_ptr;
+       image_header_t header;
+       image_header_t *hdr = &header;
+       unsigned int destLen;
+       int (*fn)();
+
+#if 1
+#endif
+
+
+
+       /* initialize malloc() area */
+       mem_malloc_init(dest_addr);
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       printf("\n Compressed Image at %08x \n ", (BOOTSTRAP_CFG_MONITOR_BASE + ((ulong)&uboot_end_data_bootstrap - dest_addr)));
+#endif
+       
+       addr = (char *)(BOOTSTRAP_CFG_MONITOR_BASE + ((ulong)&uboot_end_data_bootstrap - dest_addr));
+       memmove (&header, (char *)addr, sizeof(image_header_t));
+
+       if (ntohl(hdr->ih_magic) != IH_MAGIC) {
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+               printf ("Bad Magic Number at address 0x%08lx\n",addr);
+#endif
+               return;
+       }
+
+       data = (ulong)&header;
+       len  = sizeof(image_header_t);
+
+       checksum = ntohl(hdr->ih_hcrc);
+       hdr->ih_hcrc = 0;
+       if (crc32 (0, (char *)data, len) != checksum) {
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+               printf ("Bad Header Checksum\n");
+#endif
+               return;
+       }
+       
+       data = addr + sizeof(image_header_t);
+       len  = ntohl(hdr->ih_size);
+
+       len_ptr = (ulong *)data;
+
+    
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       printf ("Disabling all the interrupts\n");
+#endif
+       disable_interrupts();
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       printf ("   Uncompressing UBoot Image ... \n" );
+#endif
+
+       /*
+        * If we've got less than 4 MB of malloc() space,
+        * use slower decompression algorithm which requires
+        * at most 2300 KB of memory.
+        */
+       destLen = 0x0;
+
+#ifdef CONFIG_BZIP2
+       i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
+                                       0x400000, (char *)data, len,
+                                       CFG_MALLOC_LEN < (4096 * 1024), 0);
+       if (i != BZ_OK) {
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+                       printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i);
+#endif
+                       return;
+       }
+#endif /* CONFIG_BZIP2 */
+       
+#ifdef CONFIG_MICROBZIP2 
+       i = micro_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
+                                       &destLen, (char *)data, len,
+                                       CFG_MALLOC_LEN < (4096 * 1024), 0);
+       if (i != RETVAL_OK) {
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+               printf ("MICRO_BUNZIP2 ERROR %d - must RESET board to recover\n", i);
+#endif
+               //do_reset (cmdtp, flag, argc, argv);
+               return;
+       }
+#endif
+       
+#ifdef CONFIG_LZMA 
+#if 0
+       i = lzmaBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
+                                       &destLen, (char *)data, len);
+#endif
+
+       i = lzma_inflate ((unsigned char *)data, len, (unsigned char*)ntohl(hdr->ih_load), &destLen);
+       if (i != LZMA_RESULT_OK) {
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+               printf ("LZMA ERROR %d - must RESET board to recover\n", i);
+#endif
+               //do_reset (cmdtp, flag, argc, argv);
+               return;
+       }
+#endif
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       printf ("   Uncompression completed successfully with destLen %d\n ",destLen );
+#endif
+
+    fn = ntohl(hdr->ih_load);
+
+       (*fn)();
+
+       hang ();
+
+}
+
+void hang (void)
+{
+
+#ifdef DEBUG_ENABLE_BOOTSTRAP_PRINTF
+       puts ("### ERROR ### Please RESET the board ###\n");
+#endif
+       for (;;);
+}
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/console.c b/package/uboot-ifxmips/files/lib_bootstrap/console.c
new file mode 100644 (file)
index 0000000..a8fcd2a
--- /dev/null
@@ -0,0 +1,573 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
+ *
+ * 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 <stdarg.h>
+#include <malloc.h>
+#include <console.h>
+#include <exports.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_AMIGAONEG3SE
+int console_changed = 0;
+#endif
+
+#ifdef CFG_CONSOLE_IS_IN_ENV
+/*
+ * if overwrite_console returns 1, the stdin, stderr and stdout
+ * are switched to the serial port, else the settings in the
+ * environment are used
+ */
+#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE
+extern int overwrite_console (void);
+#define OVERWRITE_CONSOLE overwrite_console ()
+#else
+#define OVERWRITE_CONSOLE 0
+#endif /* CFG_CONSOLE_OVERWRITE_ROUTINE */
+
+#endif /* CFG_CONSOLE_IS_IN_ENV */
+
+static int console_setfile (int file, device_t * dev)
+{
+       int error = 0;
+
+       if (dev == NULL)
+               return -1;
+
+       switch (file) {
+       case stdin:
+       case stdout:
+       case stderr:
+               /* Start new device */
+               if (dev->start) {
+                       error = dev->start ();
+                       /* If it's not started dont use it */
+                       if (error < 0)
+                               break;
+               }
+
+               /* Assign the new device (leaving the existing one started) */
+               stdio_devices[file] = dev;
+
+               /*
+                * Update monitor functions
+                * (to use the console stuff by other applications)
+                */
+               switch (file) {
+               case stdin:
+                       gd->jt[XF_getc] = dev->getc;
+                       gd->jt[XF_tstc] = dev->tstc;
+                       break;
+               case stdout:
+                       gd->jt[XF_putc] = dev->putc;
+                       gd->jt[XF_puts] = dev->puts;
+                       gd->jt[XF_printf] = printf;
+                       break;
+               }
+               break;
+
+       default:                /* Invalid file ID */
+               error = -1;
+       }
+       return error;
+}
+
+/** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
+
+void serial_printf (const char *fmt, ...)
+{
+       va_list args;
+       uint i;
+       char printbuffer[CFG_PBSIZE];
+
+       va_start (args, fmt);
+
+       /* For this to work, printbuffer must be larger than
+        * anything we ever want to print.
+        */
+       i = vsprintf (printbuffer, fmt, args);
+       va_end (args);
+
+       serial_puts (printbuffer);
+}
+
+int fgetc (int file)
+{
+       if (file < MAX_FILES)
+               return stdio_devices[file]->getc ();
+
+       return -1;
+}
+
+int ftstc (int file)
+{
+       if (file < MAX_FILES)
+               return stdio_devices[file]->tstc ();
+
+       return -1;
+}
+
+void fputc (int file, const char c)
+{
+       if (file < MAX_FILES)
+               stdio_devices[file]->putc (c);
+}
+
+void fputs (int file, const char *s)
+{
+       if (file < MAX_FILES)
+               stdio_devices[file]->puts (s);
+}
+
+void fprintf (int file, const char *fmt, ...)
+{
+       va_list args;
+       uint i;
+       char printbuffer[CFG_PBSIZE];
+
+       va_start (args, fmt);
+
+       /* For this to work, printbuffer must be larger than
+        * anything we ever want to print.
+        */
+       i = vsprintf (printbuffer, fmt, args);
+       va_end (args);
+
+       /* Send to desired file */
+       fputs (file, printbuffer);
+}
+
+/** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
+
+int getc (void)
+{
+       if (gd->flags & GD_FLG_DEVINIT) {
+               /* Get from the standard input */
+               return fgetc (stdin);
+       }
+
+       /* Send directly to the handler */
+       return serial_getc ();
+}
+
+int tstc (void)
+{
+       if (gd->flags & GD_FLG_DEVINIT) {
+               /* Test the standard input */
+               return ftstc (stdin);
+       }
+
+       /* Send directly to the handler */
+       return serial_tstc ();
+}
+
+void putc (const char c)
+{
+#ifdef CONFIG_SILENT_CONSOLE
+       if (gd->flags & GD_FLG_SILENT)
+               return;
+#endif
+
+       if (gd->flags & GD_FLG_DEVINIT) {
+               /* Send to the standard output */
+               fputc (stdout, c);
+       } else {
+               /* Send directly to the handler */
+               serial_putc (c);
+       }
+}
+
+void puts (const char *s)
+{
+#ifdef CONFIG_SILENT_CONSOLE
+       if (gd->flags & GD_FLG_SILENT)
+               return;
+#endif
+
+       if (gd->flags & GD_FLG_DEVINIT) {
+               /* Send to the standard output */
+               fputs (stdout, s);
+       } else {
+               /* Send directly to the handler */
+               serial_puts (s);
+       }
+}
+
+void printf (const char *fmt, ...)
+{
+       va_list args;
+       uint i;
+       char printbuffer[CFG_PBSIZE];
+
+       va_start (args, fmt);
+
+       /* For this to work, printbuffer must be larger than
+        * anything we ever want to print.
+        */
+       i = vsprintf (printbuffer, fmt, args);
+       va_end (args);
+
+       /* Print the string */
+       puts (printbuffer);
+}
+
+void vprintf (const char *fmt, va_list args)
+{
+       uint i;
+       char printbuffer[CFG_PBSIZE];
+
+       /* For this to work, printbuffer must be larger than
+        * anything we ever want to print.
+        */
+       i = vsprintf (printbuffer, fmt, args);
+
+       /* Print the string */
+       puts (printbuffer);
+}
+
+/* test if ctrl-c was pressed */
+static int ctrlc_disabled = 0; /* see disable_ctrl() */
+static int ctrlc_was_pressed = 0;
+int ctrlc (void)
+{
+       if (!ctrlc_disabled && gd->have_console) {
+               if (tstc ()) {
+                       switch (getc ()) {
+                       case 0x03:              /* ^C - Control C */
+                               ctrlc_was_pressed = 1;
+                               return 1;
+                       default:
+                               break;
+                       }
+               }
+       }
+       return 0;
+}
+
+/* pass 1 to disable ctrlc() checking, 0 to enable.
+ * returns previous state
+ */
+int disable_ctrlc (int disable)
+{
+       int prev = ctrlc_disabled;      /* save previous state */
+
+       ctrlc_disabled = disable;
+       return prev;
+}
+
+int had_ctrlc (void)
+{
+       return ctrlc_was_pressed;
+}
+
+void clear_ctrlc (void)
+{
+       ctrlc_was_pressed = 0;
+}
+
+#ifdef CONFIG_MODEM_SUPPORT_DEBUG
+char   screen[1024];
+char *cursor = screen;
+int once = 0;
+inline void dbg(const char *fmt, ...)
+{
+       va_list args;
+       uint    i;
+       char    printbuffer[CFG_PBSIZE];
+
+       if (!once) {
+               memset(screen, 0, sizeof(screen));
+               once++;
+       }
+
+       va_start(args, fmt);
+
+       /* For this to work, printbuffer must be larger than
+        * anything we ever want to print.
+        */
+       i = vsprintf(printbuffer, fmt, args);
+       va_end(args);
+
+       if ((screen + sizeof(screen) - 1 - cursor) < strlen(printbuffer)+1) {
+               memset(screen, 0, sizeof(screen));
+               cursor = screen;
+       }
+       sprintf(cursor, printbuffer);
+       cursor += strlen(printbuffer);
+
+}
+#else
+inline void dbg(const char *fmt, ...)
+{
+}
+#endif
+
+/** U-Boot INIT FUNCTIONS *************************************************/
+
+int console_assign (int file, char *devname)
+{
+       int flag, i;
+
+       /* Check for valid file */
+       switch (file) {
+       case stdin:
+               flag = DEV_FLAGS_INPUT;
+               break;
+       case stdout:
+       case stderr:
+               flag = DEV_FLAGS_OUTPUT;
+               break;
+       default:
+               return -1;
+       }
+
+       /* Check for valid device name */
+
+       for (i = 1; i <= ListNumItems (devlist); i++) {
+               device_t *dev = ListGetPtrToItem (devlist, i);
+
+               if (strcmp (devname, dev->name) == 0) {
+                       if (dev->flags & flag)
+                               return console_setfile (file, dev);
+
+                       return -1;
+               }
+       }
+
+       return -1;
+}
+
+/* Called before relocation - use serial functions */
+int console_init_f (void)
+{
+       gd->have_console = 1;
+
+#ifdef CONFIG_SILENT_CONSOLE
+       if (getenv("silent") != NULL)
+               gd->flags |= GD_FLG_SILENT;
+#endif
+
+       return (0);
+}
+
+#if defined(CFG_CONSOLE_IS_IN_ENV) || defined(CONFIG_SPLASH_SCREEN) || defined(CONFIG_SILENT_CONSOLE)
+/* search a device */
+device_t *search_device (int flags, char *name)
+{
+       int i, items;
+       device_t *dev = NULL;
+
+       items = ListNumItems (devlist);
+       if (name == NULL)
+               return dev;
+
+       for (i = 1; i <= items; i++) {
+               dev = ListGetPtrToItem (devlist, i);
+               if ((dev->flags & flags) && (strcmp (name, dev->name) == 0)) {
+                       break;
+               }
+       }
+       return dev;
+}
+#endif /* CFG_CONSOLE_IS_IN_ENV || CONFIG_SPLASH_SCREEN */
+
+#ifdef CFG_CONSOLE_IS_IN_ENV
+/* Called after the relocation - use desired console functions */
+int console_init_r (void)
+{
+       char *stdinname, *stdoutname, *stderrname;
+       device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
+#ifdef CFG_CONSOLE_ENV_OVERWRITE
+       int i;
+#endif /* CFG_CONSOLE_ENV_OVERWRITE */
+
+       /* set default handlers at first */
+       gd->jt[XF_getc] = serial_getc;
+       gd->jt[XF_tstc] = serial_tstc;
+       gd->jt[XF_putc] = serial_putc;
+       gd->jt[XF_puts] = serial_puts;
+       gd->jt[XF_printf] = serial_printf;
+
+       /* stdin stdout and stderr are in environment */
+       /* scan for it */
+       stdinname  = getenv ("stdin");
+       stdoutname = getenv ("stdout");
+       stderrname = getenv ("stderr");
+
+       if (OVERWRITE_CONSOLE == 0) {   /* if not overwritten by config switch */
+               inputdev  = search_device (DEV_FLAGS_INPUT,  stdinname);
+               outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname);
+               errdev    = search_device (DEV_FLAGS_OUTPUT, stderrname);
+       }
+       /* if the devices are overwritten or not found, use default device */
+       if (inputdev == NULL) {
+               inputdev  = search_device (DEV_FLAGS_INPUT,  "serial");
+       }
+       if (outputdev == NULL) {
+               outputdev = search_device (DEV_FLAGS_OUTPUT, "serial");
+       }
+       if (errdev == NULL) {
+               errdev    = search_device (DEV_FLAGS_OUTPUT, "serial");
+       }
+       /* Initializes output console first */
+       if (outputdev != NULL) {
+               console_setfile (stdout, outputdev);
+       }
+       if (errdev != NULL) {
+               console_setfile (stderr, errdev);
+       }
+       if (inputdev != NULL) {
+               console_setfile (stdin, inputdev);
+       }
+
+       gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
+
+#ifndef CFG_CONSOLE_INFO_QUIET
+       /* Print information */
+       puts ("In:    ");
+       if (stdio_devices[stdin] == NULL) {
+               puts ("No input devices available!\n");
+       } else {
+               printf ("%s\n", stdio_devices[stdin]->name);
+       }
+
+       puts ("Out:   ");
+       if (stdio_devices[stdout] == NULL) {
+               puts ("No output devices available!\n");
+       } else {
+               printf ("%s\n", stdio_devices[stdout]->name);
+       }
+
+       puts ("Err:   ");
+       if (stdio_devices[stderr] == NULL) {
+               puts ("No error devices available!\n");
+       } else {
+               printf ("%s\n", stdio_devices[stderr]->name);
+       }
+#endif /* CFG_CONSOLE_INFO_QUIET */
+
+#ifdef CFG_CONSOLE_ENV_OVERWRITE
+       /* set the environment variables (will overwrite previous env settings) */
+       for (i = 0; i < 3; i++) {
+               setenv (stdio_names[i], stdio_devices[i]->name);
+       }
+#endif /* CFG_CONSOLE_ENV_OVERWRITE */
+
+#if 0
+       /* If nothing usable installed, use only the initial console */
+       if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
+               return (0);
+#endif
+       return (0);
+}
+
+#else /* CFG_CONSOLE_IS_IN_ENV */
+#if 0
+/* Called after the relocation - use desired console functions */
+int console_init_r (void)
+{
+       device_t *inputdev = NULL, *outputdev = NULL;
+       int i, items = ListNumItems (devlist);
+
+#ifdef CONFIG_SPLASH_SCREEN
+       /* suppress all output if splash screen is enabled and we have
+          a bmp to display                                            */
+       if (getenv("splashimage") != NULL)
+               outputdev = search_device (DEV_FLAGS_OUTPUT, "nulldev");
+#endif
+
+#ifdef CONFIG_SILENT_CONSOLE
+       /* Suppress all output if "silent" mode requested               */
+       if (gd->flags & GD_FLG_SILENT)
+               outputdev = search_device (DEV_FLAGS_OUTPUT, "nulldev");
+#endif
+
+       /* Scan devices looking for input and output devices */
+       for (i = 1;
+            (i <= items) && ((inputdev == NULL) || (outputdev == NULL));
+            i++
+           ) {
+               device_t *dev = ListGetPtrToItem (devlist, i);
+
+               if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
+                       inputdev = dev;
+               }
+               if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
+                       outputdev = dev;
+               }
+       }
+
+       /* Initializes output console first */
+       if (outputdev != NULL) {
+               console_setfile (stdout, outputdev);
+               console_setfile (stderr, outputdev);
+       }
+
+       /* Initializes input console */
+       if (inputdev != NULL) {
+               console_setfile (stdin, inputdev);
+       }
+
+       gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */
+
+#ifndef CFG_CONSOLE_INFO_QUIET
+       /* Print information */
+       puts ("In:    ");
+       if (stdio_devices[stdin] == NULL) {
+               puts ("No input devices available!\n");
+       } else {
+               printf ("%s\n", stdio_devices[stdin]->name);
+       }
+
+       puts ("Out:   ");
+       if (stdio_devices[stdout] == NULL) {
+               puts ("No output devices available!\n");
+       } else {
+               printf ("%s\n", stdio_devices[stdout]->name);
+       }
+
+       puts ("Err:   ");
+       if (stdio_devices[stderr] == NULL) {
+               puts ("No error devices available!\n");
+       } else {
+               printf ("%s\n", stdio_devices[stderr]->name);
+       }
+#endif /* CFG_CONSOLE_INFO_QUIET */
+
+       /* Setting environment variables */
+       for (i = 0; i < 3; i++) {
+               setenv (stdio_names[i], stdio_devices[i]->name);
+       }
+
+#if 0
+       /* If nothing usable installed, use only the initial console */
+       if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
+               return (0);
+#endif
+
+       return (0);
+}
+#endif
+
+#endif /* CFG_CONSOLE_IS_IN_ENV */
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/crc32.c b/package/uboot-ifxmips/files/lib_bootstrap/crc32.c
new file mode 100644 (file)
index 0000000..50ca4ff
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * This file is derived from crc32.c from the zlib-1.1.3 distribution
+ * by Jean-loup Gailly and Mark Adler.
+ */
+
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifndef USE_HOSTCC     /* Shut down "ANSI does not permit..." warnings */
+#include <common.h>    /* to get command definitions like CFG_CMD_JFFS2 */
+#endif
+
+#include "zlib.h"
+
+#define local static
+#define ZEXPORT        /* empty */
+unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local int crc_table_empty = 1;
+local uLongf crc_table[256];
+local void make_crc_table OF((void));
+
+/*
+  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The table is simply the CRC of all possible eight bit values.  This is all
+  the information needed to generate CRC's on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.
+*/
+local void make_crc_table()
+{
+  uLong c;
+  int n, k;
+  uLong poly;            /* polynomial exclusive-or pattern */
+  /* terms of polynomial defining this crc (except x^32): */
+  static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+  /* make exclusive-or pattern from polynomial (0xedb88320L) */
+  poly = 0L;
+  for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
+    poly |= 1L << (31 - p[n]);
+
+  for (n = 0; n < 256; n++)
+  {
+    c = (uLong)n;
+    for (k = 0; k < 8; k++)
+      c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+    crc_table[n] = c;
+  }
+  crc_table_empty = 0;
+}
+#else
+/* ========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+local const uLongf crc_table[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
+};
+#endif
+
+#if 0
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const uLongf * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+  if (crc_table_empty) make_crc_table();
+#endif
+  return (const uLongf *)crc_table;
+}
+#endif
+
+/* ========================================================================= */
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+/* ========================================================================= */
+uLong ZEXPORT crc32(crc, buf, len)
+    uLong crc;
+    const Bytef *buf;
+    uInt len;
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+      make_crc_table();
+#endif
+    crc = crc ^ 0xffffffffL;
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+    return crc ^ 0xffffffffL;
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
+
+/* No ones complement version. JFFS2 (and other things ?)
+ * don't use ones compliment in their CRC calculations.
+ */
+uLong ZEXPORT crc32_no_comp(uLong crc, const Bytef *buf, uInt len)
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+      make_crc_table();
+#endif
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+
+    return crc;
+}
+
+#endif /* CFG_CMD_JFFS2 */
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/ctype.c b/package/uboot-ifxmips/files/lib_bootstrap/ctype.c
new file mode 100644 (file)
index 0000000..6ed0468
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2000
+ * 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
+ */
+
+/*
+ *  linux/lib/ctype.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#include <linux/ctype.h>
+
+unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C,                       /* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,                /* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C,                       /* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C,                       /* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,                   /* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P,                       /* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D,                       /* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P,                       /* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,     /* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U,                       /* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U,                       /* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P,                       /* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,     /* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L,                       /* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L,                       /* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C,                       /* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,               /* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,               /* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/devices.c b/package/uboot-ifxmips/files/lib_bootstrap/devices.c
new file mode 100644 (file)
index 0000000..ddf8f8e
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
+ *
+ * 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 <stdarg.h>
+#include <malloc.h>
+#include <devices.h>
+#include <serial.h>
+#ifdef CONFIG_LOGBUFFER
+#include <logbuff.h>
+#endif
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#include <i2c.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+list_t devlist = 0;
+device_t *stdio_devices[] = { NULL, NULL, NULL };
+char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
+
+#if defined(CONFIG_SPLASH_SCREEN) && !defined(CFG_DEVICE_NULLDEV)
+#define        CFG_DEVICE_NULLDEV      1
+#endif
+
+
+#ifdef CFG_DEVICE_NULLDEV
+void nulldev_putc(const char c)
+{
+  /* nulldev is empty! */
+}
+
+void nulldev_puts(const char *s)
+{
+  /* nulldev is empty! */
+}
+
+int nulldev_input(void)
+{
+  /* nulldev is empty! */
+  return 0;
+}
+#endif
+
+/**************************************************************************
+ * SYSTEM DRIVERS
+ **************************************************************************
+ */
+
+static void drv_system_init (void)
+{
+       device_t dev;
+
+       memset (&dev, 0, sizeof (dev));
+
+       strcpy (dev.name, "serial");
+       dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
+       dev.putc = serial_buffered_putc;
+       dev.puts = serial_buffered_puts;
+       dev.getc = serial_buffered_getc;
+       dev.tstc = serial_buffered_tstc;
+#else
+       dev.putc = serial_putc;
+       dev.puts = serial_puts;
+       dev.getc = serial_getc;
+       dev.tstc = serial_tstc;
+#endif
+
+       device_register (&dev);
+
+#ifdef CFG_DEVICE_NULLDEV
+       memset (&dev, 0, sizeof (dev));
+
+       strcpy (dev.name, "nulldev");
+       dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+       dev.putc = nulldev_putc;
+       dev.puts = nulldev_puts;
+       dev.getc = nulldev_input;
+       dev.tstc = nulldev_input;
+
+       device_register (&dev);
+#endif
+}
+
+/**************************************************************************
+ * DEVICES
+ **************************************************************************
+ */
+
+int device_register (device_t * dev)
+{
+       ListInsertItem (devlist, dev, LIST_END);
+       return 0;
+}
+
+/* deregister the device "devname".
+ * returns 0 if success, -1 if device is assigned and 1 if devname not found
+ */
+#ifdef CFG_DEVICE_DEREGISTER
+int device_deregister(char *devname)
+{
+       int i,l,dev_index;
+       device_t *dev = NULL;
+       char temp_names[3][8];
+
+       dev_index=-1;
+       for (i=1; i<=ListNumItems(devlist); i++) {
+               dev = ListGetPtrToItem (devlist, i);
+               if(strcmp(dev->name,devname)==0) {
+                       dev_index=i;
+                       break;
+               }
+       }
+       if(dev_index<0) /* device not found */
+               return 0;
+       /* get stdio devices (ListRemoveItem changes the dev list) */
+       for (l=0 ; l< MAX_FILES; l++) {
+               if (stdio_devices[l] == dev) {
+                       /* Device is assigned -> report error */
+                       return -1;
+               }
+               memcpy (&temp_names[l][0],
+                       stdio_devices[l]->name,
+                       sizeof(stdio_devices[l]->name));
+       }
+       ListRemoveItem(devlist,NULL,dev_index);
+       /* reassign Device list */
+       for (i=1; i<=ListNumItems(devlist); i++) {
+               dev = ListGetPtrToItem (devlist, i);
+               for (l=0 ; l< MAX_FILES; l++) {
+                       if(strcmp(dev->name,temp_names[l])==0) {
+                               stdio_devices[l] = dev;
+                       }
+               }
+       }
+       return 0;
+}
+#endif /* CFG_DEVICE_DEREGISTER */
+
+int devices_init (void)
+{
+#ifndef CONFIG_ARM     /* already relocated for current ARM implementation */
+       ulong relocation_offset = gd->reloc_off;
+       int i;
+
+       /* relocate device name pointers */
+       for (i = 0; i < (sizeof (stdio_names) / sizeof (char *)); ++i) {
+               stdio_names[i] = (char *) (((ulong) stdio_names[i]) +
+                                               relocation_offset);
+       }
+#endif
+
+       /* Initialize the list */
+       devlist = ListCreate (sizeof (device_t));
+
+       if (devlist == NULL) {
+               eputs ("Cannot initialize the list of devices!\n");
+               return -1;
+       }
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+#endif
+#ifdef CONFIG_LCD
+       drv_lcd_init ();
+#endif
+#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
+       drv_video_init ();
+#endif
+#ifdef CONFIG_KEYBOARD
+       drv_keyboard_init ();
+#endif
+#ifdef CONFIG_LOGBUFFER
+       drv_logbuff_init ();
+#endif
+       drv_system_init ();
+#ifdef CONFIG_SERIAL_MULTI
+       serial_devices_init ();
+#endif
+#ifdef CONFIG_USB_TTY
+       drv_usbtty_init ();
+#endif
+#ifdef CONFIG_NETCONSOLE
+       drv_nc_init ();
+#endif
+
+       return (0);
+}
+
+int devices_done (void)
+{
+       ListDispose (devlist);
+
+       return 0;
+}
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/display_options.c b/package/uboot-ifxmips/files/lib_bootstrap/display_options.c
new file mode 100644 (file)
index 0000000..512e898
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * (C) Copyright 2000-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 <common.h>
+
+int display_options (void)
+{
+       extern char version_string[];
+
+#if defined(BUILD_TAG)
+       printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
+#else
+       printf ("\n\n%s\n\n", version_string);
+#endif
+       return 0;
+}
+
+/*
+ * print sizes as "xxx kB", "xxx.y kB", "xxx MB" or "xxx.y MB" as needed;
+ * allow for optional trailing string (like "\n")
+ */
+void print_size (ulong size, const char *s)
+{
+       ulong m, n;
+       ulong d = 1 << 20;              /* 1 MB */
+       char  c = 'M';
+
+       if (size < d) {                 /* print in kB */
+               c = 'k';
+               d = 1 << 10;
+       }
+
+       n = size / d;
+
+       m = (10 * (size - (n * d)) + (d / 2) ) / d;
+
+       if (m >= 10) {
+               m -= 10;
+               n += 1;
+       }
+
+       printf ("%2ld", n);
+       if (m) {
+               printf (".%ld", m);
+       }
+       printf (" %cB%s", c, s);
+}
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/lists.c b/package/uboot-ifxmips/files/lib_bootstrap/lists.c
new file mode 100644 (file)
index 0000000..3f117b5
--- /dev/null
@@ -0,0 +1,734 @@
+#include <common.h>
+#include <malloc.h>
+#include <lists.h>
+
+#define MAX(a,b)       (((a)>(b)) ? (a) : (b))
+#define MIN(a,b)       (((a)<(b)) ? (a) : (b))
+#define CAT4CHARS(a,b,c,d)     ((a<<24) | (b<<16) | (c<<8) | d)
+
+/* increase list size by 10% every time it is full */
+#define kDefaultAllocationPercentIncrease      10
+
+/* always increase list size by 4 items when it is full */
+#define kDefaultAllocationminNumItemsIncrease  4
+
+/*
+ * how many items to expand the list by when it becomes full
+ * = current listSize (in items) + (hiword percent of list size) + loword
+ */
+#define NUMITEMSPERALLOC(list) MAX(((*list)->listSize * \
+                                   ((*list)->percentIncrease + 100)) / 100, \
+                                   (*list)->minNumItemsIncrease )
+
+#define ITEMPTR(list,item)     &(((char *)&(*list)->itemList)[(*(list))->itemSize * (item)])
+
+#define LIST_SIGNATURE         CAT4CHARS('L', 'I', 'S', 'T');
+
+#define calloc(size,num)       malloc(size*num)
+
+/********************************************************************/
+
+Handle NewHandle (unsigned int numBytes)
+{
+       void *memPtr;
+       HandleRecord *hanPtr;
+
+       memPtr = calloc (numBytes, 1);
+       hanPtr = (HandleRecord *) calloc (sizeof (HandleRecord), 1);
+       if (hanPtr && (memPtr || numBytes == 0)) {
+               hanPtr->ptr = memPtr;
+               hanPtr->size = numBytes;
+               return (Handle) hanPtr;
+       } else {
+               free (memPtr);
+               free (hanPtr);
+               return NULL;
+       }
+}
+/********************************************************************/
+
+void DisposeHandle (Handle handle)
+{
+       if (handle) {
+               free (*handle);
+               free ((void *) handle);
+       }
+}
+/********************************************************************/
+
+unsigned int GetHandleSize (Handle handle)
+{
+       return ((HandleRecord *) handle)->size;
+}
+/********************************************************************/
+
+int SetHandleSize (Handle handle, unsigned int newSize)
+{
+       HandleRecord *hanRecPtr = (HandleRecord *) handle;
+       void *newPtr, *oldPtr;
+       unsigned int oldSize;
+
+
+       oldPtr = hanRecPtr->ptr;
+       oldSize = hanRecPtr->size;
+
+       if (oldSize == newSize)
+               return 1;
+
+       if (oldPtr == NULL) {
+               newPtr = malloc (newSize);
+       } else {
+               newPtr = realloc (oldPtr, newSize);
+       }
+       if (newPtr || (newSize == 0)) {
+               hanRecPtr->ptr = newPtr;
+               hanRecPtr->size = newSize;
+               if (newSize > oldSize)
+                       memset ((char *) newPtr + oldSize, 0, newSize - oldSize);
+               return 1;
+       } else
+               return 0;
+}
+
+#ifdef CFG_ALL_LIST_FUNCTIONS
+
+/*  Used to compare list elements by their raw data contents */
+static int ListMemBlockCmp (void *a, void *b, int size)
+{
+       return memcmp (a, b, size);
+}
+
+/***************************************************************************/
+
+/*
+ * Binary search numElements of size elementSize in array for a match
+ * to the. item. Return the index of the element that matches
+ * (0 - numElements - 1). If no match is found return the -i-1 where
+ * i is the index (0 - numElements) where the item should be placed.
+ * (*theCmp)(a,b) should return <0 if a<b, 0 if a==b, >0 if a>b.
+ *
+ * This function is like the C-Library function bsearch() except that
+ * this function returns the index where the item should be placed if
+ * it is not found.
+ */
+int BinSearch ( void *array, int numElements, int elementSize,
+               void *itemPtr, CompareFunction compareFunction)
+{
+       int low, high, mid, cmp;
+       void *arrayItemPtr;
+
+       for (low = 0, high = numElements - 1, mid = 0, cmp = -1; low <= high;) {
+               mid = (low + high) >> 1;
+
+               arrayItemPtr = (void *) (((char *) array) + (mid * elementSize));
+               cmp = compareFunction
+                       ? compareFunction (itemPtr, arrayItemPtr)
+                       : ListMemBlockCmp (itemPtr, arrayItemPtr, elementSize);
+               if (cmp == 0) {
+                       return mid;
+               } else if (cmp < 0) {
+                       high = mid - 1;
+               } else {
+                       low = mid + 1;
+               }
+       }
+       if (cmp > 0)
+               mid++;
+
+       return -mid - 1;
+}
+
+#endif /* CFG_ALL_LIST_FUNCTIONS */
+
+/*******************************************************************************/
+
+/*
+ * If numNewItems == 0 then expand the list by the number of items
+ * indicated by its allocation policy.
+ * If numNewItems > 0 then expand the list by exactly the number of
+ * items indicated.
+ * If numNewItems < 0 then expand the list by the absolute value of
+ * numNewItems plus the number of items indicated by its allocation
+ * policy.
+ * Returns 1 for success, 0 if out of memory
+*/
+static int ExpandListSpace (list_t list, int numNewItems)
+{
+       if (numNewItems == 0) {
+               numNewItems = NUMITEMSPERALLOC (list);
+       } else if (numNewItems < 0) {
+               numNewItems = (-numNewItems) + NUMITEMSPERALLOC (list);
+       }
+
+       if (SetHandleSize ((Handle) list,
+                          sizeof (ListStruct) +
+                          ((*list)->listSize +
+                          numNewItems) * (*list)->itemSize)) {
+               (*list)->listSize += numNewItems;
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+/*******************************/
+
+#ifdef CFG_ALL_LIST_FUNCTIONS
+
+/*
+ * This function reallocate the list, minus any currently unused
+ * portion of its allotted memory.
+ */
+void ListCompact (list_t list)
+{
+
+       if (!SetHandleSize ((Handle) list,
+                           sizeof (ListStruct) +
+                           (*list)->numItems * (*list)->itemSize)) {
+               return;
+       }
+
+       (*list)->listSize = (*list)->numItems;
+}
+
+#endif /* CFG_ALL_LIST_FUNCTIONS */
+
+/*******************************/
+
+list_t ListCreate (int elementSize)
+{
+       list_t list;
+
+       list = (list_t) (NewHandle (sizeof (ListStruct)));  /* create empty list */
+       if (list) {
+               (*list)->signature = LIST_SIGNATURE;
+               (*list)->numItems = 0;
+               (*list)->listSize = 0;
+               (*list)->itemSize = elementSize;
+               (*list)->percentIncrease = kDefaultAllocationPercentIncrease;
+               (*list)->minNumItemsIncrease =
+                               kDefaultAllocationminNumItemsIncrease;
+       }
+
+       return list;
+}
+
+/*******************************/
+
+void ListSetAllocationPolicy (list_t list, int minItemsPerAlloc,
+                             int percentIncreasePerAlloc)
+{
+       (*list)->percentIncrease = percentIncreasePerAlloc;
+       (*list)->minNumItemsIncrease = minItemsPerAlloc;
+}
+
+/*******************************/
+
+void ListDispose (list_t list)
+{
+       DisposeHandle ((Handle) list);
+}
+/*******************************/
+
+#ifdef CFG_ALL_LIST_FUNCTIONS
+
+void ListDisposePtrList (list_t list)
+{
+       int index;
+       int numItems;
+
+       if (list) {
+               numItems = ListNumItems (list);
+
+               for (index = 1; index <= numItems; index++)
+                       free (*(void **) ListGetPtrToItem (list, index));
+
+               ListDispose (list);
+       }
+}
+
+/*******************************/
+
+/*
+ * keeps memory, resets the number of items to 0
+ */
+void ListClear (list_t list)
+{
+       if (!list)
+               return;
+       (*list)->numItems = 0;
+}
+
+/*******************************/
+
+/*
+ * copy is only as large as necessary
+ */
+list_t ListCopy (list_t originalList)
+{
+       list_t tempList = NULL;
+       int numItems;
+
+       if (!originalList)
+               return NULL;
+
+       tempList = ListCreate ((*originalList)->itemSize);
+       if (tempList) {
+               numItems = ListNumItems (originalList);
+
+               if (!SetHandleSize ((Handle) tempList,
+                                   sizeof (ListStruct) +
+                                   numItems * (*tempList)->itemSize)) {
+                       ListDispose (tempList);
+                       return NULL;
+               }
+
+               (*tempList)->numItems = (*originalList)->numItems;
+               (*tempList)->listSize = (*originalList)->numItems;
+               (*tempList)->itemSize = (*originalList)->itemSize;
+               (*tempList)->percentIncrease = (*originalList)->percentIncrease;
+               (*tempList)->minNumItemsIncrease =
+                               (*originalList)->minNumItemsIncrease;
+
+               memcpy (ITEMPTR (tempList, 0), ITEMPTR (originalList, 0),
+                               numItems * (*tempList)->itemSize);
+       }
+
+       return tempList;
+}
+
+/********************************/
+
+/*
+ * list1 = list1 + list2
+ */
+int ListAppend (list_t list1, list_t list2)
+{
+       int numItemsL1, numItemsL2;
+
+       if (!list2)
+               return 1;
+
+       if (!list1)
+               return 0;
+       if ((*list1)->itemSize != (*list2)->itemSize)
+               return 0;
+
+       numItemsL1 = ListNumItems (list1);
+       numItemsL2 = ListNumItems (list2);
+
+       if (numItemsL2 == 0)
+               return 1;
+
+       if (!SetHandleSize ((Handle) list1,
+                           sizeof (ListStruct) + (numItemsL1 + numItemsL2) *
+                                       (*list1)->itemSize)) {
+               return 0;
+       }
+
+       (*list1)->numItems = numItemsL1 + numItemsL2;
+       (*list1)->listSize = numItemsL1 + numItemsL2;
+
+       memmove (ITEMPTR (list1, numItemsL1),
+                ITEMPTR (list2, 0),
+                numItemsL2 * (*list2)->itemSize);
+
+       return 1;
+}
+
+#endif /* CFG_ALL_LIST_FUNCTIONS */
+
+/*******************************/
+
+/*
+ * returns 1 if the item is inserted, returns 0 if out of memory or
+ * bad arguments were passed.
+ */
+int ListInsertItem (list_t list, void *ptrToItem, int itemPosition)
+{
+       return ListInsertItems (list, ptrToItem, itemPosition, 1);
+}
+
+/*******************************/
+
+int ListInsertItems (list_t list, void *ptrToItems, int firstItemPosition,
+                    int numItemsToInsert)
+{
+       int numItems = (*list)->numItems;
+
+       if (firstItemPosition == numItems + 1)
+               firstItemPosition = LIST_END;
+       else if (firstItemPosition > numItems)
+               return 0;
+
+       if ((*list)->numItems >= (*list)->listSize) {
+               if (!ExpandListSpace (list, -numItemsToInsert))
+                       return 0;
+       }
+
+       if (firstItemPosition == LIST_START) {
+               if (numItems == 0) {
+                       /* special case for empty list */
+                       firstItemPosition = LIST_END;
+               } else {
+                       firstItemPosition = 1;
+               }
+       }
+
+       if (firstItemPosition == LIST_END) {    /* add at the end of the list */
+               if (ptrToItems)
+                       memcpy (ITEMPTR (list, numItems), ptrToItems,
+                                       (*list)->itemSize * numItemsToInsert);
+               else
+                       memset (ITEMPTR (list, numItems), 0,
+                                       (*list)->itemSize * numItemsToInsert);
+
+               (*list)->numItems += numItemsToInsert;
+       } else {                                        /* move part of list up to make room for new item */
+               memmove (ITEMPTR (list, firstItemPosition - 1 + numItemsToInsert),
+                        ITEMPTR (list, firstItemPosition - 1),
+                        (numItems + 1 - firstItemPosition) * (*list)->itemSize);
+
+               if (ptrToItems)
+                       memmove (ITEMPTR (list, firstItemPosition - 1), ptrToItems,
+                                        (*list)->itemSize * numItemsToInsert);
+               else
+                       memset (ITEMPTR (list, firstItemPosition - 1), 0,
+                                       (*list)->itemSize * numItemsToInsert);
+
+               (*list)->numItems += numItemsToInsert;
+       }
+
+       return 1;
+}
+
+#ifdef CFG_ALL_LIST_FUNCTIONS
+
+/*******************************/
+
+int ListEqual (list_t list1, list_t list2)
+{
+       if (list1 == list2)
+               return 1;
+
+       if (list1 == NULL || list2 == NULL)
+               return 0;
+
+       if ((*list1)->itemSize == (*list1)->itemSize) {
+           if ((*list1)->numItems == (*list2)->numItems) {
+               return (memcmp (ITEMPTR (list1, 0), ITEMPTR (list2, 0),
+                               (*list1)->itemSize * (*list1)->numItems) == 0);
+           }
+       }
+
+       return 0;
+}
+
+/*******************************/
+
+/*
+ * The item pointed to by ptrToItem is copied over the current item
+ * at itemPosition
+ */
+void ListReplaceItem (list_t list, void *ptrToItem, int itemPosition)
+{
+       ListReplaceItems (list, ptrToItem, itemPosition, 1);
+}
+
+/*******************************/
+
+/*
+ * The item pointed to by ptrToItems is copied over the current item
+ * at itemPosition
+ */
+void ListReplaceItems ( list_t list, void *ptrToItems,
+                       int firstItemPosition, int numItemsToReplace)
+{
+
+       if (firstItemPosition == LIST_END)
+               firstItemPosition = (*list)->numItems;
+       else if (firstItemPosition == LIST_START)
+               firstItemPosition = 1;
+
+       memmove (ITEMPTR (list, firstItemPosition - 1), ptrToItems,
+                        (*list)->itemSize * numItemsToReplace);
+}
+
+/*******************************/
+
+void ListGetItem (list_t list, void *itemDestination, int itemPosition)
+{
+       ListGetItems (list, itemDestination, itemPosition, 1);
+}
+
+#endif /* CFG_ALL_LIST_FUNCTIONS */
+
+/*******************************/
+
+#if defined(CFG_ALL_LIST_FUNCTIONS) || defined(CFG_DEVICE_DEREGISTER)
+
+void ListRemoveItem (list_t list, void *itemDestination, int itemPosition)
+{
+       ListRemoveItems (list, itemDestination, itemPosition, 1);
+}
+
+/*******************************/
+
+void ListRemoveItems (list_t list, void *itemsDestination,
+                     int firstItemPosition, int numItemsToRemove)
+{
+       int firstItemAfterChunk, numToMove;
+
+       if (firstItemPosition == LIST_START)
+               firstItemPosition = 1;
+       else if (firstItemPosition == LIST_END)
+               firstItemPosition = (*list)->numItems;
+
+       if (itemsDestination != NULL)
+               memcpy (itemsDestination, ITEMPTR (list, firstItemPosition - 1),
+                               (*list)->itemSize * numItemsToRemove);
+
+       firstItemAfterChunk = firstItemPosition + numItemsToRemove;
+       numToMove = (*list)->numItems - (firstItemAfterChunk - 1);
+
+       if (numToMove > 0) {
+               /*
+                * move part of list down to cover hole left by removed item
+                */
+               memmove (ITEMPTR (list, firstItemPosition - 1),
+                                ITEMPTR (list, firstItemAfterChunk - 1),
+                                (*list)->itemSize * numToMove);
+       }
+
+       (*list)->numItems -= numItemsToRemove;
+}
+#endif /* CFG_ALL_LIST_FUNCTIONS || CFG_DEVICE_DEREGISTER */
+
+/*******************************/
+
+void ListGetItems (list_t list, void *itemsDestination,
+                  int firstItemPosition, int numItemsToGet)
+{
+
+       if (firstItemPosition == LIST_START)
+               firstItemPosition = 1;
+       else if (firstItemPosition == LIST_END)
+               firstItemPosition = (*list)->numItems;
+
+       memcpy (itemsDestination,
+               ITEMPTR (list, firstItemPosition - 1),
+               (*list)->itemSize * numItemsToGet);
+}
+
+/*******************************/
+
+/*
+ * Returns a pointer to the item at itemPosition. returns null if an
+ * errors occurred.
+ */
+void *ListGetPtrToItem (list_t list, int itemPosition)
+{
+       if (itemPosition == LIST_START)
+               itemPosition = 1;
+       else if (itemPosition == LIST_END)
+               itemPosition = (*list)->numItems;
+
+       return ITEMPTR (list, itemPosition - 1);
+}
+
+/*******************************/
+
+/*
+ * returns a pointer the lists data (abstraction violation for
+ * optimization)
+ */
+void *ListGetDataPtr (list_t list)
+{
+       return &((*list)->itemList[0]);
+}
+
+/********************************/
+
+#ifdef CFG_ALL_LIST_FUNCTIONS
+
+int ListApplyToEach (list_t list, int ascending,
+                    ListApplicationFunc funcToApply,
+                    void *callbackData)
+{
+       int result = 0, index;
+
+       if (!list || !funcToApply)
+               goto Error;
+
+       if (ascending) {
+               for (index = 1; index <= ListNumItems (list); index++) {
+                       result = funcToApply (index,
+                                             ListGetPtrToItem (list, index),
+                                             callbackData);
+                       if (result < 0)
+                               goto Error;
+               }
+       } else {
+               for (index = ListNumItems (list);
+                    index > 0 && index <= ListNumItems (list);
+                    index--) {
+                       result = funcToApply (index,
+                                             ListGetPtrToItem (list, index),
+                                             callbackData);
+                       if (result < 0)
+                               goto Error;
+               }
+       }
+
+Error:
+       return result;
+}
+
+#endif /* CFG_ALL_LIST_FUNCTIONS */
+
+/********************************/
+
+int ListGetItemSize (list_t list)
+{
+       return (*list)->itemSize;
+}
+
+/********************************/
+
+int ListNumItems (list_t list)
+{
+       return (*list)->numItems;
+}
+
+/*******************************/
+
+#ifdef CFG_ALL_LIST_FUNCTIONS
+
+void ListRemoveDuplicates (list_t list, CompareFunction compareFunction)
+{
+       int numItems, index, startIndexForFind, duplicatesIndex;
+
+       numItems = ListNumItems (list);
+
+       for (index = 1; index < numItems; index++) {
+               startIndexForFind = index + 1;
+               while (startIndexForFind <= numItems) {
+                       duplicatesIndex =
+                               ListFindItem (list,
+                                             ListGetPtrToItem (list, index),
+                                             startIndexForFind,
+                                             compareFunction);
+                       if (duplicatesIndex > 0) {
+                               ListRemoveItem (list, NULL, duplicatesIndex);
+                               numItems--;
+                               startIndexForFind = duplicatesIndex;
+                       } else {
+                               break;
+                       }
+               }
+       }
+}
+
+/*******************************/
+
+
+/*******************************/
+
+int ListFindItem (list_t list, void *ptrToItem, int startingPosition,
+                 CompareFunction compareFunction)
+{
+       int numItems, size, index, cmp;
+       void *listItemPtr;
+
+       if ((numItems = (*list)->numItems) == 0)
+               return 0;
+
+       size = (*list)->itemSize;
+
+       if (startingPosition == LIST_START)
+               startingPosition = 1;
+       else if (startingPosition == LIST_END)
+               startingPosition = numItems;
+
+       for (index = startingPosition; index <= numItems; index++) {
+               listItemPtr = ITEMPTR (list, index - 1);
+               cmp = compareFunction
+                       ? compareFunction (ptrToItem, listItemPtr)
+                       : ListMemBlockCmp (ptrToItem, listItemPtr, size);
+               if (cmp == 0)
+                       return index;
+       }
+
+       return 0;
+}
+
+/*******************************/
+
+int ShortCompare (void *a, void *b)
+{
+       if (*(short *) a < *(short *) b)
+               return -1;
+       if (*(short *) a > *(short *) b)
+               return 1;
+       return 0;
+}
+
+/*******************************/
+
+int IntCompare (void *a, void *b)
+{
+       if (*(int *) a < *(int *) b)
+               return -1;
+       if (*(int *) a > *(int *) b)
+               return 1;
+       return 0;
+}
+
+/*******************************/
+
+int CStringCompare (void *a, void *b)
+{
+       return strcmp (*(char **) a, *(char **) b);
+}
+
+/*******************************/
+
+
+int ListBinSearch (list_t list, void *ptrToItem,
+                  CompareFunction compareFunction)
+{
+       int index;
+
+       index = BinSearch (ITEMPTR (list, 0),
+                          (int) (*list)->numItems,
+                          (int) (*list)->itemSize, ptrToItem,
+                          compareFunction);
+
+       if (index >= 0)
+               index++;                        /* lists start from 1 */
+       else
+               index = 0;                      /* item not found */
+
+       return index;
+}
+
+/**************************************************************************/
+
+/*
+ * Reserves memory for numItems in the list. If it succeeds then
+ * numItems items can be inserted without possibility of an out of
+ * memory error (useful to simplify error recovery in complex
+ * functions). Returns 1 if success, 0 if out of memory.
+ */
+int ListPreAllocate (list_t list, int numItems)
+{
+       if ((*list)->listSize - (*list)->numItems < numItems) {
+               return ExpandListSpace (list,
+                                       numItems - ((*list)->listSize -
+                                               (*list)->numItems));
+       } else {
+               return 1;       /* enough items are already pre-allocated */
+       }
+}
+
+#endif /* CFG_ALL_LIST_FUNCTIONS */
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/string.c b/package/uboot-ifxmips/files/lib_bootstrap/string.c
new file mode 100644 (file)
index 0000000..e0b793a
--- /dev/null
@@ -0,0 +1,578 @@
+/*
+ *  linux/lib/string.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+/*
+ * stupid library routines.. The optimized versions should generally be found
+ * as inline code in <asm-xx/string.h>
+ *
+ * These are buggy as well..
+ *
+ * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
+ * -  Added strsep() which will replace strtok() soon (because strsep() is
+ *    reentrant and should be faster). Use only strsep() in new code, please.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <malloc.h>
+
+
+#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */
+/**
+ * strnicmp - Case insensitive, length-limited string comparison
+ * @s1: One string
+ * @s2: The other string
+ * @len: the maximum number of characters to compare
+ */
+int strnicmp(const char *s1, const char *s2, size_t len)
+{
+       /* Yes, Virginia, it had better be unsigned */
+       unsigned char c1, c2;
+
+       c1 = 0; c2 = 0;
+       if (len) {
+               do {
+                       c1 = *s1; c2 = *s2;
+                       s1++; s2++;
+                       if (!c1)
+                               break;
+                       if (!c2)
+                               break;
+                       if (c1 == c2)
+                               continue;
+                       c1 = tolower(c1);
+                       c2 = tolower(c2);
+                       if (c1 != c2)
+                               break;
+               } while (--len);
+       }
+       return (int)c1 - (int)c2;
+}
+#endif
+
+char * ___strtok;
+
+#ifndef __HAVE_ARCH_STRCPY
+/**
+ * strcpy - Copy a %NUL terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ */
+char * strcpy(char * dest,const char *src)
+{
+       char *tmp = dest;
+
+       while ((*dest++ = *src++) != '\0')
+               /* nothing */;
+       return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCPY
+/**
+ * strncpy - Copy a length-limited, %NUL-terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @count: The maximum number of bytes to copy
+ *
+ * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
+ * However, the result is not %NUL-terminated if the source exceeds
+ * @count bytes.
+ */
+char * strncpy(char * dest,const char *src,size_t count)
+{
+       char *tmp = dest;
+
+       while (count-- && (*dest++ = *src++) != '\0')
+               /* nothing */;
+
+       return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRCAT
+/**
+ * strcat - Append one %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ */
+char * strcat(char * dest, const char * src)
+{
+       char *tmp = dest;
+
+       while (*dest)
+               dest++;
+       while ((*dest++ = *src++) != '\0')
+               ;
+
+       return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCAT
+/**
+ * strncat - Append a length-limited, %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ * @count: The maximum numbers of bytes to copy
+ *
+ * Note that in contrast to strncpy, strncat ensures the result is
+ * terminated.
+ */
+char * strncat(char *dest, const char *src, size_t count)
+{
+       char *tmp = dest;
+
+       if (count) {
+               while (*dest)
+                       dest++;
+               while ((*dest++ = *src++)) {
+                       if (--count == 0) {
+                               *dest = '\0';
+                               break;
+                       }
+               }
+       }
+
+       return tmp;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRCMP
+/**
+ * strcmp - Compare two strings
+ * @cs: One string
+ * @ct: Another string
+ */
+int strcmp(const char * cs,const char * ct)
+{
+       register signed char __res;
+
+       while (1) {
+               if ((__res = *cs - *ct++) != 0 || !*cs++)
+                       break;
+       }
+
+       return __res;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNCMP
+/**
+ * strncmp - Compare two length-limited strings
+ * @cs: One string
+ * @ct: Another string
+ * @count: The maximum number of bytes to compare
+ */
+int strncmp(const char * cs,const char * ct,size_t count)
+{
+       register signed char __res = 0;
+
+       while (count) {
+               if ((__res = *cs - *ct++) != 0 || !*cs++)
+                       break;
+               count--;
+       }
+
+       return __res;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRCHR
+/**
+ * strchr - Find the first occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char * strchr(const char * s, int c)
+{
+       for(; *s != (char) c; ++s)
+               if (*s == '\0')
+                       return NULL;
+       return (char *) s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRRCHR
+/**
+ * strrchr - Find the last occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char * strrchr(const char * s, int c)
+{
+       const char *p = s + strlen(s);
+       do {
+          if (*p == (char)c)
+              return (char *)p;
+       } while (--p >= s);
+       return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRLEN
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+size_t strlen(const char * s)
+{
+       const char *sc;
+
+       for (sc = s; *sc != '\0'; ++sc)
+               /* nothing */;
+       return sc - s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRNLEN
+/**
+ * strnlen - Find the length of a length-limited string
+ * @s: The string to be sized
+ * @count: The maximum number of bytes to search
+ */
+size_t strnlen(const char * s, size_t count)
+{
+       const char *sc;
+
+       for (sc = s; count-- && *sc != '\0'; ++sc)
+               /* nothing */;
+       return sc - s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRDUP
+char * strdup(const char *s)
+{
+       char *new;
+
+       if ((s == NULL) ||
+           ((new = malloc (strlen(s) + 1)) == NULL) ) {
+               return NULL;
+       }
+
+       strcpy (new, s);
+       return new;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSPN
+/**
+ * strspn - Calculate the length of the initial substring of @s which only
+ *     contain letters in @accept
+ * @s: The string to be searched
+ * @accept: The string to search for
+ */
+size_t strspn(const char *s, const char *accept)
+{
+       const char *p;
+       const char *a;
+       size_t count = 0;
+
+       for (p = s; *p != '\0'; ++p) {
+               for (a = accept; *a != '\0'; ++a) {
+                       if (*p == *a)
+                               break;
+               }
+               if (*a == '\0')
+                       return count;
+               ++count;
+       }
+
+       return count;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRPBRK
+/**
+ * strpbrk - Find the first occurrence of a set of characters
+ * @cs: The string to be searched
+ * @ct: The characters to search for
+ */
+char * strpbrk(const char * cs,const char * ct)
+{
+       const char *sc1,*sc2;
+
+       for( sc1 = cs; *sc1 != '\0'; ++sc1) {
+               for( sc2 = ct; *sc2 != '\0'; ++sc2) {
+                       if (*sc1 == *sc2)
+                               return (char *) sc1;
+               }
+       }
+       return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRTOK
+/**
+ * strtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * WARNING: strtok is deprecated, use strsep instead.
+ */
+char * strtok(char * s,const char * ct)
+{
+       char *sbegin, *send;
+
+       sbegin  = s ? s : ___strtok;
+       if (!sbegin) {
+               return NULL;
+       }
+       sbegin += strspn(sbegin,ct);
+       if (*sbegin == '\0') {
+               ___strtok = NULL;
+               return( NULL );
+       }
+       send = strpbrk( sbegin, ct);
+       if (send && *send != '\0')
+               *send++ = '\0';
+       ___strtok = send;
+       return (sbegin);
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSEP
+/**
+ * strsep - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * strsep() updates @s to point after the token, ready for the next call.
+ *
+ * It returns empty tokens, too, behaving exactly like the libc function
+ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
+ * Same semantics, slimmer shape. ;)
+ */
+char * strsep(char **s, const char *ct)
+{
+       char *sbegin = *s, *end;
+
+       if (sbegin == NULL)
+               return NULL;
+
+       end = strpbrk(sbegin, ct);
+       if (end)
+               *end++ = '\0';
+       *s = end;
+
+       return sbegin;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSWAB
+/**
+ * strswab - swap adjacent even and odd bytes in %NUL-terminated string
+ * s: address of the string
+ *
+ * returns the address of the swapped string or NULL on error. If
+ * string length is odd, last byte is untouched.
+ */
+char *strswab(const char *s)
+{
+       char *p, *q;
+
+       if ((NULL == s) || ('\0' == *s)) {
+               return (NULL);
+       }
+
+       for (p=(char *)s, q=p+1; (*p != '\0') && (*q != '\0'); p+=2, q+=2) {
+               char  tmp;
+
+               tmp = *p;
+               *p  = *q;
+               *q  = tmp;
+       }
+
+       return (char *) s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMSET
+/**
+ * memset - Fill a region of memory with the given value
+ * @s: Pointer to the start of the area.
+ * @c: The byte to fill the area with
+ * @count: The size of the area.
+ *
+ * Do not use memset() to access IO space, use memset_io() instead.
+ */
+void * memset(void * s,int c,size_t count)
+{
+       char *xs = (char *) s;
+
+       while (count--)
+               *xs++ = c;
+
+       return s;
+}
+#endif
+
+#ifndef __HAVE_ARCH_BCOPY
+/**
+ * bcopy - Copy one area of memory to another
+ * @src: Where to copy from
+ * @dest: Where to copy to
+ * @count: The size of the area.
+ *
+ * Note that this is the same as memcpy(), with the arguments reversed.
+ * memcpy() is the standard, bcopy() is a legacy BSD function.
+ *
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
+ */
+char * bcopy(const char * src, char * dest, int count)
+{
+       char *tmp = dest;
+
+       while (count--)
+               *tmp++ = *src++;
+
+       return dest;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMCPY
+/**
+ * memcpy - Copy one area of memory to another
+ * @dest: Where to copy to
+ * @src: Where to copy from
+ * @count: The size of the area.
+ *
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
+ */
+void * memcpy(void * dest,const void *src,size_t count)
+{
+       char *tmp = (char *) dest, *s = (char *) src;
+
+       while (count--)
+               *tmp++ = *s++;
+
+       return dest;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMMOVE
+/**
+ * memmove - Copy one area of memory to another
+ * @dest: Where to copy to
+ * @src: Where to copy from
+ * @count: The size of the area.
+ *
+ * Unlike memcpy(), memmove() copes with overlapping areas.
+ */
+void * memmove(void * dest,const void *src,size_t count)
+{
+       char *tmp, *s;
+
+       if (dest <= src) {
+               tmp = (char *) dest;
+               s = (char *) src;
+               while (count--)
+                       *tmp++ = *s++;
+               }
+       else {
+               tmp = (char *) dest + count;
+               s = (char *) src + count;
+               while (count--)
+                       *--tmp = *--s;
+               }
+
+       return dest;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMCMP
+/**
+ * memcmp - Compare two areas of memory
+ * @cs: One area of memory
+ * @ct: Another area of memory
+ * @count: The size of the area.
+ */
+int memcmp(const void * cs,const void * ct,size_t count)
+{
+       const unsigned char *su1, *su2;
+       int res = 0;
+
+       for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+               if ((res = *su1 - *su2) != 0)
+                       break;
+       return res;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMSCAN
+/**
+ * memscan - Find a character in an area of memory.
+ * @addr: The memory area
+ * @c: The byte to search for
+ * @size: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or 1 byte past
+ * the area if @c is not found
+ */
+void * memscan(void * addr, int c, size_t size)
+{
+       unsigned char * p = (unsigned char *) addr;
+
+       while (size) {
+               if (*p == c)
+                       return (void *) p;
+               p++;
+               size--;
+       }
+       return (void *) p;
+}
+#endif
+
+#ifndef __HAVE_ARCH_STRSTR
+/**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char * strstr(const char * s1,const char * s2)
+{
+       int l1, l2;
+
+       l2 = strlen(s2);
+       if (!l2)
+               return (char *) s1;
+       l1 = strlen(s1);
+       while (l1 >= l2) {
+               l1--;
+               if (!memcmp(s1,s2,l2))
+                       return (char *) s1;
+               s1++;
+       }
+       return NULL;
+}
+#endif
+
+#ifndef __HAVE_ARCH_MEMCHR
+/**
+ * memchr - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or %NULL
+ * if @c is not found
+ */
+void *memchr(const void *s, int c, size_t n)
+{
+       const unsigned char *p = s;
+       while (n-- != 0) {
+               if ((unsigned char)c == *p++) {
+                       return (void *)(p-1);
+               }
+       }
+       return NULL;
+}
+
+#endif
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/time.c b/package/uboot-ifxmips/files/lib_bootstrap/time.c
new file mode 100644 (file)
index 0000000..cd8dc72
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+
+static inline void mips_compare_set(u32 v)
+{
+       asm volatile ("mtc0 %0, $11" : : "r" (v));
+}
+
+static inline void mips_count_set(u32 v)
+{
+       asm volatile ("mtc0 %0, $9" : : "r" (v));
+}
+
+
+static inline u32 mips_count_get(void)
+{
+       u32 count;
+
+       asm volatile ("mfc0 %0, $9" : "=r" (count) :);
+       return count;
+}
+
+/*
+ * timer without interrupts
+ */
+
+int timer_init(void)
+{
+       mips_compare_set(0);
+       mips_count_set(0);
+
+       return 0;
+}
+
+void reset_timer(void)
+{
+       mips_count_set(0);
+}
+
+ulong get_timer(ulong base)
+{
+       return mips_count_get() - base;
+}
+
+void set_timer(ulong t)
+{
+       mips_count_set(t);
+}
+
+void udelay (unsigned long usec)
+{
+       ulong tmo;
+       ulong start = get_timer(0);
+
+       tmo = usec * (CFG_HZ / 1000000);
+       while ((ulong)((mips_count_get() - start)) < tmo)
+               /*NOP*/;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On MIPS it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+       return mips_count_get();
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On MIPS it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+       return CFG_HZ;
+}
diff --git a/package/uboot-ifxmips/files/lib_bootstrap/vsprintf.c b/package/uboot-ifxmips/files/lib_bootstrap/vsprintf.c
new file mode 100644 (file)
index 0000000..2740f2e
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ *  linux/lib/vsprintf.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
+/*
+ * Wirzenius wrote this portably, Torvalds fucked it up :-)
+ */
+
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+
+#include <common.h>
+#if !defined (CONFIG_PANIC_HANG)
+#include <command.h>
+/*cmd_boot.c*/
+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#endif
+
+unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+{
+       unsigned long result = 0,value;
+
+       if (*cp == '0') {
+               cp++;
+               if ((*cp == 'x') && isxdigit(cp[1])) {
+                       base = 16;
+                       cp++;
+               }
+               if (!base) {
+                       base = 8;
+               }
+       }
+       if (!base) {
+               base = 10;
+       }
+       while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+           ? toupper(*cp) : *cp)-'A'+10) < base) {
+               result = result*base + value;
+               cp++;
+       }
+       if (endp)
+               *endp = (char *)cp;
+       return result;
+}
+
+long simple_strtol(const char *cp,char **endp,unsigned int base)
+{
+       if(*cp=='-')
+               return -simple_strtoul(cp+1,endp,base);
+       return simple_strtoul(cp,endp,base);
+}
+
+#ifdef CFG_64BIT_STRTOUL
+unsigned long long simple_strtoull (const char *cp, char **endp, unsigned int base)
+{
+       unsigned long long result = 0, value;
+
+       if (*cp == '0') {
+               cp++;
+               if ((*cp == 'x') && isxdigit (cp[1])) {
+                       base = 16;
+                       cp++;
+               }
+               if (!base) {
+                       base = 8;
+               }
+       }
+       if (!base) {
+               base = 10;
+       }
+       while (isxdigit (*cp) && (value = isdigit (*cp)
+                               ? *cp - '0'
+                               : (islower (*cp) ? toupper (*cp) : *cp) - 'A' + 10) < base) {
+               result = result * base + value;
+               cp++;
+       }
+       if (endp)
+               *endp = (char *) cp;
+       return result;
+}
+#endif /* CFG_64BIT_STRTOUL */
+
+/* we use this so that we can do without the ctype library */
+#define is_digit(c)    ((c) >= '0' && (c) <= '9')
+
+static int skip_atoi(const char **s)
+{
+       int i=0;
+
+       while (is_digit(**s))
+               i = i*10 + *((*s)++) - '0';
+       return i;
+}
+
+#define ZEROPAD        1               /* pad with zero */
+#define SIGN   2               /* unsigned/signed long */
+#define PLUS   4               /* show plus */
+#define SPACE  8               /* space if plus */
+#define LEFT   16              /* left justified */
+#define SPECIAL        32              /* 0x */
+#define LARGE  64              /* use 'ABCDEF' instead of 'abcdef' */
+
+#define do_div(n,base) ({ \
+       int __res; \
+       __res = ((unsigned long) n) % (unsigned) base; \
+       n = ((unsigned long) n) / (unsigned) base; \
+       __res; \
+})
+
+#ifdef CFG_64BIT_VSPRINTF
+static char * number(char * str, long long num, int base, int size, int precision ,int type)
+#else
+static char * number(char * str, long num, int base, int size, int precision ,int type)
+#endif
+{
+       char c,sign,tmp[66];
+       const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+       int i;
+
+       if (type & LARGE)
+               digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+       if (type & LEFT)
+               type &= ~ZEROPAD;
+       if (base < 2 || base > 36)
+               return 0;
+       c = (type & ZEROPAD) ? '0' : ' ';
+       sign = 0;
+       if (type & SIGN) {
+               if (num < 0) {
+                       sign = '-';
+                       num = -num;
+                       size--;
+               } else if (type & PLUS) {
+                       sign = '+';
+                       size--;
+               } else if (type & SPACE) {
+                       sign = ' ';
+                       size--;
+               }
+       }
+       if (type & SPECIAL) {
+               if (base == 16)
+                       size -= 2;
+               else if (base == 8)
+                       size--;
+       }
+       i = 0;
+       if (num == 0)
+               tmp[i++]='0';
+       else while (num != 0)
+               tmp[i++] = digits[do_div(num,base)];
+       if (i > precision)
+               precision = i;
+       size -= precision;
+       if (!(type&(ZEROPAD+LEFT)))
+               while(size-->0)
+                       *str++ = ' ';
+       if (sign)
+               *str++ = sign;
+       if (type & SPECIAL) {
+               if (base==8)
+                       *str++ = '0';
+               else if (base==16) {
+                       *str++ = '0';
+                       *str++ = digits[33];
+               }
+       }
+       if (!(type & LEFT))
+               while (size-- > 0)
+                       *str++ = c;
+       while (i < precision--)
+               *str++ = '0';
+       while (i-- > 0)
+               *str++ = tmp[i];
+       while (size-- > 0)
+               *str++ = ' ';
+       return str;
+}
+
+/* Forward decl. needed for IP address printing stuff... */
+int sprintf(char * buf, const char *fmt, ...);
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+       int len;
+#ifdef CFG_64BIT_VSPRINTF
+       unsigned long long num;
+#else
+       unsigned long num;
+#endif
+       int i, base;
+       char * str;
+       const char *s;
+
+       int flags;              /* flags to number() */
+
+       int field_width;        /* width of output field */
+       int precision;          /* min. # of digits for integers; max
+                                  number of chars for from string */
+       int qualifier;          /* 'h', 'l', or 'q' for integer fields */
+
+       for (str=buf ; *fmt ; ++fmt) {
+               if (*fmt != '%') {
+                       *str++ = *fmt;
+                       continue;
+               }
+
+               /* process flags */
+               flags = 0;
+               repeat:
+                       ++fmt;          /* this also skips first '%' */
+                       switch (*fmt) {
+                               case '-': flags |= LEFT; goto repeat;
+                               case '+': flags |= PLUS; goto repeat;
+                               case ' ': flags |= SPACE; goto repeat;
+                               case '#': flags |= SPECIAL; goto repeat;
+                               case '0': flags |= ZEROPAD; goto repeat;
+                               }
+
+               /* get field width */
+               field_width = -1;
+               if (is_digit(*fmt))
+                       field_width = skip_atoi(&fmt);
+               else if (*fmt == '*') {
+                       ++fmt;
+                       /* it's the next argument */
+                       field_width = va_arg(args, int);
+                       if (field_width < 0) {
+                               field_width = -field_width;
+                               flags |= LEFT;
+                       }
+               }
+
+               /* get the precision */
+               precision = -1;
+               if (*fmt == '.') {
+                       ++fmt;
+                       if (is_digit(*fmt))
+                               precision = skip_atoi(&fmt);
+                       else if (*fmt == '*') {
+                               ++fmt;
+                               /* it's the next argument */
+                               precision = va_arg(args, int);
+                       }
+                       if (precision < 0)
+                               precision = 0;
+               }
+
+               /* get the conversion qualifier */
+               qualifier = -1;
+               if (*fmt == 'h' || *fmt == 'l' || *fmt == 'q') {
+                       qualifier = *fmt;
+                       ++fmt;
+               }
+
+               /* default base */
+               base = 10;
+
+               switch (*fmt) {
+               case 'c':
+                       if (!(flags & LEFT))
+                               while (--field_width > 0)
+                                       *str++ = ' ';
+                       *str++ = (unsigned char) va_arg(args, int);
+                       while (--field_width > 0)
+                               *str++ = ' ';
+                       continue;
+
+               case 's':
+                       s = va_arg(args, char *);
+                       if (!s)
+                               s = "<NULL>";
+
+                       len = strnlen(s, precision);
+
+                       if (!(flags & LEFT))
+                               while (len < field_width--)
+                                       *str++ = ' ';
+                       for (i = 0; i < len; ++i)
+                               *str++ = *s++;
+                       while (len < field_width--)
+                               *str++ = ' ';
+                       continue;
+
+               case 'p':
+                       if (field_width == -1) {
+                               field_width = 2*sizeof(void *);
+                               flags |= ZEROPAD;
+                       }
+                       str = number(str,
+                               (unsigned long) va_arg(args, void *), 16,
+                               field_width, precision, flags);
+                       continue;
+
+
+               case 'n':
+                       if (qualifier == 'l') {
+                               long * ip = va_arg(args, long *);
+                               *ip = (str - buf);
+                       } else {
+                               int * ip = va_arg(args, int *);
+                               *ip = (str - buf);
+                       }
+                       continue;
+
+               case '%':
+                       *str++ = '%';
+                       continue;
+
+               /* integer number formats - set up the flags and "break" */
+               case 'o':
+                       base = 8;
+                       break;
+
+               case 'X':
+                       flags |= LARGE;
+               case 'x':
+                       base = 16;
+                       break;
+
+               case 'd':
+               case 'i':
+                       flags |= SIGN;
+               case 'u':
+                       break;
+
+               default:
+                       *str++ = '%';
+                       if (*fmt)
+                               *str++ = *fmt;
+                       else
+                               --fmt;
+                       continue;
+               }
+#ifdef CFG_64BIT_VSPRINTF
+               if (qualifier == 'q')  /* "quad" for 64 bit variables */
+                       num = va_arg(args, unsigned long long);
+               else
+#endif
+               if (qualifier == 'l')
+                       num = va_arg(args, unsigned long);
+               else if (qualifier == 'h') {
+                       num = (unsigned short) va_arg(args, int);
+                       if (flags & SIGN)
+                               num = (short) num;
+               } else if (flags & SIGN)
+                       num = va_arg(args, int);
+               else
+                       num = va_arg(args, unsigned int);
+               str = number(str, num, base, field_width, precision, flags);
+       }
+       *str = '\0';
+       return str-buf;
+}
+
+int sprintf(char * buf, const char *fmt, ...)
+{
+       va_list args;
+       int i;
+
+       va_start(args, fmt);
+       i=vsprintf(buf,fmt,args);
+       va_end(args);
+       return i;
+}
+
+void panic(const char *fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       vprintf(fmt, args);
+       putc('\n');
+       va_end(args);
+#if defined (CONFIG_PANIC_HANG)
+       hang();
+#else
+       udelay (100000);        /* allow messages to go out */
+       do_reset (NULL, 0, 0, NULL);
+#endif
+}
diff --git a/package/uboot-ifxmips/files/lib_generic/LzmaDecode.c b/package/uboot-ifxmips/files/lib_generic/LzmaDecode.c
new file mode 100644 (file)
index 0000000..99d1117
--- /dev/null
@@ -0,0 +1,600 @@
+/*
+  LzmaDecode.c
+  LZMA Decoder (optimized for Speed version)
+  
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this Code, expressly permits you to 
+  statically or dynamically link your Code (or bind by name) to the 
+  interfaces of this file without subjecting your linked Code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifdef CONFIG_LZMA
+
+#include "LzmaDecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+#define RC_TEST { if (Buffer == BufferLim) \
+  { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) { printf("ERROR, %s, %d\n", __FILE__, __LINE__); return result; } \
+  BufferLim = Buffer + size; if (size == 0) { printf("ERROR, %s, %d\n", __FILE__, __LINE__); return LZMA_RESULT_DATA_ERROR; } }}
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) { printf("ERROR, %s, %d\n", __FILE__, __LINE__); return LZMA_RESULT_DATA_ERROR; } }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+  { UpdateBit0(p); mi <<= 1; A0; } else \
+  { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 
+  
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)               
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+  { int i = numLevels; res = 1; \
+  do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+  res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+  unsigned char prop0;
+  if (size < LZMA_PROPERTIES_SIZE)
+  {
+    printf("ERROR: %s, %d\n", __FILE__, __LINE__);
+    return LZMA_RESULT_DATA_ERROR;
+  }
+  prop0 = propsData[0];
+  if (prop0 >= (9 * 5 * 5))
+  {
+    printf("ERROR: %s, %d\n", __FILE__, __LINE__);
+    return LZMA_RESULT_DATA_ERROR;
+  }
+  {
+    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+    propsRes->lc = prop0;
+    /*
+    unsigned char remainder = (unsigned char)(prop0 / 9);
+    propsRes->lc = prop0 % 9;
+    propsRes->pb = remainder / 5;
+    propsRes->lp = remainder % 5;
+    */
+  }
+
+  #ifdef _LZMA_OUT_READ
+  {
+    int i;
+    propsRes->DictionarySize = 0;
+    for (i = 0; i < 4; i++)
+      propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+    if (propsRes->DictionarySize == 0)
+      propsRes->DictionarySize = 1;
+  }
+  #endif
+  return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *InCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+  CProb *p = vs->Probs;
+  SizeT nowPos = 0;
+  Byte previousByte = 0;
+  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+  int lc = vs->Properties.lc;
+
+  #ifdef _LZMA_OUT_READ
+  
+  UInt32 Range = vs->Range;
+  UInt32 Code = vs->Code;
+  #ifdef _LZMA_IN_CB
+  const Byte *Buffer = vs->Buffer;
+  const Byte *BufferLim = vs->BufferLim;
+  #else
+  const Byte *Buffer = inStream;
+  const Byte *BufferLim = inStream + inSize;
+  #endif
+  int state = vs->State;
+  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+  int len = vs->RemainLen;
+  UInt32 globalPos = vs->GlobalPos;
+  UInt32 distanceLimit = vs->DistanceLimit;
+
+  Byte *dictionary = vs->Dictionary;
+  UInt32 dictionarySize = vs->Properties.DictionarySize;
+  UInt32 dictionaryPos = vs->DictionaryPos;
+
+  Byte tempDictionary[4];
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+  if (len == kLzmaStreamWasFinishedId)
+    return LZMA_RESULT_OK;
+
+  if (dictionarySize == 0)
+  {
+    dictionary = tempDictionary;
+    dictionarySize = 1;
+    tempDictionary[0] = vs->TempDictionary[0];
+  }
+
+  if (len == kLzmaNeedInitId)
+  {
+    {
+      UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+      UInt32 i;
+      for (i = 0; i < numProbs; i++)
+        p[i] = kBitModelTotal >> 1; 
+      rep0 = rep1 = rep2 = rep3 = 1;
+      state = 0;
+      globalPos = 0;
+      distanceLimit = 0;
+      dictionaryPos = 0;
+      dictionary[dictionarySize - 1] = 0;
+      #ifdef _LZMA_IN_CB
+      RC_INIT;
+      #else
+      RC_INIT(inStream, inSize);
+      #endif
+    }
+    len = 0;
+  }
+  while(len != 0 && nowPos < outSize)
+  {
+    UInt32 pos = dictionaryPos - rep0;
+    if (pos >= dictionarySize)
+      pos += dictionarySize;
+    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+    if (++dictionaryPos == dictionarySize)
+      dictionaryPos = 0;
+    len--;
+  }
+  if (dictionaryPos == 0)
+    previousByte = dictionary[dictionarySize - 1];
+  else
+    previousByte = dictionary[dictionaryPos - 1];
+
+  #else /* if !_LZMA_OUT_READ */
+
+  int state = 0;
+  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+  int len = 0;
+  const Byte *Buffer;
+  const Byte *BufferLim;
+  UInt32 Range;
+  UInt32 Code;
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+
+  {
+    UInt32 i;
+    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+    for (i = 0; i < numProbs; i++)
+      p[i] = kBitModelTotal >> 1;
+  }
+  
+  #ifdef _LZMA_IN_CB
+  RC_INIT;
+  #else
+  RC_INIT(inStream, inSize);
+  #endif
+
+  #endif /* _LZMA_OUT_READ */
+
+  while(nowPos < outSize)
+  {
+    CProb *prob;
+    UInt32 bound;
+    int posState = (int)(
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & posStateMask);
+
+    prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+    IfBit0(prob)
+    {
+      int symbol = 1;
+      UpdateBit0(prob)
+      prob = p + Literal + (LZMA_LIT_SIZE * 
+        (((
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+      if (state >= kNumLitStates)
+      {
+        int matchByte;
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        matchByte = dictionary[pos];
+        #else
+        matchByte = outStream[nowPos - rep0];
+        #endif
+        do
+        {
+          int bit;
+          CProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & 0x100);
+          probLit = prob + 0x100 + bit + symbol;
+          RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+        }
+        while (symbol < 0x100);
+      }
+      while (symbol < 0x100)
+      {
+        CProb *probLit = prob + symbol;
+        RC_GET_BIT(probLit, symbol)
+      }
+      previousByte = (Byte)symbol;
+
+      outStream[nowPos++] = previousByte;
+      #ifdef _LZMA_OUT_READ
+      if (distanceLimit < dictionarySize)
+        distanceLimit++;
+
+      dictionary[dictionaryPos] = previousByte;
+      if (++dictionaryPos == dictionarySize)
+        dictionaryPos = 0;
+      #endif
+      if (state < 4) state = 0;
+      else if (state < 10) state -= 3;
+      else state -= 6;
+    }
+    else             
+    {
+      UpdateBit1(prob);
+      prob = p + IsRep + state;
+      IfBit0(prob)
+      {
+        UpdateBit0(prob);
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        state = state < kNumLitStates ? 0 : 3;
+        prob = p + LenCoder;
+      }
+      else
+      {
+        UpdateBit1(prob);
+        prob = p + IsRepG0 + state;
+        IfBit0(prob)
+        {
+          UpdateBit0(prob);
+          prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IfBit0(prob)
+          {
+            #ifdef _LZMA_OUT_READ
+            UInt32 pos;
+            #endif
+            UpdateBit0(prob);
+            
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit == 0)
+            #else
+            if (nowPos == 0)
+            #endif
+            {
+              printf("ERROR: %s, %d\n", __FILE__, __LINE__);
+              return LZMA_RESULT_DATA_ERROR;
+            }
+            
+            state = state < kNumLitStates ? 9 : 11;
+            #ifdef _LZMA_OUT_READ
+            pos = dictionaryPos - rep0;
+            if (pos >= dictionarySize)
+              pos += dictionarySize;
+            previousByte = dictionary[pos];
+            dictionary[dictionaryPos] = previousByte;
+            if (++dictionaryPos == dictionarySize)
+              dictionaryPos = 0;
+            #else
+            previousByte = outStream[nowPos - rep0];
+            #endif
+            outStream[nowPos++] = previousByte;
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit < dictionarySize)
+              distanceLimit++;
+            #endif
+
+            continue;
+          }
+          else
+          {
+            UpdateBit1(prob);
+          }
+        }
+        else
+        {
+          UInt32 distance;
+          UpdateBit1(prob);
+          prob = p + IsRepG1 + state;
+          IfBit0(prob)
+          {
+            UpdateBit0(prob);
+            distance = rep1;
+          }
+          else 
+          {
+            UpdateBit1(prob);
+            prob = p + IsRepG2 + state;
+            IfBit0(prob)
+            {
+              UpdateBit0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UpdateBit1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = p + RepLenCoder;
+      }
+      {
+        int numBits, offset;
+        CProb *probLen = prob + LenChoice;
+        IfBit0(probLen)
+        {
+          UpdateBit0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          numBits = kLenNumLowBits;
+        }
+        else
+        {
+          UpdateBit1(probLen);
+          probLen = prob + LenChoice2;
+          IfBit0(probLen)
+          {
+            UpdateBit0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            numBits = kLenNumMidBits;
+          }
+          else
+          {
+            UpdateBit1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            numBits = kLenNumHighBits;
+          }
+        }
+        RangeDecoderBitTreeDecode(probLen, numBits, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        int posSlot;
+        state += kNumLitStates;
+        prob = p + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
+            kNumPosSlotBits);
+        RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+          rep0 = (2 | ((UInt32)posSlot & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            rep0 <<= numDirectBits;
+            prob = p + SpecPos + rep0 - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              RC_NORMALIZE
+              Range >>= 1;
+              rep0 <<= 1;
+              if (Code >= Range)
+              {
+                Code -= Range;
+                rep0 |= 1;
+              }
+            }
+            while (--numDirectBits != 0);
+            prob = p + Align;
+            rep0 <<= kNumAlignBits;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            int i = 1;
+            int mi = 1;
+            do
+            {
+              CProb *prob3 = prob + mi;
+              RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+              i <<= 1;
+            }
+            while(--numDirectBits != 0);
+          }
+        }
+        else
+          rep0 = posSlot;
+        if (++rep0 == (UInt32)(0))
+        {
+          /* it's for stream version */
+          len = kLzmaStreamWasFinishedId;
+          break;
+        }
+      }
+
+      len += kMatchMinLen;
+      #ifdef _LZMA_OUT_READ
+      if (rep0 > distanceLimit) 
+      #else
+      if (rep0 > nowPos)
+      #endif
+      {
+        printf("ERROR: %s, %d\n", __FILE__, __LINE__);
+        return LZMA_RESULT_DATA_ERROR;
+      }
+
+      #ifdef _LZMA_OUT_READ
+      if (dictionarySize - distanceLimit > (UInt32)len)
+        distanceLimit += len;
+      else
+        distanceLimit = dictionarySize;
+      #endif
+
+      do
+      {
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        previousByte = dictionary[pos];
+        dictionary[dictionaryPos] = previousByte;
+        if (++dictionaryPos == dictionarySize)
+          dictionaryPos = 0;
+        #else
+        previousByte = outStream[nowPos - rep0];
+        #endif
+        len--;
+        outStream[nowPos++] = previousByte;
+      }
+      while(len != 0 && nowPos < outSize);
+    }
+  }
+  RC_NORMALIZE;
+
+  #ifdef _LZMA_OUT_READ
+  vs->Range = Range;
+  vs->Code = Code;
+  vs->DictionaryPos = dictionaryPos;
+  vs->GlobalPos = globalPos + (UInt32)nowPos;
+  vs->DistanceLimit = distanceLimit;
+  vs->Reps[0] = rep0;
+  vs->Reps[1] = rep1;
+  vs->Reps[2] = rep2;
+  vs->Reps[3] = rep3;
+  vs->State = state;
+  vs->RemainLen = len;
+  vs->TempDictionary[0] = tempDictionary[0];
+  #endif
+
+  #ifdef _LZMA_IN_CB
+  vs->Buffer = Buffer;
+  vs->BufferLim = BufferLim;
+  #else
+  *inSizeProcessed = (SizeT)(Buffer - inStream);
+  #endif
+  *outSizeProcessed = nowPos;
+  return LZMA_RESULT_OK;
+}
+
+#endif /* CONFIG_LZMA */
diff --git a/package/uboot-ifxmips/files/lib_generic/LzmaDecode.h b/package/uboot-ifxmips/files/lib_generic/LzmaDecode.h
new file mode 100644 (file)
index 0000000..2870eeb
--- /dev/null
@@ -0,0 +1,113 @@
+/* 
+  LzmaDecode.h
+  LZMA Decoder interface
+
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs, 
+   but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+  int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+  int lc;
+  int lp;
+  int pb;
+  #ifdef _LZMA_OUT_READ
+  UInt32 DictionarySize;
+  #endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+  CLzmaProperties Properties;
+  CProb *Probs;
+
+  #ifdef _LZMA_IN_CB
+  const unsigned char *Buffer;
+  const unsigned char *BufferLim;
+  #endif
+
+  #ifdef _LZMA_OUT_READ
+  unsigned char *Dictionary;
+  UInt32 Range;
+  UInt32 Code;
+  UInt32 DictionaryPos;
+  UInt32 GlobalPos;
+  UInt32 DistanceLimit;
+  UInt32 Reps[4];
+  int State;
+  int RemainLen;
+  unsigned char TempDictionary[4];
+  #endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
diff --git a/package/uboot-ifxmips/files/lib_generic/LzmaTypes.h b/package/uboot-ifxmips/files/lib_generic/LzmaTypes.h
new file mode 100644 (file)
index 0000000..288c5e4
--- /dev/null
@@ -0,0 +1,45 @@
+/* 
+LzmaTypes.h 
+
+Types for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.40 (2006-05-01)
+*/
+
+#ifndef __LZMATYPES_H
+#define __LZMATYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif 
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif 
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif 
+
+/* #define _LZMA_SYSTEM_SIZE_T */
+/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_SYSTEM_SIZE_T
+#include <stddef.h>
+typedef size_t SizeT;
+#else
+typedef UInt32 SizeT;
+#endif
+#endif
+
+#endif
diff --git a/package/uboot-ifxmips/files/lib_generic/LzmaWrapper.c b/package/uboot-ifxmips/files/lib_generic/LzmaWrapper.c
new file mode 100644 (file)
index 0000000..6c3d702
--- /dev/null
@@ -0,0 +1,197 @@
+/******************************************************************************
+**
+** FILE NAME    : LzmaWrapper.c
+** PROJECT      : bootloader
+** MODULES      : U-boot
+**
+** DATE         : 2 Nov 2006
+** AUTHOR       : Lin Mars
+** DESCRIPTION  : LZMA decoder support for U-boot 1.1.5
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Date        $Author         $Comment
+** 2 Nov 2006   Lin Mars        init version which derived from LzmaTest.c from
+**                              LZMA v4.43 SDK
+*******************************************************************************/
+#define LZMA_NO_STDIO
+#ifndef LZMA_NO_STDIO
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include <config.h>
+#include <common.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <malloc.h>
+
+#ifdef CONFIG_LZMA
+
+#include "LzmaDecode.h"
+#include "LzmaWrapper.h"
+
+static const char *kCantReadMessage = "Can not read from source buffer";
+static const char *kCantAllocateMessage = "Not enough buffer for decompression";
+
+static size_t rpos=0, dpos=0;
+
+static int MyReadFileAndCheck(unsigned char *src, void *dest, size_t size)
+{
+  if (size == 0)
+    return 0;
+  memcpy(dest, src + rpos, size);
+  rpos += size;
+  return 1;
+}
+
+int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len)
+{
+  /* We use two 32-bit integers to construct 64-bit integer for file size.
+     You can remove outSizeHigh, if you don't need >= 4GB supporting,
+     or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+  UInt32 outSize = 0;
+  UInt32 outSizeHigh = 0;
+  SizeT outSizeFull;
+  unsigned char *outStream;
+  
+  int waitEOS = 1; 
+  /* waitEOS = 1, if there is no uncompressed size in headers, 
+   so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+  SizeT compressedSize;
+  unsigned char *inStream;
+
+  CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
+  unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+  int res;
+
+  if (sizeof(UInt32) < 4)
+  {
+    printf("LZMA decoder needs correct UInt32\n");
+    return LZMA_RESULT_DATA_ERROR;
+  }
+
+  {
+    long length=s_len;
+    if ((long)(SizeT)length != length)
+    {
+      printf("Too big compressed stream\n");
+      return LZMA_RESULT_DATA_ERROR;
+    }
+    compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
+  }
+
+  /* Read LZMA properties for compressed stream */
+
+  if (!MyReadFileAndCheck(source, properties, sizeof(properties)))
+  {
+    printf("%s\n", kCantReadMessage);
+    return LZMA_RESULT_DATA_ERROR;
+  }
+
+  /* Read uncompressed size */
+  {
+    int i;
+    for (i = 0; i < 8; i++)
+    {
+      unsigned char b;
+      if (!MyReadFileAndCheck(source, &b, 1))
+      {
+        printf("%s\n", kCantReadMessage);
+        return LZMA_RESULT_DATA_ERROR;
+      }
+      if (b != 0xFF)
+        waitEOS = 0;
+      if (i < 4)
+        outSize += (UInt32)(b) << (i * 8);
+      else
+        outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+    }
+    
+    if (waitEOS)
+    {
+      printf("Stream with EOS marker is not supported");
+      return LZMA_RESULT_DATA_ERROR;
+    }
+    outSizeFull = (SizeT)outSize;
+    if (sizeof(SizeT) >= 8)
+      outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
+    else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
+    {
+      printf("Too big uncompressed stream");
+      return LZMA_RESULT_DATA_ERROR;
+    }
+  }
+
+  /* Decode LZMA properties and allocate memory */
+  if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+  {
+    printf("Incorrect stream properties");
+    return LZMA_RESULT_DATA_ERROR;
+  }
+  state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+
+  if (outSizeFull == 0)
+    outStream = 0;
+  else
+  {
+    if (outSizeFull > d_len)
+      outStream = 0;
+    else
+      outStream = dest;
+  }
+
+  if (compressedSize == 0)
+    inStream = 0;
+  else
+  {
+    if ((compressedSize+rpos) > s_len )
+      inStream = 0;
+    else
+      inStream = source + rpos;
+  }
+
+  if (state.Probs == 0 
+    || (outStream == 0 && outSizeFull != 0)
+    || (inStream == 0 && compressedSize != 0)
+    )
+  {
+    free(state.Probs);
+    printf("%s\n", kCantAllocateMessage);
+    return LZMA_RESULT_DATA_ERROR;
+  }
+
+  /* Decompress */
+  {
+    SizeT inProcessed;
+    SizeT outProcessed;
+    res = LzmaDecode(&state,
+      inStream, compressedSize, &inProcessed,
+      outStream, outSizeFull, &outProcessed);
+    if (res != 0)
+    {
+      printf("\nDecoding error = %d\n", res);
+      res = 1;
+    }
+    else
+    {
+      *d_len = outProcessed;
+    }
+  }
+
+  free(state.Probs);
+  return res;
+}
+
+#endif /* CONFIG_LZMA */
diff --git a/package/uboot-ifxmips/files/net/ifx_eth.c b/package/uboot-ifxmips/files/net/ifx_eth.c
new file mode 100644 (file)
index 0000000..02e72ae
--- /dev/null
@@ -0,0 +1,4 @@
+
+#define IFX_ETH_INITIALIZE_EXTERN      extern int danube_switch_initialize(bd_t *);
+#define IFX_ETH_INITIALIZE(bd_t)       danube_switch_initialize(bd_t);
+
diff --git a/package/uboot-ifxmips/files/net/net_danube.c b/package/uboot-ifxmips/files/net/net_danube.c
new file mode 100644 (file)
index 0000000..1d1c98f
--- /dev/null
@@ -0,0 +1,1754 @@
+/*
+ *     Copied from Linux Monitor (LiMon) - Networking.
+ *
+ *     Copyright 1994 - 2000 Neil Russell.
+ *     (See License)
+ *     Copyright 2000 Roland Borde
+ *     Copyright 2000 Paolo Scaffardi
+ *     Copyright 2000-2002 Wolfgang Denk, wd@denx.de
+ */
+
+/*
+ * General Desription:
+ *
+ * The user interface supports commands for BOOTP, RARP, and TFTP.
+ * Also, we support ARP internally. Depending on available data,
+ * these interact as follows:
+ *
+ * BOOTP:
+ *
+ *     Prerequisites:  - own ethernet address
+ *     We want:        - own IP address
+ *                     - TFTP server IP address
+ *                     - name of bootfile
+ *     Next step:      ARP
+ *
+ * RARP:
+ *
+ *     Prerequisites:  - own ethernet address
+ *     We want:        - own IP address
+ *                     - TFTP server IP address
+ *     Next step:      ARP
+ *
+ * ARP:
+ *
+ *     Prerequisites:  - own ethernet address
+ *                     - own IP address
+ *                     - TFTP server IP address
+ *     We want:        - TFTP server ethernet address
+ *     Next step:      TFTP
+ *
+ * DHCP:
+ *
+ *     Prerequisites:  - own ethernet address
+ *     We want:                - IP, Netmask, ServerIP, Gateway IP
+ *                     - bootfilename, lease time
+ *     Next step:      - TFTP
+ *
+ * TFTP:
+ *
+ *     Prerequisites:  - own ethernet address
+ *                     - own IP address
+ *                     - TFTP server IP address
+ *                     - TFTP server ethernet address
+ *                     - name of bootfile (if unknown, we use a default name
+ *                       derived from our own IP address)
+ *     We want:        - load the boot file
+ *     Next step:      none
+ *
+ * NFS:
+ *
+ *     Prerequisites:  - own ethernet address
+ *                     - own IP address
+ *                     - name of bootfile (if unknown, we use a default name
+ *                       derived from our own IP address)
+ *     We want:        - load the boot file
+ *     Next step:      none
+ *
+ * SNTP:
+ *
+ *     Prerequisites:  - own ethernet address
+ *                     - own IP address
+ *     We want:        - network time
+ *     Next step:      none
+ */
+
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <net.h>
+#include "bootp.h"
+#include "tftp.h"
+#include "rarp.h"
+#include "nfs.h"
+#ifdef CONFIG_STATUS_LED
+#include <status_led.h>
+#include <miiphy.h>
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
+#include "sntp.h"
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ARP_TIMEOUT            5               /* Seconds before trying ARP again */
+#ifndef        CONFIG_NET_RETRY_COUNT
+# define ARP_TIMEOUT_COUNT     5               /* # of timeouts before giving up  */
+#else
+# define ARP_TIMEOUT_COUNT  (CONFIG_NET_RETRY_COUNT)
+#endif
+
+#if 0
+#define ET_DEBUG
+#endif
+
+/** BOOTP EXTENTIONS **/
+
+IPaddr_t       NetOurSubnetMask=0;             /* Our subnet mask (0=unknown)  */
+IPaddr_t       NetOurGatewayIP=0;              /* Our gateways IP address      */
+IPaddr_t       NetOurDNSIP=0;                  /* Our DNS IP address           */
+#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS2)
+IPaddr_t       NetOurDNS2IP=0;                 /* Our 2nd DNS IP address       */
+#endif
+char           NetOurNISDomain[32]={0,};       /* Our NIS domain               */
+char           NetOurHostName[32]={0,};        /* Our hostname                 */
+char           NetOurRootPath[64]={0,};        /* Our bootpath                 */
+ushort         NetBootFileSize=0;              /* Our bootfile size in blocks  */
+
+/** END OF BOOTP EXTENTIONS **/
+
+ulong          NetBootFileXferSize;    /* The actual transferred size of the bootfile (in bytes) */
+uchar          NetOurEther[6];         /* Our ethernet address                 */
+uchar          NetServerEther[6] =     /* Boot server enet address             */
+                       { 0, 0, 0, 0, 0, 0 };
+IPaddr_t       NetOurIP;               /* Our IP addr (0 = unknown)            */
+IPaddr_t       NetServerIP;            /* Our IP addr (0 = unknown)            */
+volatile uchar *NetRxPkt;              /* Current receive packet               */
+int            NetRxPktLen;            /* Current rx packet length             */
+unsigned       NetIPID;                /* IP packet ID                         */
+uchar          NetBcastAddr[6] =       /* Ethernet bcast address               */
+                       { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+uchar          NetEtherNullAddr[6] =
+                       { 0, 0, 0, 0, 0, 0 };
+#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+uchar          NetCDPAddr[6] =         /* Ethernet bcast address               */
+                       { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
+#endif
+int            NetState;               /* Network loop state                   */
+#ifdef CONFIG_NET_MULTI
+int            NetRestartWrap = 0;     /* Tried all network devices            */
+static int     NetRestarted = 0;       /* Network loop restarted               */
+static int     NetDevExists = 0;       /* At least one device configured       */
+#endif
+
+/* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */
+ushort         NetOurVLAN = 0xFFFF;            /* default is without VLAN      */
+ushort         NetOurNativeVLAN = 0xFFFF;      /* ditto                        */
+
+char           BootFile[128];          /* Boot File name                       */
+
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+IPaddr_t       NetPingIP;              /* the ip address to ping               */
+
+static void PingStart(void);
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+static void CDPStart(void);
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
+IPaddr_t       NetNtpServerIP;         /* NTP server IP address                */
+int            NetTimeOffset=0;        /* offset time from UTC                 */
+#endif
+
+#ifdef CONFIG_NETCONSOLE
+void NcStart(void);
+int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len);
+#endif
+
+volatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
+
+volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets                    */
+
+static rxhand_f *packetHandler;                /* Current RX packet handler            */
+static thand_f *timeHandler;           /* Current timeout handler              */
+static ulong   timeStart;              /* Time base value                      */
+static ulong   timeDelta;              /* Current timeout value                */
+volatile uchar *NetTxPacket = 0;       /* THE transmit packet                  */
+
+static int net_check_prereq (proto_t protocol);
+
+/**********************************************************************/
+
+IPaddr_t       NetArpWaitPacketIP;
+IPaddr_t       NetArpWaitReplyIP;
+uchar         *NetArpWaitPacketMAC;    /* MAC address of waiting packet's destination  */
+uchar         *NetArpWaitTxPacket;     /* THE transmit packet                  */
+int            NetArpWaitTxPacketSize;
+uchar          NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
+ulong          NetArpWaitTimerStart;
+int            NetArpWaitTry;
+
+void ArpRequest (void)
+{
+       int i;
+       volatile uchar *pkt;
+       ARP_t *arp;
+
+#ifdef ET_DEBUG
+       printf ("ARP broadcast %d\n", NetArpWaitTry);
+#endif
+       pkt = NetTxPacket;
+
+       pkt += NetSetEther (pkt, NetBcastAddr, PROT_ARP);
+
+       arp = (ARP_t *) pkt;
+
+       arp->ar_hrd = htons (ARP_ETHER);
+       arp->ar_pro = htons (PROT_IP);
+       arp->ar_hln = 6;
+       arp->ar_pln = 4;
+       arp->ar_op = htons (ARPOP_REQUEST);
+
+       memcpy (&arp->ar_data[0], NetOurEther, 6);              /* source ET addr       */
+       NetWriteIP ((uchar *) & arp->ar_data[6], NetOurIP);     /* source IP addr       */
+       for (i = 10; i < 16; ++i) {
+               arp->ar_data[i] = 0;                            /* dest ET addr = 0     */
+       }
+
+       if ((NetArpWaitPacketIP & NetOurSubnetMask) !=
+           (NetOurIP & NetOurSubnetMask)) {
+               if (NetOurGatewayIP == 0) {
+                       puts ("## Warning: gatewayip needed but not set\n");
+                       NetArpWaitReplyIP = NetArpWaitPacketIP;
+               } else {
+                       NetArpWaitReplyIP = NetOurGatewayIP;
+               }
+       } else {
+               NetArpWaitReplyIP = NetArpWaitPacketIP;
+       }
+
+       NetWriteIP ((uchar *) & arp->ar_data[16], NetArpWaitReplyIP);
+       (void) eth_send (NetTxPacket, (pkt - NetTxPacket) + ARP_HDR_SIZE);
+}
+
+void ArpTimeoutCheck(void)
+{
+       ulong t;
+
+       if (!NetArpWaitPacketIP)
+               return;
+
+       t = get_timer(0);
+
+       /* check for arp timeout */
+       if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) {
+               NetArpWaitTry++;
+
+               if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) {
+                       puts ("\nARP Retry count exceeded; starting again\n");
+                       NetArpWaitTry = 0;
+                       NetStartAgain();
+               } else {
+                       NetArpWaitTimerStart = t;
+                       ArpRequest();
+               }
+       }
+}
+
+/**********************************************************************/
+/*
+ *     Main network processing loop.
+ */
+
+int
+NetLoop(proto_t protocol)
+{
+       bd_t *bd = gd->bd;
+
+#ifdef CONFIG_NET_MULTI
+       NetRestarted = 0;
+       NetDevExists = 0;
+#endif
+
+       /* XXX problem with bss workaround */
+       NetArpWaitPacketMAC = NULL;
+       NetArpWaitTxPacket = NULL;
+       NetArpWaitPacketIP = 0;
+       NetArpWaitReplyIP = 0;
+       NetArpWaitTxPacket = NULL;
+       NetTxPacket = NULL;
+
+       if (!NetTxPacket) {
+               int     i;
+               /*
+                *      Setup packet buffers, aligned correctly.
+                */
+               NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
+               NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
+               for (i = 0; i < PKTBUFSRX; i++) {
+                       NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
+               }
+       }
+
+       if (!NetArpWaitTxPacket) {
+               NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
+               NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
+               NetArpWaitTxPacketSize = 0;
+       }
+
+       eth_halt();
+#ifdef CONFIG_NET_MULTI
+       eth_set_current();
+#endif
+       if (eth_init(bd) < 0) {
+               eth_halt();
+               return(-1);
+       }
+
+restart:
+#ifdef CONFIG_NET_MULTI
+       memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);
+#else
+       memcpy (NetOurEther, bd->bi_enetaddr, 6);
+#endif
+
+       NetState = NETLOOP_CONTINUE;
+
+       /*
+        *      Start the ball rolling with the given start function.  From
+        *      here on, this code is a state machine driven by received
+        *      packets and timer events.
+        */
+
+       switch (protocol) {
+#if (CONFIG_COMMANDS & CFG_CMD_NFS)
+       case NFS:
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+       case PING:
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
+       case SNTP:
+#endif
+       case NETCONS:
+       case TFTP:
+               NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
+               NetOurGatewayIP = getenv_IPaddr ("gatewayip");
+               NetOurSubnetMask= getenv_IPaddr ("netmask");
+               NetOurVLAN = getenv_VLAN("vlan");
+               NetOurNativeVLAN = getenv_VLAN("nvlan");
+
+               switch (protocol) {
+#if (CONFIG_COMMANDS & CFG_CMD_NFS)
+               case NFS:
+#endif
+               case NETCONS:
+               case TFTP:
+                       NetServerIP = getenv_IPaddr ("serverip");
+                       break;
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+               case PING:
+                       /* nothing */
+                       break;
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
+               case SNTP:
+                       /* nothing */
+                       break;
+#endif
+               default:
+                       break;
+               }
+
+               break;
+       case BOOTP:
+       case RARP:
+               /*
+                * initialize our IP addr to 0 in order to accept ANY
+                * IP addr assigned to us by the BOOTP / RARP server
+                */
+               NetOurIP = 0;
+               NetServerIP = getenv_IPaddr ("serverip");
+               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
+               NetOurNativeVLAN = getenv_VLAN("nvlan");
+       case CDP:
+               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
+               NetOurNativeVLAN = getenv_VLAN("nvlan");
+               break;
+       default:
+               break;
+       }
+
+       switch (net_check_prereq (protocol)) {
+       case 1:
+               /* network not configured */
+               eth_halt();
+               return (-1);
+
+#ifdef CONFIG_NET_MULTI
+       case 2:
+               /* network device not configured */
+               break;
+#endif /* CONFIG_NET_MULTI */
+
+       case 0:
+#ifdef CONFIG_NET_MULTI
+               NetDevExists = 1;
+#endif
+               switch (protocol) {
+               case TFTP:
+                       /* always use ARP to get server ethernet address */
+                       TftpStart();
+                       break;
+
+#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
+               case DHCP:
+                       /* Start with a clean slate... */
+                       BootpTry = 0;
+                       NetOurIP = 0;
+                       NetServerIP = getenv_IPaddr ("serverip");
+                       DhcpRequest();          /* Basically same as BOOTP */
+                       break;
+#endif /* CFG_CMD_DHCP */
+
+               case BOOTP:
+                       BootpTry = 0;
+                       BootpRequest ();
+                       break;
+
+               case RARP:
+                       RarpTry = 0;
+                       RarpRequest ();
+                       break;
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+               case PING:
+                       PingStart();
+                       break;
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_NFS)
+               case NFS:
+                       NfsStart();
+                       break;
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+               case CDP:
+                       CDPStart();
+                       break;
+#endif
+#ifdef CONFIG_NETCONSOLE
+               case NETCONS:
+                       NcStart();
+                       break;
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
+               case SNTP:
+                       SntpStart();
+                       break;
+#endif
+               default:
+                       break;
+               }
+
+               NetBootFileXferSize = 0;
+               break;
+       }
+
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+#if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED)
+       /*
+        * Echo the inverted link state to the fault LED.
+        */
+       if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) {
+               status_led_set (STATUS_LED_RED, STATUS_LED_OFF);
+       } else {
+               status_led_set (STATUS_LED_RED, STATUS_LED_ON);
+       }
+#endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */
+#endif /* CONFIG_MII, ... */
+
+       /*
+        *      Main packet reception loop.  Loop receiving packets until
+        *      someone sets `NetState' to a state that terminates.
+        */
+       for (;;) {
+               WATCHDOG_RESET();
+#ifdef CONFIG_SHOW_ACTIVITY
+               {
+                       extern void show_activity(int arg);
+                       show_activity(1);
+               }
+#endif
+               /*
+                *      Check the ethernet for a new packet.  The ethernet
+                *      receive routine will process it.
+                */
+                       eth_rx();
+
+               /*
+                *      Abort if ctrl-c was pressed.
+                */
+               if (ctrlc()) {
+                       eth_halt();
+                       puts ("\nAbort\n");
+                       return (-1);
+               }
+
+               ArpTimeoutCheck();
+
+               /*
+                *      Check for a timeout, and run the timeout handler
+                *      if we have one.
+                */
+               if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
+                       thand_f *x;
+
+#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
+#  if defined(CFG_FAULT_ECHO_LINK_DOWN) && \
+      defined(CONFIG_STATUS_LED) &&       \
+      defined(STATUS_LED_RED)
+                       /*
+                        * Echo the inverted link state to the fault LED.
+                        */
+                       if(miiphy_link(eth_get_dev()->name, CFG_FAULT_MII_ADDR)) {
+                               status_led_set (STATUS_LED_RED, STATUS_LED_OFF);
+                       } else {
+                               status_led_set (STATUS_LED_RED, STATUS_LED_ON);
+                       }
+#  endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */
+#endif /* CONFIG_MII, ... */
+                       x = timeHandler;
+                       timeHandler = (thand_f *)0;
+                       (*x)();
+               }
+
+
+               switch (NetState) {
+
+               case NETLOOP_RESTART:
+#ifdef CONFIG_NET_MULTI
+                       NetRestarted = 1;
+#endif
+                       goto restart;
+
+               case NETLOOP_SUCCESS:
+                       if (NetBootFileXferSize > 0) {
+                               char buf[10];
+                               printf("Bytes transferred = %ld (%lx hex)\n",
+                                       NetBootFileXferSize,
+                                       NetBootFileXferSize);
+                               sprintf(buf, "%lx", NetBootFileXferSize);
+                               setenv("filesize", buf);
+
+                               sprintf(buf, "%lX", (unsigned long)load_addr);
+                               setenv("fileaddr", buf);
+                       }
+                       eth_halt();
+                       return NetBootFileXferSize;
+
+               case NETLOOP_FAIL:
+                       return (-1);
+               }
+       }
+}
+
+/**********************************************************************/
+
+static void
+startAgainTimeout(void)
+{
+       NetState = NETLOOP_RESTART;
+}
+
+static void
+startAgainHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
+{
+       /* Totally ignore the packet */
+}
+
+void NetStartAgain (void)
+{
+       char *nretry;
+       int noretry = 0, once = 0;
+
+       if ((nretry = getenv ("netretry")) != NULL) {
+               noretry = (strcmp (nretry, "no") == 0);
+               once = (strcmp (nretry, "once") == 0);
+       }
+       if (noretry) {
+               eth_halt ();
+               NetState = NETLOOP_FAIL;
+               return;
+       }
+#ifndef CONFIG_NET_MULTI
+       NetSetTimeout (10 * CFG_HZ, startAgainTimeout);
+       NetSetHandler (startAgainHandler);
+#else  /* !CONFIG_NET_MULTI*/
+       eth_halt ();
+       eth_try_another (!NetRestarted);
+       eth_init (gd->bd);
+       if (NetRestartWrap) {
+               NetRestartWrap = 0;
+               if (NetDevExists && !once) {
+                       NetSetTimeout (10 * CFG_HZ, startAgainTimeout);
+                       NetSetHandler (startAgainHandler);
+               } else {
+                       NetState = NETLOOP_FAIL;
+               }
+       } else {
+               NetState = NETLOOP_RESTART;
+       }
+#endif /* CONFIG_NET_MULTI */
+}
+
+/**********************************************************************/
+/*
+ *     Miscelaneous bits.
+ */
+
+void
+NetSetHandler(rxhand_f * f)
+{
+       packetHandler = f;
+}
+
+
+void
+NetSetTimeout(ulong iv, thand_f * f)
+{
+       if (iv == 0) {
+               timeHandler = (thand_f *)0;
+       } else {
+               timeHandler = f;
+               timeStart = get_timer(0);
+               timeDelta = iv;
+       }
+}
+
+
+void
+NetSendPacket(volatile uchar * pkt, int len)
+{
+       (void) eth_send(pkt, len);
+}
+
+int
+NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)
+{
+       uchar *pkt;
+
+       /* convert to new style broadcast */
+       if (dest == 0)
+               dest = 0xFFFFFFFF;
+
+       /* if broadcast, make the ether address a broadcast and don't do ARP */
+       if (dest == 0xFFFFFFFF)
+               ether = NetBcastAddr;
+
+       /* if MAC address was not discovered yet, save the packet and do an ARP request */
+       if (memcmp(ether, NetEtherNullAddr, 6) == 0) {
+
+#ifdef ET_DEBUG
+               printf("sending ARP for %08lx\n", dest);
+#endif
+               NetArpWaitPacketIP = dest;
+               NetArpWaitPacketMAC = ether;
+
+               pkt = NetArpWaitTxPacket;
+               pkt += NetSetEther (pkt, NetArpWaitPacketMAC, PROT_IP);
+
+               NetSetIP (pkt, dest, dport, sport, len);
+               memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len);
+
+               /* size of the waiting packet */
+               NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len;
+
+               /* and do the ARP request */
+               NetArpWaitTry = 1;
+               NetArpWaitTimerStart = get_timer(0);
+               ArpRequest();
+               return 1;       /* waiting */
+       }
+
+#ifdef ET_DEBUG
+       printf("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n",
+               dest, ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]);
+#endif
+
+       pkt = (uchar *)NetTxPacket;
+       pkt += NetSetEther (pkt, ether, PROT_IP);
+       NetSetIP (pkt, dest, dport, sport, len);
+       (void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len);
+
+       return 0;       /* transmitted */
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+static ushort PingSeqNo;
+
+int PingSend(void)
+{
+       static uchar mac[6];
+       volatile IP_t *ip;
+       volatile ushort *s;
+       uchar *pkt;
+
+       /* XXX always send arp request */
+
+       memcpy(mac, NetEtherNullAddr, 6);
+
+#ifdef ET_DEBUG
+       printf("sending ARP for %08lx\n", NetPingIP);
+#endif
+
+       NetArpWaitPacketIP = NetPingIP;
+       NetArpWaitPacketMAC = mac;
+
+       pkt = NetArpWaitTxPacket;
+       pkt += NetSetEther(pkt, mac, PROT_IP);
+
+       ip = (volatile IP_t *)pkt;
+
+       /*
+        *      Construct an IP and ICMP header.  (need to set no fragment bit - XXX)
+        */
+       ip->ip_hl_v  = 0x45;            /* IP_HDR_SIZE / 4 (not including UDP) */
+       ip->ip_tos   = 0;
+       ip->ip_len   = htons(IP_HDR_SIZE_NO_UDP + 8);
+       ip->ip_id    = htons(NetIPID++);
+       ip->ip_off   = htons(0x4000);   /* No fragmentation */
+       ip->ip_ttl   = 255;
+       ip->ip_p     = 0x01;            /* ICMP */
+       ip->ip_sum   = 0;
+       NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */
+       NetCopyIP((void*)&ip->ip_dst, &NetPingIP);         /* - "" - */
+       ip->ip_sum   = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);
+
+       s = &ip->udp_src;               /* XXX ICMP starts here */
+       s[0] = htons(0x0800);           /* echo-request, code */
+       s[1] = 0;                       /* checksum */
+       s[2] = 0;                       /* identifier */
+       s[3] = htons(PingSeqNo++);      /* sequence number */
+       s[1] = ~NetCksum((uchar *)s, 8/2);
+
+       /* size of the waiting packet */
+       NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE_NO_UDP + 8;
+
+       /* and do the ARP request */
+       NetArpWaitTry = 1;
+       NetArpWaitTimerStart = get_timer(0);
+       ArpRequest();
+       return 1;       /* waiting */
+}
+
+static void
+PingTimeout (void)
+{
+       eth_halt();
+       NetState = NETLOOP_FAIL;        /* we did not get the reply */
+}
+
+static void
+PingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
+{
+       IPaddr_t tmp;
+       volatile IP_t *ip = (volatile IP_t *)pkt;
+
+       tmp = NetReadIP((void *)&ip->ip_src);
+       if (tmp != NetPingIP)
+               return;
+
+       NetState = NETLOOP_SUCCESS;
+}
+
+static void PingStart(void)
+{
+#if defined(CONFIG_NET_MULTI)
+       printf ("Using %s device\n", eth_get_name());
+#endif /* CONFIG_NET_MULTI */
+       NetSetTimeout (10 * CFG_HZ, PingTimeout);
+       NetSetHandler (PingHandler);
+
+       PingSend();
+}
+#endif /* CFG_CMD_PING */
+
+#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+
+#define CDP_DEVICE_ID_TLV              0x0001
+#define CDP_ADDRESS_TLV                        0x0002
+#define CDP_PORT_ID_TLV                        0x0003
+#define CDP_CAPABILITIES_TLV           0x0004
+#define CDP_VERSION_TLV                        0x0005
+#define CDP_PLATFORM_TLV               0x0006
+#define CDP_NATIVE_VLAN_TLV            0x000a
+#define CDP_APPLIANCE_VLAN_TLV         0x000e
+#define CDP_TRIGGER_TLV                        0x000f
+#define CDP_POWER_CONSUMPTION_TLV      0x0010
+#define CDP_SYSNAME_TLV                        0x0014
+#define CDP_SYSOBJECT_TLV              0x0015
+#define CDP_MANAGEMENT_ADDRESS_TLV     0x0016
+
+#define CDP_TIMEOUT                    (CFG_HZ/4)      /* one packet every 250ms */
+
+static int CDPSeq;
+static int CDPOK;
+
+ushort CDPNativeVLAN;
+ushort CDPApplianceVLAN;
+
+static const uchar CDP_SNAP_hdr[8] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x0C, 0x20, 0x00 };
+
+static ushort CDP_compute_csum(const uchar *buff, ushort len)
+{
+       ushort csum;
+       int     odd;
+       ulong   result = 0;
+       ushort  leftover;
+       ushort *p;
+
+       if (len > 0) {
+               odd = 1 & (ulong)buff;
+               if (odd) {
+                       result = *buff << 8;
+                       len--;
+                       buff++;
+               }
+               while (len > 1) {
+                       p = (ushort *)buff;
+                       result += *p++;
+                       buff = (uchar *)p;
+                       if (result & 0x80000000)
+                               result = (result & 0xFFFF) + (result >> 16);
+                       len -= 2;
+               }
+               if (len) {
+                       leftover = (signed short)(*(const signed char *)buff);
+                       /* CISCO SUCKS big time! (and blows too):
+                        * CDP uses the IP checksum algorithm with a twist;
+                        * for the last byte it *sign* extends and sums.
+                        */
+                       result = (result & 0xffff0000) | ((result + leftover) & 0x0000ffff);
+               }
+               while (result >> 16)
+                       result = (result & 0xFFFF) + (result >> 16);
+
+               if (odd)
+                       result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+       }
+
+       /* add up 16-bit and 17-bit words for 17+c bits */
+       result = (result & 0xffff) + (result >> 16);
+       /* add up 16-bit and 2-bit for 16+c bit */
+       result = (result & 0xffff) + (result >> 16);
+       /* add up carry.. */
+       result = (result & 0xffff) + (result >> 16);
+
+       /* negate */
+       csum = ~(ushort)result;
+
+       /* run time endian detection */
+       if (csum != htons(csum))        /* little endian */
+               csum = htons(csum);
+
+       return csum;
+}
+
+int CDPSendTrigger(void)
+{
+       volatile uchar *pkt;
+       volatile ushort *s;
+       volatile ushort *cp;
+       Ethernet_t *et;
+       int len;
+       ushort chksum;
+#if defined(CONFIG_CDP_DEVICE_ID) || defined(CONFIG_CDP_PORT_ID)   || \
+    defined(CONFIG_CDP_VERSION)   || defined(CONFIG_CDP_PLATFORM)
+       char buf[32];
+#endif
+
+       pkt = NetTxPacket;
+       et = (Ethernet_t *)pkt;
+
+       /* NOTE: trigger sent not on any VLAN */
+
+       /* form ethernet header */
+       memcpy(et->et_dest, NetCDPAddr, 6);
+       memcpy(et->et_src, NetOurEther, 6);
+
+       pkt += ETHER_HDR_SIZE;
+
+       /* SNAP header */
+       memcpy((uchar *)pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr));
+       pkt += sizeof(CDP_SNAP_hdr);
+
+       /* CDP header */
+       *pkt++ = 0x02;                          /* CDP version 2 */
+       *pkt++ = 180;                           /* TTL */
+       s = (volatile ushort *)pkt;
+       cp = s;
+       *s++ = htons(0);                        /* checksum (0 for later calculation) */
+
+       /* CDP fields */
+#ifdef CONFIG_CDP_DEVICE_ID
+       *s++ = htons(CDP_DEVICE_ID_TLV);
+       *s++ = htons(CONFIG_CDP_DEVICE_ID);
+       memset(buf, 0, sizeof(buf));
+       sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%02X%02X%02X%02X%02X%02X",
+               NetOurEther[0] & 0xff, NetOurEther[1] & 0xff,
+               NetOurEther[2] & 0xff, NetOurEther[3] & 0xff,
+               NetOurEther[4] & 0xff, NetOurEther[5] & 0xff);
+       memcpy((uchar *)s, buf, 16);
+       s += 16 / 2;
+#endif
+
+#ifdef CONFIG_CDP_PORT_ID
+       *s++ = htons(CDP_PORT_ID_TLV);
+       memset(buf, 0, sizeof(buf));
+       sprintf(buf, CONFIG_CDP_PORT_ID, eth_get_dev_index());
+       len = strlen(buf);
+       if (len & 1)    /* make it even */
+               len++;
+       *s++ = htons(len + 4);
+       memcpy((uchar *)s, buf, len);
+       s += len / 2;
+#endif
+
+#ifdef CONFIG_CDP_CAPABILITIES
+       *s++ = htons(CDP_CAPABILITIES_TLV);
+       *s++ = htons(8);
+       *(ulong *)s = htonl(CONFIG_CDP_CAPABILITIES);
+       s += 2;
+#endif
+
+#ifdef CONFIG_CDP_VERSION
+       *s++ = htons(CDP_VERSION_TLV);
+       memset(buf, 0, sizeof(buf));
+       strcpy(buf, CONFIG_CDP_VERSION);
+       len = strlen(buf);
+       if (len & 1)    /* make it even */
+               len++;
+       *s++ = htons(len + 4);
+       memcpy((uchar *)s, buf, len);
+       s += len / 2;
+#endif
+
+#ifdef CONFIG_CDP_PLATFORM
+       *s++ = htons(CDP_PLATFORM_TLV);
+       memset(buf, 0, sizeof(buf));
+       strcpy(buf, CONFIG_CDP_PLATFORM);
+       len = strlen(buf);
+       if (len & 1)    /* make it even */
+               len++;
+       *s++ = htons(len + 4);
+       memcpy((uchar *)s, buf, len);
+       s += len / 2;
+#endif
+
+#ifdef CONFIG_CDP_TRIGGER
+       *s++ = htons(CDP_TRIGGER_TLV);
+       *s++ = htons(8);
+       *(ulong *)s = htonl(CONFIG_CDP_TRIGGER);
+       s += 2;
+#endif
+
+#ifdef CONFIG_CDP_POWER_CONSUMPTION
+       *s++ = htons(CDP_POWER_CONSUMPTION_TLV);
+       *s++ = htons(6);
+       *s++ = htons(CONFIG_CDP_POWER_CONSUMPTION);
+#endif
+
+       /* length of ethernet packet */
+       len = (uchar *)s - ((uchar *)NetTxPacket + ETHER_HDR_SIZE);
+       et->et_protlen = htons(len);
+
+       len = ETHER_HDR_SIZE + sizeof(CDP_SNAP_hdr);
+       chksum = CDP_compute_csum((uchar *)NetTxPacket + len, (uchar *)s - (NetTxPacket + len));
+       if (chksum == 0)
+               chksum = 0xFFFF;
+       *cp = htons(chksum);
+
+       (void) eth_send(NetTxPacket, (uchar *)s - NetTxPacket);
+       return 0;
+}
+
+static void
+CDPTimeout (void)
+{
+       CDPSeq++;
+
+       if (CDPSeq < 3) {
+               NetSetTimeout (CDP_TIMEOUT, CDPTimeout);
+               CDPSendTrigger();
+               return;
+       }
+
+       /* if not OK try again */
+       if (!CDPOK)
+               NetStartAgain();
+       else
+               NetState = NETLOOP_SUCCESS;
+}
+
+static void
+CDPDummyHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
+{
+       /* nothing */
+}
+
+static void
+CDPHandler(const uchar * pkt, unsigned len)
+{
+       const uchar *t;
+       const ushort *ss;
+       ushort type, tlen;
+       uchar applid;
+       ushort vlan, nvlan;
+
+       /* minimum size? */
+       if (len < sizeof(CDP_SNAP_hdr) + 4)
+               goto pkt_short;
+
+       /* check for valid CDP SNAP header */
+       if (memcmp(pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)) != 0)
+               return;
+
+       pkt += sizeof(CDP_SNAP_hdr);
+       len -= sizeof(CDP_SNAP_hdr);
+
+       /* Version of CDP protocol must be >= 2 and TTL != 0 */
+       if (pkt[0] < 0x02 || pkt[1] == 0)
+               return;
+
+       /* if version is greater than 0x02 maybe we'll have a problem; output a warning */
+       if (pkt[0] != 0x02)
+               printf("** WARNING: CDP packet received with a protocol version %d > 2\n",
+                               pkt[0] & 0xff);
+
+       if (CDP_compute_csum(pkt, len) != 0)
+               return;
+
+       pkt += 4;
+       len -= 4;
+
+       vlan = htons(-1);
+       nvlan = htons(-1);
+       while (len > 0) {
+               if (len < 4)
+                       goto pkt_short;
+
+               ss = (const ushort *)pkt;
+               type = ntohs(ss[0]);
+               tlen = ntohs(ss[1]);
+               if (tlen > len) {
+                       goto pkt_short;
+               }
+
+               pkt += tlen;
+               len -= tlen;
+
+               ss += 2;        /* point ss to the data of the TLV */
+               tlen -= 4;
+
+               switch (type) {
+                       case CDP_DEVICE_ID_TLV:
+                               break;
+                       case CDP_ADDRESS_TLV:
+                               break;
+                       case CDP_PORT_ID_TLV:
+                               break;
+                       case CDP_CAPABILITIES_TLV:
+                               break;
+                       case CDP_VERSION_TLV:
+                               break;
+                       case CDP_PLATFORM_TLV:
+                               break;
+                       case CDP_NATIVE_VLAN_TLV:
+                               nvlan = *ss;
+                               break;
+                       case CDP_APPLIANCE_VLAN_TLV:
+                               t = (const uchar *)ss;
+                               while (tlen > 0) {
+                                       if (tlen < 3)
+                                               goto pkt_short;
+
+                                       applid = t[0];
+                                       ss = (const ushort *)(t + 1);
+
+#ifdef CONFIG_CDP_APPLIANCE_VLAN_TYPE
+                                       if (applid == CONFIG_CDP_APPLIANCE_VLAN_TYPE)
+                                               vlan = *ss;
+#else
+                                       vlan = ntohs(*ss);      /* XXX will this work; dunno */
+#endif
+                                       t += 3; tlen -= 3;
+                               }
+                               break;
+                       case CDP_TRIGGER_TLV:
+                               break;
+                       case CDP_POWER_CONSUMPTION_TLV:
+                               break;
+                       case CDP_SYSNAME_TLV:
+                               break;
+                       case CDP_SYSOBJECT_TLV:
+                               break;
+                       case CDP_MANAGEMENT_ADDRESS_TLV:
+                               break;
+               }
+       }
+
+       CDPApplianceVLAN = vlan;
+       CDPNativeVLAN = nvlan;
+
+       CDPOK = 1;
+       return;
+
+ pkt_short:
+       printf("** CDP packet is too short\n");
+       return;
+}
+
+static void CDPStart(void)
+{
+#if defined(CONFIG_NET_MULTI)
+       printf ("Using %s device\n", eth_get_name());
+#endif
+       CDPSeq = 0;
+       CDPOK = 0;
+
+       CDPNativeVLAN = htons(-1);
+       CDPApplianceVLAN = htons(-1);
+
+       NetSetTimeout (CDP_TIMEOUT, CDPTimeout);
+       NetSetHandler (CDPDummyHandler);
+
+       CDPSendTrigger();
+}
+#endif /* CFG_CMD_CDP */
+
+
+void
+NetReceive(volatile uchar * inpkt, int len)
+{
+       Ethernet_t *et;
+       IP_t    *ip;
+       ARP_t   *arp;
+       IPaddr_t tmp;
+       int     x;
+       uchar *pkt;
+#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+       int iscdp;
+#endif
+       ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid;
+
+#ifdef ET_DEBUG
+       printf("packet received\n");
+#endif
+
+       NetRxPkt = inpkt;
+       NetRxPktLen = len;
+       et = (Ethernet_t *)inpkt;
+
+       /* too small packet? */
+       if (len < ETHER_HDR_SIZE)
+               return;
+
+#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+       /* keep track if packet is CDP */
+       iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0;
+#endif
+
+       myvlanid = ntohs(NetOurVLAN);
+       if (myvlanid == (ushort)-1)
+               myvlanid = VLAN_NONE;
+       mynvlanid = ntohs(NetOurNativeVLAN);
+       if (mynvlanid == (ushort)-1)
+               mynvlanid = VLAN_NONE;
+
+       x = ntohs(et->et_protlen);
+
+#ifdef ET_DEBUG
+       printf("packet received\n");
+#endif
+
+       if (x < 1514) {
+               /*
+                *      Got a 802 packet.  Check the other protocol field.
+                */
+               x = ntohs(et->et_prot);
+
+               ip = (IP_t *)(inpkt + E802_HDR_SIZE);
+               len -= E802_HDR_SIZE;
+
+       } else if (x != PROT_VLAN) {    /* normal packet */
+               ip = (IP_t *)(inpkt + ETHER_HDR_SIZE);
+               len -= ETHER_HDR_SIZE;
+
+       } else {                        /* VLAN packet */
+               VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)et;
+
+#ifdef ET_DEBUG
+               printf("VLAN packet received\n");
+#endif
+               /* too small packet? */
+               if (len < VLAN_ETHER_HDR_SIZE)
+                       return;
+
+               /* if no VLAN active */
+               if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE
+#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+                               && iscdp == 0
+#endif
+                               )
+                       return;
+
+               cti = ntohs(vet->vet_tag);
+               vlanid = cti & VLAN_IDMASK;
+               x = ntohs(vet->vet_type);
+
+               ip = (IP_t *)(inpkt + VLAN_ETHER_HDR_SIZE);
+               len -= VLAN_ETHER_HDR_SIZE;
+       }
+
+#ifdef ET_DEBUG
+       printf("Receive from protocol 0x%x\n", x);
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_CDP)
+       if (iscdp) {
+               CDPHandler((uchar *)ip, len);
+               return;
+       }
+#endif
+
+       if ((myvlanid & VLAN_IDMASK) != VLAN_NONE) {
+               if (vlanid == VLAN_NONE)
+                       vlanid = (mynvlanid & VLAN_IDMASK);
+               /* not matched? */
+               if (vlanid != (myvlanid & VLAN_IDMASK))
+                       return;
+       }
+
+       switch (x) {
+
+       case PROT_ARP:
+               /*
+                * We have to deal with two types of ARP packets:
+                * - REQUEST packets will be answered by sending  our
+                *   IP address - if we know it.
+                * - REPLY packates are expected only after we asked
+                *   for the TFTP server's or the gateway's ethernet
+                *   address; so if we receive such a packet, we set
+                *   the server ethernet address
+                */
+#ifdef ET_DEBUG
+               puts ("Got ARP\n");
+#endif
+               arp = (ARP_t *)ip;
+               if (len < ARP_HDR_SIZE) {
+                       printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
+                       return;
+               }
+               if (ntohs(arp->ar_hrd) != ARP_ETHER) {
+                       return;
+               }
+               if (ntohs(arp->ar_pro) != PROT_IP) {
+                       return;
+               }
+               if (arp->ar_hln != 6) {
+                       return;
+               }
+               if (arp->ar_pln != 4) {
+                       return;
+               }
+
+               if (NetOurIP == 0) {
+                       return;
+               }
+
+               if (NetReadIP(&arp->ar_data[16]) != NetOurIP) {
+                       return;
+               }
+
+               switch (ntohs(arp->ar_op)) {
+               case ARPOP_REQUEST:             /* reply with our IP address    */
+#ifdef ET_DEBUG
+                       puts ("Got ARP REQUEST, return our IP\n");
+#endif
+                       pkt = (uchar *)et;
+                       pkt += NetSetEther(pkt, et->et_src, PROT_ARP);
+                       arp->ar_op = htons(ARPOP_REPLY);
+                       memcpy   (&arp->ar_data[10], &arp->ar_data[0], 6);
+                       NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]);
+                       memcpy   (&arp->ar_data[ 0], NetOurEther, 6);
+                       NetCopyIP(&arp->ar_data[ 6], &NetOurIP);
+                       (void) eth_send((uchar *)et, (pkt - (uchar *)et) + ARP_HDR_SIZE);
+                       return;
+
+               case ARPOP_REPLY:               /* arp reply */
+                       /* are we waiting for a reply */
+                       if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC)
+                               break;
+#ifdef ET_DEBUG
+                       printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+                               arp->ar_data[0], arp->ar_data[1],
+                               arp->ar_data[2], arp->ar_data[3],
+                               arp->ar_data[4], arp->ar_data[5]);
+#endif
+
+                       tmp = NetReadIP(&arp->ar_data[6]);
+
+                       /* matched waiting packet's address */
+                       if (tmp == NetArpWaitReplyIP) {
+#ifdef ET_DEBUG
+                               puts ("Got it\n");
+#endif
+                               /* save address for later use */
+                               memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6);
+
+#ifdef CONFIG_NETCONSOLE
+                               (*packetHandler)(0,0,0,0);
+#endif
+                               /* modify header, and transmit it */
+                               memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6);
+                               (void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize);
+
+                               /* no arp request pending now */
+                               NetArpWaitPacketIP = 0;
+                               NetArpWaitTxPacketSize = 0;
+                               NetArpWaitPacketMAC = NULL;
+
+                       }
+                       return;
+               default:
+#ifdef ET_DEBUG
+                       printf("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op));
+#endif
+                       return;
+               }
+               break;
+
+       case PROT_RARP:
+#ifdef ET_DEBUG
+               puts ("Got RARP\n");
+#endif
+               arp = (ARP_t *)ip;
+               if (len < ARP_HDR_SIZE) {
+                       printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
+                       return;
+               }
+
+               if ((ntohs(arp->ar_op) != RARPOP_REPLY) ||
+                       (ntohs(arp->ar_hrd) != ARP_ETHER)   ||
+                       (ntohs(arp->ar_pro) != PROT_IP)     ||
+                       (arp->ar_hln != 6) || (arp->ar_pln != 4)) {
+
+                       puts ("invalid RARP header\n");
+               } else {
+                       NetCopyIP(&NetOurIP,    &arp->ar_data[16]);
+                       if (NetServerIP == 0)
+                               NetCopyIP(&NetServerIP, &arp->ar_data[ 6]);
+                       memcpy (NetServerEther, &arp->ar_data[ 0], 6);
+
+                       (*packetHandler)(0,0,0,0);
+               }
+               break;
+
+       case PROT_IP:
+#ifdef ET_DEBUG
+               puts ("Got IP\n");
+#endif
+               if (len < IP_HDR_SIZE) {
+                       debug ("len bad %d < %d\n", len, IP_HDR_SIZE);
+                       return;
+               }
+               if (len < ntohs(ip->ip_len)) {
+                       printf("len bad %d < %d\n", len, ntohs(ip->ip_len));
+                       return;
+               }
+               len = ntohs(ip->ip_len);
+#ifdef ET_DEBUG
+               printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff);
+#endif
+               if ((ip->ip_hl_v & 0xf0) != 0x40) {
+                       return;
+               }
+               if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */
+                       return;
+               }
+               if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) {
+                       puts ("checksum bad\n");
+                       return;
+               }
+               tmp = NetReadIP(&ip->ip_dst);
+               if (NetOurIP && tmp != NetOurIP && tmp != 0xFFFFFFFF) {
+                       return;
+               }
+               /*
+                * watch for ICMP host redirects
+                *
+                * There is no real handler code (yet). We just watch
+                * for ICMP host redirect messages. In case anybody
+                * sees these messages: please contact me
+                * (wd@denx.de), or - even better - send me the
+                * necessary fixes :-)
+                *
+                * Note: in all cases where I have seen this so far
+                * it was a problem with the router configuration,
+                * for instance when a router was configured in the
+                * BOOTP reply, but the TFTP server was on the same
+                * subnet. So this is probably a warning that your
+                * configuration might be wrong. But I'm not really
+                * sure if there aren't any other situations.
+                */
+               if (ip->ip_p == IPPROTO_ICMP) {
+                       ICMP_t *icmph = (ICMP_t *)&(ip->udp_src);
+
+                       switch (icmph->type) {
+                       case ICMP_REDIRECT:
+                               if (icmph->code != ICMP_REDIR_HOST)
+                                       return;
+                               puts (" ICMP Host Redirect to ");
+                               print_IPaddr(icmph->un.gateway);
+                               putc(' ');
+                               return;
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+                       case ICMP_ECHO_REPLY:
+                               /*
+                                *      IP header OK.  Pass the packet to the current handler.
+                                */
+                               /* XXX point to ip packet */
+                               (*packetHandler)((uchar *)ip, 0, 0, 0);
+                               return;
+#endif
+                       default:
+                               return;
+                       }
+               } else if (ip->ip_p != IPPROTO_UDP) {   /* Only UDP packets */
+                       return;
+               }
+
+#ifdef CONFIG_UDP_CHECKSUM
+               if (ip->udp_xsum != 0) {
+                       ulong   xsum;
+                       ushort *sumptr;
+                       ushort  sumlen;
+
+                       xsum  = ip->ip_p;
+                       xsum += (ntohs(ip->udp_len));
+                       xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff;
+                       xsum += (ntohl(ip->ip_src) >>  0) & 0x0000ffff;
+                       xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff;
+                       xsum += (ntohl(ip->ip_dst) >>  0) & 0x0000ffff;
+
+                       sumlen = ntohs(ip->udp_len);
+                       sumptr = (ushort *) &(ip->udp_src);
+
+                       while (sumlen > 1) {
+                               ushort sumdata;
+
+                               sumdata = *sumptr++;
+                               xsum += ntohs(sumdata);
+                               sumlen -= 2;
+                       }
+                       if (sumlen > 0) {
+                               ushort sumdata;
+
+                               sumdata = *(unsigned char *) sumptr;
+                               sumdata = (sumdata << 8) & 0xff00;
+                               xsum += sumdata;
+                       }
+                       while ((xsum >> 16) != 0) {
+                               xsum = (xsum & 0x0000ffff) + ((xsum >> 16) & 0x0000ffff);
+                       }
+                       if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) {
+                               printf(" UDP wrong checksum %08x %08x\n", xsum, ntohs(ip->udp_xsum));
+                               return;
+                       }
+               }
+#endif
+
+#ifdef CONFIG_NETCONSOLE
+               nc_input_packet((uchar *)ip +IP_HDR_SIZE,
+                                               ntohs(ip->udp_dst),
+                                               ntohs(ip->udp_src),
+                                               ntohs(ip->udp_len) - 8);
+#endif
+               /*
+                *      IP header OK.  Pass the packet to the current handler.
+                */
+               (*packetHandler)((uchar *)ip +IP_HDR_SIZE,
+                                               ntohs(ip->udp_dst),
+                                               ntohs(ip->udp_src),
+                                               ntohs(ip->udp_len) - 8);
+               break;
+       }
+}
+
+
+/**********************************************************************/
+
+static int net_check_prereq (proto_t protocol)
+{
+       switch (protocol) {
+               /* Fall through */
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+       case PING:
+               if (NetPingIP == 0) {
+                       puts ("*** ERROR: ping address not given\n");
+                       return (1);
+               }
+               goto common;
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_SNTP)
+       case SNTP:
+               if (NetNtpServerIP == 0) {
+                       puts ("*** ERROR: NTP server address not given\n");
+                       return (1);
+               }
+               goto common;
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_NFS)
+       case NFS:
+#endif
+       case NETCONS:
+       case TFTP:
+               if (NetServerIP == 0) {
+                       puts ("*** ERROR: `serverip' not set\n");
+                       return (1);
+               }
+#if (CONFIG_COMMANDS & (CFG_CMD_PING | CFG_CMD_SNTP))
+    common:
+#endif
+
+               if (NetOurIP == 0) {
+                       puts ("*** ERROR: `ipaddr' not set\n");
+                       return (1);
+               }
+               /* Fall through */
+
+       case DHCP:
+       case RARP:
+       case BOOTP:
+       case CDP:
+               if (memcmp (NetOurEther, "\0\0\0\0\0\0", 6) == 0) {
+#ifdef CONFIG_NET_MULTI
+                       extern int eth_get_dev_index (void);
+                       int num = eth_get_dev_index ();
+
+                       switch (num) {
+                       case -1:
+                               puts ("*** ERROR: No ethernet found.\n");
+                               return (1);
+                       case 0:
+                               puts ("*** ERROR: `ethaddr' not set\n");
+                               break;
+                       default:
+                               printf ("*** ERROR: `eth%daddr' not set\n",
+                                       num);
+                               break;
+                       }
+
+                       NetStartAgain ();
+                       return (2);
+#else
+                       puts ("*** ERROR: `ethaddr' not set\n");
+                       return (1);
+#endif
+               }
+               /* Fall through */
+       default:
+               return (0);
+       }
+       return (0);             /* OK */
+}
+/**********************************************************************/
+
+int
+NetCksumOk(uchar * ptr, int len)
+{
+       return !((NetCksum(ptr, len) + 1) & 0xfffe);
+}
+
+
+unsigned
+NetCksum(uchar * ptr, int len)
+{
+       ulong   xsum;
+       ushort *p = (ushort *)ptr;
+
+       xsum = 0;
+       while (len-- > 0)
+               xsum += *p++;
+       xsum = (xsum & 0xffff) + (xsum >> 16);
+       xsum = (xsum & 0xffff) + (xsum >> 16);
+       return (xsum & 0xffff);
+}
+
+int
+NetEthHdrSize(void)
+{
+       ushort myvlanid;
+
+       myvlanid = ntohs(NetOurVLAN);
+       if (myvlanid == (ushort)-1)
+               myvlanid = VLAN_NONE;
+
+       return ((myvlanid & VLAN_IDMASK) == VLAN_NONE) ? ETHER_HDR_SIZE : VLAN_ETHER_HDR_SIZE;
+}
+
+int
+NetSetEther(volatile uchar * xet, uchar * addr, uint prot)
+{
+       Ethernet_t *et = (Ethernet_t *)xet;
+       ushort myvlanid;
+
+       myvlanid = ntohs(NetOurVLAN);
+       if (myvlanid == (ushort)-1)
+               myvlanid = VLAN_NONE;
+
+       memcpy (et->et_dest, addr, 6);
+       memcpy (et->et_src, NetOurEther, 6);
+       if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) {
+       et->et_protlen = htons(prot);
+               return ETHER_HDR_SIZE;
+       } else {
+               VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)xet;
+
+               vet->vet_vlan_type = htons(PROT_VLAN);
+               vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK));
+               vet->vet_type = htons(prot);
+               return VLAN_ETHER_HDR_SIZE;
+       }
+}
+
+void
+NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)
+{
+       volatile IP_t *ip = (IP_t *)xip;
+
+       /*
+        *      If the data is an odd number of bytes, zero the
+        *      byte after the last byte so that the checksum
+        *      will work.
+        */
+       if (len & 1)
+               xip[IP_HDR_SIZE + len] = 0;
+
+       /*
+        *      Construct an IP and UDP header.
+        *      (need to set no fragment bit - XXX)
+        */
+       ip->ip_hl_v  = 0x45;            /* IP_HDR_SIZE / 4 (not including UDP) */
+       ip->ip_tos   = 0;
+       ip->ip_len   = htons(IP_HDR_SIZE + len);
+       ip->ip_id    = htons(NetIPID++);
+       ip->ip_off   = htons(0x4000);   /* No fragmentation */
+       ip->ip_ttl   = 255;
+       ip->ip_p     = 17;              /* UDP */
+       ip->ip_sum   = 0;
+       NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */
+       NetCopyIP((void*)&ip->ip_dst, &dest);      /* - "" - */
+       ip->udp_src  = htons(sport);
+       ip->udp_dst  = htons(dport);
+       ip->udp_len  = htons(8 + len);
+       ip->udp_xsum = 0;
+       ip->ip_sum   = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);
+}
+
+void copy_filename (char *dst, char *src, int size)
+{
+       if (*src && (*src == '"')) {
+               ++src;
+               --size;
+       }
+
+       while ((--size > 0) && *src && (*src != '"')) {
+               *dst++ = *src++;
+       }
+       *dst = '\0';
+}
+
+#endif /* CFG_CMD_NET */
+
+void ip_to_string (IPaddr_t x, char *s)
+{
+       x = ntohl (x);
+       sprintf (s, "%d.%d.%d.%d",
+                (int) ((x >> 24) & 0xff),
+                (int) ((x >> 16) & 0xff),
+                (int) ((x >> 8) & 0xff), (int) ((x >> 0) & 0xff)
+       );
+}
+
+IPaddr_t string_to_ip(char *s)
+{
+       IPaddr_t addr;
+       char *e;
+       int i;
+
+       if (s == NULL)
+               return(0);
+
+       for (addr=0, i=0; i<4; ++i) {
+               ulong val = s ? simple_strtoul(s, &e, 10) : 0;
+               addr <<= 8;
+               addr |= (val & 0xFF);
+               if (s) {
+                       s = (*e) ? e+1 : e;
+               }
+       }
+
+       return (htonl(addr));
+}
+
+void VLAN_to_string(ushort x, char *s)
+{
+       x = ntohs(x);
+
+       if (x == (ushort)-1)
+               x = VLAN_NONE;
+
+       if (x == VLAN_NONE)
+               strcpy(s, "none");
+       else
+               sprintf(s, "%d", x & VLAN_IDMASK);
+}
+
+ushort string_to_VLAN(char *s)
+{
+       ushort id;
+
+       if (s == NULL)
+               return htons(VLAN_NONE);
+
+       if (*s < '0' || *s > '9')
+               id = VLAN_NONE;
+       else
+               id = (ushort)simple_strtoul(s, NULL, 10);
+
+       return htons(id);
+}
+
+void print_IPaddr (IPaddr_t x)
+{
+       char tmp[16];
+
+       ip_to_string (x, tmp);
+
+       puts (tmp);
+}
+
+IPaddr_t getenv_IPaddr (char *var)
+{
+       return (string_to_ip(getenv(var)));
+}
+
+ushort getenv_VLAN(char *var)
+{
+       return (string_to_VLAN(getenv(var)));
+}
diff --git a/package/uboot-ifxmips/files/net/nfs_danube.c b/package/uboot-ifxmips/files/net/nfs_danube.c
new file mode 100644 (file)
index 0000000..de789e1
--- /dev/null
@@ -0,0 +1,778 @@
+/*
+ * NFS support driver - based on etherboot and U-BOOT's tftp.c
+ *
+ * Masami Komiya <mkomiya@sonare.it> 2004
+ *
+ */
+
+/* NOTE: the NFS code is heavily inspired by the NetBSD netboot code (read:
+ * large portions are copied verbatim) as distributed in OSKit 0.97.  A few
+ * changes were necessary to adapt the code to Etherboot and to fix several
+ * inconsistencies.  Also the RPC message preparation is done "by hand" to
+ * avoid adding netsprintf() which I find hard to understand and use.  */
+
+/* NOTE 2: Etherboot does not care about things beyond the kernel image, so
+ * it loads the kernel image off the boot server (ARP_SERVER) and does not
+ * access the client root disk (root-path in dhcpd.conf), which would use
+ * ARP_ROOTSERVER.  The root disk is something the operating system we are
+ * about to load needs to use. This is different from the OSKit 0.97 logic.  */
+
+/* NOTE 3: Symlink handling introduced by Anselm M Hoffmeister, 2003-July-14
+ * If a symlink is encountered, it is followed as far as possible (recursion
+ * possible, maximum 16 steps). There is no clearing of ".."'s inside the
+ * path, so please DON'T DO THAT. thx. */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <malloc.h>
+#include "nfs.h"
+#include "bootp.h"
+
+/*#define NFS_DEBUG*/
+
+#if ((CONFIG_COMMANDS & CFG_CMD_NET) && (CONFIG_COMMANDS & CFG_CMD_NFS))
+
+#define HASHES_PER_LINE 65     /* Number of "loading" hashes per line  */
+#define NFS_TIMEOUT 60
+
+static int fs_mounted = 0;
+static unsigned long rpc_id = 0;
+static int nfs_offset = -1;
+static int nfs_len;
+
+static char dirfh[NFS_FHSIZE]; /* file handle of directory */
+static char filefh[NFS_FHSIZE]; /* file handle of kernel image */
+
+static int     NfsDownloadState;
+static IPaddr_t NfsServerIP;
+static int     NfsSrvMountPort;
+static int     NfsSrvNfsPort;
+static int     NfsOurPort;
+static int     NfsTimeoutCount;
+static int     NfsState;
+#define STATE_PRCLOOKUP_PROG_MOUNT_REQ 1
+#define STATE_PRCLOOKUP_PROG_NFS_REQ   2
+#define STATE_MOUNT_REQ                        3
+#define STATE_UMOUNT_REQ               4
+#define STATE_LOOKUP_REQ               5
+#define STATE_READ_REQ                 6
+#define STATE_READLINK_REQ             7
+
+static char default_filename[64];
+static char *nfs_filename;
+static char *nfs_path;
+static char nfs_path_buff[2048];
+
+static __inline__ int
+store_block (uchar * src, unsigned offset, unsigned len)
+{
+       ulong newsize = offset + len;
+#ifdef CFG_DIRECT_FLASH_NFS
+       int i, rc = 0;
+
+       for (i=0; i<CFG_MAX_FLASH_BANKS; i++) {
+               /* start address in flash? */
+               if (load_addr + offset >= flash_info[i].start[0]) {
+                       rc = 1;
+                       break;
+               }
+       }
+
+       if (rc) { /* Flash is destination for this packet */
+               rc = flash_write ((uchar *)src, (ulong)(load_addr+offset), len);
+               if (rc) {
+                       flash_perror (rc);
+                       return -1;
+               }
+       } else
+#endif /* CFG_DIRECT_FLASH_NFS */
+       {
+               (void)memcpy ((void *)(load_addr + offset), src, len);
+       }
+
+       if (NetBootFileXferSize < (offset+len))
+               NetBootFileXferSize = newsize;
+       return 0;
+}
+
+static char*
+basename (char *path)
+{
+       char *fname;
+
+       fname = path + strlen(path) - 1;
+       while (fname >= path) {
+               if (*fname == '/') {
+                       fname++;
+                       break;
+               }
+               fname--;
+       }
+       return fname;
+}
+
+static char*
+dirname (char *path)
+{
+       char *fname;
+
+       fname = basename (path);
+       --fname;
+       *fname = '\0';
+       return path;
+}
+
+/**************************************************************************
+RPC_ADD_CREDENTIALS - Add RPC authentication/verifier entries
+**************************************************************************/
+static long *rpc_add_credentials (long *p)
+{
+       int hl;
+       int hostnamelen;
+       char hostname[256];
+
+       strcpy (hostname, "");
+       hostnamelen=strlen (hostname);
+
+       /* Here's the executive summary on authentication requirements of the
+        * various NFS server implementations:  Linux accepts both AUTH_NONE
+        * and AUTH_UNIX authentication (also accepts an empty hostname field
+        * in the AUTH_UNIX scheme).  *BSD refuses AUTH_NONE, but accepts
+        * AUTH_UNIX (also accepts an empty hostname field in the AUTH_UNIX
+        * scheme).  To be safe, use AUTH_UNIX and pass the hostname if we have
+        * it (if the BOOTP/DHCP reply didn't give one, just use an empty
+        * hostname).  */
+
+       hl = (hostnamelen + 3) & ~3;
+
+       /* Provide an AUTH_UNIX credential.  */
+       *p++ = htonl(1);                /* AUTH_UNIX */
+       *p++ = htonl(hl+20);            /* auth length */
+       *p++ = htonl(0);                /* stamp */
+       *p++ = htonl(hostnamelen);      /* hostname string */
+       if (hostnamelen & 3) {
+               *(p + hostnamelen / 4) = 0; /* add zero padding */
+       }
+       memcpy (p, hostname, hostnamelen);
+       p += hl / 4;
+       *p++ = 0;                       /* uid */
+       *p++ = 0;                       /* gid */
+       *p++ = 0;                       /* auxiliary gid list */
+
+       /* Provide an AUTH_NONE verifier.  */
+       *p++ = 0;                       /* AUTH_NONE */
+       *p++ = 0;                       /* auth length */
+
+       return p;
+}
+
+/**************************************************************************
+RPC_LOOKUP - Lookup RPC Port numbers
+**************************************************************************/
+static void
+rpc_req (int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
+{
+       struct rpc_t pkt;
+       unsigned long id;
+       uint32_t *p;
+       int pktlen;
+       int sport;
+
+       id = ++rpc_id;
+       pkt.u.call.id = htonl(id);
+       pkt.u.call.type = htonl(MSG_CALL);
+       pkt.u.call.rpcvers = htonl(2);  /* use RPC version 2 */
+       pkt.u.call.prog = htonl(rpc_prog);
+       pkt.u.call.vers = htonl(2);     /* portmapper is version 2 */
+       pkt.u.call.proc = htonl(rpc_proc);
+       p = (uint32_t *)&(pkt.u.call.data);
+
+       if (datalen)
+               memcpy ((char *)p, (char *)data, datalen*sizeof(uint32_t));
+
+       pktlen = (char *)p + datalen*sizeof(uint32_t) - (char *)&pkt;
+
+       memcpy ((char *)NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE, (char *)&pkt, pktlen);
+
+       if (rpc_prog == PROG_PORTMAP)
+               sport = SUNRPC_PORT;
+       else if (rpc_prog == PROG_MOUNT)
+               sport = NfsSrvMountPort;
+       else
+               sport = NfsSrvNfsPort;
+
+       NetSendUDPPacket (NetServerEther, NfsServerIP, sport, NfsOurPort, pktlen);
+}
+
+/**************************************************************************
+RPC_LOOKUP - Lookup RPC Port numbers
+**************************************************************************/
+static void
+rpc_lookup_req (int prog, int ver)
+{
+       uint32_t data[16];
+
+       data[0] = 0; data[1] = 0;       /* auth credential */
+       data[2] = 0; data[3] = 0;       /* auth verifier */
+       data[4] = htonl(prog);
+       data[5] = htonl(ver);
+       data[6] = htonl(17);    /* IP_UDP */
+       data[7] = 0;
+
+       rpc_req (PROG_PORTMAP, PORTMAP_GETPORT, data, 8);
+}
+
+/**************************************************************************
+NFS_MOUNT - Mount an NFS Filesystem
+**************************************************************************/
+static void
+nfs_mount_req (char *path)
+{
+       uint32_t data[1024];
+       uint32_t *p;
+       int len;
+       int pathlen;
+
+       pathlen = strlen (path);
+
+       p = &(data[0]);
+       p = (uint32_t *)rpc_add_credentials((long *)p);
+
+       *p++ = htonl(pathlen);
+       if (pathlen & 3) *(p + pathlen / 4) = 0;
+       memcpy (p, path, pathlen);
+       p += (pathlen + 3) / 4;
+
+       len = (uint32_t *)p - (uint32_t *)&(data[0]);
+
+       rpc_req (PROG_MOUNT, MOUNT_ADDENTRY, data, len);
+}
+
+/**************************************************************************
+NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
+**************************************************************************/
+static void
+nfs_umountall_req (void)
+{
+       uint32_t data[1024];
+       uint32_t *p;
+       int len;
+
+       if ((NfsSrvMountPort == -1) || (!fs_mounted)) {
+               /* Nothing mounted, nothing to umount */
+               return;
+       }
+
+       p = &(data[0]);
+       p = (uint32_t *)rpc_add_credentials ((long *)p);
+
+       len = (uint32_t *)p - (uint32_t *)&(data[0]);
+
+       rpc_req (PROG_MOUNT, MOUNT_UMOUNTALL, data, len);
+}
+
+/***************************************************************************
+ * NFS_READLINK (AH 2003-07-14)
+ * This procedure is called when read of the first block fails -
+ * this probably happens when it's a directory or a symlink
+ * In case of successful readlink(), the dirname is manipulated,
+ * so that inside the nfs() function a recursion can be done.
+ **************************************************************************/
+static void
+nfs_readlink_req (void)
+{
+       uint32_t data[1024];
+       uint32_t *p;
+       int len;
+
+       p = &(data[0]);
+       p = (uint32_t *)rpc_add_credentials ((long *)p);
+
+       memcpy (p, filefh, NFS_FHSIZE);
+       p += (NFS_FHSIZE / 4);
+
+       len = (uint32_t *)p - (uint32_t *)&(data[0]);
+
+       rpc_req (PROG_NFS, NFS_READLINK, data, len);
+}
+
+/**************************************************************************
+NFS_LOOKUP - Lookup Pathname
+**************************************************************************/
+static void
+nfs_lookup_req (char *fname)
+{
+       uint32_t data[1024];
+       uint32_t *p;
+       int len;
+       int fnamelen;
+
+       fnamelen = strlen (fname);
+
+       p = &(data[0]);
+       p = (uint32_t *)rpc_add_credentials ((long *)p);
+
+       memcpy (p, dirfh, NFS_FHSIZE);
+       p += (NFS_FHSIZE / 4);
+       *p++ = htonl(fnamelen);
+       if (fnamelen & 3) *(p + fnamelen / 4) = 0;
+       memcpy (p, fname, fnamelen);
+       p += (fnamelen + 3) / 4;
+
+       len = (uint32_t *)p - (uint32_t *)&(data[0]);
+
+       rpc_req (PROG_NFS, NFS_LOOKUP, data, len);
+}
+
+/**************************************************************************
+NFS_READ - Read File on NFS Server
+**************************************************************************/
+static void
+nfs_read_req (int offset, int readlen)
+{
+       uint32_t data[1024];
+       uint32_t *p;
+       int len;
+
+       p = &(data[0]);
+       p = (uint32_t *)rpc_add_credentials ((long *)p);
+
+       memcpy (p, filefh, NFS_FHSIZE);
+       p += (NFS_FHSIZE / 4);
+       *p++ = htonl(offset);
+       *p++ = htonl(readlen);
+       *p++ = 0;
+
+       len = (uint32_t *)p - (uint32_t *)&(data[0]);
+
+       rpc_req (PROG_NFS, NFS_READ, data, len);
+}
+
+/**************************************************************************
+RPC request dispatcher
+**************************************************************************/
+
+static void
+NfsSend (void)
+{
+#ifdef NFS_DEBUG
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       switch (NfsState) {
+       case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
+               rpc_lookup_req (PROG_MOUNT, 1);
+               break;
+       case STATE_PRCLOOKUP_PROG_NFS_REQ:
+               rpc_lookup_req (PROG_NFS, 2);
+               break;
+       case STATE_MOUNT_REQ:
+               nfs_mount_req (nfs_path);
+               break;
+       case STATE_UMOUNT_REQ:
+               nfs_umountall_req ();
+               break;
+       case STATE_LOOKUP_REQ:
+               nfs_lookup_req (nfs_filename);
+               break;
+       case STATE_READ_REQ:
+               nfs_read_req (nfs_offset, nfs_len);
+               break;
+       case STATE_READLINK_REQ:
+               nfs_readlink_req ();
+               break;
+       }
+}
+
+/**************************************************************************
+Handlers for the reply from server
+**************************************************************************/
+
+static int
+rpc_lookup_reply (int prog, uchar *pkt, unsigned len)
+{
+       struct rpc_t rpc_pkt;
+
+       memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+
+#ifdef NFS_DEBUG
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+               return -1;
+
+       if (rpc_pkt.u.reply.rstatus  ||
+           rpc_pkt.u.reply.verifier ||
+           rpc_pkt.u.reply.astatus  ||
+           rpc_pkt.u.reply.astatus) {
+               return -1;
+       }
+
+       switch (prog) {
+       case PROG_MOUNT:
+               NfsSrvMountPort = ntohl(rpc_pkt.u.reply.data[0]);
+               break;
+       case PROG_NFS:
+               NfsSrvNfsPort = ntohl(rpc_pkt.u.reply.data[0]);
+               break;
+       }
+
+       return 0;
+}
+
+static int
+nfs_mount_reply (uchar *pkt, unsigned len)
+{
+       struct rpc_t rpc_pkt;
+
+#ifdef NFS_DEBUG
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+
+       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+               return -1;
+
+       if (rpc_pkt.u.reply.rstatus  ||
+           rpc_pkt.u.reply.verifier ||
+           rpc_pkt.u.reply.astatus  ||
+           rpc_pkt.u.reply.data[0]) {
+               return -1;
+       }
+
+       fs_mounted = 1;
+       memcpy (dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
+
+       return 0;
+}
+
+static int
+nfs_umountall_reply (uchar *pkt, unsigned len)
+{
+       struct rpc_t rpc_pkt;
+
+#ifdef NFS_DEBUG
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+
+       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+               return -1;
+
+       if (rpc_pkt.u.reply.rstatus  ||
+           rpc_pkt.u.reply.verifier ||
+           rpc_pkt.u.reply.astatus) {
+               return -1;
+       }
+
+       fs_mounted = 0;
+       memset (dirfh, 0, sizeof(dirfh));
+
+       return 0;
+}
+
+static int
+nfs_lookup_reply (uchar *pkt, unsigned len)
+{
+       struct rpc_t rpc_pkt;
+
+#ifdef NFS_DEBUG
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+
+       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+               return -1;
+
+       if (rpc_pkt.u.reply.rstatus  ||
+           rpc_pkt.u.reply.verifier ||
+           rpc_pkt.u.reply.astatus  ||
+           rpc_pkt.u.reply.data[0]) {
+               return -1;
+       }
+
+       memcpy (filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
+
+       return 0;
+}
+
+static int
+nfs_readlink_reply (uchar *pkt, unsigned len)
+{
+       struct rpc_t rpc_pkt;
+       int rlen;
+
+#ifdef NFS_DEBUG
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+
+       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+               return -1;
+
+       if (rpc_pkt.u.reply.rstatus  ||
+           rpc_pkt.u.reply.verifier ||
+           rpc_pkt.u.reply.astatus  ||
+           rpc_pkt.u.reply.data[0]) {
+               return -1;
+       }
+
+       rlen = ntohl (rpc_pkt.u.reply.data[1]); /* new path length */
+
+       if (*((char *)&(rpc_pkt.u.reply.data[2])) != '/') {
+               int pathlen;
+               strcat (nfs_path, "/");
+               pathlen = strlen(nfs_path);
+               memcpy (nfs_path+pathlen, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
+               nfs_path[pathlen+rlen+1] = 0;
+       } else {
+               memcpy (nfs_path, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
+               nfs_path[rlen] = 0;
+       }
+       return 0;
+}
+
+static int
+nfs_read_reply (uchar *pkt, unsigned len)
+{
+       struct rpc_t rpc_pkt;
+       int rlen;
+
+#ifdef NFS_DEBUG_nop
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       memcpy ((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply));
+
+       if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+               return -1;
+
+       if (rpc_pkt.u.reply.rstatus  ||
+           rpc_pkt.u.reply.verifier ||
+           rpc_pkt.u.reply.astatus  ||
+           rpc_pkt.u.reply.data[0]) {
+               if (rpc_pkt.u.reply.rstatus) {
+                       return -9999;
+               }
+               if (rpc_pkt.u.reply.astatus) {
+                       return -9999;
+               }
+               return -ntohl(rpc_pkt.u.reply.data[0]);;
+       }
+
+       if ((nfs_offset!=0) && !((nfs_offset) % (NFS_READ_SIZE/2*10*HASHES_PER_LINE))) {
+               puts ("\n\t ");
+       }
+       if (!(nfs_offset % ((NFS_READ_SIZE/2)*10))) {
+               putc ('#');
+       }
+
+       rlen = ntohl(rpc_pkt.u.reply.data[18]);
+       if ( store_block ((uchar *)pkt+sizeof(rpc_pkt.u.reply), nfs_offset, rlen) )
+               return -9999;
+
+       return rlen;
+}
+
+/**************************************************************************
+Interfaces of U-BOOT
+**************************************************************************/
+
+static void
+NfsTimeout (void)
+{
+       puts ("Timeout\n");
+       NetState = NETLOOP_FAIL;
+       return;
+}
+
+static void
+NfsHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)
+{
+       int rlen;
+
+#ifdef NFS_DEBUG
+       printf ("%s\n", __FUNCTION__);
+#endif
+
+       if (dest != NfsOurPort) return;
+
+       switch (NfsState) {
+       case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
+               rpc_lookup_reply (PROG_MOUNT, pkt, len);
+               NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ;
+               NfsSend ();
+               break;
+
+       case STATE_PRCLOOKUP_PROG_NFS_REQ:
+               rpc_lookup_reply (PROG_NFS, pkt, len);
+               NfsState = STATE_MOUNT_REQ;
+               NfsSend ();
+               break;
+
+       case STATE_MOUNT_REQ:
+               if (nfs_mount_reply(pkt, len)) {
+                       puts ("*** ERROR: Cannot mount\n");
+                       /* just to be sure... */
+                       NfsState = STATE_UMOUNT_REQ;
+                       NfsSend ();
+               } else {
+                       NfsState = STATE_LOOKUP_REQ;
+                       NfsSend ();
+               }
+               break;
+
+       case STATE_UMOUNT_REQ:
+               if (nfs_umountall_reply(pkt, len)) {
+                       puts ("*** ERROR: Cannot umount\n");
+                       NetState = NETLOOP_FAIL;
+               } else {
+                       puts ("\ndone\n");
+                       NetState = NfsDownloadState;
+               }
+               break;
+
+       case STATE_LOOKUP_REQ:
+               if (nfs_lookup_reply(pkt, len)) {
+                       puts ("*** ERROR: File lookup fail\n");
+                       NfsState = STATE_UMOUNT_REQ;
+                       NfsSend ();
+               } else {
+                       NfsState = STATE_READ_REQ;
+                       nfs_offset = 0;
+                       nfs_len = NFS_READ_SIZE;
+                       NfsSend ();
+               }
+               break;
+
+       case STATE_READLINK_REQ:
+               if (nfs_readlink_reply(pkt, len)) {
+                       puts ("*** ERROR: Symlink fail\n");
+                       NfsState = STATE_UMOUNT_REQ;
+                       NfsSend ();
+               } else {
+#ifdef NFS_DEBUG
+                       printf ("Symlink --> %s\n", nfs_path);
+#endif
+                       nfs_filename = basename (nfs_path);
+                       nfs_path     = dirname (nfs_path);
+
+                       NfsState = STATE_MOUNT_REQ;
+                       NfsSend ();
+               }
+               break;
+
+       case STATE_READ_REQ:
+               rlen = nfs_read_reply (pkt, len);
+               NetSetTimeout (NFS_TIMEOUT * CFG_HZ, NfsTimeout);
+               if (rlen > 0) {
+                       nfs_offset += rlen;
+                       NfsSend ();
+               }
+               else if ((rlen == -NFSERR_ISDIR)||(rlen == -NFSERR_INVAL)) {
+                       /* symbolic link */
+                       NfsState = STATE_READLINK_REQ;
+                       NfsSend ();
+               } else {
+                       if ( ! rlen ) NfsDownloadState = NETLOOP_SUCCESS;
+                       NfsState = STATE_UMOUNT_REQ;
+                       NfsSend ();
+               }
+               break;
+       }
+}
+
+
+void
+NfsStart (void)
+{
+#ifdef NFS_DEBUG
+       printf ("%s\n", __FUNCTION__);
+#endif
+       NfsDownloadState = NETLOOP_FAIL;
+
+       NfsServerIP = NetServerIP;
+       nfs_path = (char *)nfs_path_buff;
+
+       if (nfs_path == NULL) {
+               NetState = NETLOOP_FAIL;
+               puts ("*** ERROR: Fail allocate memory\n");
+               return;
+       }
+
+       if (BootFile[0] == '\0') {
+               sprintf (default_filename, "/nfsroot/%02lX%02lX%02lX%02lX.img",
+                       NetOurIP & 0xFF,
+                       (NetOurIP >>  8) & 0xFF,
+                       (NetOurIP >> 16) & 0xFF,
+                       (NetOurIP >> 24) & 0xFF );
+               strcpy (nfs_path, default_filename);
+
+               printf ("*** Warning: no boot file name; using '%s'\n",
+                       nfs_path);
+       } else {
+               char *p=BootFile;
+
+               p = strchr (p, ':');
+
+               if (p != NULL) {
+                       NfsServerIP = string_to_ip (BootFile);
+                       ++p;
+                       strcpy (nfs_path, p);
+               } else {
+                       strcpy (nfs_path, BootFile);
+               }
+       }
+
+       nfs_filename = basename (nfs_path);
+       nfs_path     = dirname (nfs_path);
+
+#if defined(CONFIG_NET_MULTI)
+       printf ("Using %s device\n", eth_get_name());
+#endif
+
+       puts ("File transfer via NFS from server "); print_IPaddr (NfsServerIP);
+       puts ("; our IP address is ");              print_IPaddr (NetOurIP);
+
+       /* Check if we need to send across this subnet */
+       if (NetOurGatewayIP && NetOurSubnetMask) {
+               IPaddr_t OurNet     = NetOurIP    & NetOurSubnetMask;
+               IPaddr_t ServerNet  = NetServerIP & NetOurSubnetMask;
+
+               if (OurNet != ServerNet) {
+                       puts ("; sending through gateway ");
+                       print_IPaddr (NetOurGatewayIP) ;
+               }
+       }
+       printf ("\nFilename '%s/%s'.", nfs_path, nfs_filename);
+
+       if (NetBootFileSize) {
+               printf (" Size is 0x%x Bytes = ", NetBootFileSize<<9);
+               print_size (NetBootFileSize<<9, "");
+       }
+       printf ("\nLoad address: 0x%lx\n"
+               "Loading: *\b", load_addr);
+
+       NetSetTimeout (NFS_TIMEOUT * CFG_HZ, NfsTimeout);
+       NetSetHandler (NfsHandler);
+
+       NfsTimeoutCount = 0;
+       NfsState = STATE_PRCLOOKUP_PROG_MOUNT_REQ;
+
+       /*NfsOurPort = 4096 + (get_ticks() % 3072);*/
+       /*FIX ME !!!*/
+       NfsOurPort = 1000;
+
+       /* zero out server ether in case the server ip has changed */
+       memset (NetServerEther, 0, 6);
+
+       NfsSend ();
+}
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_NFS */
diff --git a/package/uboot-ifxmips/files/net/tftp_danube.c b/package/uboot-ifxmips/files/net/tftp_danube.c
new file mode 100644 (file)
index 0000000..f3a5471
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ *     Copyright 1994, 1995, 2000 Neil Russell.
+ *     (See License)
+ *     Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include "tftp.h"
+#include "bootp.h"
+
+#undef ET_DEBUG
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+#define WELL_KNOWN_PORT        69              /* Well known TFTP port #               */
+#define TIMEOUT                5               /* Seconds to timeout for a lost pkt    */
+#ifndef        CONFIG_NET_RETRY_COUNT
+# define TIMEOUT_COUNT 10              /* # of timeouts before giving up  */
+#else
+# define TIMEOUT_COUNT  (CONFIG_NET_RETRY_COUNT * 2)
+#endif
+                                       /* (for checking the image size)        */
+#define HASHES_PER_LINE        65              /* Number of "loading" hashes per line  */
+
+/*
+ *     TFTP operations.
+ */
+#define TFTP_RRQ       1
+#define TFTP_WRQ       2
+#define TFTP_DATA      3
+#define TFTP_ACK       4
+#define TFTP_ERROR     5
+#define TFTP_OACK      6
+
+
+static int     TftpServerPort;         /* The UDP port at their end            */
+static int     TftpOurPort;            /* The UDP port at our end              */
+static int     TftpTimeoutCount;
+static ulong   TftpBlock;              /* packet sequence number               */
+static ulong   TftpLastBlock;          /* last packet sequence number received */
+static ulong   TftpBlockWrap;          /* count of sequence number wraparounds */
+static ulong   TftpBlockWrapOffset;    /* memory offset due to wrapping        */
+static int     TftpState;
+
+#define STATE_RRQ      1
+#define STATE_DATA     2
+#define STATE_TOO_LARGE        3
+#define STATE_BAD_MAGIC        4
+#define STATE_OACK     5
+
+#define TFTP_BLOCK_SIZE                512                 /* default TFTP block size  */
+#define TFTP_SEQUENCE_SIZE     ((ulong)(1<<16))    /* sequence number is 16 bit */
+
+#define DEFAULT_NAME_LEN       (8 + 4 + 1)
+static char default_filename[DEFAULT_NAME_LEN];
+static char *tftp_filename;
+
+#ifdef CFG_DIRECT_FLASH_TFTP
+extern flash_info_t flash_info[];
+#endif
+
+static __inline__ void
+store_block (unsigned block, uchar * src, unsigned len)
+{
+       ulong offset = block * TFTP_BLOCK_SIZE + TftpBlockWrapOffset;
+       ulong newsize = offset + len;
+#ifdef CFG_DIRECT_FLASH_TFTP
+       int i, rc = 0;
+
+       for (i=0; i<CFG_MAX_FLASH_BANKS; i++) {
+               /* start address in flash? */
+               if (load_addr + offset >= flash_info[i].start[0]) {
+                       rc = 1;
+                       break;
+               }
+       }
+
+       if (rc) { /* Flash is destination for this packet */
+               rc = flash_write ((char *)src, (ulong)(load_addr+offset), len);
+               if (rc) {
+                       flash_perror (rc);
+                       NetState = NETLOOP_FAIL;
+                       return;
+               }
+       }
+       else
+#endif /* CFG_DIRECT_FLASH_TFTP */
+       {
+               (void)memcpy((void *)(load_addr + offset), src, len);
+       }
+
+       if (NetBootFileXferSize < newsize)
+               NetBootFileXferSize = newsize;
+}
+
+static void TftpSend (void);
+static void TftpTimeout (void);
+
+/**********************************************************************/
+
+static void
+TftpSend (void)
+{
+       volatile uchar *        pkt;
+       volatile uchar *        xp;
+       int                     len = 0;
+       volatile ushort *s;
+
+       /*
+        *      We will always be sending some sort of packet, so
+        *      cobble together the packet headers now.
+        */
+       pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;
+
+       switch (TftpState) {
+
+       case STATE_RRQ:
+               xp = pkt;
+               s = (ushort *)pkt;
+               *s++ = htons(TFTP_RRQ);
+               pkt = (uchar *)s;
+               strcpy ((char *)pkt, tftp_filename);
+               pkt += strlen(tftp_filename) + 1;
+               strcpy ((char *)pkt, "octet");
+               pkt += 5 /*strlen("octet")*/ + 1;
+               strcpy ((char *)pkt, "timeout");
+               pkt += 7 /*strlen("timeout")*/ + 1;
+               sprintf((char *)pkt, "%d", TIMEOUT);
+#ifdef ET_DEBUG
+               printf("send option \"timeout %s\"\n", (char *)pkt);
+#endif
+               pkt += strlen((char *)pkt) + 1;
+               len = pkt - xp;
+               break;
+
+       case STATE_DATA:
+       case STATE_OACK:
+               xp = pkt;
+               s = (ushort *)pkt;
+               *s++ = htons(TFTP_ACK);
+               *s++ = htons(TftpBlock);
+               pkt = (uchar *)s;
+               len = pkt - xp;
+               break;
+
+       case STATE_TOO_LARGE:
+               xp = pkt;
+               s = (ushort *)pkt;
+               *s++ = htons(TFTP_ERROR);
+               *s++ = htons(3);
+               pkt = (uchar *)s;
+               strcpy ((char *)pkt, "File too large");
+               pkt += 14 /*strlen("File too large")*/ + 1;
+               len = pkt - xp;
+               break;
+
+       case STATE_BAD_MAGIC:
+               xp = pkt;
+               s = (ushort *)pkt;
+               *s++ = htons(TFTP_ERROR);
+               *s++ = htons(2);
+               pkt = (uchar *)s;
+               strcpy ((char *)pkt, "File has bad magic");
+               pkt += 18 /*strlen("File has bad magic")*/ + 1;
+               len = pkt - xp;
+               break;
+       }
+
+       NetSendUDPPacket(NetServerEther, NetServerIP, TftpServerPort, TftpOurPort, len);
+}
+
+
+static void
+TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
+{
+       ushort proto;
+       ushort *s;
+
+       if (dest != TftpOurPort) {
+               return;
+       }
+       if (TftpState != STATE_RRQ && src != TftpServerPort) {
+               return;
+       }
+
+       if (len < 2) {
+               return;
+       }
+       len -= 2;
+       /* warning: don't use increment (++) in ntohs() macros!! */
+       s = (ushort *)pkt;
+       proto = *s++;
+       pkt = (uchar *)s;
+       switch (ntohs(proto)) {
+
+       case TFTP_RRQ:
+       case TFTP_WRQ:
+       case TFTP_ACK:
+               break;
+       default:
+               break;
+
+       case TFTP_OACK:
+#ifdef ET_DEBUG
+               printf("Got OACK: %s %s\n", pkt, pkt+strlen(pkt)+1);
+#endif
+               TftpState = STATE_OACK;
+               TftpServerPort = src;
+               TftpSend (); /* Send ACK */
+               break;
+       case TFTP_DATA:
+               if (len < 2)
+                       return;
+               len -= 2;
+               TftpBlock = ntohs(*(ushort *)pkt);
+
+               /*
+                * RFC1350 specifies that the first data packet will
+                * have sequence number 1. If we receive a sequence
+                * number of 0 this means that there was a wrap
+                * around of the (16 bit) counter.
+                */
+               if (TftpBlock == 0) {
+                       TftpBlockWrap++;
+                       TftpBlockWrapOffset += TFTP_BLOCK_SIZE * TFTP_SEQUENCE_SIZE;
+                       printf ("\n\t %lu MB received\n\t ", TftpBlockWrapOffset>>20);
+               } else {
+                       if (((TftpBlock - 1) % 10) == 0) {
+                               putc ('#');
+                       } else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) {
+                               puts ("\n\t ");
+                       }
+               }
+
+#ifdef ET_DEBUG
+               if (TftpState == STATE_RRQ) {
+                       puts ("Server did not acknowledge timeout option!\n");
+               }
+#endif
+
+               if (TftpState == STATE_RRQ || TftpState == STATE_OACK) {
+                       /* first block received */
+                       TftpState = STATE_DATA;
+                       TftpServerPort = src;
+                       TftpLastBlock = 0;
+                       TftpBlockWrap = 0;
+                       TftpBlockWrapOffset = 0;
+
+                       if (TftpBlock != 1) {   /* Assertion */
+                               printf ("\nTFTP error: "
+                                       "First block is not block 1 (%ld)\n"
+                                       "Starting again\n\n",
+                                       TftpBlock);
+                               NetStartAgain ();
+                               break;
+                       }
+               }
+
+               if (TftpBlock == TftpLastBlock) {
+                       /*
+                        *      Same block again; ignore it.
+                        */
+                       break;
+               }
+
+               TftpLastBlock = TftpBlock;
+               NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout);
+
+               store_block (TftpBlock - 1, pkt + 2, len);
+
+               /*
+                *      Acknoledge the block just received, which will prompt
+                *      the server for the next one.
+                */
+               TftpSend ();
+
+               if (len < TFTP_BLOCK_SIZE) {
+                       /*
+                        *      We received the whole thing.  Try to
+                        *      run it.
+                        */
+                       puts ("\ndone\n");
+                       NetState = NETLOOP_SUCCESS;
+               }
+               break;
+
+       case TFTP_ERROR:
+               printf ("\nTFTP error: '%s' (%d)\n",
+                                       pkt + 2, ntohs(*(ushort *)pkt));
+               puts ("Starting again\n\n");
+               NetStartAgain ();
+               break;
+       }
+}
+
+
+static void
+TftpTimeout (void)
+{
+       if (++TftpTimeoutCount > TIMEOUT_COUNT) {
+               puts ("\nRetry count exceeded; starting again\n");
+               NetStartAgain ();
+       } else {
+               puts ("T ");
+               NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout);
+               TftpSend ();
+       }
+}
+
+
+void
+TftpStart (void)
+{
+#ifdef CONFIG_TFTP_PORT
+       char *ep;             /* Environment pointer */
+#endif
+
+       if (BootFile[0] == '\0') {
+               sprintf(default_filename, "%02lX%02lX%02lX%02lX.img",
+                       NetOurIP & 0xFF,
+                       (NetOurIP >>  8) & 0xFF,
+                       (NetOurIP >> 16) & 0xFF,
+                       (NetOurIP >> 24) & 0xFF );
+               tftp_filename = default_filename;
+
+               printf ("*** Warning: no boot file name; using '%s'\n",
+                       tftp_filename);
+       } else {
+               tftp_filename = BootFile;
+       }
+
+#if defined(CONFIG_NET_MULTI)
+       printf ("Using %s device\n", eth_get_name());
+#endif
+       puts ("TFTP from server ");     print_IPaddr (NetServerIP);
+       puts ("; our IP address is ");  print_IPaddr (NetOurIP);
+
+       /* Check if we need to send across this subnet */
+       if (NetOurGatewayIP && NetOurSubnetMask) {
+           IPaddr_t OurNet     = NetOurIP    & NetOurSubnetMask;
+           IPaddr_t ServerNet  = NetServerIP & NetOurSubnetMask;
+
+           if (OurNet != ServerNet) {
+               puts ("; sending through gateway ");
+               print_IPaddr (NetOurGatewayIP) ;
+           }
+       }
+       putc ('\n');
+
+       printf ("Filename '%s'.", tftp_filename);
+
+       if (NetBootFileSize) {
+               printf (" Size is 0x%x Bytes = ", NetBootFileSize<<9);
+               print_size (NetBootFileSize<<9, "");
+       }
+
+       putc ('\n');
+
+       printf ("Load address: 0x%lx\n", load_addr);
+
+       puts ("Loading: *\b");
+
+       NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout);
+       NetSetHandler (TftpHandler);
+
+       TftpServerPort = WELL_KNOWN_PORT;
+       TftpTimeoutCount = 0;
+       TftpState = STATE_RRQ;
+       /* Use a pseudo-random port unless a specific port is set */
+       TftpOurPort = 1024 + (get_timer(0) % 3072);
+#ifdef CONFIG_TFTP_PORT
+       if ((ep = getenv("tftpdstp")) != NULL) {
+               TftpServerPort = simple_strtol(ep, NULL, 10);
+       }
+       if ((ep = getenv("tftpsrcp")) != NULL) {
+               TftpOurPort= simple_strtol(ep, NULL, 10);
+       }
+#endif
+       TftpBlock = 0;
+
+       /* zero out server ether in case the server ip has changed */
+       memset(NetServerEther, 0, 6);
+
+       TftpSend ();
+}
+
+#endif /* CFG_CMD_NET */
diff --git a/package/uboot-ifxmips/files/tools/crc32_danube.c b/package/uboot-ifxmips/files/tools/crc32_danube.c
new file mode 100644 (file)
index 0000000..3d99b69
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * This file is derived from crc32.c from the zlib-1.1.3 distribution
+ * by Jean-loup Gailly and Mark Adler.
+ */
+
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifndef USE_HOSTCC     /* Shut down "ANSI does not permit..." warnings */
+#include <common.h>    /* to get command definitions like CFG_CMD_JFFS2 */
+#endif
+
+#include "zlib.h"
+
+#define local static
+#define ZEXPORT        /* empty */
+unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local int crc_table_empty = 1;
+local uLongf crc_table[256];
+local void make_crc_table OF((void));
+
+/*
+  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The table is simply the CRC of all possible eight bit values.  This is all
+  the information needed to generate CRC's on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.
+*/
+local void make_crc_table()
+{
+  uLong c;
+  int n, k;
+  uLong poly;            /* polynomial exclusive-or pattern */
+  /* terms of polynomial defining this crc (except x^32): */
+  static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+  /* make exclusive-or pattern from polynomial (0xedb88320L) */
+  poly = 0L;
+  for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
+    poly |= 1L << (31 - p[n]);
+
+  for (n = 0; n < 256; n++)
+  {
+    c = (uLong)n;
+    for (k = 0; k < 8; k++)
+      c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+    crc_table[n] = c;
+  }
+  crc_table_empty = 0;
+}
+#else
+/* ========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+local const uLongf crc_table[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
+};
+#endif
+
+#if 0
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const uLongf * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+  if (crc_table_empty) make_crc_table();
+#endif
+  return (const uLongf *)crc_table;
+}
+#endif
+
+/* ========================================================================= */
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+/* ========================================================================= */
+uLong ZEXPORT crc32(crc, buf, len)
+    uLong crc;
+    const Bytef *buf;
+    uInt len;
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+      make_crc_table();
+#endif
+    crc = crc ^ 0xffffffffL;
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+    return crc ^ 0xffffffffL;
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) || \
+       ((CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY))
+
+/* No ones complement version. JFFS2 (and other things ?)
+ * don't use ones compliment in their CRC calculations.
+ */
+uLong ZEXPORT crc32_no_comp(uLong crc, const Bytef *buf, uInt len)
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+      make_crc_table();
+#endif
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+
+    return crc;
+}
+
+#endif /* CFG_CMD_JFFS2 */
diff --git a/package/uboot-ifxmips/files/tools/environment_danube.c b/package/uboot-ifxmips/files/tools/environment_danube.c
new file mode 100644 (file)
index 0000000..19bdeb0
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASSEMBLY__
+#define        __ASSEMBLY__                    /* Dirty trick to get only #defines     */
+#endif
+#define        __ASM_STUB_PROCESSOR_H__        /* don't include asm/processor.         */
+#include <config.h>
+#undef __ASSEMBLY__
+#include <environment.h>
+
+/*
+ * Handle HOSTS that have prepended
+ * crap on symbol names, not TARGETS.
+ */
+#if defined(__APPLE__)
+/* Leading underscore on symbols */
+#  define SYM_CHAR "_"
+#else /* No leading character on symbols */
+#  define SYM_CHAR
+#endif
+
+/*
+ * Generate embedded environment table
+ * inside U-Boot image, if needed.
+ */
+#if defined(ENV_IS_EMBEDDED)
+/*
+ * Only put the environment in it's own section when we are building
+ * U-Boot proper.  The host based program "tools/envcrc" does not need
+ * a seperate section.  Note that ENV_CRC is only defined when building
+ * U-Boot itself.
+ */
+#if (defined(CONFIG_CMI)       || \
+     defined(CONFIG_FADS)      || \
+     defined(CONFIG_HYMOD)     || \
+     defined(CONFIG_ICU862)    || \
+     defined(CONFIG_R360MPI)   || \
+     defined(CONFIG_TQM8xxL)   || \
+     defined(CONFIG_RRVISION)  || \
+     defined(CONFIG_TRAB)      || \
+     defined(CONFIG_PPCHAMELEONEVB) || \
+     defined(CONFIG_M5271EVB)  || \
+     defined(CONFIG_NAND_U_BOOT))      && \
+     defined(ENV_CRC) /* Environment embedded in U-Boot .ppcenv section */
+/* XXX - This only works with GNU C */
+#  define __PPCENV__ __attribute__ ((section(".ppcenv")))
+#  define __PPCTEXT__ __attribute__ ((section(".text")))
+
+#elif defined(USE_HOSTCC) /* Native for 'tools/envcrc' */
+#  define __PPCENV__ /*XXX DO_NOT_DEL_THIS_COMMENT*/
+#  define __PPCTEXT__ /*XXX DO_NOT_DEL_THIS_COMMENT*/
+
+#else /* Environment is embedded in U-Boot's .text section */
+/* XXX - This only works with GNU C */
+#  define __PPCENV__ __attribute__ ((section(".text")))
+#  define __PPCTEXT__ __attribute__ ((section(".text")))
+#endif
+
+/*
+ * Macros to generate global absolutes.
+ */
+#define GEN_SYMNAME(str) SYM_CHAR #str
+#define GEN_VALUE(str) #str
+#define GEN_ABS(name, value) \
+               asm (".globl " GEN_SYMNAME(name)); \
+               asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))
+
+/*
+ * Macros to transform values
+ * into environment strings.
+ */
+#define XMK_STR(x)     #x
+#define MK_STR(x)      XMK_STR(x)
+
+/*
+ * Check to see if we are building with a
+ * computed CRC.  Otherwise define it as ~0.
+ */
+#if !defined(ENV_CRC)
+#  define ENV_CRC      ~0
+#endif
+
+env_t environment __PPCENV__ = {
+       ENV_CRC,        /* CRC Sum */
+#ifdef CFG_REDUNDAND_ENVIRONMENT
+       1,              /* Flags: valid */
+#endif
+       {
+#if defined(CONFIG_BOOTARGS)
+       "bootargs="     CONFIG_BOOTARGS                 "\0"
+#endif
+#if defined(CONFIG_BOOTCOMMAND)
+       "bootcmd="      CONFIG_BOOTCOMMAND              "\0"
+#endif
+#if defined(CONFIG_RAMBOOTCOMMAND)
+       "ramboot="      CONFIG_RAMBOOTCOMMAND           "\0"
+#endif
+#if defined(CONFIG_NFSBOOTCOMMAND)
+       "nfsboot="      CONFIG_NFSBOOTCOMMAND           "\0"
+#endif
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+       "bootdelay="    MK_STR(CONFIG_BOOTDELAY)        "\0"
+#endif
+#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
+       "baudrate="     MK_STR(CONFIG_BAUDRATE)         "\0"
+#endif
+#ifdef CONFIG_LOADS_ECHO
+       "loads_echo="   MK_STR(CONFIG_LOADS_ECHO)       "\0"
+#endif
+#ifdef CONFIG_ETHADDR
+       "ethaddr="      MK_STR(CONFIG_ETHADDR)          "\0"
+#endif
+#ifdef CONFIG_ETH1ADDR
+       "eth1addr="     MK_STR(CONFIG_ETH1ADDR)         "\0"
+#endif
+#ifdef CONFIG_ETH2ADDR
+       "eth2addr="     MK_STR(CONFIG_ETH2ADDR)         "\0"
+#endif
+#ifdef CONFIG_ETH3ADDR
+       "eth3addr="     MK_STR(CONFIG_ETH3ADDR)         "\0"
+#endif
+#ifdef CONFIG_ETHPRIME
+       "ethprime="     CONFIG_ETHPRIME                 "\0"
+#endif
+#ifdef CONFIG_IPADDR
+       "ipaddr="       MK_STR(CONFIG_IPADDR)           "\0"
+#endif
+#ifdef CONFIG_SERVERIP
+       "serverip="     MK_STR(CONFIG_SERVERIP)         "\0"
+#endif
+#ifdef CFG_AUTOLOAD
+       "autoload="     CFG_AUTOLOAD                    "\0"
+#endif
+#ifdef CONFIG_ROOTPATH
+       "rootpath="     MK_STR(CONFIG_ROOTPATH)         "\0"
+#endif
+#ifdef CONFIG_GATEWAYIP
+       "gatewayip="    MK_STR(CONFIG_GATEWAYIP)        "\0"
+#endif
+#ifdef CONFIG_NETMASK
+       "netmask="      MK_STR(CONFIG_NETMASK)          "\0"
+#endif
+#ifdef CONFIG_HOSTNAME
+       "hostname="     MK_STR(CONFIG_HOSTNAME)         "\0"
+#endif
+#ifdef CONFIG_BOOTFILE
+       "bootfile="     MK_STR(CONFIG_BOOTFILE)         "\0"
+#endif
+#ifdef CONFIG_LOADADDR
+       "loadaddr="     MK_STR(CONFIG_LOADADDR)         "\0"
+#endif
+#ifdef CONFIG_PREBOOT
+       "preboot="      CONFIG_PREBOOT                  "\0"
+#endif
+#ifdef CONFIG_CLOCKS_IN_MHZ
+       "clocks_in_mhz=" "1"                            "\0"
+#endif
+#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
+       "pcidelay="     MK_STR(CONFIG_PCI_BOOTDELAY)    "\0"
+#endif
+#ifdef  CONFIG_EXTRA_ENV_SETTINGS
+       CONFIG_EXTRA_ENV_SETTINGS
+#endif
+       "\0"            /* Term. env_t.data with 2 NULs */
+       }
+};
+#ifdef CFG_ENV_ADDR_REDUND
+env_t redundand_environment __PPCENV__ = {
+       0,              /* CRC Sum: invalid */
+       0,              /* Flags:   invalid */
+       {
+       "\0"
+       }
+};
+#endif /* CFG_ENV_ADDR_REDUND */
+
+/*
+ * These will end up in the .text section
+ * if the environment strings are embedded
+ * in the image.  When this is used for
+ * tools/envcrc, they are placed in the
+ * .data/.sdata section.
+ *
+ */
+unsigned long env_size __PPCTEXT__ = sizeof(env_t);
+
+/*
+ * Add in absolutes.
+ */
+GEN_ABS(env_offset, CFG_ENV_OFFSET);
+
+#endif /* ENV_IS_EMBEDDED */
diff --git a/package/uboot-ifxmips/patches/100-ifx.patch b/package/uboot-ifxmips/patches/100-ifx.patch
new file mode 100644 (file)
index 0000000..5661320
--- /dev/null
@@ -0,0 +1,1773 @@
+--- a/Makefile
++++ b/Makefile
+@@ -24,7 +24,7 @@
+ VERSION = 1
+ PATCHLEVEL = 1
+ SUBLEVEL = 5
+-EXTRAVERSION =
++EXTRAVERSION = -IFX-LXDB
+ U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+ VERSION_FILE = $(obj)include/version_autogenerated.h
+@@ -44,6 +44,25 @@
+ # Deal with colliding definitions from tcsh etc.
+ VENDOR=
++# Default algorithm form compressing u-boot.bin
++ifndef COMPRESS
++COMPRESS=none
++COMPRESS_FILE=$(obj)u-boot.img
++else
++ifeq ($(COMPRESS),lzma)
++COMPRESS_FILE=$(obj)u-boot.limg
++endif
++ifeq ($(COMPRESS),bz2)
++COMPRESS_FILE=$(obj)u-boot.bzimg
++endif
++ifeq ($(COMPRESS),gzip)
++COMPRESS_FILE=$(obj)u-boot.zimg
++endif
++ifeq ($(COMPRESS),none)
++COMPRESS_FILE=$(obj)u-boot.img
++endif
++endif
++
+ #########################################################################
+ #
+ # U-boot build supports producing a object files to the separate external
+@@ -155,6 +174,11 @@
+ endif
+ endif
++
++
++
++
++
+ export        CROSS_COMPILE
+ # load other configuration
+@@ -163,7 +187,9 @@
+ #########################################################################
+ # U-Boot objects....order is important (i.e. start must be first)
+-OBJS  = cpu/$(CPU)/start.o
++OBJS  = cpu/$(CPU)/$(BOARDDIR)/start.o
++OBJS_BOOTSTRAP  = cpu/$(CPU)/$(BOARDDIR)/start_bootstrap.o
++
+ ifeq ($(CPU),i386)
+ OBJS += cpu/$(CPU)/start16.o
+ OBJS += cpu/$(CPU)/reset.o
+@@ -186,11 +212,11 @@
+ LIBS  = lib_generic/libgeneric.a
+ LIBS += board/$(BOARDDIR)/lib$(BOARD).a
+-LIBS += cpu/$(CPU)/lib$(CPU).a
++LIBS += cpu/$(CPU)/$(BOARDDIR)/lib$(CPU).a
+ ifdef SOC
+ LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
+ endif
+-LIBS += lib_$(ARCH)/lib$(ARCH).a
++LIBS += lib_$(ARCH)/$(BOARDIR)/lib$(ARCH).a
+ LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
+       fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
+ LIBS += net/libnet.a
+@@ -198,27 +224,54 @@
+ LIBS += rtc/librtc.a
+ LIBS += dtt/libdtt.a
+ LIBS += drivers/libdrivers.a
+-LIBS += drivers/nand/libnand.a
+-LIBS += drivers/nand_legacy/libnand_legacy.a
++#LIBS += drivers/nand_$(BOARDDIR)/libnand.a
++#LIBS += drivers/nand_legacy/libnand_legacy.a
+ LIBS += drivers/sk98lin/libsk98lin.a
+ LIBS += post/libpost.a post/cpu/libcpu.a
+ LIBS += common/libcommon.a
+ LIBS += $(BOARDLIBS)
+ LIBS := $(addprefix $(obj),$(LIBS))
++
++
++LIBS_BOOTSTRAP  = lib_bootstrap/libbootstrap.a 
++LIBS_BOOTSTRAP+= board/$(BOARDDIR)/lib$(BOARD).a 
++#LIBS_BOOTSTRAP+= board/ifx/libifx.a 
++LIBS_BOOTSTRAP+= cpu/$(CPU)/$(BOARDDIR)/lib$(CPU).a
++
++#HEAD_OBJS = cpu/$(CPU)/$(BOARDDIR)/start.o lib_$(ARCH)/board.o
++
++#HEAD_LIBS  = board/$(BOARDDIR)/lib$(BOARD).a
++#HEAD_LIBS += cpu/$(CPU)/$(BOARDDIR)/lib$(CPU).a
++#HEAD_LIBS += lib_$(ARCH)/lib$(ARCH).a
++#HEAD_LIBS += lib_generic/libgeneric.a
++#HEAD_LIBS += common/console.o
++#HEAD_LIBS += common/devices.o
++#HEAD_LIBS += common/cmd_bootm.o
++
++#.PHONY : $(LIBS) $(HEAD_LIBS)
+ .PHONY : $(LIBS)
++.PHONY : $(LIBS_BOOTSTRAP)
+ # Add GCC lib
+ PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
+ # The "tools" are needed early, so put this first
+ # Don't include stuff already done in $(LIBS)
++        #examples 
+ SUBDIRS       = tools \
+-        examples \
+         post \
+         post/cpu
+ .PHONY : $(SUBDIRS)
++# HEAD_SUBDIRS = tools
++#HEAD_SUBDIRS = lib_generic \
++#       cpu/$(CPU) \
++#       board/$(BOARDDIR) \
++#       common \
++#       lib_$(ARCH)
++#.PHONY : $(HEAD_SUBDIRS)
++
+ ifeq ($(CONFIG_NAND_U_BOOT),y)
+ NAND_SPL = nand_spl
+ U_BOOT_NAND = $(obj)u-boot-nand.bin
+@@ -227,13 +280,76 @@
+ __OBJS := $(subst $(obj),,$(OBJS))
+ __LIBS := $(subst $(obj),,$(LIBS))
++#__HEAD_OBJS := $(subst $(obj),,$(HEAD_OBJS))
++#__HEAD_LIBS := $(subst $(obj),,$(HEAD_LIBS))
++
+ #########################################################################
+ #########################################################################
+ ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
++#IFX_ALL = $(obj)u-boot.ifx $(obj)head.srec $(obj)head.bin $(obj)head $(obj)head.map $(COMPRESS_FILE) $(obj)u-boot.srec
++IFX_ALL = $(obj)u-boot.srec $(obj)u-boot.ifx $(obj)u-boot.lzimg $(obj)System.map $(obj)bootstrap.bin
+ all:          $(ALL)
++ifx_all:      $(IFX_ALL)
++
++
++$(obj)u-boot.ifx: $(obj)System.map $(obj)bootstrap.bin $(obj)u-boot.lzimg     
++              @cat $(obj)bootstrap.bin > $(obj)u-boot.ifx
++              @cat $(obj)u-boot.lzimg >> $(obj)u-boot.ifx
++
++$(obj)u-boot.lzimg: $(obj)u-boot.bin System.map
++#             @lzma -f -z --best -v $(obj)u-boot.bin
++              @lzma e $(obj)u-boot.bin $(obj)u-boot.bin.lzma
++              @./tools/mkimage -A mips -T firmware -C lzma \
++              -a 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -e 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -n 'u-boot image' -d $(obj)u-boot.bin.lzma $@
++
++$(obj)ld_uboot.img: $(obj)u-boot.ifx $(obj)u-boot.lzimg $(obj)System.map $(obj)bootstrap.bin  
++              @  cp -f $(obj)u-boot.ifx $(obj)u-boot.bin
++              @ ./mkbootimg.incaip2 $(obj)ld_uboot.img < ld_uboot.conf
++
++
++
++
++$(obj)u-boot.zimg:    $(obj)u-boot.bin $(obj)System.map
++              gzip $(obj)u-boot.bin
++              ./tools/mkimage -A $(ARCH) -T firmware -C gzip \
++                -a 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -e 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
++                       sed -e 's/"[     ]*$$/ for $(BOARD) board"/') \
++              -d u-boot.gz $@
++
++$(obj)u-boot.bzimg:   $(obj)u-boot.bin $(obj)System.map
++              bzip $(obj)u-boot.bin
++              ./tools/mkimage -A $(ARCH) -T firmware -C bzip2 \
++              -a 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -e 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
++                      sed -e 's/"[     ]*$$/ for $(BOARD) board"/') \
++              -d u-boot.bz2 $@
++
++$(obj)u-boot.limg:    $(obj)u-boot.bin $(obj)System.map
++#             @lzma -f -z --best -v $(obj)u-boot.bin
++              @lzma e $(obj)u-boot.bin $(obj)u-boot.bin.lzma
++              ./tools/mkimage -A $(ARCH) -T firmware -C lzma \
++              -a 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -e 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
++                      sed -e 's/"[     ]*$$/ for $(BOARD) board"/') \
++              -d u-boot.bin.lzma $@
++
++$(obj)u-boot.img:     $(obj)u-boot.bin $(obj)System.map
++              ./tools/mkimage -A $(ARCH) -T firmware -C none \
++              -a 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -e 0x$(shell grep "T _start" $(TOPDIR)/System.map | awk '{ printf "%s", $$1 }') \
++              -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
++                      sed -e 's/"[     ]*$$/ for $(BOARD) board"/') \
++              -d u-boot.bin $@
++
+ $(obj)u-boot.hex:     $(obj)u-boot
+               $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
+@@ -243,28 +359,36 @@
+ $(obj)u-boot.bin:     $(obj)u-boot
+               $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+-$(obj)u-boot.img:     $(obj)u-boot.bin
+-              ./tools/mkimage -A $(ARCH) -T firmware -C none \
+-              -a $(TEXT_BASE) -e 0 \
+-              -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
+-                      sed -e 's/"[     ]*$$/ for $(BOARD) board"/') \
+-              -d $< $@
+-
+ $(obj)u-boot.dis:     $(obj)u-boot
+               $(OBJDUMP) -d $< > $@
+-$(obj)u-boot:         depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
++$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
+               UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
+               cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
+                       --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
+                       -Map u-boot.map -o u-boot
++
++
++$(obj)bootstrap.bin:  $(obj)bootstrap
++              $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
++
++$(obj)bootstrap :             depend version $(SUBDIRS) $(OBJS_BOOTSTRAP) $(LIBS_BOOTSTRAP) $(LDSCRIPT_BOOTSTRAP)
++              UNDEF_SYM=`$(OBJDUMP) -x $(LIBS_BOOTSTRAP) |sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
++              $(LD) $(LDFLAGS_BOOTSTRAP) $$UNDEF_SYM $(OBJS_BOOTSTRAP) \
++                      --start-group $(LIBS_BOOTSTRAP) --end-group $(PLATFORM_LIBS) \
++                      -Map bootstrap.map -o bootstrap
++
+ $(OBJS):
+-              $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))
++              $(MAKE) -C cpu/$(CPU)/$(BOARDDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))
+ $(LIBS):
+               $(MAKE) -C $(dir $(subst $(obj),,$@))
++
++$(LIBS_BOOTSTRAP):
++              $(MAKE) -C `dirname $@`
++
+ $(SUBDIRS):
+               $(MAKE) -C $@ all
+@@ -295,14 +419,14 @@
+ tags ctags:
+               ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) include \
+-                              lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
++                              lib_generic board/$(BOARDDIR) cpu/$(CPU)/$(BOARDDIR) lib_$(ARCH) \
+                               fs/cramfs fs/fat fs/fdos fs/jffs2 \
+                               net disk rtc dtt drivers drivers/sk98lin common \
+                       \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
+ etags:
+               etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) include \
+-                              lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
++                              lib_generic board/$(BOARDDIR) cpu/$(CPU)/$(BOARDDIR) lib_$(ARCH) \
+                               fs/cramfs fs/fat fs/fdos fs/jffs2 \
+                               net disk rtc dtt drivers drivers/sk98lin common \
+                       \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
+@@ -2032,7 +2156,20 @@
+ # MIPS
+ #========================================================================
+ #########################################################################
+-## MIPS32 4Kc
++## Infineon MIPS generic u-boot config 
++#########################################################################
++danube_config:        unconfig
++      @$(MKCONFIG) $(@:_config=) mips mips danube
++
++amazon_config:        unconfig
++      @$(MKCONFIG) $(@:_config=) mips mips amazon
++
++
++incaip2_config:       unconfig
++      @$(MKCONFIG) $(@:_config=) mips mips incaip2
++
++#########################################################################
++## MIPS32 4kc
+ #########################################################################
+ xtract_incaip = $(subst _100MHz,,$(subst _133MHz,,$(subst _150MHz,,$(subst _config,,$1))))
+@@ -2246,6 +2383,8 @@
+       rm -f $(obj)include/bmp_logo.h
+       find nand_spl -lname "*" -print | xargs rm -f
+       rm -f nand_spl/u-boot-spl nand_spl/u-boot-spl.map
++      rm -f lib_bootstrap/*.o
++      rm -f lib_bootstrap/*.a
+ clobber:      clean
+       find $(OBJTREE) -type f \( -name .depend \
+@@ -2254,7 +2393,7 @@
+               | xargs -0 rm -f
+       rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS $(obj)include/version_autogenerated.h
+       rm -fr $(obj)*.*~
+-      rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
++      rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL) $(IFX_ALL)
+       rm -f $(obj)tools/crc32.c $(obj)tools/environment.c $(obj)tools/env/crc32.c
+       rm -f $(obj)tools/inca-swap-bytes $(obj)cpu/mpc824x/bedbug_603e.c
+       rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
+--- /dev/null
++++ b/build_danube.sh
+@@ -0,0 +1,28 @@
++#!/bin/sh
++IFX_CONFIG_FLASH_SIZE=8
++IFX_CONFIG_MEMORY_SIZE=30
++CONFIG_RAM_TEXT_BASE=0xA0400000
++
++#prepare_headers()
++#{
++#     cp -f include/flash_$1.h \
++#     include/flash.h
++#     cp -f include/net_$1.h \
++#     include/net.h
++#     cp -f include/asm-mips/cacheops_$1.h \
++#     include/asm-mips/cacheops.h
++#     cp -f include/asm-mips/mipsregs_$1.h \
++#     include/asm-mips/mipsregs.h
++#}
++#prepare_headers "danube"
++UBOOT_COMPRESS=lzma
++UBOOT_CFLAGS="-DCONFIG_IFX_MIPS -DCONFIG_LZMA -DIFX_CONFIG_MEMORY_SIZE=${IFX_CONFIG_MEMORY_SIZE} -DIFX_CONFIG_FLASH_SIZE=${IFX_CONFIG_FLASH_SIZE}"
++
++rm -f .config_ok
++
++make CROSS_COMPILE="mips-linux-uclibc-" CROSS_COMPILE_UCLIBC=1 COMPRESS=${UBOOT_COMPRESS} PLATFORM_CPU=mips32r2 IFX_CFLAGS="${UBOOT_CFLAGS}" UBOOT_RAM_TEXT_BASE=${CONFIG_RAM_TEXT_BASE} CPU_TYPE=${IFX_CONFIG_CPU} danube_config distclean
++
++CROSS_COMPILE="mips-linux-uclibc-" CROSS_COMPILE_UCLIBC=1 COMPRESS=${UBOOT_COMPRESS} PLATFORM_CPU=mips32r2 IFX_CFLAGS="${UBOOT_CFLAGS}" make UBOOT_RAM_TEXT_BASE=${CONFIG_RAM_TEXT_BASE} CPU_TYPE=${IFX_CONFIG_CPU} danube_config
++       echo -n > .config_ok
++
++CROSS_COMPILE="mips-linux-uclibc-" CROSS_COMPILE_UCLIBC=1 COMPRESS=${UBOOT_COMPRESS} PLATFORM_CPU=mips32r2 IFX_CFLAGS="${UBOOT_CFLAGS}" make UBOOT_RAM_TEXT_BASE=${CONFIG_RAM_TEXT_BASE} BOOTSTRAP_PRINTF_STATUS=$2 CPU_TYPE=${IFX_CONFIG_CPU} ifx_all
+--- a/common/Makefile
++++ b/common/Makefile
+@@ -46,7 +46,7 @@
+         env_nand.o env_dataflash.o env_flash.o env_eeprom.o \
+         env_nvram.o env_nowhere.o \
+         exports.o \
+-        flash.o fpga.o ft_build.o \
++        flash_$(BOARD).o fpga.o ft_build.o \
+         hush.o kgdb.o lcd.o lists.o lynxkdi.o \
+         memsize.o miiphybb.o miiphyutil.o \
+         s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
+@@ -60,7 +60,7 @@
+ all:  $(LIB) $(AOBJS)
+-$(LIB): $(obj).depend $(OBJS)
++$(LIB): $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+ $(obj)environment.o: $(src)environment.c $(obj)../tools/envcrc
+--- a/common/cmd_bootm.c
++++ b/common/cmd_bootm.c
+@@ -31,6 +31,7 @@
+ #include <malloc.h>
+ #include <zlib.h>
+ #include <bzlib.h>
++#include <LzmaWrapper.h>
+ #include <environment.h>
+ #include <asm/byteorder.h>
+@@ -79,6 +80,8 @@
+ # define CHUNKSZ (64 * 1024)
+ #endif
++#ifndef CFG_HEAD_CODE
++
+ int  gunzip (void *, int, unsigned char *, unsigned long *);
+ static void *zalloc(void *, unsigned, unsigned);
+@@ -341,6 +344,7 @@
+ #endif        /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
+               }
+               break;
++#ifndef CONFIG_REMOVE_GZIP
+       case IH_COMP_GZIP:
+               printf ("   Uncompressing %s ... ", name);
+               if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,
+@@ -350,6 +354,7 @@
+                       do_reset (cmdtp, flag, argc, argv);
+               }
+               break;
++#endif /* CONFIG_REMOVE_GZIP */
+ #ifdef CONFIG_BZIP2
+       case IH_COMP_BZIP2:
+               printf ("   Uncompressing %s ... ", name);
+@@ -369,6 +374,18 @@
+               }
+               break;
+ #endif /* CONFIG_BZIP2 */
++#ifdef CONFIG_LZMA
++      case IH_COMP_LZMA:
++              printf ("   Uncompressing %s ... ", name);
++              i = lzma_inflate ((unsigned char *)data, len, (unsigned char*)ntohl(hdr->ih_load), &unc_len);
++              if (i != LZMA_RESULT_OK) {
++                      printf ("LZMA ERROR %d - must RESET board to recover\n", i);
++                      SHOW_BOOT_PROGRESS (-6);
++                      udelay(100000);
++                      do_reset (cmdtp, flag, argc, argv);
++              }
++              break;
++#endif /* CONFIG_LZMA */
+       default:
+               if (iflag)
+                       enable_interrupts();
+@@ -1176,6 +1193,8 @@
+ );
+ #endif        /* CFG_CMD_IMLS */
++#endif        /* ! CFG_HEAD_CODE */
++
+ void
+ print_image_hdr (image_header_t *hdr)
+ {
+@@ -1270,12 +1289,15 @@
+       case IH_COMP_NONE:      comp = "uncompressed";          break;
+       case IH_COMP_GZIP:      comp = "gzip compressed";       break;
+       case IH_COMP_BZIP2:     comp = "bzip2 compressed";      break;
++      case IH_COMP_LZMA:      comp = "lzma compressed";       break;  
+       default:                comp = "unknown compression";   break;
+       }
+       printf ("%s %s %s (%s)", arch, os, type, comp);
+ }
++#ifndef CFG_HEAD_CODE
++
+ #define       ZALLOC_ALIGNMENT        16
+ static void *zalloc(void *x, unsigned items, unsigned size)
+@@ -1427,3 +1449,5 @@
+ }
+ #endif /* CONFIG_LYNXKDI */
++
++#endif /* ! CFG_HEAD_CODE */
+--- a/common/cmd_flash.c
++++ b/common/cmd_flash.c
+@@ -196,9 +196,17 @@
+ }
+ static int
+-flash_fill_sect_ranges (ulong addr_first, ulong addr_last,
+-                      int *s_first, int *s_last,
+-                      int *s_count )
++flash_fill_sect_ranges(
++      ulong *addr_first_sect_start,
++      ulong addr_first,
++      ulong *addr_last_sect_end,
++      ulong addr_last,
++      int *s_first,
++      int *s_last,
++      int *bPartialStart,
++      int *bPartialEnd,
++      int *s_count,
++      unsigned int bPartialErase)
+ {
+       flash_info_t *info;
+       ulong bank;
+@@ -211,9 +219,7 @@
+               s_last [bank] = -1;     /* last  sector to erase        */
+       }
+-      for (bank=0,info=&flash_info[0];
+-           (bank < CFG_MAX_FLASH_BANKS) && (addr_first <= addr_last);
+-           ++bank, ++info) {
++      for (bank=0, info=&flash_info[0]; (bank < CFG_MAX_FLASH_BANKS) && (addr_first <= addr_last); ++bank, ++info) {
+               ulong b_end;
+               int sect;
+               short s_end;
+@@ -225,7 +231,6 @@
+               b_end = info->start[0] + info->size - 1;        /* bank end addr */
+               s_end = info->sector_count - 1;                 /* last sector   */
+-
+               for (sect=0; sect < info->sector_count; ++sect) {
+                       ulong end;      /* last address in current sect */
+@@ -238,11 +243,21 @@
+                       if (addr_first == info->start[sect]) {
+                               s_first[bank] = sect;
++                      } else if (addr_first > info->start[sect] && addr_first <= end && bPartialErase) {
++                              *addr_first_sect_start = info->start[sect];
++                              s_first[bank] = sect;
++                              *bPartialStart = 1;
+                       }
++
+                       if (addr_last  == end) {
+                               s_last[bank]  = sect;
++                      } else if (addr_last >= info->start[sect] && addr_last < end && bPartialErase) {
++                              *addr_last_sect_end = end;
++                              s_last[bank] = sect;
++                              *bPartialEnd = 1;
+                       }
+               }
++              
+               if (s_first[bank] >= 0) {
+                       if (s_last[bank] < 0) {
+                               if (addr_last > b_end) {
+@@ -316,6 +331,8 @@
+       struct part_info *part;
+       u8 dev_type, dev_num, pnum;
+ #endif
++      unsigned int bPartialErase = 0;
++
+       int rcode = 0;
+       if (argc < 2) {
+@@ -368,8 +385,8 @@
+               }
+       }
+ #endif
+-
+-      if (argc != 3) {
++      
++      if (argc != 4) {
+               printf ("Usage:\n%s\n", cmdtp->usage);
+               return 1;
+       }
+@@ -397,11 +414,117 @@
+               return 1;
+       }
+-      rcode = flash_sect_erase(addr_first, addr_last);
++      printf ("Erase Flash from 0x%08lx to 0x%08lx\n", addr_first, addr_last);
++      if(argc == 4) {
++              bPartialErase = simple_strtoul(argv[3], NULL, 10);
++      }
++
++      rcode = flash_sect_erase(addr_first, addr_last, bPartialErase);
+       return rcode;
+ }
+-int flash_sect_erase (ulong addr_first, ulong addr_last)
++int flerase_Partial(
++      ulong addr_first_sect_start,
++      ulong addr_first,
++      ulong addr_last_sect_end,
++      ulong addr_last,
++      flash_info_t *info,
++      int first_sect,
++      int last_sect,
++      int bFirstPartial,
++      int bLastPartial) {
++      unsigned int firstMemLen = 0;
++      unsigned int lastMemLen = 0;
++      unsigned int sectMemLen = 0;
++      uchar *pSavedFirstMem = NULL;
++      uchar *pSavedLastMem = NULL;
++      uchar *pSavedSectMem = NULL;
++      int bSectPartial = 0;
++      int rt_code = 0;
++
++      debug("%s ... 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%p, %d, %d, %d, %d\n", __FUNCTION__, addr_first_sect_start, addr_first, addr_last_sect_end, addr_last, info, first_sect, last_sect, bFirstPartial, bLastPartial);
++
++      if (bFirstPartial && bLastPartial && (first_sect == last_sect))
++      {
++              ulong b_end = info->start[0] + info->size - 1;
++              ulong end = (first_sect == (info->sector_count - 1)) ? b_end : info->start[first_sect + 1] - 1;
++              sectMemLen = end - info->start[first_sect] + 1;
++              pSavedSectMem = (uchar *)calloc(sectMemLen, sizeof(char));
++              if (pSavedSectMem == NULL)
++              {
++                      debug("calloc %u FAILED\n", sectMemLen);
++                      rt_code = 1;
++                      goto ret;
++              }
++              memset(pSavedSectMem, 0xff, sectMemLen);
++              bSectPartial = 1;
++              memcpy(pSavedSectMem, (uchar *)addr_first_sect_start, addr_first - addr_first_sect_start);
++              memcpy(pSavedSectMem + (addr_last - info->start[first_sect]) + 1, addr_last + 1, end - addr_last);
++      }
++      else
++      {
++              if (bFirstPartial){
++                      firstMemLen = addr_first - addr_first_sect_start + 1;
++                      pSavedFirstMem = (uchar *)calloc(firstMemLen,sizeof(char));
++                      memcpy(pSavedFirstMem,(uchar *)addr_first_sect_start,firstMemLen - 1);
++              }
++              if (bLastPartial){
++                      lastMemLen = addr_last_sect_end - addr_last + 1;
++                      pSavedLastMem = (uchar *)calloc(lastMemLen,sizeof(char));
++                      memcpy(pSavedLastMem,(uchar *)addr_last + 1,lastMemLen - 1);
++              }
++      }
++
++      if (bFirstPartial){
++              if(flash_erase (info, first_sect, first_sect)) {
++                      printf("%s ... Couldn't erase sector %d\n", __FUNCTION__, first_sect);
++                      rt_code = 1;
++                      goto ret;
++              }
++              debug("%s ... erase sector %d done!\n", __FUNCTION__, first_sect);
++      }
++      
++      if (bLastPartial && first_sect != last_sect){
++              if(flash_erase (info, last_sect, last_sect)) {
++                      printf("%s ... Couldn't erase sector %d\n", __FUNCTION__, last_sect);
++                      rt_code = 1;
++                      goto ret;
++              }
++              debug("%s ... erase sector %d done!\n", __FUNCTION__, last_sect);
++      }
++
++      if (bFirstPartial && bLastPartial && (first_sect == last_sect))
++      {
++              flash_write(pSavedSectMem, (uchar *)addr_first_sect_start, sectMemLen);
++              debug("flash_write from 0x%08x with len %u\n", addr_first_sect_start, sectMemLen);
++      }
++      else
++      {
++              if (bFirstPartial){
++                      if(flash_write(pSavedFirstMem,(uchar *)addr_first_sect_start,firstMemLen - 1)) {
++                              printf("%s ... Couldn't write at 0x%08lx length %d\n", __FUNCTION__, addr_first_sect_start,firstMemLen - 1);
++                              rt_code = 1;
++                              goto ret;
++                      }
++              }
++              if (bLastPartial){
++                      if(flash_write(pSavedLastMem,(uchar *)addr_last + 1,lastMemLen - 1)) {
++                              printf("%s ... Couldn't write at 0x%08lx length %d\n", __FUNCTION__, addr_last, lastMemLen - 1);
++                              rt_code = 1;
++                      }
++              }
++      }
++ret:
++      if (bFirstPartial)
++              free(pSavedFirstMem);
++      if (bLastPartial)
++              free(pSavedLastMem);
++      if (bSectPartial)
++              free(pSavedSectMem);
++      return rt_code;
++}
++
++int flash_sect_erase (ulong addr_first, ulong addr_last, unsigned int bPartialErase)
+ {
+       flash_info_t *info;
+       ulong bank;
+@@ -413,27 +536,66 @@
+       int erased = 0;
+       int planned;
+       int rcode = 0;
+-
+-      rcode = flash_fill_sect_ranges (addr_first, addr_last,
+-                                      s_first, s_last, &planned );
++      int bPartialStart = 0;          // Start sector has to be erased partially
++      int bPartialEnd = 0;            // End sector has to be erased partially
++      ulong addr_first_sect_start = 0;// Sector start address of location addr_start
++      ulong addr_last_sect_end = 0;   // Sector end address of location addr_last
++
++      rcode = flash_fill_sect_ranges (
++                      &addr_first_sect_start,
++                      addr_first,
++                      &addr_last_sect_end,
++                      addr_last,
++                      s_first,
++                      s_last,
++                      &bPartialStart,
++                      &bPartialEnd,
++                      &planned,
++                      bPartialErase );
+       if (planned && (rcode == 0)) {
+-              for (bank=0,info=&flash_info[0];
+-                   (bank < CFG_MAX_FLASH_BANKS) && (rcode == 0);
+-                   ++bank, ++info) {
++              for (bank=0, info=&flash_info[0]; (bank < CFG_MAX_FLASH_BANKS) && (rcode == 0); ++bank, ++info) {
++                      ulong b_end = info->start[0] + info->size - 1;  /* bank end addr */
+                       if (s_first[bank]>=0) {
+-                              erased += s_last[bank] - s_first[bank] + 1;
+-                              debug ("Erase Flash from 0x%08lx to 0x%08lx "
+-                                      "in Bank # %ld ",
+-                                      info->start[s_first[bank]],
+-                                      (s_last[bank] == info->sector_count) ?
+-                                              info->start[0] + info->size - 1:
+-                                              info->start[s_last[bank]+1] - 1,
+-                                      bank+1);
+-                              rcode = flash_erase (info, s_first[bank], s_last[bank]);
++                              if(bPartialErase) {
++                                      rcode = flerase_Partial(
++                                                      addr_first_sect_start,
++                                                      addr_first,
++                                                      addr_last_sect_end,
++                                                      addr_last,
++                                                      info,
++                                                      s_first[bank],
++                                                      s_last[bank],
++                                                      bPartialStart,
++                                                      bPartialEnd);
++                              }                       
++
++                              //Erase full sectores
++                              if (bPartialStart)
++                                      s_first[bank] += 1;
++                              if (bPartialEnd)
++                                      s_last[bank] -= 1;
++                              if (s_last[bank] >= s_first[bank]) {
++                                      erased += s_last[bank] - s_first[bank] + 1;
++                                      debug ("Erase Flash from 0x%08lx to 0x%08lx in Bank # %ld ",
++                                              info->start[s_first[bank]],
++                                              (s_last[bank] == info->sector_count) ?
++                                                      info->start[0] + info->size - 1:
++                                                      info->start[s_last[bank]+1] - 1,
++                                              bank + 1);
++                                      rcode = flash_erase (info, s_first[bank], s_last[bank]);
++                              }
+                       }
+               }
+-              printf ("Erased %d sectors\n", erased);
++              
++              if (erased && !bPartialErase) {
++                      printf ("Erased %d sectors\n", erased);
++              } else if (bPartialErase){
++                      printf ("Partial erased from 0x%08lx to 0x%08lx\n", addr_first, addr_last);
++              } else {
++                      printf ("Error: start and/or end address not on sector boundary\n");
++                      rcode = 1;
++              }
+       } else if (rcode == 0) {
+               puts ("Error: start and/or end address"
+                       " not on sector boundary\n");
+@@ -629,8 +791,22 @@
+       int protected, i;
+       int planned;
+       int rcode;
+-
+-      rcode = flash_fill_sect_ranges( addr_first, addr_last, s_first, s_last, &planned );
++      int bPartialStart = 0;          // Start sector has to be erased partially
++      int bPartialEnd = 0;            // End sector has to be erased partially
++      ulong addr_first_sect_start = 0;// Sector start address of location addr_start
++      ulong addr_last_sect_end = 0;   // Sector end address of location addr_last
++
++      rcode = flash_fill_sect_ranges (
++                      &addr_first_sect_start,
++                      addr_first,
++                      &addr_last_sect_end,
++                      addr_last,
++                      s_first,
++                      s_last,
++                      &bPartialStart,
++                      &bPartialEnd,
++                      &planned,
++                      1 );
+       protected = 0;
+@@ -690,7 +866,7 @@
+ );
+ U_BOOT_CMD(
+-      erase,   3,   1,  do_flerase,
++      erase,   4,   1,  do_flerase,
+       "erase   - erase FLASH memory\n",
+       "start end\n"
+       "    - erase FLASH from addr 'start' to addr 'end'\n"
+--- a/common/cmd_nvedit.c
++++ b/common/cmd_nvedit.c
+@@ -540,8 +540,19 @@
+       extern char * env_name_spec;
+       printf ("Saving Environment to %s...\n", env_name_spec);
+-
++#if 1
++      if(saveenv() == 0) {
++#ifdef UBOOT_ENV_COPY
++              saveenv_copy();
++#else
++              ;
++#endif //UBOOT_ENV_COPY
++      } else
++              return 1;
++      return 0;
++#else
+       return (saveenv() ? 1 : 0);
++#endif
+ }
+--- a/common/console.c
++++ b/common/console.c
+@@ -324,7 +324,7 @@
+ #endif
+ /** U-Boot INIT FUNCTIONS *************************************************/
+-
++#ifndef CFG_HEAD_CODE
+ int console_assign (int file, char *devname)
+ {
+       int flag, i;
+@@ -357,7 +357,7 @@
+       return -1;
+ }
+-
++#endif        //CFG_HEAD_CODE
+ /* Called before relocation - use serial functions */
+ int console_init_f (void)
+ {
+@@ -392,6 +392,7 @@
+ }
+ #endif /* CFG_CONSOLE_IS_IN_ENV || CONFIG_SPLASH_SCREEN */
++#ifndef CFG_HEAD_CODE
+ #ifdef CFG_CONSOLE_IS_IN_ENV
+ /* Called after the relocation - use desired console functions */
+ int console_init_r (void)
+@@ -570,3 +571,4 @@
+ }
+ #endif /* CFG_CONSOLE_IS_IN_ENV */
++#endif        //CFG_HEAD_CODE
+--- a/common/devices.c
++++ b/common/devices.c
+@@ -39,6 +39,7 @@
+ list_t devlist = 0;
+ device_t *stdio_devices[] = { NULL, NULL, NULL };
+ char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
++#ifndef CFG_HEAD_CODE
+ #if defined(CONFIG_SPLASH_SCREEN) && !defined(CFG_DEVICE_NULLDEV)
+ #define       CFG_DEVICE_NULLDEV      1
+@@ -214,3 +215,5 @@
+       return 0;
+ }
++#endif //CFG_HEAD_CODE
++
+--- a/common/env_common.c
++++ b/common/env_common.c
+@@ -219,7 +219,9 @@
+        * We must allocate a buffer for the environment
+        */
+       env_ptr = (env_t *)malloc (CFG_ENV_SIZE);
+-      DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
++      if(!env_ptr)
++              DEBUGF ("malloc env_ptr error!!\n");
++      DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__, __LINE__, env_ptr);
+ #endif
+       /*
+@@ -227,6 +229,10 @@
+        */
+       env_get_char = env_get_char_memory;
++      //leejack
++      DEBUGF ("%s[%d] gd->env_valid=%d\n", __FUNCTION__, __LINE__, gd->env_valid);
++      DEBUGF ("%s[%d] CFG_ENV_SIZE=%d\n", __FUNCTION__, __LINE__, CFG_ENV_SIZE);
++
+       if (gd->env_valid == 0) {
+ #if defined(CONFIG_GTH)       || defined(CFG_ENV_IS_NOWHERE)  /* Environment not changable */
+               puts ("Using default environment\n\n");
+@@ -242,18 +248,17 @@
+               }
+               memset (env_ptr, 0, sizeof(env_t));
+-              memcpy (env_ptr->data,
+-                      default_environment,
+-                      sizeof(default_environment));
++              memcpy (env_ptr->data, default_environment, sizeof(default_environment));
++
+ #ifdef CFG_REDUNDAND_ENVIRONMENT
+               env_ptr->flags = 0xFF;
+ #endif
+               env_crc_update ();
+               gd->env_valid = 1;
+-      }
+-      else {
++      } else {
+               env_relocate_spec ();
+       }
++
+       gd->env_addr = (ulong)&(env_ptr->data);
+ #ifdef CONFIG_AMIGAONEG3SE
+--- a/common/env_flash.c
++++ b/common/env_flash.c
+@@ -66,7 +66,6 @@
+ #endif
+ #else /* ! ENV_IS_EMBEDDED */
+-
+ env_t *env_ptr = (env_t *)CFG_ENV_ADDR;
+ #ifdef CMD_SAVEENV
+ static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
+@@ -201,6 +200,7 @@
+       debug (" %08lX ... %08lX ...",
+               (ulong)&(flash_addr_new->data),
+               sizeof(env_ptr->data)+(ulong)&(flash_addr_new->data));
++      
+       if ((rc = flash_write((char *)env_ptr->data,
+                       (ulong)&(flash_addr_new->data),
+                       sizeof(env_ptr->data))) ||
+@@ -256,7 +256,6 @@
+ #endif /* CMD_SAVEENV */
+ #else /* ! CFG_ENV_ADDR_REDUND */
+-
+ int  env_init(void)
+ {
+ #ifdef CONFIG_OMAP2420H4
+@@ -280,8 +279,55 @@
+ #ifdef CMD_SAVEENV
++#ifdef UBOOT_ENV_COPY
++int saveenv_copy(void) {
++      uchar *env_buffer = (char *)env_ptr;
++      char *kernel_addr;
++      char *rootfs_addr;
++      char *rootfs_size;
++      ulong start_addr,end_addr,rootfs_end_addr;
++      ulong flash_start;
++
++      kernel_addr = getenv("f_kernel_addr");
++      end_addr = simple_strtoul(kernel_addr,NULL,16) - 1;
++      start_addr = end_addr - CFG_ENV_SIZE - sizeof(UBOOTCONFIG_COPY_HEADER) + 1;
++
++      rootfs_addr = getenv("f_rootfs_addr");
++      rootfs_size = getenv("f_rootfs_size");
++      rootfs_end_addr = simple_strtoul(rootfs_addr,NULL,16) + simple_strtoul(rootfs_size,NULL,16);
++
++      if(rootfs_end_addr >= start_addr)
++      {
++              printf("Can not copy the environment at 0x%08lx as no space left.\nf_kernel_addr = 0x%08lx while rootfs_end_addr = 0x%08lx\n",start_addr,end_addr,rootfs_end_addr);
++              return 1;
++      }
++
++      debug ("Protect off %08lX ... %08lX\n", (ulong)rootfs_end_addr, end_addr);
++      if (flash_sect_protect (0, rootfs_end_addr, end_addr))
++              return 1;
++
++      //delete the old environment copy, if found
++      flash_start = rootfs_end_addr;
++      while(flash_start + sizeof(UBOOTCONFIG_COPY_HEADER) + ENV_SIZE < end_addr)
++      {
++              if(strncmp((char *)flash_start,UBOOTCONFIG_COPY_HEADER,sizeof(UBOOTCONFIG_COPY_HEADER)) == 0)
++              {
++                      flash_sect_erase(flash_start,flash_start + sizeof(UBOOTCONFIG_COPY_HEADER),1);
++              }
++              flash_start += 1;
++      }
++      flash_sect_erase(start_addr,end_addr,1);
++      flash_write(UBOOTCONFIG_COPY_HEADER,start_addr,sizeof(UBOOTCONFIG_COPY_HEADER));
++      flash_write(env_buffer,start_addr + sizeof(UBOOTCONFIG_COPY_HEADER), CFG_ENV_SIZE);
++      flash_sect_protect (1, rootfs_end_addr, end_addr);
++      printf("saved copy of the env at 0x%08lx\n",start_addr);
++      return 0;
++}
++#endif        //UBOOT_ENV_COPY
++
+ int saveenv(void)
+ {
++#define debug printf
+       int     len, rc;
+       ulong   end_addr;
+       ulong   flash_sect_addr;
+@@ -331,7 +377,7 @@
+               return 1;
+       puts ("Erasing Flash...");
+-      if (flash_sect_erase (flash_sect_addr, end_addr))
++      if (flash_sect_erase (flash_sect_addr, end_addr, 1))
+               return 1;
+       puts ("Writing to Flash... ");
+--- a/common/hush.c
++++ b/common/hush.c
+@@ -3167,9 +3167,11 @@
+       int code = 0;
+ #endif
+       do {
++              printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+               ctx.type = flag;
+               initialize_context(&ctx);
+               update_ifs_map();
++              printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+               if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset((uchar *)";$&|", 0);
+               inp->promptmode=1;
+               rcode = parse_stream(&temp, &ctx, inp, '\n');
+@@ -3180,9 +3182,12 @@
+                       syntax();
+ #ifdef __U_BOOT__
+                       flag_repeat = 0;
++printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+ #endif
++              printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+               }
+               if (rcode != 1 && ctx.old_flag == 0) {
++                      printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+                       done_word(&temp, &ctx);
+                       done_pipe(&ctx,PIPE_SEQ);
+ #ifndef __U_BOOT__
+@@ -3202,6 +3207,7 @@
+                       if (code == -1)
+                           flag_repeat = 0;
+ #endif
++              printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+               } else {
+                       if (ctx.old_flag != 0) {
+                               free(ctx.stack);
+@@ -3215,6 +3221,7 @@
+                       temp.quote = 0;
+                       inp->p = NULL;
+                       free_pipe_list(ctx.list_head,0);
++              printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+               }
+               b_free(&temp);
+       } while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP));   /* loop on syntax errors, return on EOF */
+@@ -3235,9 +3242,12 @@
+ #ifdef __U_BOOT__
+       char *p = NULL;
+       int rcode;
++      printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+       if ( !s || !*s)
+               return 1;
++      printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+       if (!(p = strchr(s, '\n')) || *++p) {
++              printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+               p = xmalloc(strlen(s) + 2);
+               strcpy(p, s);
+               strcat(p, "\n");
+@@ -3247,6 +3257,7 @@
+               return rcode;
+       } else {
+ #endif
++      printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
+       setup_string_in_str(&input, s);
+       return parse_stream_outer(&input, flag);
+ #ifdef __U_BOOT__
+--- a/config.mk
++++ b/config.mk
+@@ -77,7 +77,7 @@
+ sinclude $(TOPDIR)/$(ARCH)_config.mk  # include architecture dependend rules
+ endif
+ ifdef CPU
+-sinclude $(TOPDIR)/cpu/$(CPU)/config.mk       # include  CPU  specific rules
++sinclude $(TOPDIR)/cpu/$(CPU)/$(BOARD)/config.mk      # include  CPU  specific rules
+ endif
+ ifdef SOC
+ sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk        # include  SoC  specific rules
+@@ -130,7 +130,8 @@
+ ARFLAGS = crv
+ RELFLAGS= $(PLATFORM_RELFLAGS)
+ DBGFLAGS= -g # -DDEBUG
+-OPTFLAGS= -Os #-fomit-frame-pointer
++OPTFLAGS= -Os 
++#-O2 #-fomit-frame-pointer
+ ifndef LDSCRIPT
+ #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
+ ifeq ($(CONFIG_NAND_U_BOOT),y)
+@@ -139,12 +140,15 @@
+ LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
+ endif
+ endif
++
++LDSCRIPT_BOOTSTRAP := $(TOPDIR)/board/$(BOARDDIR)/u-boot-bootstrap.lds
++
+ OBJCFLAGS += --gap-fill=0xff
+ gccincdir := $(shell $(CC) -print-file-name=include)
+ CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS)               \
+-      -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE)           \
++      -D__KERNEL__ -DUBOOT_RAM_TEXT_BASE=$(UBOOT_RAM_TEXT_BASE)               \
+ ifneq ($(OBJTREE),$(SRCTREE))
+ CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include
+@@ -180,7 +184,10 @@
+ AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS)
+-LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
++LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(UBOOT_RAM_TEXT_BASE) $(PLATFORM_LDFLAGS)
++LDFLAGS_BOOTSTRAP += -Bstatic -T $(LDSCRIPT_BOOTSTRAP) -Ttext $(BOOTSTRAP_TEXT_BASE) $(PLATFORM_LDFLAGS)
++
++#HEAD_LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(HEAD_FLASH_TEXT_BASE) $(PLATFORM_LDFLAGS)
+ # Location of a usable BFD library, where we define "usable" as
+ # "built for ${HOST}, supports ${TARGET}".  Sensible values are
+@@ -211,10 +218,17 @@
+ #########################################################################
++AFLAGS := $(AFLAGS) $(IFX_CFLAGS)
++CFLAGS := $(CFLAGS) $(IFX_CFLAGS)
++CPPFLAGS := $(CPPFLAGS) $(IFX_CFLAGS)
++
++#########################################################################
++
+ export        CONFIG_SHELL HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE \
+       AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP \
+       MAKE
+-export        TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS
++#export       UBOOT_RAM_TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS
++export        UBOOT_RAM_TEXT_BASE BOOTSTRAP_TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS
+ #########################################################################
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -50,14 +50,14 @@
+         videomodes.o w83c553f.o \
+         ks8695eth.o \
+         pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o  \
+-        rpx_pcmcia.o
++        rpx_pcmcia.o ifx_sw.o
+ SRCS  := $(COBJS:.o=.c)
+ OBJS  := $(addprefix $(obj),$(COBJS))
+ all:  $(LIB)
+-$(LIB): $(obj).depend $(OBJS)
++$(LIB):  $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+ #########################################################################
+--- a/include/asm-mips/mipsregs.h
++++ b/include/asm-mips/mipsregs.h
+@@ -48,6 +48,7 @@
+ #define CP0_CAUSE $13
+ #define CP0_EPC $14
+ #define CP0_PRID $15
++#define CP0_EBASE $15,1
+ #define CP0_CONFIG $16
+ #define CP0_LLADDR $17
+ #define CP0_WATCHLO $18
+@@ -330,11 +331,32 @@
+ #  define KSU_USER            0x00000010
+ #  define KSU_SUPERVISOR      0x00000008
+ #  define KSU_KERNEL          0x00000000
++#ifdef CONFIG_DANUBE  /* MIPS 24KE */
++/* bits 5 & 6 & 7: reserved */
++/* bits 8~15: IM0~7 */
++/* bits 16: reserved */
++#define ST0_CEE                       0x00020000
++/* bits 18: always 0 */
++#define ST0_NMI                       0x00080000
++#define ST0_SR                        0x00100000
++#define ST0_TS                        0x00200000
++#define ST0_BEV                       0x00400000
++/* bits 23: reserved */
++#define ST0_MX                        0x01000000
++#define ST0_RE                        0x02000000
++#define ST0_FR                        0x04000000
++#define ST0_RP                        0x08000000
++#define ST0_CU0                       0x10000000
++#define ST0_CU1                       0x20000000
++#define ST0_CU2                       0x40000000
++#define ST0_CU3                       0x80000000
++#else
+ #define ST0_UX                        0x00000020
+ #define ST0_SX                        0x00000040
+ #define ST0_KX                        0x00000080
+ #define ST0_DE                        0x00010000
+ #define ST0_CE                        0x00020000
++#endif
+ /*
+  * Bitfields in the R[23]000 cp0 status register.
+@@ -471,6 +493,14 @@
+ #define  CAUSEF_BD            (1   << 31)
+ /*
++ * Bits in the coprocessor 0 EBase register 
++ */
++#define EBASEB_CPUNUM         0
++#define EBASEF_CPUNUM         (0x3ff << EBASEB_CPUNUM)
++#define EBASEB_EXPBASE                12
++#define EBASEF_EXPBASE                (0x3ffff << EBASEB_EXPBASE)
++
++/*
+  * Bits in the coprozessor 0 config register.
+  */
+ #define CONF_CM_CACHABLE_NO_WA                0
+@@ -544,4 +574,10 @@
+ #define CEB_KERNEL    2       /* Count events in kernel mode EXL = ERL = 0 */
+ #define CEB_EXL               1       /* Count events with EXL = 1, ERL = 0 */
++/*
++ * Bits in ErrCtl register
++ */
++#define ECCB_WST      29
++#define ECCF_WST      (0x1 << ECCB_WST)
++
+ #endif /* _ASM_MIPSREGS_H */
+--- a/include/cmd_confdefs.h
++++ b/include/cmd_confdefs.h
+@@ -94,6 +94,7 @@
+ #define CFG_CMD_EXT2  0x1000000000000000ULL   /* EXT2 Support                 */
+ #define CFG_CMD_SNTP  0x2000000000000000ULL   /* SNTP support                 */
+ #define CFG_CMD_DISPLAY       0x4000000000000000ULL   /* Display support              */
++#define CFG_CMD_DHRYSTONE     0x8000000000000000ULL   /* Dhrystone benchmark support          */
+ #define CFG_CMD_ALL   0xFFFFFFFFFFFFFFFFULL   /* ALL commands                 */
+@@ -141,6 +142,7 @@
+                       CFG_CMD_SPI     | \
+                       CFG_CMD_UNIVERSE | \
+                       CFG_CMD_USB     | \
++                      CFG_CMD_DHRYSTONE | \
+                       CFG_CMD_VFD     )
+ /* Default configuration
+--- /dev/null
++++ b/include/config.h
+@@ -0,0 +1,2 @@
++/* Automatically generated - do not edit */
++#include <configs/danube.h>
+--- /dev/null
++++ b/include/config.mk
+@@ -0,0 +1,3 @@
++ARCH   = mips
++CPU    = mips
++BOARD  = danube
+--- a/include/flash.h
++++ b/include/flash.h
+@@ -79,7 +79,7 @@
+ extern unsigned long flash_init (void);
+ extern void flash_print_info (flash_info_t *);
+ extern int flash_erase        (flash_info_t *, int, int);
+-extern int flash_sect_erase (ulong addr_first, ulong addr_last);
++extern int flash_sect_erase (ulong addr_first, ulong addr_last, unsigned int bPartialErase);
+ extern int flash_sect_protect (int flag, ulong addr_first, ulong addr_last);
+ /* common/flash.c */
+@@ -299,6 +299,10 @@
+ #define TOSH_ID_FVT160        0xC2            /* TC58FVT160 ID (16 M, top )           */
+ #define TOSH_ID_FVB160        0x43            /* TC58FVT160 ID (16 M, bottom )        */
++#define MX_ID_29LV320AB 0x22A822A8      /* MXIC  MX29LV320AB ID (32 M, bottom ) joelin       */
++#define MX_ID_29LV160BB 0x22492249      /* MXIC  MX29LV160BB ID (16 M, bottom ) joelin       */
++#define MX_ID_29LV640BB 0x22cb22cb      /* MXIC  MX29LV640BB ID (64 M, bottom ) joelin       */
++
+ /*-----------------------------------------------------------------------
+  * Internal FLASH identification codes
+  *
+@@ -422,6 +426,10 @@
+ #define FLASH_S29GL064M 0x00F0                /* Spansion S29GL064M-R6                */
+ #define FLASH_S29GL128N 0x00F1                /* Spansion S29GL128N                   */
++#define FLASH_29LV320AB 0x00B0          /* MXIC MX29LV320AB( 32M = 4M x 16 ) joelin 10/07/2004*/
++#define FLASH_29LV160BB 0x00B1          /* MXIC MX29LV160BB( 16M = 2M x 16 ) joelin 11/22/2004*/
++#define FLASH_29LV640BB 0x00B2          /* MXIC MX29LV640BB( 64M = 8M x 16 ) liupeng*/
++
+ #define FLASH_UNKNOWN 0xFFFF          /* unknown flash type                   */
+--- a/include/image.h
++++ b/include/image.h
+@@ -132,6 +132,7 @@
+ #define IH_COMP_NONE          0       /*  No   Compression Used       */
+ #define IH_COMP_GZIP          1       /* gzip  Compression Used       */
+ #define IH_COMP_BZIP2         2       /* bzip2 Compression Used       */
++#define IH_COMP_LZMA          3       /* lzma Compression Used        */
+ #define IH_MAGIC      0x27051956      /* Image Magic Number           */
+ #define IH_NMLEN              32      /* Image Name Length            */
+--- /dev/null
++++ b/include/syscall.h
+@@ -0,0 +1,42 @@
++#ifndef __MON_SYS_CALL_H__
++#define __MON_SYS_CALL_H__
++
++#ifndef __ASSEMBLY__
++
++#include <common.h>
++
++/* These are declarations of system calls available in C code */
++int  mon_getc(void);
++int  mon_tstc(void);
++void mon_putc(const char);
++void mon_puts(const char*);
++void mon_printf(const char* fmt, ...);
++void mon_install_hdlr(int, interrupt_handler_t*, void*);
++void mon_free_hdlr(int);
++void *mon_malloc(size_t);
++void mon_free(void*);
++void mon_udelay(unsigned long);
++unsigned long mon_get_timer(unsigned long);
++
++#endif    /* ifndef __ASSEMBLY__ */
++
++#define NR_SYSCALLS            11        /* number of syscalls */
++
++
++/*
++ * Make sure these functions are in the same order as they
++ * appear in the "examples/syscall.S" file !!!
++ */
++#define SYSCALL_GETC           0
++#define SYSCALL_TSTC           1
++#define SYSCALL_PUTC           2
++#define SYSCALL_PUTS           3
++#define SYSCALL_PRINTF         4
++#define SYSCALL_INSTALL_HDLR   5
++#define SYSCALL_FREE_HDLR      6
++#define SYSCALL_MALLOC         7
++#define SYSCALL_FREE           8
++#define SYSCALL_UDELAY         9
++#define SYSCALL_GET_TIMER     10
++
++#endif
+--- /dev/null
++++ b/include/version_autogenerated.h
+@@ -0,0 +1 @@
++#define U_BOOT_VERSION "U-Boot 1.1.5-IFX-LXDB-g71af1545"
+--- /dev/null
++++ b/ld_uboot.conf
+@@ -0,0 +1,8 @@
++TAG_DWNLD() 
++{ 
++   0xA0B00000 "u-boot.bin" /* Download u-boot image */ 
++};
++TAG_START()
++{
++   0xA0B00000
++}; /* Start u-boot image */
+--- a/lib_generic/Makefile
++++ b/lib_generic/Makefile
+@@ -28,7 +28,7 @@
+ COBJS = bzlib.o bzlib_crctable.o bzlib_decompress.o \
+         bzlib_randtable.o bzlib_huffman.o \
+         crc32.o ctype.o display_options.o ldiv.o \
+-        string.o vsprintf.o zlib.o
++        string.o vsprintf.o zlib.o LzmaDecode.o LzmaWrapper.o
+ SRCS  := $(COBJS:.o=.c)
+ OBJS  := $(addprefix $(obj),$(COBJS))
+--- a/lib_mips/board.c
++++ b/lib_mips/board.c
+@@ -29,6 +29,25 @@
+ #include <net.h>
+ #include <environment.h>
++#ifdef CFG_HEAD_CODE
++#undef CONFIG_MICROBZIP2
++
++#ifdef CONFIG_BZIP2
++#include <bzlib.h>
++#endif
++
++#ifdef CONFIG_MICROBZIP2
++#include <micro_bzlib.h>
++#endif
++
++#ifdef CONFIG_LZMA
++#include <LzmaWrapper.h>
++#endif
++
++#include <image.h>
++#include "head.h"
++#endif //CFG_HEAD_CODE
++
+ DECLARE_GLOBAL_DATA_PTR;
+ #if ( ((CFG_ENV_ADDR+CFG_ENV_SIZE) < CFG_MONITOR_BASE) || \
+@@ -39,8 +58,6 @@
+ #define       TOTAL_MALLOC_LEN        CFG_MALLOC_LEN
+ #endif
+-#undef DEBUG
+-
+ extern int timer_init(void);
+ extern int incaip_set_cpuclk(void);
+@@ -79,6 +96,25 @@
+               mem_malloc_end - mem_malloc_start);
+ }
++#ifdef CFG_HEAD_CODE
++void *malloc(unsigned int size) {
++      if(size < (mem_malloc_end - mem_malloc_start)) {
++              mem_malloc_start += size;
++              //printf("malloc : size required = 0x%08lx and pointer = 0x%08lx\n",size,mem_malloc_start - size);
++              return (void *)(mem_malloc_start - size);
++      }
++      return NULL;
++}
++
++void *realloc(void *src,unsigned int size) {
++      return NULL;
++}
++
++void free(void *src) {
++      return;
++}
++#endif //CFG_HEAD_CODE 
++
+ void *sbrk (ptrdiff_t increment)
+ {
+       ulong old = mem_malloc_brk;
+@@ -99,7 +135,11 @@
+ #else
+       int board_type = 0;     /* use dummy arg */
+ #endif
++#ifdef CONFIG_USE_DDR_RAM
++      puts ("DDR-DRAM:  ");
++#else
+       puts ("DRAM:  ");
++#endif
+       if ((gd->ram_size = initdram (board_type)) > 0) {
+               print_size (gd->ram_size, "\n");
+@@ -116,26 +156,29 @@
+       return (0);
+ }
++#ifndef CFG_HEAD_CODE
+ static void display_flash_config(ulong size)
+ {
+       puts ("Flash: ");
+       print_size (size, "\n");
+ }
+-
++#endif
+ static int init_baudrate (void)
+ {
++#ifndef CFG_HEAD_CODE
+       char tmp[64];   /* long enough for environment variables */
+       int i = getenv_r ("baudrate", tmp, sizeof (tmp));
+       gd->baudrate = (i > 0)
+                       ? (int) simple_strtoul (tmp, NULL, 10)
+                       : CONFIG_BAUDRATE;
+-
++#else //CFG_HEAD_CODE
++      gd->baudrate = CONFIG_BAUDRATE; 
++#endif //CFG_HEAD_CODE
+       return (0);
+ }
+-
+ /*
+  * Breath some life into the board...
+  *
+@@ -160,7 +203,9 @@
+ init_fnc_t *init_sequence[] = {
+       timer_init,
++#ifndef CFG_HEAD_CODE
+       env_init,               /* initialize environment */
++#endif //CFG_HEAD_CODE
+ #ifdef CONFIG_INCA_IP
+       incaip_set_cpuclk,      /* set cpu clock according to environment variable */
+ #endif
+@@ -179,7 +224,11 @@
+       gd_t gd_data, *id;
+       bd_t *bd;
+       init_fnc_t **init_fnc_ptr;
++#ifdef CFG_HEAD_CODE
++      ulong addr, addr_sp, len = (ulong)&uboot_end - CFG_HEAD_BASE;
++#else //CFG_HEAD_CODE
+       ulong addr, addr_sp, len = (ulong)&uboot_end - CFG_MONITOR_BASE;
++#endif //CFG_HEAD_CODE
+       ulong *s;
+ #ifdef CONFIG_PURPLE
+       void copy_code (ulong);
+@@ -278,7 +327,8 @@
+ #ifdef CONFIG_PURPLE
+       copy_code(addr);
+ #endif
+-
++      
++      puts("\n relocate_code start");
+       relocate_code (addr_sp, id, addr);
+       /* NOTREACHED - relocate_code() does not return */
+@@ -292,7 +342,93 @@
+  *
+  ************************************************************************
+  */
++#ifdef CFG_HEAD_CODE
++
++extern void print_image_hdr (image_header_t *hdr);
++extern void jump_unconditional (ulong addr);
++
++void board_init_r (gd_t *id, ulong dest_addr) {
++      int i;
++      ulong   addr;
++      ulong   data, len, checksum;
++      ulong  *len_ptr;
++      image_header_t header;
++      image_header_t *hdr = &header;
++      unsigned int destLen;
++      puts("\n relocate code finish.\n");
++
++      /* initialize malloc() area */
++      mem_malloc_init();
++
++      addr = CFG_HEAD_BASE + CFG_UBOOT_OFFSET;
++      memmove (&header, (char *)addr, sizeof(image_header_t));
++
++      if (ntohl(hdr->ih_magic) != IH_MAGIC) {
++              printf ("Bad Magic Number at address 0x%08lx\n",addr);
++              return;
++      }
++
++      data = (ulong)&header;
++      len  = sizeof(image_header_t);
++
++      checksum = ntohl(hdr->ih_hcrc);
++      hdr->ih_hcrc = 0;
++      if (crc32 (0, (char *)data, len) != checksum) {
++              printf ("Bad Header Checksum\n");
++              return;
++      }
++
++      print_image_hdr (hdr);
++
++      data = addr + sizeof(image_header_t);
++      len  = ntohl(hdr->ih_size);
++      len_ptr = (ulong *)data;
++
++      debug ("Disabling all the interrupts\n");
++      disable_interrupts();
++
++      debug ("   Uncompressing UBoot Image ... \n" );
++      /*
++       * If we've got less than 4 MB of malloc() space,
++       * use slower decompression algorithm which requires
++       * at most 2300 KB of memory.
++       */
++      destLen = 0x0;
++
++#ifdef CONFIG_BZIP2
++      i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
++                                      0x400000, (char *)data, len,
++                                      CFG_MALLOC_LEN < (4096 * 1024), 0);
++      if (i != BZ_OK) {
++                      printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i);
++                      return;
++      }
++#elif CONFIG_MICROBZIP2
++      i = micro_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
++                                      &destLen, (char *)data, len,
++                                      CFG_MALLOC_LEN < (4096 * 1024), 0);
++      if (i != RETVAL_OK) {
++              printf ("MICRO_BUNZIP2 ERROR %d - must RESET board to recover\n", i);
++              return;
++      }
++#elif CONFIG_LZMA
++      i = lzma_inflate ((char *)data, len, (char*)ntohl(hdr->ih_load), &destLen);
++      if (i != LZMA_RESULT_OK) {
++              printf ("LZMA ERROR %d - must RESET board to recover\n", i);
++              return;
++      }
++#else
++      printf ("NONE Compressing u-boot body!!\n");
++      memmove ((void *)ntohl(hdr->ih_load), (uchar *)data, len);
++      destLen = len;
++#endif
++      debug ("   Uncompression completed successfully with destLen %d.\n ",destLen );
++      debug ("Head: Jumping to u-boot in the ram at 0x%08lx\n", CFG_MONITOR_BASE);
++
++      jump_unconditional(CFG_MONITOR_BASE);
++}
++#else //CFG_HEAD_CODE
+ void board_init_r (gd_t *id, ulong dest_addr)
+ {
+       cmd_tbl_t *cmdtp;
+@@ -305,6 +441,8 @@
+       bd_t *bd;
+       int i;
++      puts("\n relocate code finish.\n");
++
+       gd = id;
+       gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
+@@ -321,10 +459,10 @@
+               ulong addr;
+               addr = (ulong) (cmdtp->cmd) + gd->reloc_off;
+-#if 0
+-              printf ("Command \"%s\": 0x%08lx => 0x%08lx\n",
++
++              debug ("Command \"%s\": 0x%08lx => 0x%08lx\n",
+                               cmdtp->name, (ulong) (cmdtp->cmd), addr);
+-#endif
++
+               cmdtp->cmd =
+                       (int (*)(struct cmd_tbl_s *, int, int, char *[]))addr;
+@@ -424,6 +562,7 @@
+       /* NOTREACHED - no way out of command loop except booting */
+ }
++#endif //CFG_HEAD_CODE
+ void hang (void)
+ {
+--- /dev/null
++++ b/lib_mips/head.h
+@@ -0,0 +1,3 @@
++
++//#define CFG_HEAD_LEN                0x00006000
++#define CFG_UBOOT_OFFSET      CFG_HEAD_LEN
+--- a/lib_mips/time.c
++++ b/lib_mips/time.c
+@@ -80,6 +80,17 @@
+               /*NOP*/;
+ }
++void mdelay (unsigned long msec)
++{
++       int i,j;
++       for(i=0;i<msec;i++)
++       {
++          udelay(1000);
++
++       }
++
++}
++
+ /*
+  * This function is derived from PowerPC code (read timebase as long long).
+  * On MIPS it just returns the timer value.
+--- a/net/eth.c
++++ b/net/eth.c
+@@ -25,6 +25,9 @@
+ #include <command.h>
+ #include <net.h>
+ #include <miiphy.h>
++#if defined(CONFIG_IFX_MIPS)
++#       include "ifx_eth.c"
++#endif
+ #if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI)
+@@ -54,6 +57,9 @@
+ extern int skge_initialize(bd_t*);
+ extern int tsec_initialize(bd_t*, int, char *);
+ extern int npe_initialize(bd_t *);
++#if defined(CONFIG_IFX_MIPS)
++      IFX_ETH_INITIALIZE_EXTERN
++#endif
+ static struct eth_device *eth_devices, *eth_current;
+@@ -235,7 +241,9 @@
+ #if defined(CONFIG_RTL8169)
+       rtl8169_initialize(bis);
+ #endif
+-
++#if defined(CONFIG_IFX_MIPS)
++      IFX_ETH_INITIALIZE(bis)
++#endif
+       if (!eth_devices) {
+               puts ("No ethernet found.\n");
+       } else {
+--- a/tools/Makefile
++++ b/tools/Makefile
+@@ -23,7 +23,7 @@
+ BIN_FILES     = img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX)
+-OBJ_LINKS     = environment.o crc32.o
++OBJ_LINKS     = environment_$(BOARDDIR).o crc32_$(BOARDDIR).o
+ OBJ_FILES     = img2srec.o mkimage.o envcrc.o gen_eth_addr.o bmp_logo.o
+ ifeq ($(ARCH),mips)
+@@ -117,7 +117,7 @@
+ CPPFLAGS   = -idirafter $(SRCTREE)/include \
+               -idirafter $(OBJTREE)/include2 \
+               -idirafter $(OBJTREE)/include \
+-              -DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC
++              -DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC $(IFX_CFLAGS)
+ CFLAGS     = $(HOST_CFLAGS) $(CPPFLAGS) -O
+ AFLAGS           = -D__ASSEMBLY__ $(CPPFLAGS)
+ CC       = $(HOSTCC)
+@@ -126,14 +126,14 @@
+ all:  $(obj).depend $(BINS) $(LOGO_H) subdirs
+-$(obj)envcrc$(SFX):   $(obj)envcrc.o $(obj)crc32.o $(obj)environment.o
++$(obj)envcrc$(SFX):   $(obj)envcrc.o $(obj)crc32_$(BOARDDIR).o $(obj)environment_$(BOARDDIR).o
+               $(CC) $(CFLAGS) -o $@ $^
+ $(obj)img2srec$(SFX): $(obj)img2srec.o
+               $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
+               $(STRIP) $@
+-$(obj)mkimage$(SFX):  $(obj)mkimage.o $(obj)crc32.o
++$(obj)mkimage$(SFX):  $(obj)mkimage.o $(obj)crc32_$(BOARDDIR).o
+               $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
+               $(STRIP) $@
+@@ -160,7 +160,7 @@
+ $(obj)envcrc.o:       $(src)envcrc.c
+               $(CC) -g $(CFLAGS) -c -o $@ $<
+-$(obj)crc32.o:        $(obj)crc32.c
++$(obj)crc32_$(BOARDDIR).o:    $(obj)crc32_$(BOARDDIR).c
+               $(CC) -g $(CFLAGS) -c -o $@ $<
+ $(obj)mkimage.o:      $(src)mkimage.c
+@@ -192,16 +192,16 @@
+               done
+ endif
+-$(obj)environment.c:
+-              @rm -f $(obj)environment.c
+-              ln -s $(src)../common/environment.c $(obj)environment.c
++$(obj)environment_$(BOARDDIR).c:
++              @rm -f $(obj)environment_$(BOARDDIR).c
++              ln -s $(src)../common/environment_$(BOARDDIR).c $(obj)environment_$(BOARDDIR).c
+-$(obj)environment.o:  $(obj)environment.c
++$(obj)environment_$(BOARDDIR).o:      $(obj)environment_$(BOARDDIR).c
+               $(CC) -g $(HOST_ENVIRO_CFLAGS) $(CPPFLAGS) -c -o $@ $<
+-$(obj)crc32.c:
+-              @rm -f $(obj)crc32.c
+-              ln -s $(src)../lib_generic/crc32.c $(obj)crc32.c
++$(obj)crc32_$(BOARDDIR).c:
++              @rm -f $(obj)crc32_$(BOARDDIR).c
++              ln -s $(src)../lib_generic/crc32_$(BOARDDIR).c $(obj)crc32_$(BOARDDIR).c
+ $(LOGO_H):    $(obj)bmp_logo $(LOGO_BMP)
+               $(obj)./bmp_logo $(LOGO_BMP) >$@
+--- a/tools/mkimage.c
++++ b/tools/mkimage.c
+@@ -28,6 +28,7 @@
+ #ifndef __WIN32__
+ #include <netinet/in.h>               /* for host / network byte order conversions    */
+ #endif
++#include <sys/types.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <time.h>
+@@ -138,6 +139,7 @@
+     { IH_COMP_NONE,   "none",         "uncompressed",         },
+     { IH_COMP_BZIP2,  "bzip2",        "bzip2 compressed",     },
+     { IH_COMP_GZIP,   "gzip",         "gzip compressed",      },
++    { IH_COMP_LZMA,   "lzma",         "lzma compressed",      },
+     { -1,             "",             "",                     },
+ };
+@@ -445,7 +447,7 @@
+       }
+       /* We're a bit of paranoid */
+-#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__)
++#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) && !defined(__APPLE__)
+       (void) fdatasync (ifd);
+ #else
+       (void) fsync (ifd);
+@@ -495,7 +497,7 @@
+       (void) munmap((void *)ptr, sbuf.st_size);
+       /* We're a bit of paranoid */
+-#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__)
++#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) && !defined(__APPLE__)
+       (void) fdatasync (ifd);
+ #else
+       (void) fsync (ifd);
diff --git a/target/linux/etrax/Makefile b/target/linux/etrax/Makefile
deleted file mode 100644 (file)
index dcc0c37..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# 
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-
-ARCH:=cris
-BOARD:=etrax
-BOARDNAME:=Foxboard (ETRAX 100LX)
-FEATURES:=squashfs jffs2 broken
-LINUX_VERSION:=2.6.25.17
-
-include $(INCLUDE_DIR)/target.mk
-
-KERNELNAME:="zImage"
-
-define Target/Description
-       Build firmware images for the FOXBOARD made by acmesystems.it
-endef
-
-$(eval $(call BuildTarget))
diff --git a/target/linux/etrax/config-default b/target/linux/etrax/config-default
deleted file mode 100644 (file)
index f869b8a..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_BASE_SMALL=0
-CONFIG_BITREVERSE=y
-CONFIG_BOUNCE=y
-CONFIG_CLASSIC_RCU=y
-CONFIG_CRIS=y
-# CONFIG_CRIS_MACH_ARTPEC3 is not set
-CONFIG_CRYPTO_AEAD=m
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_AUTHENC=m
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_MANAGER=y
-# CONFIG_ETRAX100LX is not set
-CONFIG_ETRAX100LX_V2=y
-# CONFIG_ETRAXFS is not set
-CONFIG_ETRAX_ARCH_V10=y
-# CONFIG_ETRAX_ARCH_V32 is not set
-CONFIG_ETRAX_AXISFLASHMAP=y
-CONFIG_ETRAX_CMDLINE="root=/dev/mtdblock1 rootfstype=squashfs,jffs2 init=/etc/preinit noinitrd console=ttyS0,115200"
-# CONFIG_ETRAX_CSP0_LEDS is not set
-# CONFIG_ETRAX_DEBUG_PORT0 is not set
-# CONFIG_ETRAX_DEBUG_PORT1 is not set
-# CONFIG_ETRAX_DEBUG_PORT2 is not set
-# CONFIG_ETRAX_DEBUG_PORT3 is not set
-CONFIG_ETRAX_DEBUG_PORT_NULL=y
-CONFIG_ETRAX_DEF_R_BUS_CONFIG=0x4
-CONFIG_ETRAX_DEF_R_PORT_PA_DATA=0xf0
-CONFIG_ETRAX_DEF_R_PORT_PA_DIR=0x1c
-CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=0x00
-CONFIG_ETRAX_DEF_R_PORT_PB_DATA=0x03
-CONFIG_ETRAX_DEF_R_PORT_PB_DIR=0xce
-CONFIG_ETRAX_DEF_R_SDRAM_CONFIG=0x09603737
-CONFIG_ETRAX_DEF_R_SDRAM_TIMING=0x80008002
-CONFIG_ETRAX_DEF_R_WAITSTATES=0x95f8
-CONFIG_ETRAX_DRAM_SIZE=32
-CONFIG_ETRAX_DRAM_VIRTUAL_BASE=c0000000
-CONFIG_ETRAX_DS1302=y
-CONFIG_ETRAX_DS1302_RSTBIT=2
-CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT=y
-CONFIG_ETRAX_DS1302_SCLBIT=1
-CONFIG_ETRAX_DS1302_SDABIT=0
-CONFIG_ETRAX_DS1302_TRICKLE_CHARGE=0
-CONFIG_ETRAX_ETHERNET=y
-CONFIG_ETRAX_FAST_TIMER=y
-CONFIG_ETRAX_FLASH1_SIZE=0
-CONFIG_ETRAX_FLASH_BUSWIDTH=2
-CONFIG_ETRAX_GPIO=y
-CONFIG_ETRAX_I2C=y
-CONFIG_ETRAX_I2C_CLK_PORT=1
-CONFIG_ETRAX_I2C_DATA_PORT=0
-# CONFIG_ETRAX_I2C_EEPROM is not set
-CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
-# CONFIG_ETRAX_KMALLOCED_MODULES is not set
-CONFIG_ETRAX_LED1G=2
-CONFIG_ETRAX_LED1R=2
-CONFIG_ETRAX_LED2G=3
-CONFIG_ETRAX_LED2R=3
-CONFIG_ETRAX_LED3G=2
-CONFIG_ETRAX_LED3R=2
-CONFIG_ETRAX_NANDFLASH_BUSWIDTH=1
-CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y
-# CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set
-# CONFIG_ETRAX_NO_LEDS is not set
-CONFIG_ETRAX_PA_BUTTON_BITMASK=02
-CONFIG_ETRAX_PA_CHANGEABLE_BITS=0xFF
-CONFIG_ETRAX_PA_CHANGEABLE_DIR=0xFF
-CONFIG_ETRAX_PA_LEDS=y
-CONFIG_ETRAX_PB_CHANGEABLE_BITS=0xFF
-CONFIG_ETRAX_PB_CHANGEABLE_DIR=0xFF
-# CONFIG_ETRAX_PB_LEDS is not set
-# CONFIG_ETRAX_PCF8563 is not set
-CONFIG_ETRAX_PTABLE_SECTOR=0
-CONFIG_ETRAX_RESCUE_SER0=y
-# CONFIG_ETRAX_RESCUE_SER1 is not set
-# CONFIG_ETRAX_RESCUE_SER2 is not set
-# CONFIG_ETRAX_RESCUE_SER3 is not set
-# CONFIG_ETRAX_RS485 is not set
-CONFIG_ETRAX_RTC=y
-CONFIG_ETRAX_SDRAM=y
-CONFIG_ETRAX_SER0_CD_ON_PA_BIT=-1
-CONFIG_ETRAX_SER0_CD_ON_PB_BIT=-1
-CONFIG_ETRAX_SER0_DSR_ON_PA_BIT=-1
-CONFIG_ETRAX_SER0_DSR_ON_PB_BIT=-1
-CONFIG_ETRAX_SER0_DTR_ON_PA_BIT=-1
-CONFIG_ETRAX_SER0_DTR_ON_PB_BIT=-1
-# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED is not set
-CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE=y
-# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA is not set
-# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set
-CONFIG_ETRAX_SER0_RI_ON_PA_BIT=-1
-CONFIG_ETRAX_SER0_RI_ON_PB_BIT=-1
-CONFIG_ETRAX_SER2_CD_ON_PA_BIT=7
-CONFIG_ETRAX_SER2_CD_ON_PB_BIT=-1
-CONFIG_ETRAX_SER2_DSR_ON_PA_BIT=6
-CONFIG_ETRAX_SER2_DSR_ON_PB_BIT=-1
-CONFIG_ETRAX_SER2_DTR_ON_PA_BIT=4
-CONFIG_ETRAX_SER2_DTR_ON_PB_BIT=-1
-# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED is not set
-# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE is not set
-CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA=y
-# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PB is not set
-CONFIG_ETRAX_SER2_RI_ON_PA_BIT=5
-CONFIG_ETRAX_SER2_RI_ON_PB_BIT=-1
-CONFIG_ETRAX_SER3_CD_ON_PA_BIT=-1
-CONFIG_ETRAX_SER3_CD_ON_PB_BIT=-1
-CONFIG_ETRAX_SER3_DSR_ON_PA_BIT=-1
-CONFIG_ETRAX_SER3_DSR_ON_PB_BIT=-1
-CONFIG_ETRAX_SER3_DTR_ON_PA_BIT=-1
-CONFIG_ETRAX_SER3_DTR_ON_PB_BIT=-1
-# CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED is not set
-CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE=y
-# CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PA is not set
-# CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PB is not set
-CONFIG_ETRAX_SER3_RI_ON_PA_BIT=-1
-CONFIG_ETRAX_SER3_RI_ON_PB_BIT=-1
-CONFIG_ETRAX_SERIAL=y
-# CONFIG_ETRAX_SERIAL_FAST_TIMER is not set
-# CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST is not set
-CONFIG_ETRAX_SERIAL_PORT0=y
-# CONFIG_ETRAX_SERIAL_PORT0_DMA0_OUT is not set
-# CONFIG_ETRAX_SERIAL_PORT0_DMA1_IN is not set
-# CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT is not set
-# CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN is not set
-CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN=y
-CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT=y
-# CONFIG_ETRAX_SERIAL_PORT1 is not set
-CONFIG_ETRAX_SERIAL_PORT2=y
-CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT=y
-CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN=y
-# CONFIG_ETRAX_SERIAL_PORT2_DMA6_OUT is not set
-# CONFIG_ETRAX_SERIAL_PORT2_DMA7_IN is not set
-# CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN is not set
-# CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT is not set
-CONFIG_ETRAX_SERIAL_PORT3=y
-# CONFIG_ETRAX_SERIAL_PORT3_DMA2_OUT is not set
-# CONFIG_ETRAX_SERIAL_PORT3_DMA3_IN is not set
-CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT=y
-CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN=y
-# CONFIG_ETRAX_SERIAL_PORT3_DMA8_OUT is not set
-# CONFIG_ETRAX_SERIAL_PORT3_DMA9_IN is not set
-# CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN is not set
-# CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT is not set
-CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS=1
-# CONFIG_ETRAX_SOFT_SHUTDOWN is not set
-# CONFIG_ETRAX_SYNCHRONOUS_SERIAL is not set
-CONFIG_ETRAX_USB_HOST=y
-CONFIG_ETRAX_USB_HOST_PORT1=y
-CONFIG_ETRAX_USB_HOST_PORT2=y
-# CONFIG_ETRAX_VCS_SIM is not set
-# CONFIG_ETRAX_WATCHDOG is not set
-CONFIG_FAT_FS=y
-CONFIG_FORCE_MAX_ZONEORDER=6
-CONFIG_FS_POSIX_ACL=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_IOMAP=y
-# CONFIG_GEN_RTC is not set
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAVE_IDE=y
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_OPROFILE is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_I2C is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IDE is not set
-CONFIG_IEEE80211=y
-# CONFIG_IEEE80211_CRYPT_CCMP is not set
-# CONFIG_IEEE80211_CRYPT_TKIP is not set
-CONFIG_IEEE80211_CRYPT_WEP=y
-CONFIG_IEEE80211_DEBUG=y
-CONFIG_IEEE80211_SOFTMAC=y
-CONFIG_IEEE80211_SOFTMAC_DEBUG=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
-CONFIG_MSDOS_FS=y
-CONFIG_MTD=y
-CONFIG_MTDRAM_ABS_POS=0x0
-CONFIG_MTDRAM_ERASE_SIZE=128
-CONFIG_MTDRAM_TOTAL_SIZE=0
-# CONFIG_MTD_ABSENT is not set
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_MTD_BLOCK2MTD is not set
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_GEOMETRY is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-CONFIG_MTD_CHAR=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_CONCAT=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-CONFIG_MTD_MTDRAM=y
-# CONFIG_MTD_ONENAND is not set
-# CONFIG_MTD_OTP is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_PLATRAM is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_SLRAM is not set
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NO_IOPORT=y
-# CONFIG_OOM_REBOOT is not set
-# CONFIG_RTC is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SLABINFO=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-# CONFIG_SVINTO_SIM is not set
-# CONFIG_SYSTEM_PROFILER is not set
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_UID16=y
-CONFIG_USB=y
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_R8A66597_HCD is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_VFAT_FS=y
-# CONFIG_VLAN_8021Q is not set
diff --git a/target/linux/etrax/files/drivers/usb/host/hc_crisv10.c b/target/linux/etrax/files/drivers/usb/host/hc_crisv10.c
deleted file mode 100644 (file)
index 32f7caf..0000000
+++ /dev/null
@@ -1,4550 +0,0 @@
-/*
- * usb-host.c: ETRAX 100LX USB Host Controller Driver (HCD)
- *
- * Copyright (c) 2002, 2003 Axis Communications AB.
- */
-
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/system.h>
-#include <asm/arch/svinto.h>
-
-#include <linux/usb.h>
-/* Ugly include because we don't live with the other host drivers. */
-#include <../drivers/usb/core/hcd.h>
-#include <../drivers/usb/core/usb.h>
-
-#include "hc_crisv10.h"
-
-#define ETRAX_USB_HC_IRQ USB_HC_IRQ_NBR
-#define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR
-#define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR
-
-static const char *usb_hcd_version = "$Revision: 1.2 $";
-
-#undef KERN_DEBUG
-#define KERN_DEBUG ""
-
-
-#undef USB_DEBUG_RH
-#undef USB_DEBUG_EPID
-#undef USB_DEBUG_SB
-#undef USB_DEBUG_DESC
-#undef USB_DEBUG_URB
-#undef USB_DEBUG_TRACE
-#undef USB_DEBUG_BULK
-#undef USB_DEBUG_CTRL
-#undef USB_DEBUG_INTR
-#undef USB_DEBUG_ISOC
-
-#ifdef USB_DEBUG_RH
-#define dbg_rh(format, arg...) printk(KERN_DEBUG __FILE__ ": (RH) " format "\n" , ## arg)
-#else
-#define dbg_rh(format, arg...) do {} while (0)
-#endif
-
-#ifdef USB_DEBUG_EPID
-#define dbg_epid(format, arg...) printk(KERN_DEBUG __FILE__ ": (EPID) " format "\n" , ## arg)
-#else
-#define dbg_epid(format, arg...) do {} while (0)
-#endif
-
-#ifdef USB_DEBUG_SB
-#define dbg_sb(format, arg...) printk(KERN_DEBUG __FILE__ ": (SB) " format "\n" , ## arg)
-#else
-#define dbg_sb(format, arg...) do {} while (0)
-#endif
-
-#ifdef USB_DEBUG_CTRL
-#define dbg_ctrl(format, arg...) printk(KERN_DEBUG __FILE__ ": (CTRL) " format "\n" , ## arg)
-#else
-#define dbg_ctrl(format, arg...) do {} while (0)
-#endif
-
-#ifdef USB_DEBUG_BULK
-#define dbg_bulk(format, arg...) printk(KERN_DEBUG __FILE__ ": (BULK) " format "\n" , ## arg)
-#else
-#define dbg_bulk(format, arg...) do {} while (0)
-#endif
-
-#ifdef USB_DEBUG_INTR
-#define dbg_intr(format, arg...) printk(KERN_DEBUG __FILE__ ": (INTR) " format "\n" , ## arg)
-#else
-#define dbg_intr(format, arg...) do {} while (0)
-#endif
-
-#ifdef USB_DEBUG_ISOC
-#define dbg_isoc(format, arg...) printk(KERN_DEBUG __FILE__ ": (ISOC) " format "\n" , ## arg)
-#else
-#define dbg_isoc(format, arg...) do {} while (0)
-#endif
-
-#ifdef USB_DEBUG_TRACE
-#define DBFENTER (printk(": Entering: %s\n", __FUNCTION__))
-#define DBFEXIT  (printk(": Exiting:  %s\n", __FUNCTION__))
-#else
-#define DBFENTER do {} while (0)
-#define DBFEXIT  do {} while (0)
-#endif
-
-#define usb_pipeslow(pipe)     (((pipe) >> 26) & 1)
-
-/*-------------------------------------------------------------------
- Virtual Root Hub
- -------------------------------------------------------------------*/
-
-static __u8 root_hub_dev_des[] =
-{
-       0x12,  /*  __u8  bLength; */
-       0x01,  /*  __u8  bDescriptorType; Device */
-       0x00,  /*  __le16 bcdUSB; v1.0 */
-       0x01,
-       0x09,  /*  __u8  bDeviceClass; HUB_CLASSCODE */
-       0x00,  /*  __u8  bDeviceSubClass; */
-       0x00,  /*  __u8  bDeviceProtocol; */
-       0x08,  /*  __u8  bMaxPacketSize0; 8 Bytes */
-       0x00,  /*  __le16 idVendor; */
-       0x00,
-       0x00,  /*  __le16 idProduct; */
-       0x00,
-       0x00,  /*  __le16 bcdDevice; */
-       0x00,
-       0x00,  /*  __u8  iManufacturer; */
-       0x02,  /*  __u8  iProduct; */
-       0x01,  /*  __u8  iSerialNumber; */
-       0x01   /*  __u8  bNumConfigurations; */
-};
-
-/* Configuration descriptor */
-static __u8 root_hub_config_des[] =
-{
-       0x09,  /*  __u8  bLength; */
-       0x02,  /*  __u8  bDescriptorType; Configuration */
-       0x19,  /*  __le16 wTotalLength; */
-       0x00,
-       0x01,  /*  __u8  bNumInterfaces; */
-       0x01,  /*  __u8  bConfigurationValue; */
-       0x00,  /*  __u8  iConfiguration; */
-       0x40,  /*  __u8  bmAttributes; Bit 7: Bus-powered */
-       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 */
-       0x08,  /*  __le16 ep_wMaxPacketSize; 8 Bytes */
-       0x00,
-       0xff   /*  __u8  ep_bInterval; 255 ms */
-};
-
-static __u8 root_hub_hub_des[] =
-{
-       0x09,  /*  __u8  bLength; */
-       0x29,  /*  __u8  bDescriptorType; Hub-descriptor */
-       0x02,  /*  __u8  bNbrPorts; */
-       0x00,  /* __u16  wHubCharacteristics; */
-       0x00,
-       0x01,  /*  __u8  bPwrOn2pwrGood; 2ms */
-       0x00,  /*  __u8  bHubContrCurrent; 0 mA */
-       0x00,  /*  __u8  DeviceRemovable; *** 7 Ports max *** */
-       0xff   /*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
-};
-
-static DEFINE_TIMER(bulk_start_timer, NULL, 0, 0);
-static DEFINE_TIMER(bulk_eot_timer, NULL, 0, 0);
-
-/* We want the start timer to expire before the eot timer, because the former might start
-   traffic, thus making it unnecessary for the latter to time out. */
-#define BULK_START_TIMER_INTERVAL (HZ/10) /* 100 ms */
-#define BULK_EOT_TIMER_INTERVAL (HZ/10+2) /* 120 ms */
-
-#define OK(x) len = (x); dbg_rh("OK(%d): line: %d", x, __LINE__); break
-#define CHECK_ALIGN(x) if (((__u32)(x)) & 0x00000003) \
-{panic("Alignment check (DWORD) failed at %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);}
-
-#define SLAB_FLAG     (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
-#define KMALLOC_FLAG  (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
-
-/* Most helpful debugging aid */
-#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
-
-/* Alternative assert define which stops after a failed assert. */
-/*
-#define assert(expr)                                      \
-{                                                         \
-        if (!(expr)) {                                    \
-                err("assert failed at line %d",__LINE__); \
-                while (1);                                \
-        }                                                 \
-}
-*/
-
-
-/* FIXME: Should RX_BUF_SIZE be a config option, or maybe we should adjust it dynamically?
-   To adjust it dynamically we would have to get an interrupt when we reach the end
-   of the rx descriptor list, or when we get close to the end, and then allocate more
-   descriptors. */
-
-#define NBR_OF_RX_DESC     512
-#define RX_DESC_BUF_SIZE   1024
-#define RX_BUF_SIZE        (NBR_OF_RX_DESC * RX_DESC_BUF_SIZE)
-
-/* The number of epids is, among other things, used for pre-allocating
-   ctrl, bulk and isoc EP descriptors (one for each epid).
-   Assumed to be > 1 when initiating the DMA lists. */
-#define NBR_OF_EPIDS       32
-
-/* Support interrupt traffic intervals up to 128 ms. */
-#define MAX_INTR_INTERVAL 128
-
-/* If periodic traffic (intr or isoc) is to be used, then one entry in the EP table
-   must be "invalid". By this we mean that we shouldn't care about epid attentions
-   for this epid, or at least handle them differently from epid attentions for "valid"
-   epids. This define determines which one to use (don't change it). */
-#define INVALID_EPID     31
-/* A special epid for the bulk dummys. */
-#define DUMMY_EPID       30
-
-/* This is just a software cache for the valid entries in R_USB_EPT_DATA. */
-static __u32 epid_usage_bitmask;
-
-/* A bitfield to keep information on in/out traffic is needed to uniquely identify
-   an endpoint on a device, since the most significant bit which indicates traffic
-   direction is lacking in the ep_id field (ETRAX epids can handle both in and
-   out traffic on endpoints that are otherwise identical). The USB framework, however,
-   relies on them to be handled separately.  For example, bulk IN and OUT urbs cannot
-   be queued in the same list, since they would block each other. */
-static __u32 epid_out_traffic;
-
-/* DMA IN cache bug. Align the DMA IN buffers to 32 bytes, i.e. a cache line.
-   Since RX_DESC_BUF_SIZE is 1024 is a multiple of 32, all rx buffers will be cache aligned. */
-static volatile unsigned char RxBuf[RX_BUF_SIZE] __attribute__ ((aligned (32)));
-static volatile USB_IN_Desc_t RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned (4)));
-
-/* Pointers into RxDescList. */
-static volatile USB_IN_Desc_t *myNextRxDesc;
-static volatile USB_IN_Desc_t *myLastRxDesc;
-static volatile USB_IN_Desc_t *myPrevRxDesc;
-
-/* EP descriptors must be 32-bit aligned. */
-static volatile USB_EP_Desc_t TxCtrlEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4)));
-static volatile USB_EP_Desc_t TxBulkEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4)));
-/* After each enabled bulk EP (IN or OUT) we put two disabled EP descriptors with the eol flag set,
-   causing the DMA to stop the DMA channel. The first of these two has the intr flag set, which
-   gives us a dma8_sub0_descr interrupt. When we receive this, we advance the DMA one step in the
-   EP list and then restart the bulk channel, thus forcing a switch between bulk EP descriptors
-   in each frame. */
-static volatile USB_EP_Desc_t TxBulkDummyEPList[NBR_OF_EPIDS][2] __attribute__ ((aligned (4)));
-
-static volatile USB_EP_Desc_t TxIsocEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4)));
-static volatile USB_SB_Desc_t TxIsocSB_zout __attribute__ ((aligned (4)));
-
-static volatile USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4)));
-static volatile USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4)));
-
-/* A zout transfer makes a memory access at the address of its buf pointer, which means that setting
-   this buf pointer to 0 will cause an access to the flash. In addition to this, setting sw_len to 0
-   results in a 16/32 bytes (depending on DMA burst size) transfer. Instead, we set it to 1, and point
-   it to this buffer. */
-static int zout_buffer[4] __attribute__ ((aligned (4)));
-
-/* Cache for allocating new EP and SB descriptors. */
-static struct kmem_cache *usb_desc_cache;
-
-/* Cache for the registers allocated in the top half. */
-static struct kmem_cache *top_half_reg_cache;
-
-/* Cache for the data allocated in the isoc descr top half. */
-static struct kmem_cache *isoc_compl_cache;
-
-static struct usb_bus *etrax_usb_bus;
-
-/* This is a circular (double-linked) list of the active urbs for each epid.
-   The head is never removed, and new urbs are linked onto the list as
-   urb_entry_t elements. Don't reference urb_list directly; use the wrapper
-   functions instead. Note that working with these lists might require spinlock
-   protection. */
-static struct list_head urb_list[NBR_OF_EPIDS];
-
-/* Read about the need and usage of this lock in submit_ctrl_urb. */
-static spinlock_t urb_list_lock;
-
-/* Used when unlinking asynchronously. */
-static struct list_head urb_unlink_list;
-
-/* for returning string descriptors in UTF-16LE */
-static int ascii2utf (char *ascii, __u8 *utf, int utfmax)
-{
-       int retval;
-
-       for (retval = 0; *ascii && utfmax > 1; utfmax -= 2, retval += 2) {
-               *utf++ = *ascii++ & 0x7f;
-               *utf++ = 0;
-       }
-       return retval;
-}
-
-static int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len)
-{
-       char buf [30];
-
-       // assert (len > (2 * (sizeof (buf) + 1)));
-       // assert (strlen (type) <= 8);
-
-       // language ids
-       if (id == 0) {
-               *data++ = 4; *data++ = 3;       /* 4 bytes data */
-               *data++ = 0; *data++ = 0;       /* some language id */
-               return 4;
-
-       // serial number
-       } else if (id == 1) {
-               sprintf (buf, "%x", serial);
-
-       // product description
-       } else if (id == 2) {
-               sprintf (buf, "USB %s Root Hub", type);
-
-       // id 3 == vendor description
-
-       // unsupported IDs --> "stall"
-       } else
-           return 0;
-
-       data [0] = 2 + ascii2utf (buf, data + 2, len - 2);
-       data [1] = 3;
-       return data [0];
-}
-
-/* Wrappers around the list functions (include/linux/list.h). */
-
-static inline int urb_list_empty(int epid)
-{
-       return list_empty(&urb_list[epid]);
-}
-
-/* Returns first urb for this epid, or NULL if list is empty. */
-static inline struct urb *urb_list_first(int epid)
-{
-       struct urb *first_urb = 0;
-
-       if (!urb_list_empty(epid)) {
-               /* Get the first urb (i.e. head->next). */
-               urb_entry_t *urb_entry = list_entry((&urb_list[epid])->next, urb_entry_t, list);
-               first_urb = urb_entry->urb;
-       }
-       return first_urb;
-}
-
-/* Adds an urb_entry last in the list for this epid. */
-static inline void urb_list_add(struct urb *urb, int epid)
-{
-       urb_entry_t *urb_entry = kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG);
-       assert(urb_entry);
-
-       urb_entry->urb = urb;
-       list_add_tail(&urb_entry->list, &urb_list[epid]);
-}
-
-/* Search through the list for an element that contains this urb. (The list
-   is expected to be short and the one we are about to delete will often be
-   the first in the list.) */
-static inline urb_entry_t *__urb_list_entry(struct urb *urb, int epid)
-{
-       struct list_head *entry;
-       struct list_head *tmp;
-       urb_entry_t *urb_entry;
-
-       list_for_each_safe(entry, tmp, &urb_list[epid]) {
-               urb_entry = list_entry(entry, urb_entry_t, list);
-               assert(urb_entry);
-               assert(urb_entry->urb);
-
-               if (urb_entry->urb == urb) {
-                       return urb_entry;
-               }
-       }
-       return 0;
-}
-
-/* Delete an urb from the list. */
-static inline void urb_list_del(struct urb *urb, int epid)
-{
-       urb_entry_t *urb_entry = __urb_list_entry(urb, epid);
-       assert(urb_entry);
-
-       /* Delete entry and free. */
-       list_del(&urb_entry->list);
-       kfree(urb_entry);
-}
-
-/* Move an urb to the end of the list. */
-static inline void urb_list_move_last(struct urb *urb, int epid)
-{
-       urb_entry_t *urb_entry = __urb_list_entry(urb, epid);
-       assert(urb_entry);
-
-       list_move_tail(&urb_entry->list, &urb_list[epid]);
-}
-
-/* Get the next urb in the list. */
-static inline struct urb *urb_list_next(struct urb *urb, int epid)
-{
-       urb_entry_t *urb_entry = __urb_list_entry(urb, epid);
-
-       assert(urb_entry);
-
-       if (urb_entry->list.next != &urb_list[epid]) {
-               struct list_head *elem = urb_entry->list.next;
-               urb_entry = list_entry(elem, urb_entry_t, list);
-               return urb_entry->urb;
-       } else {
-               return NULL;
-       }
-}
-
-
-
-/* For debug purposes only. */
-static inline void urb_list_dump(int epid)
-{
-       struct list_head *entry;
-       struct list_head *tmp;
-       urb_entry_t *urb_entry;
-       int i = 0;
-
-       info("Dumping urb list for epid %d", epid);
-
-       list_for_each_safe(entry, tmp, &urb_list[epid]) {
-               urb_entry = list_entry(entry, urb_entry_t, list);
-               info("   entry %d, urb = 0x%lx", i, (unsigned long)urb_entry->urb);
-       }
-}
-
-static void init_rx_buffers(void);
-static int etrax_rh_unlink_urb(struct urb *urb);
-static void etrax_rh_send_irq(struct urb *urb);
-static void etrax_rh_init_int_timer(struct urb *urb);
-static void etrax_rh_int_timer_do(unsigned long ptr);
-
-static int etrax_usb_setup_epid(struct urb *urb);
-static int etrax_usb_lookup_epid(struct urb *urb);
-static int etrax_usb_allocate_epid(void);
-static void etrax_usb_free_epid(int epid);
-
-static int etrax_remove_from_sb_list(struct urb *urb);
-
-static void* etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size,
-       unsigned mem_flags, dma_addr_t *dma);
-static void etrax_usb_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma);
-
-static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid);
-static void etrax_usb_add_to_ctrl_sb_list(struct urb *urb, int epid);
-static void etrax_usb_add_to_intr_sb_list(struct urb *urb, int epid);
-static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid);
-
-static int etrax_usb_submit_bulk_urb(struct urb *urb);
-static int etrax_usb_submit_ctrl_urb(struct urb *urb);
-static int etrax_usb_submit_intr_urb(struct urb *urb);
-static int etrax_usb_submit_isoc_urb(struct urb *urb);
-
-static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags);
-static int etrax_usb_unlink_urb(struct urb *urb, int status);
-static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
-
-static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc);
-static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc);
-static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc);
-static void etrax_usb_hc_interrupt_bottom_half(void *data);
-
-static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data);
-
-
-/* The following is a list of interrupt handlers for the host controller interrupts we use.
-   They are called from etrax_usb_hc_interrupt_bottom_half. */
-static void etrax_usb_hc_isoc_eof_interrupt(void);
-static void etrax_usb_hc_bulk_eot_interrupt(int timer_induced);
-static void etrax_usb_hc_epid_attn_interrupt(usb_interrupt_registers_t *reg);
-static void etrax_usb_hc_port_status_interrupt(usb_interrupt_registers_t *reg);
-static void etrax_usb_hc_ctl_status_interrupt(usb_interrupt_registers_t *reg);
-
-static int etrax_rh_submit_urb (struct urb *urb);
-
-/* Forward declaration needed because they are used in the rx interrupt routine. */
-static void etrax_usb_complete_urb(struct urb *urb, int status);
-static void etrax_usb_complete_bulk_urb(struct urb *urb, int status);
-static void etrax_usb_complete_ctrl_urb(struct urb *urb, int status);
-static void etrax_usb_complete_intr_urb(struct urb *urb, int status);
-static void etrax_usb_complete_isoc_urb(struct urb *urb, int status);
-
-static int etrax_usb_hc_init(void);
-static void etrax_usb_hc_cleanup(void);
-
-static struct usb_operations etrax_usb_device_operations =
-{
-       .get_frame_number = etrax_usb_get_frame_number,
-       .submit_urb = etrax_usb_submit_urb,
-       .unlink_urb = etrax_usb_unlink_urb,
-        .buffer_alloc = etrax_usb_buffer_alloc,
-        .buffer_free = etrax_usb_buffer_free
-};
-
-/* Note that these functions are always available in their "__" variants, for use in
-   error situations. The "__" missing variants are controlled by the USB_DEBUG_DESC/
-   USB_DEBUG_URB macros. */
-static void __dump_urb(struct urb* purb)
-{
-       printk("\nurb                  :0x%08lx\n", (unsigned long)purb);
-       printk("dev                   :0x%08lx\n", (unsigned long)purb->dev);
-       printk("pipe                  :0x%08x\n", purb->pipe);
-       printk("status                :%d\n", purb->status);
-       printk("transfer_flags        :0x%08x\n", purb->transfer_flags);
-       printk("transfer_buffer       :0x%08lx\n", (unsigned long)purb->transfer_buffer);
-       printk("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-       printk("actual_length         :%d\n", purb->actual_length);
-       printk("setup_packet          :0x%08lx\n", (unsigned long)purb->setup_packet);
-       printk("start_frame           :%d\n", purb->start_frame);
-       printk("number_of_packets     :%d\n", purb->number_of_packets);
-       printk("interval              :%d\n", purb->interval);
-       printk("error_count           :%d\n", purb->error_count);
-       printk("context               :0x%08lx\n", (unsigned long)purb->context);
-       printk("complete              :0x%08lx\n\n", (unsigned long)purb->complete);
-}
-
-static void __dump_in_desc(volatile USB_IN_Desc_t *in)
-{
-       printk("\nUSB_IN_Desc at 0x%08lx\n", (unsigned long)in);
-       printk("  sw_len  : 0x%04x (%d)\n", in->sw_len, in->sw_len);
-       printk("  command : 0x%04x\n", in->command);
-       printk("  next    : 0x%08lx\n", in->next);
-       printk("  buf     : 0x%08lx\n", in->buf);
-       printk("  hw_len  : 0x%04x (%d)\n", in->hw_len, in->hw_len);
-       printk("  status  : 0x%04x\n\n", in->status);
-}
-
-static void __dump_sb_desc(volatile USB_SB_Desc_t *sb)
-{
-       char tt = (sb->command & 0x30) >> 4;
-       char *tt_string;
-
-       switch (tt) {
-       case 0:
-               tt_string = "zout";
-               break;
-       case 1:
-               tt_string = "in";
-               break;
-       case 2:
-               tt_string = "out";
-               break;
-       case 3:
-               tt_string = "setup";
-               break;
-       default:
-               tt_string = "unknown (weird)";
-       }
-
-       printk("\n   USB_SB_Desc at 0x%08lx\n", (unsigned long)sb);
-       printk("     command : 0x%04x\n", sb->command);
-       printk("        rem     : %d\n", (sb->command & 0x3f00) >> 8);
-       printk("        full    : %d\n", (sb->command & 0x40) >> 6);
-       printk("        tt      : %d (%s)\n", tt, tt_string);
-       printk("        intr    : %d\n", (sb->command & 0x8) >> 3);
-       printk("        eot     : %d\n", (sb->command & 0x2) >> 1);
-       printk("        eol     : %d\n", sb->command & 0x1);
-       printk("     sw_len  : 0x%04x (%d)\n", sb->sw_len, sb->sw_len);
-       printk("     next    : 0x%08lx\n", sb->next);
-       printk("     buf     : 0x%08lx\n\n", sb->buf);
-}
-
-
-static void __dump_ep_desc(volatile USB_EP_Desc_t *ep)
-{
-       printk("\nUSB_EP_Desc at 0x%08lx\n", (unsigned long)ep);
-       printk("  command : 0x%04x\n", ep->command);
-       printk("     ep_id   : %d\n", (ep->command & 0x1f00) >> 8);
-       printk("     enable  : %d\n", (ep->command & 0x10) >> 4);
-       printk("     intr    : %d\n", (ep->command & 0x8) >> 3);
-       printk("     eof     : %d\n", (ep->command & 0x2) >> 1);
-       printk("     eol     : %d\n", ep->command & 0x1);
-       printk("  hw_len  : 0x%04x (%d)\n", ep->hw_len, ep->hw_len);
-       printk("  next    : 0x%08lx\n", ep->next);
-       printk("  sub     : 0x%08lx\n\n", ep->sub);
-}
-
-static inline void __dump_ep_list(int pipe_type)
-{
-       volatile USB_EP_Desc_t *ep;
-       volatile USB_EP_Desc_t *first_ep;
-       volatile USB_SB_Desc_t *sb;
-
-       switch (pipe_type)
-       {
-       case PIPE_BULK:
-               first_ep = &TxBulkEPList[0];
-               break;
-       case PIPE_CONTROL:
-               first_ep = &TxCtrlEPList[0];
-               break;
-       case PIPE_INTERRUPT:
-               first_ep = &TxIntrEPList[0];
-               break;
-       case PIPE_ISOCHRONOUS:
-               first_ep = &TxIsocEPList[0];
-               break;
-       default:
-               warn("Cannot dump unknown traffic type");
-               return;
-       }
-       ep = first_ep;
-
-       printk("\n\nDumping EP list...\n\n");
-
-       do {
-               __dump_ep_desc(ep);
-               /* Cannot phys_to_virt on 0 as it turns into 80000000, which is != 0. */
-               sb = ep->sub ? phys_to_virt(ep->sub) : 0;
-               while (sb) {
-                       __dump_sb_desc(sb);
-                       sb = sb->next ? phys_to_virt(sb->next) : 0;
-               }
-               ep = (volatile USB_EP_Desc_t *)(phys_to_virt(ep->next));
-
-       } while (ep != first_ep);
-}
-
-static inline void __dump_ept_data(int epid)
-{
-       unsigned long flags;
-       __u32 r_usb_ept_data;
-
-       if (epid < 0 || epid > 31) {
-               printk("Cannot dump ept data for invalid epid %d\n", epid);
-               return;
-       }
-
-       save_flags(flags);
-       cli();
-       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-       nop();
-       r_usb_ept_data = *R_USB_EPT_DATA;
-       restore_flags(flags);
-
-       printk("\nR_USB_EPT_DATA = 0x%x for epid %d :\n", r_usb_ept_data, epid);
-       if (r_usb_ept_data == 0) {
-               /* No need for more detailed printing. */
-               return;
-       }
-       printk("  valid           : %d\n", (r_usb_ept_data & 0x80000000) >> 31);
-       printk("  hold            : %d\n", (r_usb_ept_data & 0x40000000) >> 30);
-       printk("  error_count_in  : %d\n", (r_usb_ept_data & 0x30000000) >> 28);
-       printk("  t_in            : %d\n", (r_usb_ept_data & 0x08000000) >> 27);
-       printk("  low_speed       : %d\n", (r_usb_ept_data & 0x04000000) >> 26);
-       printk("  port            : %d\n", (r_usb_ept_data & 0x03000000) >> 24);
-       printk("  error_code      : %d\n", (r_usb_ept_data & 0x00c00000) >> 22);
-       printk("  t_out           : %d\n", (r_usb_ept_data & 0x00200000) >> 21);
-       printk("  error_count_out : %d\n", (r_usb_ept_data & 0x00180000) >> 19);
-       printk("  max_len         : %d\n", (r_usb_ept_data & 0x0003f800) >> 11);
-       printk("  ep              : %d\n", (r_usb_ept_data & 0x00000780) >> 7);
-       printk("  dev             : %d\n", (r_usb_ept_data & 0x0000003f));
-}
-
-static inline void __dump_ept_data_list(void)
-{
-       int i;
-
-       printk("Dumping the whole R_USB_EPT_DATA list\n");
-
-       for (i = 0; i < 32; i++) {
-               __dump_ept_data(i);
-       }
-}
-#ifdef USB_DEBUG_DESC
-#define dump_in_desc(...) __dump_in_desc(...)
-#define dump_sb_desc(...) __dump_sb_desc(...)
-#define dump_ep_desc(...) __dump_ep_desc(...)
-#else
-#define dump_in_desc(...) do {} while (0)
-#define dump_sb_desc(...) do {} while (0)
-#define dump_ep_desc(...) do {} while (0)
-#endif
-
-#ifdef USB_DEBUG_URB
-#define dump_urb(x)     __dump_urb(x)
-#else
-#define dump_urb(x)     do {} while (0)
-#endif
-
-static void init_rx_buffers(void)
-{
-       int i;
-
-       DBFENTER;
-
-       for (i = 0; i < (NBR_OF_RX_DESC - 1); i++) {
-               RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
-               RxDescList[i].command = 0;
-               RxDescList[i].next = virt_to_phys(&RxDescList[i + 1]);
-               RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE));
-               RxDescList[i].hw_len = 0;
-               RxDescList[i].status = 0;
-
-               /* DMA IN cache bug. (struct etrax_dma_descr has the same layout as USB_IN_Desc
-                  for the relevant fields.) */
-               prepare_rx_descriptor((struct etrax_dma_descr*)&RxDescList[i]);
-
-       }
-
-       RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
-       RxDescList[i].command = IO_STATE(USB_IN_command, eol, yes);
-       RxDescList[i].next = virt_to_phys(&RxDescList[0]);
-       RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE));
-       RxDescList[i].hw_len = 0;
-       RxDescList[i].status = 0;
-
-       myNextRxDesc = &RxDescList[0];
-       myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
-       myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
-
-       *R_DMA_CH9_FIRST = virt_to_phys(myNextRxDesc);
-       *R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, start);
-
-       DBFEXIT;
-}
-
-static void init_tx_bulk_ep(void)
-{
-       int i;
-
-       DBFENTER;
-
-       for (i = 0; i < (NBR_OF_EPIDS - 1); i++) {
-               CHECK_ALIGN(&TxBulkEPList[i]);
-               TxBulkEPList[i].hw_len = 0;
-               TxBulkEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
-               TxBulkEPList[i].sub = 0;
-               TxBulkEPList[i].next = virt_to_phys(&TxBulkEPList[i + 1]);
-
-               /* Initiate two EPs, disabled and with the eol flag set. No need for any
-                  preserved epid. */
-
-               /* The first one has the intr flag set so we get an interrupt when the DMA
-                  channel is about to become disabled. */
-               CHECK_ALIGN(&TxBulkDummyEPList[i][0]);
-               TxBulkDummyEPList[i][0].hw_len = 0;
-               TxBulkDummyEPList[i][0].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) |
-                                                  IO_STATE(USB_EP_command, eol, yes) |
-                                                  IO_STATE(USB_EP_command, intr, yes));
-               TxBulkDummyEPList[i][0].sub = 0;
-               TxBulkDummyEPList[i][0].next = virt_to_phys(&TxBulkDummyEPList[i][1]);
-
-               /* The second one. */
-               CHECK_ALIGN(&TxBulkDummyEPList[i][1]);
-               TxBulkDummyEPList[i][1].hw_len = 0;
-               TxBulkDummyEPList[i][1].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) |
-                                                  IO_STATE(USB_EP_command, eol, yes));
-               TxBulkDummyEPList[i][1].sub = 0;
-               /* The last dummy's next pointer is the same as the current EP's next pointer. */
-               TxBulkDummyEPList[i][1].next = virt_to_phys(&TxBulkEPList[i + 1]);
-       }
-
-       /* Configure the last one. */
-       CHECK_ALIGN(&TxBulkEPList[i]);
-       TxBulkEPList[i].hw_len = 0;
-       TxBulkEPList[i].command = (IO_STATE(USB_EP_command, eol, yes) |
-                                  IO_FIELD(USB_EP_command, epid, i));
-       TxBulkEPList[i].sub = 0;
-       TxBulkEPList[i].next = virt_to_phys(&TxBulkEPList[0]);
-
-       /* No need configuring dummy EPs for the last one as it will never be used for
-          bulk traffic (i == INVALD_EPID at this point). */
-
-       /* Set up to start on the last EP so we will enable it when inserting traffic
-          for the first time (imitating the situation where the DMA has stopped
-          because there was no more traffic). */
-       *R_DMA_CH8_SUB0_EP = virt_to_phys(&TxBulkEPList[i]);
-       /* No point in starting the bulk channel yet.
-        *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); */
-       DBFEXIT;
-}
-
-static void init_tx_ctrl_ep(void)
-{
-       int i;
-
-       DBFENTER;
-
-       for (i = 0; i < (NBR_OF_EPIDS - 1); i++) {
-               CHECK_ALIGN(&TxCtrlEPList[i]);
-               TxCtrlEPList[i].hw_len = 0;
-               TxCtrlEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
-               TxCtrlEPList[i].sub = 0;
-               TxCtrlEPList[i].next = virt_to_phys(&TxCtrlEPList[i + 1]);
-       }
-
-       CHECK_ALIGN(&TxCtrlEPList[i]);
-       TxCtrlEPList[i].hw_len = 0;
-       TxCtrlEPList[i].command = (IO_STATE(USB_EP_command, eol, yes) |
-                                  IO_FIELD(USB_EP_command, epid, i));
-
-       TxCtrlEPList[i].sub = 0;
-       TxCtrlEPList[i].next = virt_to_phys(&TxCtrlEPList[0]);
-
-       *R_DMA_CH8_SUB1_EP = virt_to_phys(&TxCtrlEPList[0]);
-       *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start);
-
-       DBFEXIT;
-}
-
-
-static void init_tx_intr_ep(void)
-{
-       int i;
-
-       DBFENTER;
-
-       /* Read comment at zout_buffer declaration for an explanation to this. */
-       TxIntrSB_zout.sw_len = 1;
-       TxIntrSB_zout.next = 0;
-       TxIntrSB_zout.buf = virt_to_phys(&zout_buffer[0]);
-       TxIntrSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) |
-                                IO_STATE(USB_SB_command, tt, zout) |
-                                IO_STATE(USB_SB_command, full, yes) |
-                                IO_STATE(USB_SB_command, eot, yes) |
-                                IO_STATE(USB_SB_command, eol, yes));
-
-       for (i = 0; i < (MAX_INTR_INTERVAL - 1); i++) {
-               CHECK_ALIGN(&TxIntrEPList[i]);
-               TxIntrEPList[i].hw_len = 0;
-               TxIntrEPList[i].command =
-                       (IO_STATE(USB_EP_command, eof, yes) |
-                        IO_STATE(USB_EP_command, enable, yes) |
-                        IO_FIELD(USB_EP_command, epid, INVALID_EPID));
-               TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout);
-               TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[i + 1]);
-       }
-
-       CHECK_ALIGN(&TxIntrEPList[i]);
-       TxIntrEPList[i].hw_len = 0;
-       TxIntrEPList[i].command =
-               (IO_STATE(USB_EP_command, eof, yes) |
-                IO_STATE(USB_EP_command, eol, yes) |
-                IO_STATE(USB_EP_command, enable, yes) |
-                IO_FIELD(USB_EP_command, epid, INVALID_EPID));
-       TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout);
-       TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[0]);
-
-       *R_DMA_CH8_SUB2_EP = virt_to_phys(&TxIntrEPList[0]);
-       *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
-       DBFEXIT;
-}
-
-static void init_tx_isoc_ep(void)
-{
-       int i;
-
-       DBFENTER;
-
-       /* Read comment at zout_buffer declaration for an explanation to this. */
-       TxIsocSB_zout.sw_len = 1;
-       TxIsocSB_zout.next = 0;
-       TxIsocSB_zout.buf = virt_to_phys(&zout_buffer[0]);
-       TxIsocSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) |
-                                IO_STATE(USB_SB_command, tt, zout) |
-                                IO_STATE(USB_SB_command, full, yes) |
-                                IO_STATE(USB_SB_command, eot, yes) |
-                                IO_STATE(USB_SB_command, eol, yes));
-
-       /* The last isochronous EP descriptor is a dummy. */
-
-       for (i = 0; i < (NBR_OF_EPIDS - 1); i++) {
-               CHECK_ALIGN(&TxIsocEPList[i]);
-               TxIsocEPList[i].hw_len = 0;
-               TxIsocEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
-               TxIsocEPList[i].sub = 0;
-               TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[i + 1]);
-       }
-
-       CHECK_ALIGN(&TxIsocEPList[i]);
-       TxIsocEPList[i].hw_len = 0;
-
-       /* Must enable the last EP descr to get eof interrupt. */
-       TxIsocEPList[i].command = (IO_STATE(USB_EP_command, enable, yes) |
-                                  IO_STATE(USB_EP_command, eof, yes) |
-                                  IO_STATE(USB_EP_command, eol, yes) |
-                                  IO_FIELD(USB_EP_command, epid, INVALID_EPID));
-       TxIsocEPList[i].sub = virt_to_phys(&TxIsocSB_zout);
-       TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[0]);
-
-       *R_DMA_CH8_SUB3_EP = virt_to_phys(&TxIsocEPList[0]);
-       *R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start);
-
-       DBFEXIT;
-}
-
-static void etrax_usb_unlink_intr_urb(struct urb *urb)
-{
-       volatile USB_EP_Desc_t *first_ep;  /* First EP in the list. */
-       volatile USB_EP_Desc_t *curr_ep;   /* Current EP, the iterator. */
-       volatile USB_EP_Desc_t *next_ep;   /* The EP after current. */
-       volatile USB_EP_Desc_t *unlink_ep; /* The one we should remove from the list. */
-
-       int epid;
-
-       /* Read 8.8.4 in Designer's Reference, "Removing an EP Descriptor from the List". */
-
-       DBFENTER;
-
-       epid = ((etrax_urb_priv_t *)urb->hcpriv)->epid;
-
-       first_ep = &TxIntrEPList[0];
-       curr_ep = first_ep;
-
-
-       /* Note that this loop removes all EP descriptors with this epid. This assumes
-          that all EP descriptors belong to the one and only urb for this epid. */
-
-       do {
-               next_ep = (USB_EP_Desc_t *)phys_to_virt(curr_ep->next);
-
-               if (IO_EXTRACT(USB_EP_command, epid, next_ep->command) == epid) {
-
-                       dbg_intr("Found EP to unlink for epid %d", epid);
-
-                       /* This is the one we should unlink. */
-                       unlink_ep = next_ep;
-
-                       /* Actually unlink the EP from the DMA list. */
-                       curr_ep->next = unlink_ep->next;
-
-                       /* Wait until the DMA is no longer at this descriptor. */
-                       while (*R_DMA_CH8_SUB2_EP == virt_to_phys(unlink_ep));
-
-                       /* Now we are free to remove it and its SB descriptor.
-                          Note that it is assumed here that there is only one sb in the
-                          sb list for this ep. */
-                       kmem_cache_free(usb_desc_cache, phys_to_virt(unlink_ep->sub));
-                       kmem_cache_free(usb_desc_cache, (USB_EP_Desc_t *)unlink_ep);
-               }
-
-               curr_ep = phys_to_virt(curr_ep->next);
-
-       } while (curr_ep != first_ep);
-        urb->hcpriv = NULL;
-}
-
-void etrax_usb_do_intr_recover(int epid)
-{
-       USB_EP_Desc_t *first_ep, *tmp_ep;
-
-       DBFENTER;
-
-       first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP);
-       tmp_ep = first_ep;
-
-       /* What this does is simply to walk the list of interrupt
-          ep descriptors and enable those that are disabled. */
-
-       do {
-               if (IO_EXTRACT(USB_EP_command, epid, tmp_ep->command) == epid &&
-                   !(tmp_ep->command & IO_MASK(USB_EP_command, enable))) {
-                       tmp_ep->command |= IO_STATE(USB_EP_command, enable, yes);
-               }
-
-               tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->next);
-
-       } while (tmp_ep != first_ep);
-
-
-       DBFEXIT;
-}
-
-static int etrax_rh_unlink_urb (struct urb *urb)
-{
-       etrax_hc_t *hc;
-
-       DBFENTER;
-
-       hc = urb->dev->bus->hcpriv;
-
-       if (hc->rh.urb == urb) {
-               hc->rh.send = 0;
-               del_timer(&hc->rh.rh_int_timer);
-       }
-
-       DBFEXIT;
-       return 0;
-}
-
-static void etrax_rh_send_irq(struct urb *urb)
-{
-       __u16 data = 0;
-       etrax_hc_t *hc = urb->dev->bus->hcpriv;
-       DBFENTER;
-
-/*
-  dbg_rh("R_USB_FM_NUMBER   : 0x%08X", *R_USB_FM_NUMBER);
-  dbg_rh("R_USB_FM_REMAINING: 0x%08X", *R_USB_FM_REMAINING);
-*/
-
-       data |= (hc->rh.wPortChange_1) ? (1 << 1) : 0;
-       data |= (hc->rh.wPortChange_2) ? (1 << 2) : 0;
-
-       *((__u16 *)urb->transfer_buffer) = cpu_to_le16(data);
-       /* FIXME: Why is actual_length set to 1 when data is 2 bytes?
-          Since only 1 byte is used, why not declare data as __u8? */
-       urb->actual_length = 1;
-       urb->status = 0;
-
-       if (hc->rh.send && urb->complete) {
-               dbg_rh("wPortChange_1: 0x%04X", hc->rh.wPortChange_1);
-               dbg_rh("wPortChange_2: 0x%04X", hc->rh.wPortChange_2);
-
-               urb->complete(urb, NULL);
-       }
-
-       DBFEXIT;
-}
-
-static void etrax_rh_init_int_timer(struct urb *urb)
-{
-       etrax_hc_t *hc;
-
-       DBFENTER;
-
-       hc = urb->dev->bus->hcpriv;
-       hc->rh.interval = urb->interval;
-       init_timer(&hc->rh.rh_int_timer);
-       hc->rh.rh_int_timer.function = etrax_rh_int_timer_do;
-       hc->rh.rh_int_timer.data = (unsigned long)urb;
-       /* FIXME: Is the jiffies resolution enough? All intervals < 10 ms will be mapped
-          to 0, and the rest to the nearest lower 10 ms. */
-       hc->rh.rh_int_timer.expires = jiffies + ((HZ * hc->rh.interval) / 1000);
-       add_timer(&hc->rh.rh_int_timer);
-
-       DBFEXIT;
-}
-
-static void etrax_rh_int_timer_do(unsigned long ptr)
-{
-       struct urb *urb;
-       etrax_hc_t *hc;
-
-       DBFENTER;
-
-       urb = (struct urb*)ptr;
-       hc = urb->dev->bus->hcpriv;
-
-       if (hc->rh.send) {
-               etrax_rh_send_irq(urb);
-       }
-
-       DBFEXIT;
-}
-
-static int etrax_usb_setup_epid(struct urb *urb)
-{
-       int epid;
-       char devnum, endpoint, out_traffic, slow;
-       int maxlen;
-       unsigned long flags;
-
-       DBFENTER;
-
-       epid = etrax_usb_lookup_epid(urb);
-       if ((epid != -1)){
-               /* An epid that fits this urb has been found. */
-               DBFEXIT;
-               return epid;
-       }
-
-       /* We must find and initiate a new epid for this urb. */
-       epid = etrax_usb_allocate_epid();
-
-       if (epid == -1) {
-               /* Failed to allocate a new epid. */
-               DBFEXIT;
-               return epid;
-       }
-
-       /* We now have a new epid to use. Initiate it. */
-       set_bit(epid, (void *)&epid_usage_bitmask);
-
-       devnum = usb_pipedevice(urb->pipe);
-       endpoint = usb_pipeendpoint(urb->pipe);
-       slow = usb_pipeslow(urb->pipe);
-       maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-       if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
-               /* We want both IN and OUT control traffic to be put on the same EP/SB list. */
-               out_traffic = 1;
-       } else {
-               out_traffic = usb_pipeout(urb->pipe);
-       }
-
-       save_flags(flags);
-       cli();
-
-       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-       nop();
-
-       if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-               *R_USB_EPT_DATA_ISO = IO_STATE(R_USB_EPT_DATA_ISO, valid, yes) |
-                       /* FIXME: Change any to the actual port? */
-                       IO_STATE(R_USB_EPT_DATA_ISO, port, any) |
-                       IO_FIELD(R_USB_EPT_DATA_ISO, max_len, maxlen) |
-                       IO_FIELD(R_USB_EPT_DATA_ISO, ep, endpoint) |
-                       IO_FIELD(R_USB_EPT_DATA_ISO, dev, devnum);
-       } else {
-               *R_USB_EPT_DATA = IO_STATE(R_USB_EPT_DATA, valid, yes) |
-                       IO_FIELD(R_USB_EPT_DATA, low_speed, slow) |
-                       /* FIXME: Change any to the actual port? */
-                       IO_STATE(R_USB_EPT_DATA, port, any) |
-                       IO_FIELD(R_USB_EPT_DATA, max_len, maxlen) |
-                       IO_FIELD(R_USB_EPT_DATA, ep, endpoint) |
-                       IO_FIELD(R_USB_EPT_DATA, dev, devnum);
-       }
-
-       restore_flags(flags);
-
-       if (out_traffic) {
-               set_bit(epid, (void *)&epid_out_traffic);
-       } else {
-               clear_bit(epid, (void *)&epid_out_traffic);
-       }
-
-       dbg_epid("Setting up epid %d with devnum %d, endpoint %d and max_len %d (%s)",
-                epid, devnum, endpoint, maxlen, out_traffic ? "OUT" : "IN");
-
-       DBFEXIT;
-       return epid;
-}
-
-static void etrax_usb_free_epid(int epid)
-{
-       unsigned long flags;
-
-       DBFENTER;
-
-       if (!test_bit(epid, (void *)&epid_usage_bitmask)) {
-               warn("Trying to free unused epid %d", epid);
-               DBFEXIT;
-               return;
-       }
-
-       save_flags(flags);
-       cli();
-
-       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-       nop();
-       while (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold));
-       /* This will, among other things, set the valid field to 0. */
-       *R_USB_EPT_DATA = 0;
-       restore_flags(flags);
-
-       clear_bit(epid, (void *)&epid_usage_bitmask);
-
-
-       dbg_epid("Freed epid %d", epid);
-
-       DBFEXIT;
-}
-
-static int etrax_usb_lookup_epid(struct urb *urb)
-{
-       int i;
-       __u32 data;
-       char devnum, endpoint, slow, out_traffic;
-       int maxlen;
-       unsigned long flags;
-
-       DBFENTER;
-
-       devnum = usb_pipedevice(urb->pipe);
-       endpoint = usb_pipeendpoint(urb->pipe);
-       slow = usb_pipeslow(urb->pipe);
-       maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-       if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
-               /* We want both IN and OUT control traffic to be put on the same EP/SB list. */
-               out_traffic = 1;
-       } else {
-               out_traffic = usb_pipeout(urb->pipe);
-       }
-
-       /* Step through att epids. */
-       for (i = 0; i < NBR_OF_EPIDS; i++) {
-               if (test_bit(i, (void *)&epid_usage_bitmask) &&
-                   test_bit(i, (void *)&epid_out_traffic) == out_traffic) {
-
-                       save_flags(flags);
-                       cli();
-                       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, i);
-                       nop();
-
-                       if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-                               data = *R_USB_EPT_DATA_ISO;
-                               restore_flags(flags);
-
-                               if ((IO_MASK(R_USB_EPT_DATA_ISO, valid) & data) &&
-                                   (IO_EXTRACT(R_USB_EPT_DATA_ISO, dev, data) == devnum) &&
-                                   (IO_EXTRACT(R_USB_EPT_DATA_ISO, ep, data) == endpoint) &&
-                                   (IO_EXTRACT(R_USB_EPT_DATA_ISO, max_len, data) == maxlen)) {
-                                       dbg_epid("Found epid %d for devnum %d, endpoint %d (%s)",
-                                                i, devnum, endpoint, out_traffic ? "OUT" : "IN");
-                                       DBFEXIT;
-                                       return i;
-                               }
-                       } else {
-                               data = *R_USB_EPT_DATA;
-                               restore_flags(flags);
-
-                               if ((IO_MASK(R_USB_EPT_DATA, valid) & data) &&
-                                   (IO_EXTRACT(R_USB_EPT_DATA, dev, data) == devnum) &&
-                                   (IO_EXTRACT(R_USB_EPT_DATA, ep, data) == endpoint) &&
-                                   (IO_EXTRACT(R_USB_EPT_DATA, low_speed, data) == slow) &&
-                                   (IO_EXTRACT(R_USB_EPT_DATA, max_len, data) == maxlen)) {
-                                       dbg_epid("Found epid %d for devnum %d, endpoint %d (%s)",
-                                                i, devnum, endpoint, out_traffic ? "OUT" : "IN");
-                                       DBFEXIT;
-                                       return i;
-                               }
-                       }
-               }
-       }
-
-       DBFEXIT;
-       return -1;
-}
-
-static int etrax_usb_allocate_epid(void)
-{
-       int i;
-
-       DBFENTER;
-
-       for (i = 0; i < NBR_OF_EPIDS; i++) {
-               if (!test_bit(i, (void *)&epid_usage_bitmask)) {
-                       dbg_epid("Found free epid %d", i);
-                       DBFEXIT;
-                       return i;
-               }
-       }
-
-       dbg_epid("Found no free epids");
-       DBFEXIT;
-       return -1;
-}
-
-static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags)
-{
-       etrax_hc_t *hc;
-       int ret = -EINVAL;
-
-       DBFENTER;
-
-       if (!urb->dev || !urb->dev->bus) {
-               return -ENODEV;
-       }
-       if (usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)) <= 0) {
-               info("Submit urb to pipe with maxpacketlen 0, pipe 0x%X\n", urb->pipe);
-               return -EMSGSIZE;
-       }
-
-       if (urb->timeout) {
-               /* FIXME. */
-               warn("urb->timeout specified, ignoring.");
-       }
-
-       hc = (etrax_hc_t*)urb->dev->bus->hcpriv;
-
-       if (usb_pipedevice(urb->pipe) == hc->rh.devnum) {
-               /* This request is for the Virtual Root Hub. */
-               ret = etrax_rh_submit_urb(urb);
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_BULK) {
-
-               ret = etrax_usb_submit_bulk_urb(urb);
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
-
-               ret = etrax_usb_submit_ctrl_urb(urb);
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
-               int bustime;
-
-               if (urb->bandwidth == 0) {
-                       bustime = usb_check_bandwidth(urb->dev, urb);
-                       if (bustime < 0) {
-                               ret = bustime;
-                       } else {
-                               ret = etrax_usb_submit_intr_urb(urb);
-                               if (ret == 0)
-                                       usb_claim_bandwidth(urb->dev, urb, bustime, 0);
-                       }
-               } else {
-                       /* Bandwidth already set. */
-                       ret = etrax_usb_submit_intr_urb(urb);
-               }
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-               int bustime;
-
-               if (urb->bandwidth == 0) {
-                       bustime = usb_check_bandwidth(urb->dev, urb);
-                       if (bustime < 0) {
-                               ret = bustime;
-                       } else {
-                               ret = etrax_usb_submit_isoc_urb(urb);
-                               if (ret == 0)
-                                       usb_claim_bandwidth(urb->dev, urb, bustime, 0);
-                       }
-               } else {
-                       /* Bandwidth already set. */
-                       ret = etrax_usb_submit_isoc_urb(urb);
-               }
-       }
-
-       DBFEXIT;
-
-        if (ret != 0)
-          printk("Submit URB error %d\n", ret);
-
-       return ret;
-}
-
-static int etrax_usb_unlink_urb(struct urb *urb, int status)
-{
-       etrax_hc_t *hc;
-       etrax_urb_priv_t *urb_priv;
-       int epid;
-       unsigned int flags;
-
-       DBFENTER;
-
-       if (!urb) {
-               return -EINVAL;
-       }
-
-       /* Disable interrupts here since a descriptor interrupt for the isoc epid
-          will modify the sb list.  This could possibly be done more granular, but
-          unlink_urb should not be used frequently anyway.
-       */
-
-       save_flags(flags);
-       cli();
-
-       if (!urb->dev || !urb->dev->bus) {
-               restore_flags(flags);
-               return -ENODEV;
-       }
-       if (!urb->hcpriv) {
-               /* This happens if a device driver calls unlink on an urb that
-                  was never submitted (lazy driver) or if the urb was completed
-                  while unlink was being called. */
-               restore_flags(flags);
-               return 0;
-       }
-       if (urb->transfer_flags & URB_ASYNC_UNLINK) {
-               /* FIXME. */
-               /* If URB_ASYNC_UNLINK is set:
-                  unlink
-                  move to a separate urb list
-                  call complete at next sof with ECONNRESET
-
-                  If not:
-                  wait 1 ms
-                  unlink
-                  call complete with ENOENT
-               */
-               warn("URB_ASYNC_UNLINK set, ignoring.");
-       }
-
-       /* One might think that urb->status = -EINPROGRESS would be a requirement for unlinking,
-          but that doesn't work for interrupt and isochronous traffic since they are completed
-          repeatedly, and urb->status is set then. That may in itself be a bug though. */
-
-       hc = urb->dev->bus->hcpriv;
-       urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-       epid = urb_priv->epid;
-
-       /* Set the urb status (synchronous unlink). */
-       urb->status = -ENOENT;
-       urb_priv->urb_state = UNLINK;
-
-       if (usb_pipedevice(urb->pipe) == hc->rh.devnum) {
-               int ret;
-               ret = etrax_rh_unlink_urb(urb);
-               DBFEXIT;
-               restore_flags(flags);
-               return ret;
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_BULK) {
-
-               dbg_bulk("Unlink of bulk urb (0x%lx)", (unsigned long)urb);
-
-               if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-                       /* The EP was enabled, disable it and wait. */
-                       TxBulkEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-
-                       /* Ah, the luxury of busy-wait. */
-                       while (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[epid]));
-               }
-               /* Kicking dummy list out of the party. */
-               TxBulkEPList[epid].next = virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]);
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
-
-               dbg_ctrl("Unlink of ctrl urb (0x%lx)", (unsigned long)urb);
-
-               if (TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-                       /* The EP was enabled, disable it and wait. */
-                       TxCtrlEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-
-                       /* Ah, the luxury of busy-wait. */
-                       while (*R_DMA_CH8_SUB1_EP == virt_to_phys(&TxCtrlEPList[epid]));
-               }
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
-
-               dbg_intr("Unlink of intr urb (0x%lx)", (unsigned long)urb);
-
-               /* Separate function because it's a tad more complicated. */
-               etrax_usb_unlink_intr_urb(urb);
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-
-               dbg_isoc("Unlink of isoc urb (0x%lx)", (unsigned long)urb);
-
-               if (TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-                       /* The EP was enabled, disable it and wait. */
-                       TxIsocEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-
-                       /* Ah, the luxury of busy-wait. */
-                       while (*R_DMA_CH8_SUB3_EP == virt_to_phys(&TxIsocEPList[epid]));
-               }
-       }
-
-       /* Note that we need to remove the urb from the urb list *before* removing its SB
-          descriptors. (This means that the isoc eof handler might get a null urb when we
-          are unlinking the last urb.) */
-
-       if (usb_pipetype(urb->pipe) == PIPE_BULK) {
-
-               urb_list_del(urb, epid);
-               TxBulkEPList[epid].sub = 0;
-               etrax_remove_from_sb_list(urb);
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
-
-               urb_list_del(urb, epid);
-               TxCtrlEPList[epid].sub = 0;
-               etrax_remove_from_sb_list(urb);
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
-
-               urb_list_del(urb, epid);
-               /* Sanity check (should never happen). */
-               assert(urb_list_empty(epid));
-
-               /* Release allocated bandwidth. */
-               usb_release_bandwidth(urb->dev, urb, 0);
-
-       } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-
-               if (usb_pipeout(urb->pipe)) {
-
-                       USB_SB_Desc_t *iter_sb, *prev_sb, *next_sb;
-
-                       if (__urb_list_entry(urb, epid)) {
-
-                               urb_list_del(urb, epid);
-                               iter_sb = TxIsocEPList[epid].sub ? phys_to_virt(TxIsocEPList[epid].sub) : 0;
-                               prev_sb = 0;
-                               while (iter_sb && (iter_sb != urb_priv->first_sb)) {
-                                       prev_sb = iter_sb;
-                                       iter_sb = iter_sb->next ? phys_to_virt(iter_sb->next) : 0;
-                               }
-
-                               if (iter_sb == 0) {
-                                       /* Unlink of the URB currently being transmitted. */
-                                       prev_sb = 0;
-                                       iter_sb = TxIsocEPList[epid].sub ? phys_to_virt(TxIsocEPList[epid].sub) : 0;
-                               }
-
-                               while (iter_sb && (iter_sb != urb_priv->last_sb)) {
-                                       iter_sb = iter_sb->next ? phys_to_virt(iter_sb->next) : 0;
-                               }
-                               if (iter_sb) {
-                                       next_sb = iter_sb->next ? phys_to_virt(iter_sb->next) : 0;
-                               } else {
-                                       /* This should only happen if the DMA has completed
-                                          processing the SB list for this EP while interrupts
-                                          are disabled. */
-                                       dbg_isoc("Isoc urb not found, already sent?");
-                                       next_sb = 0;
-                               }
-                               if (prev_sb) {
-                                       prev_sb->next = next_sb ? virt_to_phys(next_sb) : 0;
-                               } else {
-                                       TxIsocEPList[epid].sub = next_sb ? virt_to_phys(next_sb) : 0;
-                               }
-
-                               etrax_remove_from_sb_list(urb);
-                               if (urb_list_empty(epid)) {
-                                       TxIsocEPList[epid].sub = 0;
-                                       dbg_isoc("Last isoc out urb epid %d", epid);
-                               } else if (next_sb || prev_sb) {
-                                       dbg_isoc("Re-enable isoc out epid %d", epid);
-
-                                       TxIsocEPList[epid].hw_len = 0;
-                                       TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-                               } else {
-                                       TxIsocEPList[epid].sub = 0;
-                                       dbg_isoc("URB list non-empty and no SB list, EP disabled");
-                               }
-                       } else {
-                               dbg_isoc("Urb 0x%p not found, completed already?", urb);
-                       }
-               } else {
-
-                       urb_list_del(urb, epid);
-
-                       /* For in traffic there is only one SB descriptor for each EP even
-                          though there may be several urbs (all urbs point at the same SB). */
-                       if (urb_list_empty(epid)) {
-                               /* No more urbs, remove the SB. */
-                               TxIsocEPList[epid].sub = 0;
-                               etrax_remove_from_sb_list(urb);
-                       } else {
-                               TxIsocEPList[epid].hw_len = 0;
-                               TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-                       }
-               }
-               /* Release allocated bandwidth. */
-               usb_release_bandwidth(urb->dev, urb, 1);
-       }
-       /* Free the epid if urb list is empty. */
-       if (urb_list_empty(epid)) {
-               etrax_usb_free_epid(epid);
-       }
-       restore_flags(flags);
-
-       /* Must be done before calling completion handler. */
-       kfree(urb_priv);
-       urb->hcpriv = 0;
-
-       if (urb->complete) {
-               urb->complete(urb, NULL);
-       }
-
-       DBFEXIT;
-       return 0;
-}
-
-static int etrax_usb_get_frame_number(struct usb_device *usb_dev)
-{
-       DBFENTER;
-       DBFEXIT;
-       return (*R_USB_FM_NUMBER & 0x7ff);
-}
-
-static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc)
-{
-       DBFENTER;
-
-       /* This interrupt handler could be used when unlinking EP descriptors. */
-
-       if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub0_descr)) {
-               USB_EP_Desc_t *ep;
-
-               //dbg_bulk("dma8_sub0_descr (BULK) intr.");
-
-               /* It should be safe clearing the interrupt here, since we don't expect to get a new
-                  one until we restart the bulk channel. */
-               *R_DMA_CH8_SUB0_CLR_INTR = IO_STATE(R_DMA_CH8_SUB0_CLR_INTR, clr_descr, do);
-
-               /* Wait while the DMA is running (though we don't expect it to be). */
-               while (*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd));
-
-               /* Advance the DMA to the next EP descriptor. */
-               ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB0_EP);
-
-               //dbg_bulk("descr intr: DMA is at 0x%lx", (unsigned long)ep);
-
-               /* ep->next is already a physical address; no need for a virt_to_phys. */
-               *R_DMA_CH8_SUB0_EP = ep->next;
-
-               /* Start the DMA bulk channel again. */
-               *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
-       }
-       if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub1_descr)) {
-               struct urb *urb;
-               int epid;
-               etrax_urb_priv_t *urb_priv;
-               unsigned long int flags;
-
-               dbg_ctrl("dma8_sub1_descr (CTRL) intr.");
-               *R_DMA_CH8_SUB1_CLR_INTR = IO_STATE(R_DMA_CH8_SUB1_CLR_INTR, clr_descr, do);
-
-               /* The complete callback gets called so we cli. */
-               save_flags(flags);
-               cli();
-
-               for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) {
-                       if ((TxCtrlEPList[epid].sub == 0) ||
-                           (epid == DUMMY_EPID) ||
-                           (epid == INVALID_EPID)) {
-                               /* Nothing here to see. */
-                               continue;
-                       }
-
-                       /* Get the first urb (if any). */
-                       urb = urb_list_first(epid);
-
-                       if (urb) {
-
-                               /* Sanity check. */
-                               assert(usb_pipetype(urb->pipe) == PIPE_CONTROL);
-
-                               urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-                               assert(urb_priv);
-
-                               if (urb_priv->urb_state == WAITING_FOR_DESCR_INTR) {
-                                       assert(!(TxCtrlEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable)));
-
-                                       etrax_usb_complete_urb(urb, 0);
-                               }
-                       }
-               }
-               restore_flags(flags);
-       }
-       if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub2_descr)) {
-               dbg_intr("dma8_sub2_descr (INTR) intr.");
-               *R_DMA_CH8_SUB2_CLR_INTR = IO_STATE(R_DMA_CH8_SUB2_CLR_INTR, clr_descr, do);
-       }
-       if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub3_descr)) {
-               struct urb *urb;
-               int epid;
-               int epid_done;
-               etrax_urb_priv_t *urb_priv;
-               USB_SB_Desc_t *sb_desc;
-
-               usb_isoc_complete_data_t *comp_data = NULL;
-
-               /* One or more isoc out transfers are done. */
-               dbg_isoc("dma8_sub3_descr (ISOC) intr.");
-
-               /* For each isoc out EP search for the first sb_desc with the intr flag
-                  set.  This descriptor must be the last packet from an URB.  Then
-                  traverse the URB list for the EP until the URB with urb_priv->last_sb
-                  matching the intr-marked sb_desc is found.  All URBs before this have
-                  been sent.
-               */
-
-               for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) {
-                       /* Skip past epids with no SB lists, epids used for in traffic,
-                          and special (dummy, invalid) epids. */
-                       if ((TxIsocEPList[epid].sub == 0) ||
-                           (test_bit(epid, (void *)&epid_out_traffic) == 0) ||
-                           (epid == DUMMY_EPID) ||
-                           (epid == INVALID_EPID)) {
-                               /* Nothing here to see. */
-                               continue;
-                       }
-                       sb_desc = phys_to_virt(TxIsocEPList[epid].sub);
-
-                       /* Find the last descriptor of the currently active URB for this ep.
-                          This is the first descriptor in the sub list marked for a descriptor
-                          interrupt. */
-                       while (sb_desc && !IO_EXTRACT(USB_SB_command, intr, sb_desc->command)) {
-                               sb_desc = sb_desc->next ? phys_to_virt(sb_desc->next) : 0;
-                       }
-                       assert(sb_desc);
-
-                       dbg_isoc("Check epid %d, sub 0x%p, SB 0x%p",
-                                epid,
-                                phys_to_virt(TxIsocEPList[epid].sub),
-                                sb_desc);
-
-                       epid_done = 0;
-
-                       /* Get the first urb (if any). */
-                       urb = urb_list_first(epid);
-                       assert(urb);
-
-                       while (urb && !epid_done) {
-
-                               /* Sanity check. */
-                               assert(usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS);
-
-                               if (!usb_pipeout(urb->pipe)) {
-                                       /* descr interrupts are generated only for out pipes. */
-                                       epid_done = 1;
-                                       continue;
-                               }
-
-                               urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-                               assert(urb_priv);
-
-                               if (sb_desc != urb_priv->last_sb) {
-
-                                       /* This urb has been sent. */
-                                       dbg_isoc("out URB 0x%p sent", urb);
-
-                                       urb_priv->urb_state = TRANSFER_DONE;
-
-                               } else if ((sb_desc == urb_priv->last_sb) &&
-                                          !(TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable))) {
-
-                                       assert((sb_desc->command & IO_MASK(USB_SB_command, eol)) == IO_STATE(USB_SB_command, eol, yes));
-                                       assert(sb_desc->next == 0);
-
-                                       dbg_isoc("out URB 0x%p last in list, epid disabled", urb);
-                                       TxIsocEPList[epid].sub = 0;
-                                       TxIsocEPList[epid].hw_len = 0;
-                                       urb_priv->urb_state = TRANSFER_DONE;
-
-                                       epid_done = 1;
-
-                               } else {
-                                       epid_done = 1;
-                               }
-                               if (!epid_done) {
-                                       urb = urb_list_next(urb, epid);
-                               }
-                       }
-
-               }
-
-               *R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do);
-
-               comp_data = (usb_isoc_complete_data_t*)kmem_cache_alloc(isoc_compl_cache, GFP_ATOMIC);
-               assert(comp_data != NULL);
-
-                INIT_WORK(&comp_data->usb_bh, etrax_usb_isoc_descr_interrupt_bottom_half, comp_data);
-                schedule_work(&comp_data->usb_bh);
-       }
-
-       DBFEXIT;
-        return IRQ_HANDLED;
-}
-
-static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data)
-{
-       usb_isoc_complete_data_t *comp_data = (usb_isoc_complete_data_t*)data;
-
-       struct urb *urb;
-       int epid;
-       int epid_done;
-       etrax_urb_priv_t *urb_priv;
-
-       DBFENTER;
-
-       dbg_isoc("dma8_sub3_descr (ISOC) bottom half.");
-
-       for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) {
-               unsigned long flags;
-
-               save_flags(flags);
-               cli();
-
-               epid_done = 0;
-
-               /* The descriptor interrupt handler has marked all transmitted isoch. out
-                  URBs with TRANSFER_DONE.  Now we traverse all epids and for all that
-                  have isoch. out traffic traverse its URB list and complete the
-                  transmitted URB.
-               */
-
-               while (!epid_done) {
-
-                       /* Get the first urb (if any). */
-                       urb = urb_list_first(epid);
-                       if (urb == 0) {
-                               epid_done = 1;
-                               continue;
-                       }
-
-                       if (usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) {
-                                       epid_done = 1;
-                                       continue;
-                       }
-
-                       if (!usb_pipeout(urb->pipe)) {
-                               /* descr interrupts are generated only for out pipes. */
-                               epid_done = 1;
-                               continue;
-                       }
-
-                       dbg_isoc("Check epid %d, SB 0x%p", epid, (char*)TxIsocEPList[epid].sub);
-
-                       urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-                       assert(urb_priv);
-
-                       if (urb_priv->urb_state == TRANSFER_DONE) {
-                               int i;
-                               struct usb_iso_packet_descriptor *packet;
-
-                               /* This urb has been sent. */
-                               dbg_isoc("Completing isoc out URB 0x%p", urb);
-
-                               for (i = 0; i < urb->number_of_packets; i++) {
-                                       packet = &urb->iso_frame_desc[i];
-                                       packet->status = 0;
-                                       packet->actual_length = packet->length;
-                               }
-
-                               etrax_usb_complete_isoc_urb(urb, 0);
-
-                               if (urb_list_empty(epid)) {
-                                       etrax_usb_free_epid(epid);
-                                       epid_done = 1;
-                               }
-                       } else {
-                               epid_done = 1;
-                       }
-               }
-               restore_flags(flags);
-
-       }
-       kmem_cache_free(isoc_compl_cache, comp_data);
-
-       DBFEXIT;
-}
-
-
-
-static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc)
-{
-       struct urb *urb;
-       etrax_urb_priv_t *urb_priv;
-       int epid = 0;
-       unsigned long flags;
-
-       /* Isoc diagnostics. */
-       static int curr_fm = 0;
-       static int prev_fm = 0;
-
-       DBFENTER;
-
-       /* Clear this interrupt. */
-       *R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do);
-
-       /* Note that this while loop assumes that all packets span only
-          one rx descriptor. */
-
-       /* The reason we cli here is that we call the driver's callback functions. */
-       save_flags(flags);
-       cli();
-
-       while (myNextRxDesc->status & IO_MASK(USB_IN_status, eop)) {
-
-               epid = IO_EXTRACT(USB_IN_status, epid, myNextRxDesc->status);
-               urb = urb_list_first(epid);
-
-               //printk("eop for epid %d, first urb 0x%lx\n", epid, (unsigned long)urb);
-
-               if (!urb) {
-                       err("No urb for epid %d in rx interrupt", epid);
-                       __dump_ept_data(epid);
-                       goto skip_out;
-               }
-
-               /* Note that we cannot indescriminately assert(usb_pipein(urb->pipe)) since
-                  ctrl pipes are not. */
-
-               if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) {
-                       __u32 r_usb_ept_data;
-                       int no_error = 0;
-
-                       assert(test_bit(epid, (void *)&epid_usage_bitmask));
-
-                       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-                       nop();
-                       if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-                               r_usb_ept_data = *R_USB_EPT_DATA_ISO;
-
-                               if ((r_usb_ept_data & IO_MASK(R_USB_EPT_DATA_ISO, valid)) &&
-                                   (IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code, r_usb_ept_data) == 0) &&
-                                   (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata))) {
-                                       /* Not an error, just a failure to receive an expected iso
-                                          in packet in this frame.  This is not documented
-                                          in the designers reference.
-                                       */
-                                       no_error++;
-                               } else {
-                                       warn("R_USB_EPT_DATA_ISO for epid %d = 0x%x", epid, r_usb_ept_data);
-                               }
-                       } else {
-                               r_usb_ept_data = *R_USB_EPT_DATA;
-                               warn("R_USB_EPT_DATA for epid %d = 0x%x", epid, r_usb_ept_data);
-                       }
-
-                       if (!no_error){
-                               warn("error in rx desc->status, epid %d, first urb = 0x%lx",
-                                    epid, (unsigned long)urb);
-                               __dump_in_desc(myNextRxDesc);
-
-                               warn("R_USB_STATUS = 0x%x", *R_USB_STATUS);
-
-                               /* Check that ept was disabled when error occurred. */
-                               switch (usb_pipetype(urb->pipe)) {
-                               case PIPE_BULK:
-                                       assert(!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)));
-                                       break;
-                               case PIPE_CONTROL:
-                                       assert(!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)));
-                                       break;
-                               case PIPE_INTERRUPT:
-                                       assert(!(TxIntrEPList[epid].command & IO_MASK(USB_EP_command, enable)));
-                                       break;
-                               case PIPE_ISOCHRONOUS:
-                                       assert(!(TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)));
-                                       break;
-                               default:
-                                       warn("etrax_usb_rx_interrupt: bad pipetype %d in urb 0x%p",
-                                            usb_pipetype(urb->pipe),
-                                            urb);
-                               }
-                               etrax_usb_complete_urb(urb, -EPROTO);
-                               goto skip_out;
-                       }
-               }
-
-               urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-               assert(urb_priv);
-
-               if ((usb_pipetype(urb->pipe) == PIPE_BULK) ||
-                   (usb_pipetype(urb->pipe) == PIPE_CONTROL) ||
-                   (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
-
-                       if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) {
-                               /* We get nodata for empty data transactions, and the rx descriptor's
-                                  hw_len field is not valid in that case. No data to copy in other
-                                  words. */
-                       } else {
-                               /* Make sure the data fits in the buffer. */
-                               assert(urb_priv->rx_offset + myNextRxDesc->hw_len
-                                      <= urb->transfer_buffer_length);
-
-                               memcpy(urb->transfer_buffer + urb_priv->rx_offset,
-                                      phys_to_virt(myNextRxDesc->buf), myNextRxDesc->hw_len);
-                               urb_priv->rx_offset += myNextRxDesc->hw_len;
-                       }
-
-                       if (myNextRxDesc->status & IO_MASK(USB_IN_status, eot)) {
-                               if ((usb_pipetype(urb->pipe) == PIPE_CONTROL) &&
-                                   ((TxCtrlEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable)) ==
-                                    IO_STATE(USB_EP_command, enable, yes))) {
-                                       /* The EP is still enabled, so the OUT packet used to ack
-                                          the in data is probably not processed yet.  If the EP
-                                          sub pointer has not moved beyond urb_priv->last_sb mark
-                                          it for a descriptor interrupt and complete the urb in
-                                          the descriptor interrupt handler.
-                                       */
-                                       USB_SB_Desc_t *sub = TxCtrlEPList[urb_priv->epid].sub ? phys_to_virt(TxCtrlEPList[urb_priv->epid].sub) : 0;
-
-                                       while ((sub != NULL) && (sub != urb_priv->last_sb)) {
-                                               sub = sub->next ? phys_to_virt(sub->next) : 0;
-                                       }
-                                       if (sub != NULL) {
-                                               /* The urb has not been fully processed. */
-                                               urb_priv->urb_state = WAITING_FOR_DESCR_INTR;
-                                       } else {
-                                               warn("(CTRL) epid enabled and urb (0x%p) processed, ep->sub=0x%p", urb, (char*)TxCtrlEPList[urb_priv->epid].sub);
-                                               etrax_usb_complete_urb(urb, 0);
-                                       }
-                               } else {
-                                       etrax_usb_complete_urb(urb, 0);
-                               }
-                       }
-
-               } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-
-                       struct usb_iso_packet_descriptor *packet;
-
-                       if (urb_priv->urb_state == UNLINK) {
-                               info("Ignoring rx data for urb being unlinked.");
-                               goto skip_out;
-                       } else if (urb_priv->urb_state == NOT_STARTED) {
-                               info("What? Got rx data for urb that isn't started?");
-                               goto skip_out;
-                       }
-
-                       packet = &urb->iso_frame_desc[urb_priv->isoc_packet_counter];
-                       packet->status = 0;
-
-                       if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) {
-                               /* We get nodata for empty data transactions, and the rx descriptor's
-                                  hw_len field is not valid in that case. We copy 0 bytes however to
-                                  stay in synch. */
-                               packet->actual_length = 0;
-                       } else {
-                               packet->actual_length = myNextRxDesc->hw_len;
-                               /* Make sure the data fits in the buffer. */
-                               assert(packet->actual_length <= packet->length);
-                               memcpy(urb->transfer_buffer + packet->offset,
-                                      phys_to_virt(myNextRxDesc->buf), packet->actual_length);
-                       }
-
-                       /* Increment the packet counter. */
-                       urb_priv->isoc_packet_counter++;
-
-                       /* Note that we don't care about the eot field in the rx descriptor's status.
-                          It will always be set for isoc traffic. */
-                       if (urb->number_of_packets == urb_priv->isoc_packet_counter) {
-
-                               /* Out-of-synch diagnostics. */
-                               curr_fm = (*R_USB_FM_NUMBER & 0x7ff);
-                               if (((prev_fm + urb_priv->isoc_packet_counter) % (0x7ff + 1)) != curr_fm) {
-                                       /* This test is wrong, if there is more than one isoc
-                                          in endpoint active it will always calculate wrong
-                                          since prev_fm is shared by all endpoints.
-
-                                          FIXME Make this check per URB using urb->start_frame.
-                                       */
-                                       dbg_isoc("Out of synch? Previous frame = %d, current frame = %d",
-                                                prev_fm, curr_fm);
-
-                               }
-                               prev_fm = curr_fm;
-
-                               /* Complete the urb with status OK. */
-                               etrax_usb_complete_isoc_urb(urb, 0);
-                       }
-               }
-
-       skip_out:
-
-               /* DMA IN cache bug. Flush the DMA IN buffer from the cache. (struct etrax_dma_descr
-                  has the same layout as USB_IN_Desc for the relevant fields.) */
-               prepare_rx_descriptor((struct etrax_dma_descr*)myNextRxDesc);
-
-               myPrevRxDesc = myNextRxDesc;
-               myPrevRxDesc->command |= IO_MASK(USB_IN_command, eol);
-               myLastRxDesc->command &= ~IO_MASK(USB_IN_command, eol);
-               myLastRxDesc = myPrevRxDesc;
-
-               myNextRxDesc->status = 0;
-               myNextRxDesc = phys_to_virt(myNextRxDesc->next);
-       }
-
-       restore_flags(flags);
-
-       DBFEXIT;
-
-        return IRQ_HANDLED;
-}
-
-
-/* This function will unlink the SB descriptors associated with this urb. */
-static int etrax_remove_from_sb_list(struct urb *urb)
-{
-       USB_SB_Desc_t *next_sb, *first_sb, *last_sb;
-       etrax_urb_priv_t *urb_priv;
-       int i = 0;
-
-       DBFENTER;
-
-       urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-       assert(urb_priv);
-
-       /* Just a sanity check. Since we don't fiddle with the DMA list the EP descriptor
-          doesn't really need to be disabled, it's just that we expect it to be. */
-       if (usb_pipetype(urb->pipe) == PIPE_BULK) {
-               assert(!(TxBulkEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable)));
-       } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
-               assert(!(TxCtrlEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable)));
-       }
-
-       first_sb = urb_priv->first_sb;
-       last_sb = urb_priv->last_sb;
-
-       assert(first_sb);
-       assert(last_sb);
-
-       while (first_sb != last_sb) {
-               next_sb = (USB_SB_Desc_t *)phys_to_virt(first_sb->next);
-               kmem_cache_free(usb_desc_cache, first_sb);
-               first_sb = next_sb;
-               i++;
-       }
-       kmem_cache_free(usb_desc_cache, last_sb);
-       i++;
-       dbg_sb("%d SB descriptors freed", i);
-       /* Compare i with urb->number_of_packets for Isoc traffic.
-          Should be same when calling unlink_urb */
-
-       DBFEXIT;
-
-       return i;
-}
-
-static int etrax_usb_submit_bulk_urb(struct urb *urb)
-{
-       int epid;
-       int empty;
-       unsigned long flags;
-       etrax_urb_priv_t *urb_priv;
-
-       DBFENTER;
-
-       /* Epid allocation, empty check and list add must be protected.
-          Read about this in etrax_usb_submit_ctrl_urb. */
-
-       spin_lock_irqsave(&urb_list_lock, flags);
-       epid = etrax_usb_setup_epid(urb);
-       if (epid == -1) {
-               DBFEXIT;
-               spin_unlock_irqrestore(&urb_list_lock, flags);
-               return -ENOMEM;
-       }
-       empty = urb_list_empty(epid);
-       urb_list_add(urb, epid);
-       spin_unlock_irqrestore(&urb_list_lock, flags);
-
-       dbg_bulk("Adding bulk %s urb 0x%lx to %s list, epid %d",
-                usb_pipein(urb->pipe) ? "IN" : "OUT", (unsigned long)urb, empty ? "empty" : "", epid);
-
-       /* Mark the urb as being in progress. */
-       urb->status = -EINPROGRESS;
-
-       /* Setup the hcpriv data. */
-       urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG);
-       assert(urb_priv != NULL);
-       /* This sets rx_offset to 0. */
-       urb_priv->urb_state = NOT_STARTED;
-       urb->hcpriv = urb_priv;
-
-       if (empty) {
-               etrax_usb_add_to_bulk_sb_list(urb, epid);
-       }
-
-       DBFEXIT;
-
-       return 0;
-}
-
-static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid)
-{
-       USB_SB_Desc_t *sb_desc;
-       etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-       unsigned long flags;
-       char maxlen;
-
-       DBFENTER;
-
-       dbg_bulk("etrax_usb_add_to_bulk_sb_list, urb 0x%lx", (unsigned long)urb);
-
-       maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-
-       sb_desc = kmem_cache_zalloc(usb_desc_cache, SLAB_FLAG);
-       assert(sb_desc != NULL);
-
-
-       if (usb_pipeout(urb->pipe)) {
-
-               dbg_bulk("Grabbing bulk OUT, urb 0x%lx, epid %d", (unsigned long)urb, epid);
-
-               /* This is probably a sanity check of the bulk transaction length
-                  not being larger than 64 kB. */
-               if (urb->transfer_buffer_length > 0xffff) {
-                       panic("urb->transfer_buffer_length > 0xffff");
-               }
-
-               sb_desc->sw_len = urb->transfer_buffer_length;
-
-               /* The rem field is don't care if it's not a full-length transfer, so setting
-                  it shouldn't hurt. Also, rem isn't used for OUT traffic. */
-               sb_desc->command = (IO_FIELD(USB_SB_command, rem, 0) |
-                                   IO_STATE(USB_SB_command, tt, out) |
-                                   IO_STATE(USB_SB_command, eot, yes) |
-                                   IO_STATE(USB_SB_command, eol, yes));
-
-               /* The full field is set to yes, even if we don't actually check that this is
-                  a full-length transfer (i.e., that transfer_buffer_length % maxlen = 0).
-                  Setting full prevents the USB controller from sending an empty packet in
-                  that case.  However, if URB_ZERO_PACKET was set we want that. */
-               if (!(urb->transfer_flags & URB_ZERO_PACKET)) {
-                       sb_desc->command |= IO_STATE(USB_SB_command, full, yes);
-               }
-
-               sb_desc->buf = virt_to_phys(urb->transfer_buffer);
-               sb_desc->next = 0;
-
-       } else if (usb_pipein(urb->pipe)) {
-
-               dbg_bulk("Grabbing bulk IN, urb 0x%lx, epid %d", (unsigned long)urb, epid);
-
-               sb_desc->sw_len = urb->transfer_buffer_length ?
-                       (urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
-
-               /* The rem field is don't care if it's not a full-length transfer, so setting
-                  it shouldn't hurt. */
-               sb_desc->command =
-                       (IO_FIELD(USB_SB_command, rem,
-                                 urb->transfer_buffer_length % maxlen) |
-                        IO_STATE(USB_SB_command, tt, in) |
-                        IO_STATE(USB_SB_command, eot, yes) |
-                        IO_STATE(USB_SB_command, eol, yes));
-
-               sb_desc->buf = 0;
-               sb_desc->next = 0;
-       }
-
-       urb_priv->first_sb = sb_desc;
-       urb_priv->last_sb = sb_desc;
-       urb_priv->epid = epid;
-
-       urb->hcpriv = urb_priv;
-
-       /* Reset toggle bits and reset error count. */
-       save_flags(flags);
-       cli();
-
-       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-       nop();
-
-       /* FIXME: Is this a special case since the hold field is checked,
-          or should we check hold in a lot of other cases as well? */
-       if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) {
-               panic("Hold was set in %s", __FUNCTION__);
-       }
-
-       /* Reset error counters (regardless of which direction this traffic is). */
-       *R_USB_EPT_DATA &=
-               ~(IO_MASK(R_USB_EPT_DATA, error_count_in) |
-                 IO_MASK(R_USB_EPT_DATA, error_count_out));
-
-       /* Software must preset the toggle bits. */
-       if (usb_pipeout(urb->pipe)) {
-               char toggle =
-                       usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
-               *R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_out);
-               *R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_out, toggle);
-       } else {
-               char toggle =
-                       usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
-               *R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_in);
-               *R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_in, toggle);
-       }
-
-       /* Assert that the EP descriptor is disabled. */
-       assert(!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)));
-
-       /* The reason we set the EP's sub pointer directly instead of
-          walking the SB list and linking it last in the list is that we only
-          have one active urb at a time (the rest are queued). */
-
-       /* Note that we cannot have interrupts running when we have set the SB descriptor
-          but the EP is not yet enabled.  If a bulk eot happens for another EP, we will
-          find this EP disabled and with a SB != 0, which will make us think that it's done. */
-       TxBulkEPList[epid].sub = virt_to_phys(sb_desc);
-       TxBulkEPList[epid].hw_len = 0;
-       /* Note that we don't have to fill in the ep_id field since this
-          was done when we allocated the EP descriptors in init_tx_bulk_ep. */
-
-       /* Check if the dummy list is already with us (if several urbs were queued). */
-       if (TxBulkEPList[epid].next != virt_to_phys(&TxBulkDummyEPList[epid][0])) {
-
-               dbg_bulk("Inviting dummy list to the party for urb 0x%lx, epid %d",
-                        (unsigned long)urb, epid);
-
-               /* The last EP in the dummy list already has its next pointer set to
-                  TxBulkEPList[epid].next. */
-
-               /* We don't need to check if the DMA is at this EP or not before changing the
-                  next pointer, since we will do it in one 32-bit write (EP descriptors are
-                  32-bit aligned). */
-               TxBulkEPList[epid].next = virt_to_phys(&TxBulkDummyEPList[epid][0]);
-       }
-       /* Enable the EP descr. */
-       dbg_bulk("Enabling bulk EP for urb 0x%lx, epid %d", (unsigned long)urb, epid);
-       TxBulkEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-
-       /* Everything is set up, safe to enable interrupts again. */
-       restore_flags(flags);
-
-       /* If the DMA bulk channel isn't running, we need to restart it if it
-          has stopped at the last EP descriptor (DMA stopped because there was
-          no more traffic) or if it has stopped at a dummy EP with the intr flag
-          set (DMA stopped because we were too slow in inserting new traffic). */
-       if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) {
-
-               USB_EP_Desc_t *ep;
-               ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB0_EP);
-               dbg_bulk("DMA channel not running in add");
-               dbg_bulk("DMA is at 0x%lx", (unsigned long)ep);
-
-               if (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[NBR_OF_EPIDS - 1]) ||
-                   (ep->command & 0x8) >> 3) {
-                       *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
-                       /* Update/restart the bulk start timer since we just started the channel. */
-                       mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL);
-                       /* Update/restart the bulk eot timer since we just inserted traffic. */
-                       mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL);
-               }
-       }
-
-       DBFEXIT;
-}
-
-static void etrax_usb_complete_bulk_urb(struct urb *urb, int status)
-{
-       etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-       int epid = urb_priv->epid;
-       unsigned long flags;
-
-       DBFENTER;
-
-       if (status)
-               warn("Completing bulk urb with status %d.", status);
-
-       dbg_bulk("Completing bulk urb 0x%lx for epid %d", (unsigned long)urb, epid);
-
-       /* Update the urb list. */
-       urb_list_del(urb, epid);
-
-       /* For an IN pipe, we always set the actual length, regardless of whether there was
-          an error or not (which means the device driver can use the data if it wants to). */
-       if (usb_pipein(urb->pipe)) {
-               urb->actual_length = urb_priv->rx_offset;
-       } else {
-               /* Set actual_length for OUT urbs also; the USB mass storage driver seems
-                  to want that. We wouldn't know of any partial writes if there was an error. */
-               if (status == 0) {
-                       urb->actual_length = urb->transfer_buffer_length;
-               } else {
-                       urb->actual_length = 0;
-               }
-       }
-
-       /* FIXME: Is there something of the things below we shouldn't do if there was an error?
-          Like, maybe we shouldn't toggle the toggle bits, or maybe we shouldn't insert more traffic. */
-
-       save_flags(flags);
-       cli();
-
-       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-       nop();
-
-       /* We need to fiddle with the toggle bits because the hardware doesn't do it for us. */
-       if (usb_pipeout(urb->pipe)) {
-               char toggle =
-                       IO_EXTRACT(R_USB_EPT_DATA, t_out, *R_USB_EPT_DATA);
-               usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-                             usb_pipeout(urb->pipe), toggle);
-       } else {
-               char toggle =
-                       IO_EXTRACT(R_USB_EPT_DATA, t_in, *R_USB_EPT_DATA);
-               usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-                             usb_pipeout(urb->pipe), toggle);
-       }
-       restore_flags(flags);
-
-       /* Remember to free the SBs. */
-       etrax_remove_from_sb_list(urb);
-       kfree(urb_priv);
-       urb->hcpriv = 0;
-
-       /* If there are any more urb's in the list we'd better start sending */
-       if (!urb_list_empty(epid)) {
-
-               struct urb *new_urb;
-
-               /* Get the first urb. */
-               new_urb = urb_list_first(epid);
-               assert(new_urb);
-
-               dbg_bulk("More bulk for epid %d", epid);
-
-               etrax_usb_add_to_bulk_sb_list(new_urb, epid);
-       }
-
-       urb->status = status;
-
-       /* We let any non-zero status from the layer above have precedence. */
-       if (status == 0) {
-               /* URB_SHORT_NOT_OK means that short reads (shorter than the endpoint's max length)
-                  is to be treated as an error. */
-               if (urb->transfer_flags & URB_SHORT_NOT_OK) {
-                       if (usb_pipein(urb->pipe) &&
-                           (urb->actual_length !=
-                            usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)))) {
-                               urb->status = -EREMOTEIO;
-                       }
-               }
-       }
-
-       if (urb->complete) {
-               urb->complete(urb, NULL);
-       }
-
-       if (urb_list_empty(epid)) {
-               /* This means that this EP is now free, deconfigure it. */
-               etrax_usb_free_epid(epid);
-
-               /* No more traffic; time to clean up.
-                  Must set sub pointer to 0, since we look at the sub pointer when handling
-                  the bulk eot interrupt. */
-
-               dbg_bulk("No bulk for epid %d", epid);
-
-               TxBulkEPList[epid].sub = 0;
-
-               /* Unlink the dummy list. */
-
-               dbg_bulk("Kicking dummy list out of party for urb 0x%lx, epid %d",
-                        (unsigned long)urb, epid);
-
-               /* No need to wait for the DMA before changing the next pointer.
-                  The modulo NBR_OF_EPIDS isn't actually necessary, since we will never use
-                  the last one (INVALID_EPID) for actual traffic. */
-               TxBulkEPList[epid].next =
-                       virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]);
-       }
-
-       DBFEXIT;
-}
-
-static int etrax_usb_submit_ctrl_urb(struct urb *urb)
-{
-       int epid;
-       int empty;
-       unsigned long flags;
-       etrax_urb_priv_t *urb_priv;
-
-       DBFENTER;
-
-       /* FIXME: Return -ENXIO if there is already a queued urb for this endpoint? */
-
-       /* Epid allocation, empty check and list add must be protected.
-
-          Epid allocation because if we find an existing epid for this endpoint an urb might be
-          completed (emptying the list) before we add the new urb to the list, causing the epid
-          to be de-allocated. We would then start the transfer with an invalid epid -> epid attn.
-
-          Empty check and add because otherwise we might conclude that the list is not empty,
-          after which it becomes empty before we add the new urb to the list, causing us not to
-          insert the new traffic into the SB list. */
-
-       spin_lock_irqsave(&urb_list_lock, flags);
-       epid = etrax_usb_setup_epid(urb);
-       if (epid == -1) {
-               spin_unlock_irqrestore(&urb_list_lock, flags);
-               DBFEXIT;
-               return -ENOMEM;
-       }
-       empty = urb_list_empty(epid);
-       urb_list_add(urb, epid);
-       spin_unlock_irqrestore(&urb_list_lock, flags);
-
-       dbg_ctrl("Adding ctrl urb 0x%lx to %s list, epid %d",
-                (unsigned long)urb, empty ? "empty" : "", epid);
-
-       /* Mark the urb as being in progress. */
-       urb->status = -EINPROGRESS;
-
-       /* Setup the hcpriv data. */
-       urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG);
-       assert(urb_priv != NULL);
-       /* This sets rx_offset to 0. */
-       urb_priv->urb_state = NOT_STARTED;
-       urb->hcpriv = urb_priv;
-
-       if (empty) {
-               etrax_usb_add_to_ctrl_sb_list(urb, epid);
-       }
-
-       DBFEXIT;
-
-       return 0;
-}
-
-static void etrax_usb_add_to_ctrl_sb_list(struct urb *urb, int epid)
-{
-       USB_SB_Desc_t *sb_desc_setup;
-       USB_SB_Desc_t *sb_desc_data;
-       USB_SB_Desc_t *sb_desc_status;
-
-       etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-
-       unsigned long flags;
-       char maxlen;
-
-       DBFENTER;
-
-       maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-
-       sb_desc_setup = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
-       assert(sb_desc_setup != NULL);
-       sb_desc_status = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
-       assert(sb_desc_status != NULL);
-
-       /* Initialize the mandatory setup SB descriptor (used only in control transfers) */
-       sb_desc_setup->sw_len = 8;
-       sb_desc_setup->command = (IO_FIELD(USB_SB_command, rem, 0) |
-                                 IO_STATE(USB_SB_command, tt, setup) |
-                                 IO_STATE(USB_SB_command, full, yes) |
-                                 IO_STATE(USB_SB_command, eot, yes));
-
-       sb_desc_setup->buf = virt_to_phys(urb->setup_packet);
-
-       if (usb_pipeout(urb->pipe)) {
-               dbg_ctrl("Transfer for epid %d is OUT", epid);
-
-               /* If this Control OUT transfer has an optional data stage we add an OUT token
-                  before the mandatory IN (status) token, hence the reordered SB list */
-
-               sb_desc_setup->next = virt_to_phys(sb_desc_status);
-               if (urb->transfer_buffer) {
-
-                       dbg_ctrl("This OUT transfer has an extra data stage");
-
-                       sb_desc_data = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
-                       assert(sb_desc_data != NULL);
-
-                       sb_desc_setup->next = virt_to_phys(sb_desc_data);
-
-                       sb_desc_data->sw_len = urb->transfer_buffer_length;
-                       sb_desc_data->command = (IO_STATE(USB_SB_command, tt, out) |
-                                                IO_STATE(USB_SB_command, full, yes) |
-                                                IO_STATE(USB_SB_command, eot, yes));
-                       sb_desc_data->buf = virt_to_phys(urb->transfer_buffer);
-                       sb_desc_data->next = virt_to_phys(sb_desc_status);
-               }
-
-               sb_desc_status->sw_len = 1;
-               sb_desc_status->command = (IO_FIELD(USB_SB_command, rem, 0) |
-                                          IO_STATE(USB_SB_command, tt, in) |
-                                          IO_STATE(USB_SB_command, eot, yes) |
-                                          IO_STATE(USB_SB_command, intr, yes) |
-                                          IO_STATE(USB_SB_command, eol, yes));
-
-               sb_desc_status->buf = 0;
-               sb_desc_status->next = 0;
-
-       } else if (usb_pipein(urb->pipe)) {
-
-               dbg_ctrl("Transfer for epid %d is IN", epid);
-               dbg_ctrl("transfer_buffer_length = %d", urb->transfer_buffer_length);
-               dbg_ctrl("rem is calculated to %d", urb->transfer_buffer_length % maxlen);
-
-               sb_desc_data = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
-               assert(sb_desc_data != NULL);
-
-               sb_desc_setup->next = virt_to_phys(sb_desc_data);
-
-               sb_desc_data->sw_len = urb->transfer_buffer_length ?
-                       (urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
-               dbg_ctrl("sw_len got %d", sb_desc_data->sw_len);
-
-               sb_desc_data->command =
-                       (IO_FIELD(USB_SB_command, rem,
-                                 urb->transfer_buffer_length % maxlen) |
-                        IO_STATE(USB_SB_command, tt, in) |
-                        IO_STATE(USB_SB_command, eot, yes));
-
-               sb_desc_data->buf = 0;
-               sb_desc_data->next = virt_to_phys(sb_desc_status);
-
-               /* Read comment at zout_buffer declaration for an explanation to this. */
-               sb_desc_status->sw_len = 1;
-               sb_desc_status->command = (IO_FIELD(USB_SB_command, rem, 0) |
-                                          IO_STATE(USB_SB_command, tt, zout) |
-                                          IO_STATE(USB_SB_command, full, yes) |
-                                          IO_STATE(USB_SB_command, eot, yes) |
-                                          IO_STATE(USB_SB_command, intr, yes) |
-                                          IO_STATE(USB_SB_command, eol, yes));
-
-               sb_desc_status->buf = virt_to_phys(&zout_buffer[0]);
-               sb_desc_status->next = 0;
-       }
-
-       urb_priv->first_sb = sb_desc_setup;
-       urb_priv->last_sb = sb_desc_status;
-       urb_priv->epid = epid;
-
-       urb_priv->urb_state = STARTED;
-
-       /* Reset toggle bits and reset error count, remember to di and ei */
-       /* Warning: it is possible that this locking doesn't work with bottom-halves */
-
-       save_flags(flags);
-       cli();
-
-       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-       nop();
-       if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) {
-               panic("Hold was set in %s", __FUNCTION__);
-       }
-
-
-       /* FIXME: Compare with etrax_usb_add_to_bulk_sb_list where the toggle bits
-          are set to a specific value. Why the difference? Read "Transfer and Toggle Bits
-          in Designer's Reference, p. 8 - 11. */
-       *R_USB_EPT_DATA &=
-               ~(IO_MASK(R_USB_EPT_DATA, error_count_in) |
-                 IO_MASK(R_USB_EPT_DATA, error_count_out) |
-                 IO_MASK(R_USB_EPT_DATA, t_in) |
-                 IO_MASK(R_USB_EPT_DATA, t_out));
-
-       /* Since we use the rx interrupt to complete ctrl urbs, we can enable interrupts now
-          (i.e. we don't check the sub pointer on an eot interrupt like we do for bulk traffic). */
-       restore_flags(flags);
-
-       /* Assert that the EP descriptor is disabled. */
-       assert(!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)));
-
-       /* Set up and enable the EP descriptor. */
-       TxCtrlEPList[epid].sub = virt_to_phys(sb_desc_setup);
-       TxCtrlEPList[epid].hw_len = 0;
-       TxCtrlEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-
-       /* We start the DMA sub channel without checking if it's running or not, because:
-          1) If it's already running, issuing the start command is a nop.
-          2) We avoid a test-and-set race condition. */
-       *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start);
-
-       DBFEXIT;
-}
-
-static void etrax_usb_complete_ctrl_urb(struct urb *urb, int status)
-{
-       etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-       int epid = urb_priv->epid;
-
-       DBFENTER;
-
-       if (status)
-               warn("Completing ctrl urb with status %d.", status);
-
-       dbg_ctrl("Completing ctrl epid %d, urb 0x%lx", epid, (unsigned long)urb);
-
-       /* Remove this urb from the list. */
-       urb_list_del(urb, epid);
-
-       /* For an IN pipe, we always set the actual length, regardless of whether there was
-          an error or not (which means the device driver can use the data if it wants to). */
-       if (usb_pipein(urb->pipe)) {
-               urb->actual_length = urb_priv->rx_offset;
-       }
-
-       /* FIXME: Is there something of the things below we shouldn't do if there was an error?
-          Like, maybe we shouldn't insert more traffic. */
-
-       /* Remember to free the SBs. */
-       etrax_remove_from_sb_list(urb);
-       kfree(urb_priv);
-       urb->hcpriv = 0;
-
-       /* If there are any more urbs in the list we'd better start sending. */
-       if (!urb_list_empty(epid)) {
-               struct urb *new_urb;
-
-               /* Get the first urb. */
-               new_urb = urb_list_first(epid);
-               assert(new_urb);
-
-               dbg_ctrl("More ctrl for epid %d, first urb = 0x%lx", epid, (unsigned long)new_urb);
-
-               etrax_usb_add_to_ctrl_sb_list(new_urb, epid);
-       }
-
-       urb->status = status;
-
-       /* We let any non-zero status from the layer above have precedence. */
-       if (status == 0) {
-               /* URB_SHORT_NOT_OK means that short reads (shorter than the endpoint's max length)
-                  is to be treated as an error. */
-               if (urb->transfer_flags & URB_SHORT_NOT_OK) {
-                       if (usb_pipein(urb->pipe) &&
-                           (urb->actual_length !=
-                            usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)))) {
-                               urb->status = -EREMOTEIO;
-                       }
-               }
-       }
-
-       if (urb->complete) {
-               urb->complete(urb, NULL);
-       }
-
-       if (urb_list_empty(epid)) {
-               /* No more traffic. Time to clean up. */
-               etrax_usb_free_epid(epid);
-               /* Must set sub pointer to 0. */
-               dbg_ctrl("No ctrl for epid %d", epid);
-               TxCtrlEPList[epid].sub = 0;
-       }
-
-       DBFEXIT;
-}
-
-static int etrax_usb_submit_intr_urb(struct urb *urb)
-{
-
-       int epid;
-
-       DBFENTER;
-
-       if (usb_pipeout(urb->pipe)) {
-               /* Unsupported transfer type.
-                  We don't support interrupt out traffic. (If we do, we can't support
-                  intervals for neither in or out traffic, but are forced to schedule all
-                  interrupt traffic in one frame.) */
-               return -EINVAL;
-       }
-
-       epid = etrax_usb_setup_epid(urb);
-       if (epid == -1) {
-               DBFEXIT;
-               return -ENOMEM;
-       }
-
-       if (!urb_list_empty(epid)) {
-               /* There is already a queued urb for this endpoint. */
-               etrax_usb_free_epid(epid);
-               return -ENXIO;
-       }
-
-       urb->status = -EINPROGRESS;
-
-       dbg_intr("Add intr urb 0x%lx, to list, epid %d", (unsigned long)urb, epid);
-
-       urb_list_add(urb, epid);
-       etrax_usb_add_to_intr_sb_list(urb, epid);
-
-       return 0;
-
-       DBFEXIT;
-}
-
-static void etrax_usb_add_to_intr_sb_list(struct urb *urb, int epid)
-{
-
-       volatile USB_EP_Desc_t *tmp_ep;
-       volatile USB_EP_Desc_t *first_ep;
-
-       char maxlen;
-       int interval;
-       int i;
-
-       etrax_urb_priv_t *urb_priv;
-
-       DBFENTER;
-
-       maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-       interval = urb->interval;
-
-       urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG);
-       assert(urb_priv != NULL);
-       urb->hcpriv = urb_priv;
-
-       first_ep = &TxIntrEPList[0];
-
-       /* Round of the interval to 2^n, it is obvious that this code favours
-          smaller numbers, but that is actually a good thing */
-       /* FIXME: The "rounding error" for larger intervals will be quite
-          large. For in traffic this shouldn't be a problem since it will only
-          mean that we "poll" more often. */
-       for (i = 0; interval; i++) {
-               interval = interval >> 1;
-       }
-       interval = 1 << (i - 1);
-
-       dbg_intr("Interval rounded to %d", interval);
-
-       tmp_ep = first_ep;
-       i = 0;
-       do {
-               if (tmp_ep->command & IO_MASK(USB_EP_command, eof)) {
-                       if ((i % interval) == 0) {
-                               /* Insert the traffic ep after tmp_ep */
-                               USB_EP_Desc_t *ep_desc;
-                               USB_SB_Desc_t *sb_desc;
-
-                               dbg_intr("Inserting EP for epid %d", epid);
-
-                               ep_desc = (USB_EP_Desc_t *)
-                                       kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
-                               sb_desc = (USB_SB_Desc_t *)
-                                       kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
-                               assert(ep_desc != NULL);
-                               CHECK_ALIGN(ep_desc);
-                               assert(sb_desc != NULL);
-
-                               ep_desc->sub = virt_to_phys(sb_desc);
-                               ep_desc->hw_len = 0;
-                               ep_desc->command = (IO_FIELD(USB_EP_command, epid, epid) |
-                                                   IO_STATE(USB_EP_command, enable, yes));
-
-
-                               /* Round upwards the number of packets of size maxlen
-                                  that this SB descriptor should receive. */
-                               sb_desc->sw_len = urb->transfer_buffer_length ?
-                                       (urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
-                               sb_desc->next = 0;
-                               sb_desc->buf = 0;
-                               sb_desc->command =
-                                       (IO_FIELD(USB_SB_command, rem, urb->transfer_buffer_length % maxlen) |
-                                        IO_STATE(USB_SB_command, tt, in) |
-                                        IO_STATE(USB_SB_command, eot, yes) |
-                                        IO_STATE(USB_SB_command, eol, yes));
-
-                               ep_desc->next = tmp_ep->next;
-                               tmp_ep->next = virt_to_phys(ep_desc);
-                       }
-                       i++;
-               }
-               tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->next);
-       } while (tmp_ep != first_ep);
-
-
-       /* Note that first_sb/last_sb doesn't apply to interrupt traffic. */
-       urb_priv->epid = epid;
-
-       /* We start the DMA sub channel without checking if it's running or not, because:
-          1) If it's already running, issuing the start command is a nop.
-          2) We avoid a test-and-set race condition. */
-       *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
-
-       DBFEXIT;
-}
-
-
-
-static void etrax_usb_complete_intr_urb(struct urb *urb, int status)
-{
-       etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-       int epid = urb_priv->epid;
-
-       DBFENTER;
-
-       if (status)
-               warn("Completing intr urb with status %d.", status);
-
-       dbg_intr("Completing intr epid %d, urb 0x%lx", epid, (unsigned long)urb);
-
-       urb->status = status;
-       urb->actual_length = urb_priv->rx_offset;
-
-       dbg_intr("interrupt urb->actual_length = %d", urb->actual_length);
-
-       /* We let any non-zero status from the layer above have precedence. */
-       if (status == 0) {
-               /* URB_SHORT_NOT_OK means that short reads (shorter than the endpoint's max length)
-                  is to be treated as an error. */
-               if (urb->transfer_flags & URB_SHORT_NOT_OK) {
-                       if (urb->actual_length !=
-                           usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) {
-                               urb->status = -EREMOTEIO;
-                       }
-               }
-       }
-
-       /* The driver will resubmit the URB so we need to remove it first */
-        etrax_usb_unlink_urb(urb, 0);
-       if (urb->complete) {
-               urb->complete(urb, NULL);
-       }
-
-       DBFEXIT;
-}
-
-
-static int etrax_usb_submit_isoc_urb(struct urb *urb)
-{
-       int epid;
-       unsigned long flags;
-
-       DBFENTER;
-
-       dbg_isoc("Submitting isoc urb = 0x%lx", (unsigned long)urb);
-
-       /* Epid allocation, empty check and list add must be protected.
-          Read about this in etrax_usb_submit_ctrl_urb. */
-
-       spin_lock_irqsave(&urb_list_lock, flags);
-       /* Is there an active epid for this urb ? */
-       epid = etrax_usb_setup_epid(urb);
-       if (epid == -1) {
-               DBFEXIT;
-               spin_unlock_irqrestore(&urb_list_lock, flags);
-               return -ENOMEM;
-       }
-
-       /* Ok, now we got valid endpoint, lets insert some traffic */
-
-       urb->status = -EINPROGRESS;
-
-       /* Find the last urb in the URB_List and add this urb after that one.
-          Also add the traffic, that is do an etrax_usb_add_to_isoc_sb_list.  This
-          is important to make this in "real time" since isochronous traffic is
-          time sensitive. */
-
-       dbg_isoc("Adding isoc urb to (possibly empty) list");
-       urb_list_add(urb, epid);
-       etrax_usb_add_to_isoc_sb_list(urb, epid);
-       spin_unlock_irqrestore(&urb_list_lock, flags);
-
-       DBFEXIT;
-
-       return 0;
-}
-
-static void etrax_usb_check_error_isoc_ep(const int epid)
-{
-       unsigned long int flags;
-       int error_code;
-       __u32 r_usb_ept_data;
-
-       /* We can't read R_USB_EPID_ATTN here since it would clear the iso_eof,
-          bulk_eot and epid_attn interrupts.  So we just check the status of
-          the epid without testing if for it in R_USB_EPID_ATTN. */
-
-
-       save_flags(flags);
-       cli();
-       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-       nop();
-       /* Note that although there are separate R_USB_EPT_DATA and R_USB_EPT_DATA_ISO
-          registers, they are located at the same address and are of the same size.
-          In other words, this read should be ok for isoc also. */
-       r_usb_ept_data = *R_USB_EPT_DATA;
-       restore_flags(flags);
-
-       error_code = IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code, r_usb_ept_data);
-
-       if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) {
-               warn("Hold was set for epid %d.", epid);
-               return;
-       }
-
-       if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA_ISO, error_code, no_error)) {
-
-               /* This indicates that the SB list of the ept was completed before
-                  new data was appended to it.  This is not an error, but indicates
-                  large system or USB load and could possibly cause trouble for
-                  very timing sensitive USB device drivers so we log it.
-               */
-               info("Isoc. epid %d disabled with no error", epid);
-               return;
-
-       } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA_ISO, error_code, stall)) {
-               /* Not really a protocol error, just says that the endpoint gave
-                  a stall response. Note that error_code cannot be stall for isoc. */
-               panic("Isoc traffic cannot stall");
-
-       } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA_ISO, error_code, bus_error)) {
-               /* Two devices responded to a transaction request. Must be resolved
-                  by software. FIXME: Reset ports? */
-               panic("Bus error for epid %d."
-                     " Two devices responded to transaction request",
-                     epid);
-
-       } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, buffer_error)) {
-               /* DMA overrun or underrun. */
-               warn("Buffer overrun/underrun for epid %d. DMA too busy?", epid);
-
-               /* It seems that error_code = buffer_error in
-                  R_USB_EPT_DATA/R_USB_EPT_DATA_ISO and ourun = yes in R_USB_STATUS
-                  are the same error. */
-       }
-}
-
-
-static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid)
-{
-
-       int i = 0;
-
-       etrax_urb_priv_t *urb_priv;
-       USB_SB_Desc_t *prev_sb_desc,  *next_sb_desc, *temp_sb_desc;
-
-       DBFENTER;
-
-       prev_sb_desc = next_sb_desc = temp_sb_desc = NULL;
-
-       urb_priv = kzalloc(sizeof(etrax_urb_priv_t), GFP_ATOMIC);
-       assert(urb_priv != NULL);
-
-       urb->hcpriv = urb_priv;
-       urb_priv->epid = epid;
-
-       if (usb_pipeout(urb->pipe)) {
-
-               if (urb->number_of_packets == 0) panic("etrax_usb_add_to_isoc_sb_list 0 packets\n");
-
-               dbg_isoc("Transfer for epid %d is OUT", epid);
-               dbg_isoc("%d packets in URB", urb->number_of_packets);
-
-               /* Create one SB descriptor for each packet and link them together. */
-               for (i = 0; i < urb->number_of_packets; i++) {
-                       if (!urb->iso_frame_desc[i].length)
-                               continue;
-
-                       next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC);
-                       assert(next_sb_desc != NULL);
-
-                       if (urb->iso_frame_desc[i].length > 0) {
-
-                               next_sb_desc->command = (IO_STATE(USB_SB_command, tt, out) |
-                                                        IO_STATE(USB_SB_command, eot, yes));
-
-                               next_sb_desc->sw_len = urb->iso_frame_desc[i].length;
-                               next_sb_desc->buf = virt_to_phys((char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset);
-
-                               /* Check if full length transfer. */
-                               if (urb->iso_frame_desc[i].length ==
-                                   usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) {
-                                       next_sb_desc->command |= IO_STATE(USB_SB_command, full, yes);
-                               }
-                       } else {
-                               dbg_isoc("zero len packet");
-                               next_sb_desc->command = (IO_FIELD(USB_SB_command, rem, 0) |
-                                                        IO_STATE(USB_SB_command, tt, zout) |
-                                                        IO_STATE(USB_SB_command, eot, yes) |
-                                                        IO_STATE(USB_SB_command, full, yes));
-
-                               next_sb_desc->sw_len = 1;
-                               next_sb_desc->buf = virt_to_phys(&zout_buffer[0]);
-                       }
-
-                       /* First SB descriptor that belongs to this urb */
-                       if (i == 0)
-                               urb_priv->first_sb = next_sb_desc;
-                       else
-                               prev_sb_desc->next = virt_to_phys(next_sb_desc);
-
-                       prev_sb_desc = next_sb_desc;
-               }
-
-               next_sb_desc->command |= (IO_STATE(USB_SB_command, intr, yes) |
-                                         IO_STATE(USB_SB_command, eol, yes));
-               next_sb_desc->next = 0;
-               urb_priv->last_sb = next_sb_desc;
-
-       } else if (usb_pipein(urb->pipe)) {
-
-               dbg_isoc("Transfer for epid %d is IN", epid);
-               dbg_isoc("transfer_buffer_length = %d", urb->transfer_buffer_length);
-               dbg_isoc("rem is calculated to %d", urb->iso_frame_desc[urb->number_of_packets - 1].length);
-
-               /* Note that in descriptors for periodic traffic are not consumed. This means that
-                  the USB controller never propagates in the SB list. In other words, if there already
-                  is an SB descriptor in the list for this EP we don't have to do anything. */
-               if (TxIsocEPList[epid].sub == 0) {
-                       dbg_isoc("Isoc traffic not already running, allocating SB");
-
-                       next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC);
-                       assert(next_sb_desc != NULL);
-
-                       next_sb_desc->command = (IO_STATE(USB_SB_command, tt, in) |
-                                                IO_STATE(USB_SB_command, eot, yes) |
-                                                IO_STATE(USB_SB_command, eol, yes));
-
-                       next_sb_desc->next = 0;
-                       next_sb_desc->sw_len = 1; /* Actual number of packets is not relevant
-                                                    for periodic in traffic as long as it is more
-                                                    than zero.  Set to 1 always. */
-                       next_sb_desc->buf = 0;
-
-                       /* The rem field is don't care for isoc traffic, so we don't set it. */
-
-                       /* Only one SB descriptor that belongs to this urb. */
-                       urb_priv->first_sb = next_sb_desc;
-                       urb_priv->last_sb = next_sb_desc;
-
-               } else {
-
-                       dbg_isoc("Isoc traffic already running, just setting first/last_sb");
-
-                       /* Each EP for isoc in will have only one SB descriptor, setup when submitting the
-                          already active urb. Note that even though we may have several first_sb/last_sb
-                          pointing at the same SB descriptor, they are freed only once (when the list has
-                          become empty). */
-                       urb_priv->first_sb = phys_to_virt(TxIsocEPList[epid].sub);
-                       urb_priv->last_sb = phys_to_virt(TxIsocEPList[epid].sub);
-                       return;
-               }
-
-       }
-
-       /* Find the spot to insert this urb and add it. */
-       if (TxIsocEPList[epid].sub == 0) {
-               /* First SB descriptor inserted in this list (in or out). */
-               dbg_isoc("Inserting SB desc first in list");
-               TxIsocEPList[epid].hw_len = 0;
-               TxIsocEPList[epid].sub = virt_to_phys(urb_priv->first_sb);
-
-       } else {
-               /* Isochronous traffic is already running, insert new traffic last (only out). */
-               dbg_isoc("Inserting SB desc last in list");
-               temp_sb_desc = phys_to_virt(TxIsocEPList[epid].sub);
-               while ((temp_sb_desc->command & IO_MASK(USB_SB_command, eol)) !=
-                      IO_STATE(USB_SB_command, eol, yes)) {
-                       assert(temp_sb_desc->next);
-                       temp_sb_desc = phys_to_virt(temp_sb_desc->next);
-               }
-               dbg_isoc("Appending list on desc 0x%p", temp_sb_desc);
-
-               /* Next pointer must be set before eol is removed. */
-               temp_sb_desc->next = virt_to_phys(urb_priv->first_sb);
-               /* Clear the previous end of list flag since there is a new in the
-                  added SB descriptor list. */
-               temp_sb_desc->command &= ~IO_MASK(USB_SB_command, eol);
-
-               if (!(TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable))) {
-                       /* 8.8.5 in Designer's Reference says we should check for and correct
-                          any errors in the EP here.  That should not be necessary if epid_attn
-                          is handled correctly, so we assume all is ok. */
-                       dbg_isoc("EP disabled");
-                       etrax_usb_check_error_isoc_ep(epid);
-
-                       /* The SB list was exhausted. */
-                       if (virt_to_phys(urb_priv->last_sb) != TxIsocEPList[epid].sub) {
-                               /* The new sublist did not get processed before the EP was
-                                  disabled.  Setup the EP again. */
-                               dbg_isoc("Set EP sub to new list");
-                               TxIsocEPList[epid].hw_len = 0;
-                               TxIsocEPList[epid].sub = virt_to_phys(urb_priv->first_sb);
-                       }
-               }
-       }
-
-       if (urb->transfer_flags & URB_ISO_ASAP) {
-               /* The isoc transfer should be started as soon as possible. The start_frame
-                  field is a return value if URB_ISO_ASAP was set. Comparing R_USB_FM_NUMBER
-                  with a USB Chief trace shows that the first isoc IN token is sent 2 frames
-                  later. I'm not sure how this affects usage of the start_frame field by the
-                  device driver, or how it affects things when USB_ISO_ASAP is not set, so
-                  therefore there's no compensation for the 2 frame "lag" here. */
-               urb->start_frame = (*R_USB_FM_NUMBER & 0x7ff);
-               TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-               urb_priv->urb_state = STARTED;
-               dbg_isoc("URB_ISO_ASAP set, urb->start_frame set to %d", urb->start_frame);
-       } else {
-               /* Not started yet. */
-               urb_priv->urb_state = NOT_STARTED;
-               dbg_isoc("urb_priv->urb_state set to NOT_STARTED");
-       }
-
-       /* We start the DMA sub channel without checking if it's running or not, because:
-         1) If it's already running, issuing the start command is a nop.
-         2) We avoid a test-and-set race condition. */
-       *R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start);
-
-       DBFEXIT;
-}
-
-static void etrax_usb_complete_isoc_urb(struct urb *urb, int status)
-{
-       etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-       int epid = urb_priv->epid;
-       int auto_resubmit = 0;
-
-       DBFENTER;
-       dbg_isoc("complete urb 0x%p, status %d", urb, status);
-
-       if (status)
-               warn("Completing isoc urb with status %d.", status);
-
-       if (usb_pipein(urb->pipe)) {
-               int i;
-
-               /* Make that all isoc packets have status and length set before
-                  completing the urb. */
-               for (i = urb_priv->isoc_packet_counter; i < urb->number_of_packets; i++) {
-                       urb->iso_frame_desc[i].actual_length = 0;
-                       urb->iso_frame_desc[i].status = -EPROTO;
-               }
-
-               urb_list_del(urb, epid);
-
-               if (!list_empty(&urb_list[epid])) {
-                       ((etrax_urb_priv_t *)(urb_list_first(epid)->hcpriv))->urb_state = STARTED;
-               } else {
-                       unsigned long int flags;
-                       if (TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-                               /* The EP was enabled, disable it and wait. */
-                               TxIsocEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-
-                               /* Ah, the luxury of busy-wait. */
-                               while (*R_DMA_CH8_SUB3_EP == virt_to_phys(&TxIsocEPList[epid]));
-                       }
-
-                       etrax_remove_from_sb_list(urb);
-                       TxIsocEPList[epid].sub = 0;
-                       TxIsocEPList[epid].hw_len = 0;
-
-                       save_flags(flags);
-                       cli();
-                       etrax_usb_free_epid(epid);
-                       restore_flags(flags);
-               }
-
-               urb->hcpriv = 0;
-               kfree(urb_priv);
-
-               /* Release allocated bandwidth. */
-               usb_release_bandwidth(urb->dev, urb, 0);
-       } else if (usb_pipeout(urb->pipe)) {
-               int freed_descr;
-
-               dbg_isoc("Isoc out urb complete 0x%p", urb);
-
-               /* Update the urb list. */
-               urb_list_del(urb, epid);
-
-               freed_descr = etrax_remove_from_sb_list(urb);
-               dbg_isoc("freed %d descriptors of %d packets", freed_descr, urb->number_of_packets);
-               assert(freed_descr == urb->number_of_packets);
-               urb->hcpriv = 0;
-               kfree(urb_priv);
-
-               /* Release allocated bandwidth. */
-               usb_release_bandwidth(urb->dev, urb, 0);
-       }
-
-       urb->status = status;
-       if (urb->complete) {
-               urb->complete(urb, NULL);
-       }
-
-       if (auto_resubmit) {
-               /* Check that urb was not unlinked by the complete callback. */
-               if (__urb_list_entry(urb, epid)) {
-                       /* Move this one down the list. */
-                       urb_list_move_last(urb, epid);
-
-                       /* Mark the now first urb as started (may already be). */
-                       ((etrax_urb_priv_t *)(urb_list_first(epid)->hcpriv))->urb_state = STARTED;
-
-                       /* Must set this to 0 since this urb is still active after
-                          completion. */
-                       urb_priv->isoc_packet_counter = 0;
-               } else {
-                       warn("(ISOC) automatic resubmit urb 0x%p removed by complete.", urb);
-               }
-       }
-
-       DBFEXIT;
-}
-
-static void etrax_usb_complete_urb(struct urb *urb, int status)
-{
-       switch (usb_pipetype(urb->pipe)) {
-       case PIPE_BULK:
-               etrax_usb_complete_bulk_urb(urb, status);
-               break;
-       case PIPE_CONTROL:
-               etrax_usb_complete_ctrl_urb(urb, status);
-               break;
-       case PIPE_INTERRUPT:
-               etrax_usb_complete_intr_urb(urb, status);
-               break;
-       case PIPE_ISOCHRONOUS:
-               etrax_usb_complete_isoc_urb(urb, status);
-               break;
-       default:
-               err("Unknown pipetype");
-       }
-}
-
-
-
-static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc)
-{
-       usb_interrupt_registers_t *reg;
-       unsigned long flags;
-       __u32 irq_mask;
-       __u8 status;
-       __u32 epid_attn;
-       __u16 port_status_1;
-       __u16 port_status_2;
-       __u32 fm_number;
-
-       DBFENTER;
-
-       /* Read critical registers into local variables, do kmalloc afterwards. */
-       save_flags(flags);
-       cli();
-
-       irq_mask = *R_USB_IRQ_MASK_READ;
-       /* Reading R_USB_STATUS clears the ctl_status interrupt. Note that R_USB_STATUS
-          must be read before R_USB_EPID_ATTN since reading the latter clears the
-          ourun and perror fields of R_USB_STATUS. */
-       status = *R_USB_STATUS;
-
-       /* Reading R_USB_EPID_ATTN clears the iso_eof, bulk_eot and epid_attn interrupts. */
-       epid_attn = *R_USB_EPID_ATTN;
-
-       /* Reading R_USB_RH_PORT_STATUS_1 and R_USB_RH_PORT_STATUS_2 clears the
-          port_status interrupt. */
-       port_status_1 = *R_USB_RH_PORT_STATUS_1;
-       port_status_2 = *R_USB_RH_PORT_STATUS_2;
-
-       /* Reading R_USB_FM_NUMBER clears the sof interrupt. */
-       /* Note: the lower 11 bits contain the actual frame number, sent with each sof. */
-       fm_number = *R_USB_FM_NUMBER;
-
-       restore_flags(flags);
-
-       reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, GFP_ATOMIC);
-
-       assert(reg != NULL);
-
-       reg->hc = (etrax_hc_t *)vhc;
-
-       /* Now put register values into kmalloc'd area. */
-       reg->r_usb_irq_mask_read = irq_mask;
-       reg->r_usb_status = status;
-       reg->r_usb_epid_attn = epid_attn;
-       reg->r_usb_rh_port_status_1 = port_status_1;
-       reg->r_usb_rh_port_status_2 = port_status_2;
-       reg->r_usb_fm_number = fm_number;
-
-        INIT_WORK(&reg->usb_bh, etrax_usb_hc_interrupt_bottom_half, reg);
-        schedule_work(&reg->usb_bh);
-
-       DBFEXIT;
-
-        return IRQ_HANDLED;
-}
-
-static void etrax_usb_hc_interrupt_bottom_half(void *data)
-{
-       usb_interrupt_registers_t *reg = (usb_interrupt_registers_t *)data;
-       __u32 irq_mask = reg->r_usb_irq_mask_read;
-
-       DBFENTER;
-
-       /* Interrupts are handled in order of priority. */
-       if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, epid_attn)) {
-               etrax_usb_hc_epid_attn_interrupt(reg);
-       }
-       if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, port_status)) {
-               etrax_usb_hc_port_status_interrupt(reg);
-       }
-       if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, ctl_status)) {
-               etrax_usb_hc_ctl_status_interrupt(reg);
-       }
-       if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, iso_eof)) {
-               etrax_usb_hc_isoc_eof_interrupt();
-       }
-       if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, bulk_eot)) {
-               /* Update/restart the bulk start timer since obviously the channel is running. */
-               mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL);
-               /* Update/restart the bulk eot timer since we just received an bulk eot interrupt. */
-               mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL);
-
-               etrax_usb_hc_bulk_eot_interrupt(0);
-       }
-
-       kmem_cache_free(top_half_reg_cache, reg);
-
-       DBFEXIT;
-}
-
-
-void etrax_usb_hc_isoc_eof_interrupt(void)
-{
-       struct urb *urb;
-       etrax_urb_priv_t *urb_priv;
-       int epid;
-       unsigned long flags;
-
-       DBFENTER;
-
-       /* Do not check the invalid epid (it has a valid sub pointer). */
-       for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) {
-
-               /* Do not check the invalid epid (it has a valid sub pointer). */
-               if ((epid == DUMMY_EPID) || (epid == INVALID_EPID))
-                       continue;
-
-               /* Disable interrupts to block the isoc out descriptor interrupt handler
-                  from being called while the isoc EPID list is being checked.
-               */
-               save_flags(flags);
-               cli();
-
-               if (TxIsocEPList[epid].sub == 0) {
-                       /* Nothing here to see. */
-                       restore_flags(flags);
-                       continue;
-               }
-
-               /* Get the first urb (if any). */
-               urb = urb_list_first(epid);
-               if (urb == 0) {
-                       warn("Ignoring NULL urb");
-                       restore_flags(flags);
-                       continue;
-               }
-               if (usb_pipein(urb->pipe)) {
-
-                       /* Sanity check. */
-                       assert(usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS);
-
-                       urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-                       assert(urb_priv);
-
-                       if (urb_priv->urb_state == NOT_STARTED) {
-
-                               /* If ASAP is not set and urb->start_frame is the current frame,
-                                  start the transfer. */
-                               if (!(urb->transfer_flags & URB_ISO_ASAP) &&
-                                   (urb->start_frame == (*R_USB_FM_NUMBER & 0x7ff))) {
-
-                                       dbg_isoc("Enabling isoc IN EP descr for epid %d", epid);
-                                       TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-
-                                       /* This urb is now active. */
-                                       urb_priv->urb_state = STARTED;
-                                       continue;
-                               }
-                       }
-               }
-               restore_flags(flags);
-       }
-
-       DBFEXIT;
-
-}
-
-void etrax_usb_hc_bulk_eot_interrupt(int timer_induced)
-{
-       int epid;
-
-       /* The technique is to run one urb at a time, wait for the eot interrupt at which
-          point the EP descriptor has been disabled. */
-
-       DBFENTER;
-       dbg_bulk("bulk eot%s", timer_induced ? ", called by timer" : "");
-
-       for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
-
-               if (!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) &&
-                   (TxBulkEPList[epid].sub != 0)) {
-
-                       struct urb *urb;
-                       etrax_urb_priv_t *urb_priv;
-                       unsigned long flags;
-                       __u32 r_usb_ept_data;
-
-                       /* Found a disabled EP descriptor which has a non-null sub pointer.
-                          Verify that this ctrl EP descriptor got disabled no errors.
-                          FIXME: Necessary to check error_code? */
-                       dbg_bulk("for epid %d?", epid);
-
-                       /* Get the first urb. */
-                       urb = urb_list_first(epid);
-
-                       /* FIXME: Could this happen for valid reasons? Why did it disappear? Because of
-                          wrong unlinking? */
-                       if (!urb) {
-                               warn("NULL urb for epid %d", epid);
-                               continue;
-                       }
-
-                       assert(urb);
-                       urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
-                       assert(urb_priv);
-
-                       /* Sanity checks. */
-                       assert(usb_pipetype(urb->pipe) == PIPE_BULK);
-                       if (phys_to_virt(TxBulkEPList[epid].sub) != urb_priv->last_sb) {
-                               err("bulk endpoint got disabled before reaching last sb");
-                       }
-
-                       /* For bulk IN traffic, there seems to be a race condition between
-                          between the bulk eot and eop interrupts, or rather an uncertainty regarding
-                          the order in which they happen. Normally we expect the eop interrupt from
-                          DMA channel 9 to happen before the eot interrupt.
-
-                          Therefore, we complete the bulk IN urb in the rx interrupt handler instead. */
-
-                       if (usb_pipein(urb->pipe)) {
-                               dbg_bulk("in urb, continuing");
-                               continue;
-                       }
-
-                       save_flags(flags);
-                       cli();
-                       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-                       nop();
-                       r_usb_ept_data = *R_USB_EPT_DATA;
-                       restore_flags(flags);
-
-                       if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) ==
-                           IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-                               /* This means that the endpoint has no error, is disabled
-                                  and had inserted traffic, i.e. transfer successfully completed. */
-                               etrax_usb_complete_bulk_urb(urb, 0);
-                       } else {
-                               /* Shouldn't happen. We expect errors to be caught by epid attention. */
-                               err("Found disabled bulk EP desc, error_code != no_error");
-                       }
-               }
-       }
-
-       /* Normally, we should find (at least) one disabled EP descriptor with a valid sub pointer.
-          However, because of the uncertainty in the deliverance of the eop/eot interrupts, we may
-          not.  Also, we might find two disabled EPs when handling an eot interrupt, and then find
-          none the next time. */
-
-       DBFEXIT;
-
-}
-
-void etrax_usb_hc_epid_attn_interrupt(usb_interrupt_registers_t *reg)
-{
-       /* This function handles the epid attention interrupt.  There are a variety of reasons
-          for this interrupt to happen (Designer's Reference, p. 8 - 22 for the details):
-
-          invalid ep_id  - Invalid epid in an EP (EP disabled).
-          stall          - Not strictly an error condition (EP disabled).
-          3rd error      - Three successive transaction errors  (EP disabled).
-          buffer ourun   - Buffer overrun or underrun (EP disabled).
-          past eof1      - Intr or isoc transaction proceeds past EOF1.
-          near eof       - Intr or isoc transaction would not fit inside the frame.
-          zout transfer  - If zout transfer for a bulk endpoint (EP disabled).
-          setup transfer - If setup transfer for a non-ctrl endpoint (EP disabled). */
-
-       int epid;
-
-
-       DBFENTER;
-
-       assert(reg != NULL);
-
-       /* Note that we loop through all epids. We still want to catch errors for
-          the invalid one, even though we might handle them differently. */
-       for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
-
-               if (test_bit(epid, (void *)&reg->r_usb_epid_attn)) {
-
-                       struct urb *urb;
-                       __u32 r_usb_ept_data;
-                       unsigned long flags;
-                       int error_code;
-
-                       save_flags(flags);
-                       cli();
-                       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-                       nop();
-                       /* Note that although there are separate R_USB_EPT_DATA and R_USB_EPT_DATA_ISO
-                          registers, they are located at the same address and are of the same size.
-                          In other words, this read should be ok for isoc also. */
-                       r_usb_ept_data = *R_USB_EPT_DATA;
-                       restore_flags(flags);
-
-                       /* First some sanity checks. */
-                       if (epid == INVALID_EPID) {
-                               /* FIXME: What if it became disabled? Could seriously hurt interrupt
-                                  traffic. (Use do_intr_recover.) */
-                               warn("Got epid_attn for INVALID_EPID (%d).", epid);
-                               err("R_USB_EPT_DATA = 0x%x", r_usb_ept_data);
-                               err("R_USB_STATUS = 0x%x", reg->r_usb_status);
-                               continue;
-                       } else  if (epid == DUMMY_EPID) {
-                               /* We definitely don't care about these ones. Besides, they are
-                                  always disabled, so any possible disabling caused by the
-                                  epid attention interrupt is irrelevant. */
-                               warn("Got epid_attn for DUMMY_EPID (%d).", epid);
-                               continue;
-                       }
-
-                       /* Get the first urb in the urb list for this epid. We blatantly assume
-                          that only the first urb could have caused the epid attention.
-                          (For bulk and ctrl, only one urb is active at any one time. For intr
-                          and isoc we remove them once they are completed.) */
-                       urb = urb_list_first(epid);
-
-                       if (urb == NULL) {
-                               err("Got epid_attn for epid %i with no urb.", epid);
-                               err("R_USB_EPT_DATA = 0x%x", r_usb_ept_data);
-                               err("R_USB_STATUS = 0x%x", reg->r_usb_status);
-                               continue;
-                       }
-
-                       switch (usb_pipetype(urb->pipe)) {
-                       case PIPE_BULK:
-                               warn("Got epid attn for bulk endpoint, epid %d", epid);
-                               break;
-                       case PIPE_CONTROL:
-                               warn("Got epid attn for control endpoint, epid %d", epid);
-                               break;
-                       case PIPE_INTERRUPT:
-                               warn("Got epid attn for interrupt endpoint, epid %d", epid);
-                               break;
-                       case PIPE_ISOCHRONOUS:
-                               warn("Got epid attn for isochronous endpoint, epid %d", epid);
-                               break;
-                       }
-
-                       if (usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) {
-                               if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) {
-                                       warn("Hold was set for epid %d.", epid);
-                                       continue;
-                               }
-                       }
-
-                       /* Even though error_code occupies bits 22 - 23 in both R_USB_EPT_DATA and
-                          R_USB_EPT_DATA_ISOC, we separate them here so we don't forget in other places. */
-                       if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-                               error_code = IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code, r_usb_ept_data);
-                       } else {
-                               error_code = IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data);
-                       }
-
-                       /* Using IO_STATE_VALUE on R_USB_EPT_DATA should be ok for isoc also. */
-                       if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-
-                               /* Isoc traffic doesn't have error_count_in/error_count_out. */
-                               if ((usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) &&
-                                   (IO_EXTRACT(R_USB_EPT_DATA, error_count_in, r_usb_ept_data) == 3 ||
-                                    IO_EXTRACT(R_USB_EPT_DATA, error_count_out, r_usb_ept_data) == 3)) {
-                                       /* 3rd error. */
-                                       warn("3rd error for epid %i", epid);
-                                       etrax_usb_complete_urb(urb, -EPROTO);
-
-                               } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
-
-                                       warn("Perror for epid %d", epid);
-
-                                       if (!(r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, valid))) {
-                                               /* invalid ep_id */
-                                               panic("Perror because of invalid epid."
-                                                     " Deconfigured too early?");
-                                       } else {
-                                               /* past eof1, near eof, zout transfer, setup transfer */
-
-                                               /* Dump the urb and the relevant EP descriptor list. */
-
-                                               __dump_urb(urb);
-                                               __dump_ept_data(epid);
-                                               __dump_ep_list(usb_pipetype(urb->pipe));
-
-                                               panic("Something wrong with DMA descriptor contents."
-                                                     " Too much traffic inserted?");
-                                       }
-                               } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
-                                       /* buffer ourun */
-                                       panic("Buffer overrun/underrun for epid %d. DMA too busy?", epid);
-                               }
-
-                       } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, stall)) {
-                               /* Not really a protocol error, just says that the endpoint gave
-                                  a stall response. Note that error_code cannot be stall for isoc. */
-                               if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-                                       panic("Isoc traffic cannot stall");
-                               }
-
-                               warn("Stall for epid %d", epid);
-                               etrax_usb_complete_urb(urb, -EPIPE);
-
-                       } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, bus_error)) {
-                               /* Two devices responded to a transaction request. Must be resolved
-                                  by software. FIXME: Reset ports? */
-                               panic("Bus error for epid %d."
-                                     " Two devices responded to transaction request",
-                                     epid);
-
-                       } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, buffer_error)) {
-                               /* DMA overrun or underrun. */
-                               warn("Buffer overrun/underrun for epid %d. DMA too busy?", epid);
-
-                               /* It seems that error_code = buffer_error in
-                                  R_USB_EPT_DATA/R_USB_EPT_DATA_ISO and ourun = yes in R_USB_STATUS
-                                  are the same error. */
-                               etrax_usb_complete_urb(urb, -EPROTO);
-                       }
-               }
-       }
-
-       DBFEXIT;
-
-}
-
-void etrax_usb_bulk_start_timer_func(unsigned long dummy)
-{
-
-       /* We might enable an EP descriptor behind the current DMA position when it's about
-          to decide that there are no more bulk traffic and it should stop the bulk channel.
-          Therefore we periodically check if the bulk channel is stopped and there is an
-          enabled bulk EP descriptor, in which case we start the bulk channel. */
-       dbg_bulk("bulk_start_timer timed out.");
-
-       if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) {
-               int epid;
-
-               dbg_bulk("Bulk DMA channel not running.");
-
-               for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
-                       if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-                               dbg_bulk("Found enabled EP for epid %d, starting bulk channel.\n",
-                                        epid);
-                               *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
-
-                               /* Restart the bulk eot timer since we just started the bulk channel. */
-                               mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL);
-
-                               /* No need to search any further. */
-                               break;
-                       }
-               }
-       } else {
-               dbg_bulk("Bulk DMA channel running.");
-       }
-}
-
-void etrax_usb_hc_port_status_interrupt(usb_interrupt_registers_t *reg)
-{
-       etrax_hc_t *hc = reg->hc;
-       __u16 r_usb_rh_port_status_1 = reg->r_usb_rh_port_status_1;
-       __u16 r_usb_rh_port_status_2 = reg->r_usb_rh_port_status_2;
-
-       DBFENTER;
-
-       /* The Etrax RH does not include a wPortChange register, so this has to be handled in software
-          (by saving the old port status value for comparison when the port status interrupt happens).
-          See section 11.16.2.6.2 in the USB 1.1 spec for details. */
-
-       dbg_rh("hc->rh.prev_wPortStatus_1 = 0x%x", hc->rh.prev_wPortStatus_1);
-       dbg_rh("hc->rh.prev_wPortStatus_2 = 0x%x", hc->rh.prev_wPortStatus_2);
-       dbg_rh("r_usb_rh_port_status_1 = 0x%x", r_usb_rh_port_status_1);
-       dbg_rh("r_usb_rh_port_status_2 = 0x%x", r_usb_rh_port_status_2);
-
-       /* C_PORT_CONNECTION is set on any transition. */
-       hc->rh.wPortChange_1 |=
-               ((r_usb_rh_port_status_1 & (1 << RH_PORT_CONNECTION)) !=
-                (hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_CONNECTION))) ?
-               (1 << RH_PORT_CONNECTION) : 0;
-
-       hc->rh.wPortChange_2 |=
-               ((r_usb_rh_port_status_2 & (1 << RH_PORT_CONNECTION)) !=
-                (hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_CONNECTION))) ?
-               (1 << RH_PORT_CONNECTION) : 0;
-
-       /* C_PORT_ENABLE is _only_ set on a one to zero transition, i.e. when
-          the port is disabled, not when it's enabled. */
-       hc->rh.wPortChange_1 |=
-               ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_ENABLE))
-                && !(r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ?
-               (1 << RH_PORT_ENABLE) : 0;
-
-       hc->rh.wPortChange_2 |=
-               ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_ENABLE))
-                && !(r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ?
-               (1 << RH_PORT_ENABLE) : 0;
-
-       /* C_PORT_SUSPEND is set to one when the device has transitioned out
-          of the suspended state, i.e. when suspend goes from one to zero. */
-       hc->rh.wPortChange_1 |=
-               ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_SUSPEND))
-                && !(r_usb_rh_port_status_1 & (1 << RH_PORT_SUSPEND))) ?
-               (1 << RH_PORT_SUSPEND) : 0;
-
-       hc->rh.wPortChange_2 |=
-               ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_SUSPEND))
-                && !(r_usb_rh_port_status_2 & (1 << RH_PORT_SUSPEND))) ?
-               (1 << RH_PORT_SUSPEND) : 0;
-
-
-       /* C_PORT_RESET is set when reset processing on this port is complete. */
-       hc->rh.wPortChange_1 |=
-               ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_RESET))
-                && !(r_usb_rh_port_status_1 & (1 << RH_PORT_RESET))) ?
-               (1 << RH_PORT_RESET) : 0;
-
-       hc->rh.wPortChange_2 |=
-               ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_RESET))
-                && !(r_usb_rh_port_status_2 & (1 << RH_PORT_RESET))) ?
-               (1 << RH_PORT_RESET) : 0;
-
-       /* Save the new values for next port status change. */
-       hc->rh.prev_wPortStatus_1 = r_usb_rh_port_status_1;
-       hc->rh.prev_wPortStatus_2 = r_usb_rh_port_status_2;
-
-       dbg_rh("hc->rh.wPortChange_1 set to 0x%x", hc->rh.wPortChange_1);
-       dbg_rh("hc->rh.wPortChange_2 set to 0x%x", hc->rh.wPortChange_2);
-
-       DBFEXIT;
-
-}
-
-void etrax_usb_hc_ctl_status_interrupt(usb_interrupt_registers_t *reg)
-{
-       DBFENTER;
-
-       /* FIXME: What should we do if we get ourun or perror? Dump the EP and SB
-          list for the corresponding epid? */
-       if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
-               panic("USB controller got ourun.");
-       }
-       if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
-
-               /* Before, etrax_usb_do_intr_recover was called on this epid if it was
-                  an interrupt pipe. I don't see how re-enabling all EP descriptors
-                  will help if there was a programming error. */
-               panic("USB controller got perror.");
-       }
-
-       if (reg->r_usb_status & IO_MASK(R_USB_STATUS, device_mode)) {
-               /* We should never operate in device mode. */
-               panic("USB controller in device mode.");
-       }
-
-       /* These if-statements could probably be nested. */
-       if (reg->r_usb_status & IO_MASK(R_USB_STATUS, host_mode)) {
-               info("USB controller in host mode.");
-       }
-       if (reg->r_usb_status & IO_MASK(R_USB_STATUS, started)) {
-               info("USB controller started.");
-       }
-       if (reg->r_usb_status & IO_MASK(R_USB_STATUS, running)) {
-               info("USB controller running.");
-       }
-
-       DBFEXIT;
-
-}
-
-
-static int etrax_rh_submit_urb(struct urb *urb)
-{
-       struct usb_device *usb_dev = urb->dev;
-       etrax_hc_t *hc = usb_dev->bus->hcpriv;
-       unsigned int pipe = urb->pipe;
-       struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet;
-       void *data = urb->transfer_buffer;
-       int leni = urb->transfer_buffer_length;
-       int len = 0;
-       int stat = 0;
-
-       __u16 bmRType_bReq;
-       __u16 wValue;
-       __u16 wIndex;
-       __u16 wLength;
-
-       DBFENTER;
-
-       /* FIXME: What is this interrupt urb that is sent to the root hub? */
-       if (usb_pipetype (pipe) == PIPE_INTERRUPT) {
-               dbg_rh("Root-Hub submit IRQ: every %d ms", urb->interval);
-               hc->rh.urb = urb;
-               hc->rh.send = 1;
-               /* FIXME: We could probably remove this line since it's done
-                  in etrax_rh_init_int_timer. (Don't remove it from
-                  etrax_rh_init_int_timer though.) */
-               hc->rh.interval = urb->interval;
-               etrax_rh_init_int_timer(urb);
-               DBFEXIT;
-
-               return 0;
-       }
-
-       bmRType_bReq = cmd->bRequestType | (cmd->bRequest << 8);
-       wValue = le16_to_cpu(cmd->wValue);
-       wIndex = le16_to_cpu(cmd->wIndex);
-       wLength = le16_to_cpu(cmd->wLength);
-
-       dbg_rh("bmRType_bReq : 0x%04x (%d)", bmRType_bReq, bmRType_bReq);
-       dbg_rh("wValue       : 0x%04x (%d)", wValue, wValue);
-       dbg_rh("wIndex       : 0x%04x (%d)", wIndex, wIndex);
-       dbg_rh("wLength      : 0x%04x (%d)", wLength, 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 = cpu_to_le16 (1);
-               OK (2);
-
-       case RH_GET_STATUS | RH_INTERFACE:
-               *(__u16 *) data = cpu_to_le16 (0);
-               OK (2);
-
-       case RH_GET_STATUS | RH_ENDPOINT:
-               *(__u16 *) data = cpu_to_le16 (0);
-               OK (2);
-
-       case RH_GET_STATUS | RH_CLASS:
-               *(__u32 *) data = cpu_to_le32 (0);
-               OK (4);         /* hub power ** */
-
-       case RH_GET_STATUS | RH_OTHER | RH_CLASS:
-               if (wIndex == 1) {
-                       *((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_1);
-                       *((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_1);
-               } else if (wIndex == 2) {
-                       *((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_2);
-                       *((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_2);
-               } else {
-                       dbg_rh("RH_GET_STATUS whith invalid wIndex!");
-                       OK(0);
-               }
-
-               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_OVER_CURRENT):
-                       OK (0); /* hub power over current ** */
-               }
-               break;
-
-       case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
-               switch (wValue) {
-               case (RH_PORT_ENABLE):
-                       if (wIndex == 1) {
-
-                               dbg_rh("trying to do disable port 1");
-
-                               *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, yes);
-
-                               while (hc->rh.prev_wPortStatus_1 &
-                                      IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes));
-                               *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no);
-                               dbg_rh("Port 1 is disabled");
-
-                       } else if (wIndex == 2) {
-
-                               dbg_rh("trying to do disable port 2");
-
-                               *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, yes);
-
-                               while (hc->rh.prev_wPortStatus_2 &
-                                      IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, yes));
-                               *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no);
-                               dbg_rh("Port 2 is disabled");
-
-                       } else {
-                               dbg_rh("RH_CLEAR_FEATURE->RH_PORT_ENABLE "
-                                      "with invalid wIndex == %d!", wIndex);
-                       }
-
-                       OK (0);
-               case (RH_PORT_SUSPEND):
-                       /* Opposite to suspend should be resume, so we'll do a resume. */
-                       /* FIXME: USB 1.1, 11.16.2.2 says:
-                          "Clearing the PORT_SUSPEND feature causes a host-initiated resume
-                          on the specified port. If the port is not in the Suspended state,
-                          the hub should treat this request as a functional no-operation."
-                          Shouldn't we check if the port is in a suspended state before
-                          resuming? */
-
-                       /* Make sure the controller isn't busy. */
-                       while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-
-                       if (wIndex == 1) {
-                               *R_USB_COMMAND =
-                                       IO_STATE(R_USB_COMMAND, port_sel, port1) |
-                                       IO_STATE(R_USB_COMMAND, port_cmd, resume) |
-                                       IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
-                       } else if (wIndex == 2) {
-                               *R_USB_COMMAND =
-                                       IO_STATE(R_USB_COMMAND, port_sel, port2) |
-                                       IO_STATE(R_USB_COMMAND, port_cmd, resume) |
-                                       IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
-                       } else {
-                               dbg_rh("RH_CLEAR_FEATURE->RH_PORT_SUSPEND "
-                                      "with invalid wIndex == %d!", wIndex);
-                       }
-
-                       OK (0);
-               case (RH_PORT_POWER):
-                       OK (0); /* port power ** */
-               case (RH_C_PORT_CONNECTION):
-                       if (wIndex == 1) {
-                               hc->rh.wPortChange_1 &= ~(1 << RH_PORT_CONNECTION);
-                       } else if (wIndex == 2) {
-                               hc->rh.wPortChange_2 &= ~(1 << RH_PORT_CONNECTION);
-                       } else {
-                               dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_CONNECTION "
-                                      "with invalid wIndex == %d!", wIndex);
-                       }
-
-                       OK (0);
-               case (RH_C_PORT_ENABLE):
-                       if (wIndex == 1) {
-                               hc->rh.wPortChange_1 &= ~(1 << RH_PORT_ENABLE);
-                       } else if (wIndex == 2) {
-                               hc->rh.wPortChange_2 &= ~(1 << RH_PORT_ENABLE);
-                       } else {
-                               dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_ENABLE "
-                                      "with invalid wIndex == %d!", wIndex);
-                       }
-                       OK (0);
-               case (RH_C_PORT_SUSPEND):
-/*** WR_RH_PORTSTAT(RH_PS_PSSC); */
-                       OK (0);
-               case (RH_C_PORT_OVER_CURRENT):
-                       OK (0); /* port power over current ** */
-               case (RH_C_PORT_RESET):
-                       if (wIndex == 1) {
-                               hc->rh.wPortChange_1 &= ~(1 << RH_PORT_RESET);
-                       } else if (wIndex == 2) {
-                               hc->rh.wPortChange_2 &= ~(1 << RH_PORT_RESET);
-                       } else {
-                               dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_RESET "
-                                      "with invalid index == %d!", wIndex);
-                       }
-
-                       OK (0);
-
-               }
-               break;
-
-       case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
-               switch (wValue) {
-               case (RH_PORT_SUSPEND):
-
-                       /* Make sure the controller isn't busy. */
-                       while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-
-                       if (wIndex == 1) {
-                               *R_USB_COMMAND =
-                                       IO_STATE(R_USB_COMMAND, port_sel, port1) |
-                                       IO_STATE(R_USB_COMMAND, port_cmd, suspend) |
-                                       IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
-                       } else if (wIndex == 2) {
-                               *R_USB_COMMAND =
-                                       IO_STATE(R_USB_COMMAND, port_sel, port2) |
-                                       IO_STATE(R_USB_COMMAND, port_cmd, suspend) |
-                                       IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
-                       } else {
-                               dbg_rh("RH_SET_FEATURE->RH_PORT_SUSPEND "
-                                      "with invalid wIndex == %d!", wIndex);
-                       }
-
-                       OK (0);
-               case (RH_PORT_RESET):
-                       if (wIndex == 1) {
-
-                       port_1_reset:
-                               dbg_rh("Doing reset of port 1");
-
-                               /* Make sure the controller isn't busy. */
-                               while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-
-                               *R_USB_COMMAND =
-                                       IO_STATE(R_USB_COMMAND, port_sel, port1) |
-                                       IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-                                       IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
-
-                               /* We must wait at least 10 ms for the device to recover.
-                                  15 ms should be enough. */
-                               udelay(15000);
-
-                               /* Wait for reset bit to go low (should be done by now). */
-                               while (hc->rh.prev_wPortStatus_1 &
-                                      IO_STATE(R_USB_RH_PORT_STATUS_1, reset, yes));
-
-                               /* If the port status is
-                                  1) connected and enabled then there is a device and everything is fine
-                                  2) neither connected nor enabled then there is no device, also fine
-                                  3) connected and not enabled then we try again
-                                  (Yes, there are other port status combinations besides these.) */
-
-                               if ((hc->rh.prev_wPortStatus_1 &
-                                    IO_STATE(R_USB_RH_PORT_STATUS_1, connected, yes)) &&
-                                   (hc->rh.prev_wPortStatus_1 &
-                                    IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no))) {
-                                       dbg_rh("Connected device on port 1, but port not enabled?"
-                                              " Trying reset again.");
-                                       goto port_2_reset;
-                               }
-
-                               /* Diagnostic printouts. */
-                               if ((hc->rh.prev_wPortStatus_1 &
-                                    IO_STATE(R_USB_RH_PORT_STATUS_1, connected, no)) &&
-                                   (hc->rh.prev_wPortStatus_1 &
-                                    IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no))) {
-                                       dbg_rh("No connected device on port 1");
-                               } else if ((hc->rh.prev_wPortStatus_1 &
-                                           IO_STATE(R_USB_RH_PORT_STATUS_1, connected, yes)) &&
-                                          (hc->rh.prev_wPortStatus_1 &
-                                           IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes))) {
-                                       dbg_rh("Connected device on port 1, port 1 enabled");
-                               }
-
-                       } else if (wIndex == 2) {
-
-                       port_2_reset:
-                               dbg_rh("Doing reset of port 2");
-
-                               /* Make sure the controller isn't busy. */
-                               while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-
-                               /* Issue the reset command. */
-                               *R_USB_COMMAND =
-                                       IO_STATE(R_USB_COMMAND, port_sel, port2) |
-                                       IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-                                       IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
-
-                               /* We must wait at least 10 ms for the device to recover.
-                                  15 ms should be enough. */
-                               udelay(15000);
-
-                               /* Wait for reset bit to go low (should be done by now). */
-                               while (hc->rh.prev_wPortStatus_2 &
-                                      IO_STATE(R_USB_RH_PORT_STATUS_2, reset, yes));
-
-                               /* If the port status is
-                                  1) connected and enabled then there is a device and everything is fine
-                                  2) neither connected nor enabled then there is no device, also fine
-                                  3) connected and not enabled then we try again
-                                  (Yes, there are other port status combinations besides these.) */
-
-                               if ((hc->rh.prev_wPortStatus_2 &
-                                    IO_STATE(R_USB_RH_PORT_STATUS_2, connected, yes)) &&
-                                   (hc->rh.prev_wPortStatus_2 &
-                                    IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no))) {
-                                       dbg_rh("Connected device on port 2, but port not enabled?"
-                                              " Trying reset again.");
-                                       goto port_2_reset;
-                               }
-
-                               /* Diagnostic printouts. */
-                               if ((hc->rh.prev_wPortStatus_2 &
-                                    IO_STATE(R_USB_RH_PORT_STATUS_2, connected, no)) &&
-                                   (hc->rh.prev_wPortStatus_2 &
-                                    IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no))) {
-                                       dbg_rh("No connected device on port 2");
-                               } else if ((hc->rh.prev_wPortStatus_2 &
-                                           IO_STATE(R_USB_RH_PORT_STATUS_2, connected, yes)) &&
-                                          (hc->rh.prev_wPortStatus_2 &
-                                           IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, yes))) {
-                                       dbg_rh("Connected device on port 2, port 2 enabled");
-                               }
-
-                       } else {
-                               dbg_rh("RH_SET_FEATURE->RH_PORT_RESET with invalid wIndex = %d", wIndex);
-                       }
-
-                       /* Make sure the controller isn't busy. */
-                       while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-
-                       /* If all enabled ports were disabled the host controller goes down into
-                          started mode, so we need to bring it back into the running state.
-                          (This is safe even if it's already in the running state.) */
-                       *R_USB_COMMAND =
-                               IO_STATE(R_USB_COMMAND, port_sel, nop) |
-                               IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-                               IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
-
-                       dbg_rh("...Done");
-                       OK(0);
-
-               case (RH_PORT_POWER):
-                       OK (0); /* port power ** */
-               case (RH_PORT_ENABLE):
-                       /* There is no port enable command in the host controller, so if the
-                          port is already enabled, we do nothing. If not, we reset the port
-                          (with an ugly goto). */
-
-                       if (wIndex == 1) {
-                               if (hc->rh.prev_wPortStatus_1 &
-                                   IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no)) {
-                                       goto port_1_reset;
-                               }
-                       } else if (wIndex == 2) {
-                               if (hc->rh.prev_wPortStatus_2 &
-                                   IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no)) {
-                                       goto port_2_reset;
-                               }
-                       } else {
-                               dbg_rh("RH_SET_FEATURE->RH_GET_STATUS with invalid wIndex = %d", wIndex);
-                       }
-                       OK (0);
-               }
-               break;
-
-       case RH_SET_ADDRESS:
-               hc->rh.devnum = wValue;
-               dbg_rh("RH address set to: %d", hc->rh.devnum);
-               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));
-                       memcpy (data, root_hub_dev_des, len);
-                       OK (len);
-               case (0x02):    /* configuration descriptor */
-                       len = min_t(unsigned int, leni, min_t(unsigned int, sizeof (root_hub_config_des), wLength));
-                       memcpy (data, root_hub_config_des, len);
-                       OK (len);
-               case (0x03):    /* string descriptors */
-                       len = usb_root_hub_string (wValue & 0xff,
-                                                  0xff, "ETRAX 100LX",
-                                                  data, wLength);
-                       if (len > 0) {
-                               OK(min(leni, len));
-                       } else {
-                               stat = -EPIPE;
-                       }
-
-               }
-               break;
-
-       case RH_GET_DESCRIPTOR | RH_CLASS:
-               root_hub_hub_des[2] = hc->rh.numports;
-               len = min_t(unsigned int, leni, min_t(unsigned int, sizeof (root_hub_hub_des), wLength));
-               memcpy (data, root_hub_hub_des, len);
-               OK (len);
-
-       case RH_GET_CONFIGURATION:
-               *(__u8 *) data = 0x01;
-               OK (1);
-
-       case RH_SET_CONFIGURATION:
-               OK (0);
-
-       default:
-               stat = -EPIPE;
-       }
-
-       urb->actual_length = len;
-       urb->status = stat;
-       urb->dev = NULL;
-       if (urb->complete) {
-               urb->complete(urb, NULL);
-       }
-       DBFEXIT;
-
-       return 0;
-}
-
-static void
-etrax_usb_bulk_eot_timer_func(unsigned long dummy)
-{
-       /* Because of a race condition in the top half, we might miss a bulk eot.
-          This timer "simulates" a bulk eot if we don't get one for a while, hopefully
-          correcting the situation. */
-       dbg_bulk("bulk_eot_timer timed out.");
-       etrax_usb_hc_bulk_eot_interrupt(1);
-}
-
-static void*
-etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size,
-       unsigned mem_flags, dma_addr_t *dma)
-{
-  return kmalloc(size, mem_flags);
-}
-
-static void
-etrax_usb_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma)
-{
-  kfree(addr);
-}
-
-
-static struct device fake_device;
-
-static int __init etrax_usb_hc_init(void)
-{
-       static etrax_hc_t *hc;
-       struct usb_bus *bus;
-       struct usb_device *usb_rh;
-       int i;
-
-       DBFENTER;
-
-       info("ETRAX 100LX USB-HCD %s (c) 2001-2003 Axis Communications AB\n", usb_hcd_version);
-
-       hc = kmalloc(sizeof(etrax_hc_t), GFP_KERNEL);
-       assert(hc != NULL);
-
-       /* We use kmem_cache_* to make sure that all DMA desc. are dword aligned */
-       /* Note that we specify sizeof(USB_EP_Desc_t) as the size, but also allocate
-          SB descriptors from this cache. This is ok since sizeof(USB_EP_Desc_t) ==
-          sizeof(USB_SB_Desc_t). */
-
-       usb_desc_cache = kmem_cache_create("usb_desc_cache", sizeof(USB_EP_Desc_t), 0,
-                                          SLAB_HWCACHE_ALIGN, 0, 0);
-       assert(usb_desc_cache != NULL);
-
-       top_half_reg_cache = kmem_cache_create("top_half_reg_cache",
-                                              sizeof(usb_interrupt_registers_t),
-                                              0, SLAB_HWCACHE_ALIGN, 0, 0);
-       assert(top_half_reg_cache != NULL);
-
-       isoc_compl_cache = kmem_cache_create("isoc_compl_cache",
-                                               sizeof(usb_isoc_complete_data_t),
-                                               0, SLAB_HWCACHE_ALIGN, 0, 0);
-       assert(isoc_compl_cache != NULL);
-
-       etrax_usb_bus = bus = usb_alloc_bus(&etrax_usb_device_operations);
-       hc->bus = bus;
-       bus->bus_name="ETRAX 100LX";
-       bus->hcpriv = hc;
-
-       /* Initialize RH to the default address.
-          And make sure that we have no status change indication */
-       hc->rh.numports = 2;  /* The RH has two ports */
-       hc->rh.devnum = 1;
-       hc->rh.wPortChange_1 = 0;
-       hc->rh.wPortChange_2 = 0;
-
-       /* Also initate the previous values to zero */
-       hc->rh.prev_wPortStatus_1 = 0;
-       hc->rh.prev_wPortStatus_2 = 0;
-
-       /* Initialize the intr-traffic flags */
-       /* FIXME: This isn't used. (Besides, the error field isn't initialized.) */
-       hc->intr.sleeping = 0;
-       hc->intr.wq = NULL;
-
-       epid_usage_bitmask = 0;
-       epid_out_traffic = 0;
-
-       /* Mark the invalid epid as being used. */
-       set_bit(INVALID_EPID, (void *)&epid_usage_bitmask);
-       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, INVALID_EPID);
-       nop();
-       /* The valid bit should still be set ('invalid' is in our world; not the hardware's). */
-       *R_USB_EPT_DATA = (IO_STATE(R_USB_EPT_DATA, valid, yes) |
-                          IO_FIELD(R_USB_EPT_DATA, max_len, 1));
-
-       /* Mark the dummy epid as being used. */
-       set_bit(DUMMY_EPID, (void *)&epid_usage_bitmask);
-       *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, DUMMY_EPID);
-       nop();
-       *R_USB_EPT_DATA = (IO_STATE(R_USB_EPT_DATA, valid, no) |
-                          IO_FIELD(R_USB_EPT_DATA, max_len, 1));
-
-       /* Initialize the urb list by initiating a head for each list. */
-       for (i = 0; i < NBR_OF_EPIDS; i++) {
-               INIT_LIST_HEAD(&urb_list[i]);
-       }
-       spin_lock_init(&urb_list_lock);
-
-       INIT_LIST_HEAD(&urb_unlink_list);
-
-
-       /* Initiate the bulk start timer. */
-       init_timer(&bulk_start_timer);
-       bulk_start_timer.expires = jiffies + BULK_START_TIMER_INTERVAL;
-       bulk_start_timer.function = etrax_usb_bulk_start_timer_func;
-       add_timer(&bulk_start_timer);
-
-
-       /* Initiate the bulk eot timer. */
-       init_timer(&bulk_eot_timer);
-       bulk_eot_timer.expires = jiffies + BULK_EOT_TIMER_INTERVAL;
-       bulk_eot_timer.function = etrax_usb_bulk_eot_timer_func;
-       add_timer(&bulk_eot_timer);
-
-       /* Set up the data structures for USB traffic. Note that this must be done before
-          any interrupt that relies on sane DMA list occurrs. */
-       init_rx_buffers();
-       init_tx_bulk_ep();
-       init_tx_ctrl_ep();
-       init_tx_intr_ep();
-       init_tx_isoc_ep();
-
-        device_initialize(&fake_device);
-        kobject_set_name(&fake_device.kobj, "etrax_usb");
-        kobject_add(&fake_device.kobj);
-       kobject_uevent(&fake_device.kobj, KOBJ_ADD);
-        hc->bus->controller = &fake_device;
-       usb_register_bus(hc->bus);
-
-       *R_IRQ_MASK2_SET =
-               /* Note that these interrupts are not used. */
-               IO_STATE(R_IRQ_MASK2_SET, dma8_sub0_descr, set) |
-               /* Sub channel 1 (ctrl) descr. interrupts are used. */
-               IO_STATE(R_IRQ_MASK2_SET, dma8_sub1_descr, set) |
-               IO_STATE(R_IRQ_MASK2_SET, dma8_sub2_descr, set) |
-               /* Sub channel 3 (isoc) descr. interrupts are used. */
-               IO_STATE(R_IRQ_MASK2_SET, dma8_sub3_descr, set);
-
-       /* Note that the dma9_descr interrupt is not used. */
-       *R_IRQ_MASK2_SET =
-               IO_STATE(R_IRQ_MASK2_SET, dma9_eop, set) |
-               IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
-
-       /* FIXME: Enable iso_eof only when isoc traffic is running. */
-       *R_USB_IRQ_MASK_SET =
-               IO_STATE(R_USB_IRQ_MASK_SET, iso_eof, set) |
-               IO_STATE(R_USB_IRQ_MASK_SET, bulk_eot, set) |
-               IO_STATE(R_USB_IRQ_MASK_SET, epid_attn, set) |
-               IO_STATE(R_USB_IRQ_MASK_SET, port_status, set) |
-               IO_STATE(R_USB_IRQ_MASK_SET, ctl_status, set);
-
-
-       if (request_irq(ETRAX_USB_HC_IRQ, etrax_usb_hc_interrupt_top_half, 0,
-                       "ETRAX 100LX built-in USB (HC)", hc)) {
-               err("Could not allocate IRQ %d for USB", ETRAX_USB_HC_IRQ);
-               etrax_usb_hc_cleanup();
-               DBFEXIT;
-               return -1;
-       }
-
-       if (request_irq(ETRAX_USB_RX_IRQ, etrax_usb_rx_interrupt, 0,
-                       "ETRAX 100LX built-in USB (Rx)", hc)) {
-               err("Could not allocate IRQ %d for USB", ETRAX_USB_RX_IRQ);
-               etrax_usb_hc_cleanup();
-               DBFEXIT;
-               return -1;
-       }
-
-       if (request_irq(ETRAX_USB_TX_IRQ, etrax_usb_tx_interrupt, 0,
-                       "ETRAX 100LX built-in USB (Tx)", hc)) {
-               err("Could not allocate IRQ %d for USB", ETRAX_USB_TX_IRQ);
-               etrax_usb_hc_cleanup();
-               DBFEXIT;
-               return -1;
-       }
-
-       /* R_USB_COMMAND:
-          USB commands in host mode. The fields in this register should all be
-          written to in one write. Do not read-modify-write one field at a time. A
-          write to this register will trigger events in the USB controller and an
-          incomplete command may lead to unpredictable results, and in worst case
-          even to a deadlock in the controller.
-          (Note however that the busy field is read-only, so no need to write to it.) */
-
-       /* Check the busy bit before writing to R_USB_COMMAND. */
-
-       while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-
-       /* Reset the USB interface. */
-       *R_USB_COMMAND =
-               IO_STATE(R_USB_COMMAND, port_sel, nop) |
-               IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-               IO_STATE(R_USB_COMMAND, ctrl_cmd, reset);
-
-       /* Designer's Reference, p. 8 - 10 says we should Initate R_USB_FM_PSTART to 0x2A30 (10800),
-          to guarantee that control traffic gets 10% of the bandwidth, and periodic transfer may
-          allocate the rest (90%). This doesn't work though. Read on for a lenghty explanation.
-
-          While there is a difference between rev. 2 and rev. 3 of the ETRAX 100LX regarding the NAK
-          behaviour, it doesn't solve this problem. What happens is that a control transfer will not
-          be interrupted in its data stage when PSTART happens (the point at which periodic traffic
-          is started). Thus, if PSTART is set to 10800 and its IN or OUT token is NAKed until just before
-          PSTART happens, it will continue the IN/OUT transfer as long as it's ACKed. After it's done,
-          there may be too little time left for an isochronous transfer, causing an epid attention
-          interrupt due to perror. The work-around for this is to let the control transfers run at the
-          end of the frame instead of at the beginning, and will be interrupted just fine if it doesn't
-          fit into the frame. However, since there will *always* be a control transfer at the beginning
-          of the frame, regardless of what we set PSTART to, that transfer might be a 64-byte transfer
-          which consumes up to 15% of the frame, leaving only 85% for periodic traffic. The solution to
-          this would be to 'dummy allocate' 5% of the frame with the usb_claim_bandwidth function to make
-          sure that the periodic transfers that are inserted will always fit in the frame.
-
-          The idea was suggested that a control transfer could be split up into several 8 byte transfers,
-          so that it would be interrupted by PSTART, but since this can't be done for an IN transfer this
-          hasn't been implemented.
-
-          The value 11960 is chosen to be just after the SOF token, with a couple of bit times extra
-          for possible bit stuffing. */
-
-       *R_USB_FM_PSTART = IO_FIELD(R_USB_FM_PSTART, value, 11960);
-
-#ifdef CONFIG_ETRAX_USB_HOST_PORT1
-       *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no);
-#endif
-
-#ifdef CONFIG_ETRAX_USB_HOST_PORT2
-       *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no);
-#endif
-
-       while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-
-       /* Configure the USB interface as a host controller. */
-       *R_USB_COMMAND =
-               IO_STATE(R_USB_COMMAND, port_sel, nop) |
-               IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-               IO_STATE(R_USB_COMMAND, ctrl_cmd, host_config);
-
-       /* Note: Do not reset any ports here. Await the port status interrupts, to have a controlled
-          sequence of resetting the ports. If we reset both ports now, and there are devices
-          on both ports, we will get a bus error because both devices will answer the set address
-          request. */
-
-       while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-
-       /* Start processing of USB traffic. */
-       *R_USB_COMMAND =
-               IO_STATE(R_USB_COMMAND, port_sel, nop) |
-               IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-               IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
-
-       while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-
-       usb_rh = usb_alloc_dev(NULL, hc->bus, 0);
-       hc->bus->root_hub = usb_rh;
-        usb_rh->state = USB_STATE_ADDRESS;
-        usb_rh->speed = USB_SPEED_FULL;
-        usb_rh->devnum = 1;
-        hc->bus->devnum_next = 2;
-        usb_rh->ep0.desc.wMaxPacketSize = __const_cpu_to_le16(64);
-        usb_get_device_descriptor(usb_rh, USB_DT_DEVICE_SIZE);
-       usb_new_device(usb_rh);
-
-       DBFEXIT;
-
-       return 0;
-}
-
-static void etrax_usb_hc_cleanup(void)
-{
-       DBFENTER;
-
-       free_irq(ETRAX_USB_HC_IRQ, NULL);
-       free_irq(ETRAX_USB_RX_IRQ, NULL);
-       free_irq(ETRAX_USB_TX_IRQ, NULL);
-
-       usb_deregister_bus(etrax_usb_bus);
-
-       /* FIXME: call kmem_cache_destroy here? */
-
-       DBFEXIT;
-}
-
-module_init(etrax_usb_hc_init);
-module_exit(etrax_usb_hc_cleanup);
diff --git a/target/linux/etrax/files/drivers/usb/host/hc_crisv10.h b/target/linux/etrax/files/drivers/usb/host/hc_crisv10.h
deleted file mode 100644 (file)
index 62f7711..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-#ifndef __LINUX_ETRAX_USB_H
-#define __LINUX_ETRAX_USB_H
-
-#include <linux/types.h>
-#include <linux/list.h>
-
-typedef struct USB_IN_Desc {
-       volatile __u16 sw_len;
-       volatile __u16 command;
-       volatile unsigned long next;
-       volatile unsigned long buf;
-       volatile __u16 hw_len;
-       volatile __u16 status;
-} USB_IN_Desc_t;
-
-typedef struct USB_SB_Desc {
-       volatile __u16 sw_len;
-       volatile __u16 command;
-       volatile unsigned long next;
-       volatile unsigned long buf;
-       __u32 dummy;
-} USB_SB_Desc_t;
-
-typedef struct USB_EP_Desc {
-       volatile __u16 hw_len;
-       volatile __u16 command;
-       volatile unsigned long sub;
-       volatile unsigned long next;
-       __u32 dummy;
-} USB_EP_Desc_t;
-
-struct virt_root_hub {
-       int devnum;
-       void *urb;
-       void *int_addr;
-       int send;
-       int interval;
-       int numports;
-       struct timer_list rh_int_timer;
-       volatile __u16 wPortChange_1;
-       volatile __u16 wPortChange_2;
-       volatile __u16 prev_wPortStatus_1;
-       volatile __u16 prev_wPortStatus_2;
-};
-
-struct etrax_usb_intr_traffic {
-       int sleeping;
-       int error;
-       struct wait_queue *wq;
-};
-
-typedef struct etrax_usb_hc {
-       struct usb_bus *bus;
-       struct virt_root_hub rh;
-       struct etrax_usb_intr_traffic intr;
-} etrax_hc_t;
-
-typedef enum {
-       STARTED,
-       NOT_STARTED,
-       UNLINK,
-       TRANSFER_DONE,
-       WAITING_FOR_DESCR_INTR
-} etrax_usb_urb_state_t;
-
-
-
-typedef struct etrax_usb_urb_priv {
-       /* The first_sb field is used for freeing all SB descriptors belonging
-          to an urb. The corresponding ep descriptor's sub pointer cannot be
-          used for this since the DMA advances the sub pointer as it processes
-          the sb list. */
-       USB_SB_Desc_t *first_sb;
-       /* The last_sb field referes to the last SB descriptor that belongs to
-          this urb. This is important to know so we can free the SB descriptors
-          that ranges between first_sb and last_sb. */
-       USB_SB_Desc_t *last_sb;
-
-       /* The rx_offset field is used in ctrl and bulk traffic to keep track
-          of the offset in the urb's transfer_buffer where incoming data should be
-          copied to. */
-       __u32 rx_offset;
-
-       /* Counter used in isochronous transfers to keep track of the
-          number of packets received/transmitted.  */
-       __u32 isoc_packet_counter;
-
-       /* This field is used to pass information about the urb's current state between
-          the various interrupt handlers (thus marked volatile). */
-       volatile etrax_usb_urb_state_t urb_state;
-
-       /* Connection between the submitted urb and ETRAX epid number */
-       __u8 epid;
-
-       /* The rx_data_list field is used for periodic traffic, to hold
-          received data for later processing in the the complete_urb functions,
-          where the data us copied to the urb's transfer_buffer. Basically, we
-          use this intermediate storage because we don't know when it's safe to
-          reuse the transfer_buffer (FIXME?). */
-       struct list_head rx_data_list;
-} etrax_urb_priv_t;
-
-/* This struct is for passing data from the top half to the bottom half. */
-typedef struct usb_interrupt_registers
-{
-       etrax_hc_t *hc;
-       __u32 r_usb_epid_attn;
-       __u8 r_usb_status;
-       __u16 r_usb_rh_port_status_1;
-       __u16 r_usb_rh_port_status_2;
-       __u32 r_usb_irq_mask_read;
-       __u32 r_usb_fm_number;
-       struct work_struct usb_bh;
-} usb_interrupt_registers_t;
-
-/* This struct is for passing data from the isoc top half to the isoc bottom half. */
-typedef struct usb_isoc_complete_data
-{
-       struct urb *urb;
-       struct work_struct usb_bh;
-} usb_isoc_complete_data_t;
-
-/* This struct holds data we get from the rx descriptors for DMA channel 9
-   for periodic traffic (intr and isoc). */
-typedef struct rx_data
-{
-       void *data;
-       int length;
-       struct list_head list;
-} rx_data_t;
-
-typedef struct urb_entry
-{
-       struct urb *urb;
-       struct list_head list;
-} urb_entry_t;
-
-/* ---------------------------------------------------------------------------
-   Virtual Root HUB
-   ------------------------------------------------------------------------- */
-/* 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
-
-/* Our Vendor Specific feature */
-#define RH_REMOVE_EP               0x00
-
-
-#define RH_ACK                     0x01
-#define RH_REQ_ERR                 -1
-#define RH_NACK                    0x00
-
-/* Field definitions for */
-
-#define USB_IN_command__eol__BITNR      0 /* command macros */
-#define USB_IN_command__eol__WIDTH      1
-#define USB_IN_command__eol__no         0
-#define USB_IN_command__eol__yes        1
-
-#define USB_IN_command__intr__BITNR     3
-#define USB_IN_command__intr__WIDTH     1
-#define USB_IN_command__intr__no        0
-#define USB_IN_command__intr__yes       1
-
-#define USB_IN_status__eop__BITNR       1 /* status macros. */
-#define USB_IN_status__eop__WIDTH       1
-#define USB_IN_status__eop__no          0
-#define USB_IN_status__eop__yes         1
-
-#define USB_IN_status__eot__BITNR       5
-#define USB_IN_status__eot__WIDTH       1
-#define USB_IN_status__eot__no          0
-#define USB_IN_status__eot__yes         1
-
-#define USB_IN_status__error__BITNR     6
-#define USB_IN_status__error__WIDTH     1
-#define USB_IN_status__error__no        0
-#define USB_IN_status__error__yes       1
-
-#define USB_IN_status__nodata__BITNR    7
-#define USB_IN_status__nodata__WIDTH    1
-#define USB_IN_status__nodata__no       0
-#define USB_IN_status__nodata__yes      1
-
-#define USB_IN_status__epid__BITNR      8
-#define USB_IN_status__epid__WIDTH      5
-
-#define USB_EP_command__eol__BITNR      0
-#define USB_EP_command__eol__WIDTH      1
-#define USB_EP_command__eol__no         0
-#define USB_EP_command__eol__yes        1
-
-#define USB_EP_command__eof__BITNR      1
-#define USB_EP_command__eof__WIDTH      1
-#define USB_EP_command__eof__no         0
-#define USB_EP_command__eof__yes        1
-
-#define USB_EP_command__intr__BITNR     3
-#define USB_EP_command__intr__WIDTH     1
-#define USB_EP_command__intr__no        0
-#define USB_EP_command__intr__yes       1
-
-#define USB_EP_command__enable__BITNR   4
-#define USB_EP_command__enable__WIDTH   1
-#define USB_EP_command__enable__no      0
-#define USB_EP_command__enable__yes     1
-
-#define USB_EP_command__hw_valid__BITNR 5
-#define USB_EP_command__hw_valid__WIDTH 1
-#define USB_EP_command__hw_valid__no    0
-#define USB_EP_command__hw_valid__yes   1
-
-#define USB_EP_command__epid__BITNR     8
-#define USB_EP_command__epid__WIDTH     5
-
-#define USB_SB_command__eol__BITNR      0 /* command macros. */
-#define USB_SB_command__eol__WIDTH      1
-#define USB_SB_command__eol__no         0
-#define USB_SB_command__eol__yes        1
-
-#define USB_SB_command__eot__BITNR      1
-#define USB_SB_command__eot__WIDTH      1
-#define USB_SB_command__eot__no         0
-#define USB_SB_command__eot__yes        1
-
-#define USB_SB_command__intr__BITNR     3
-#define USB_SB_command__intr__WIDTH     1
-#define USB_SB_command__intr__no        0
-#define USB_SB_command__intr__yes       1
-
-#define USB_SB_command__tt__BITNR       4
-#define USB_SB_command__tt__WIDTH       2
-#define USB_SB_command__tt__zout        0
-#define USB_SB_command__tt__in          1
-#define USB_SB_command__tt__out         2
-#define USB_SB_command__tt__setup       3
-
-
-#define USB_SB_command__rem__BITNR      8
-#define USB_SB_command__rem__WIDTH      6
-
-#define USB_SB_command__full__BITNR     6
-#define USB_SB_command__full__WIDTH     1
-#define USB_SB_command__full__no        0
-#define USB_SB_command__full__yes       1
-
-#endif
diff --git a/target/linux/etrax/image/Config.in b/target/linux/etrax/image/Config.in
deleted file mode 100644 (file)
index 4a01de7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-config AXIS_FIMAGE
-       bool "Build fimage"
-       depends TARGET_etrax
-       default y
-
diff --git a/target/linux/etrax/image/Makefile b/target/linux/etrax/image/Makefile
deleted file mode 100644 (file)
index 9f71620..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-# 
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/image.mk
-
-define Image/BuildKernel
-       cp $(KDIR)/vmlinuz $(BIN_DIR)/openwrt-$(BOARD)-zImage
-endef
-
-define Image/Prepare
-       cp $(LINUX_DIR)/arch/cris/boot/zImage $(KDIR)/vmlinuz
-       $(MAKE) -C e100boot compile
-       $(MAKE) -C mkfimage compile
-       $(INSTALL_BIN) ./boot_linux $(BIN_DIR)
-endef
-
-define Image/Build/generic
-       mkfimage $(KDIR)/vmlinuz $(KDIR)/vmlinuz.tmp
-       cat $(KDIR)/vmlinuz.tmp $(KDIR)/root.$(1) > $(KDIR)/fimage.$(1).tmp
-       dd if=$(KDIR)/fimage.$(1).tmp of=$(KDIR)/fimage.$(1) bs=$(2) conv=sync
-       cp $(KDIR)/fimage.$(1) $(BIN_DIR)/openwrt-$(BOARD)-$(1)-fimage
-endef
-
-define Image/Build/jffs2-64k
-       $(call prepare_generic_jffs-64k,$(KDIR)/root.jff2-64k)
-       $(call Image/Build/generic,$(1),4194304)
-endef
-
-define Image/Build/squashfs
-       $(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
-       $(call Image/Build/generic,$(1),4194304)
-endef
-
-define Image/Build
-       $(call Image/Build/$(1),$(1))
-endef
-
-$(eval $(call BuildImage))
diff --git a/target/linux/etrax/image/boot_linux b/target/linux/etrax/image/boot_linux
deleted file mode 100755 (executable)
index e7d5807..0000000
+++ /dev/null
@@ -1,512 +0,0 @@
-#!/usr/bin/perl -w
-
-#*****************************************************************************
-#!
-#! FILE NAME  : boot_linux
-#!
-#! PARAMETERS : -b <bootimage>     the name of the boot image to use
-#!              -d <device>        the interface to use, e.g., eth1
-#!                                 (defaults is eth0)
-#!              -f                 save it in flash memory at address 0x10000
-#!              -F                 save it in flash memory at address 0
-#!              -h                 show some help
-#!              -i <image>         name of the image to use (default is fimage)
-#!              -o <offset>        the offset in the flash where the flashing
-#!                                 starts
-#!              -O <offset>        the offset in the image file where the
-#!                                 flashing starts from
-#!              -p                 print the resulting etrax100boot command
-#!                                 instead of executing it
-#!              -s <size>          how much to flash (default is the size of
-#!                                 the flash minus the offset specified using
-#!                                 -o or -f)
-#!              -S <size>          the size of the flash
-#!
-#!              All sizes and offsets above can be specified as decimal
-#!              numbers, or as hexadecimal numbers by prefixing them with 0x.
-#!              It is also possible to use the suffixes k and M to specify
-#!              kilo (1024) or mega (1048576).
-#!
-#! DESCRIPTION: Extract the start of the image and any registers that should
-#!              be set from the kimage or fimage file, and then boot it.
-#!
-#! FUNCTIONS  : convert_size
-#!              extract_hw_settings
-#!              get_dword
-#!              calculate_sdram_init
-#!              sdram_command
-#!              print_help
-#!
-#!----------------------------------------------------------------------------
-#! HISTORY
-#!
-#! $Log: boot_linux,v $
-#! Revision 1.16  2004/11/01 16:32:27  starvik
-#! Corrected help text to avoid confusion
-#!
-#! Revision 1.15  2003/01/29 11:48:57  pkj
-#! Calculate a flash size large enough for the given image if the
-#! -S option is not specified.
-#!
-#! Revision 1.14  2002/11/18 14:40:09  pkj
-#! Make use of the --loop option to etrax100boot when initialising
-#! SDRAM memories. This requires a lot fewer options to be passed
-#! to the boot loader.
-#!
-#! Revision 1.13  2002/08/15 16:29:02  pkj
-#! * The -S option now accepts the size in bytes (just like the -s option).
-#!   For backwards compatibility it still assumes sizes of 16 and less to
-#!   be specified in MB.
-#! * The suffixes k and M can now be used with all sizes and offsets to
-#!   specify them in kilo or mega.
-#!
-#! Revision 1.12  2002/08/15 15:27:34  pkj
-#! Use $opts{'x'} instead of $opt_x.
-#!
-#! Revision 1.11  2002/07/04 17:06:39  pkj
-#! * No longer specifies a bootfile by default (not needed any longer).
-#! * Implemented option -b to specify a bootfile.
-#! * Removed references to option -l (it was never implemented).
-#!
-#! Revision 1.10  2002/06/04 11:50:23  starvik
-#! Check if mrs_data is specified in kernelconfig (necessary for MCM)
-#!
-#! Revision 1.9  2002/01/29 10:38:26  pkj
-#! Change illegal to invalid.
-#!
-#! Revision 1.8  2001/09/13 12:32:10  pkj
-#! * Added option -S to specify the size of the flash (in MB),  as -s
-#!   is used to specify how much to flash nowadays.
-#! * Made the default size of the flash depend on the size of the image
-#!   file. If it is bigger than 0x200100 then the flash is assumed to
-#!   be 4 MB, otherwise it is assumed to be 2 MB.
-#! * Added verification of various options.
-#!
-#! Revision 1.7  2001/09/13 10:25:11  pkj
-#! Minor clean-up.
-#!
-#! Revision 1.6  2001/06/29 10:05:16  pkj
-#! Corrected check for SDRAM.
-#!
-#! Revision 1.5  2001/06/29 09:11:55  pkj
-#! Synchronised boot_elinux and boot_linux.
-#!
-#!----------------------------------------------------------------------------
-#! (C) Copyright 2001, Axis Communications AB, LUND, SWEDEN
-#!****************************************************************************
-# $Id: boot_linux,v 1.16 2004/11/01 16:32:27 starvik Exp $
-
-#****************** INCLUDE FILES SECTION ************************************
-
-use strict;
-
-use Getopt::Std;
-use File::Basename;
-
-#****************** VARIABLE DECLARATION SECTION *****************************
-
-use vars qw($my_name %opts);
-use vars qw($text_start $cmd);
-use vars qw($image_name $image_size);
-use vars qw($offset $source_offset $flash_size $flashing_size);
-use vars qw($sdram_timing_address $sdram_config_address);
-use vars qw($sdram_precharge $sdram_nop $sdram_refresh $sdram_mrs);
-
-#****************** CONSTANT SECTION *****************************************
-
-# Register addresses
-$sdram_timing_address = "b0000008";
-$sdram_config_address = "b000000c";
-
-# SDRAM commands
-$sdram_precharge = 3;
-$sdram_nop = 0;
-$sdram_refresh = 2;
-$sdram_mrs = 1;
-
-#****************** MAIN PROGRAM SECTION *************************************
-
-# The name of this program.
-$my_name = basename($0);
-
-# Get options
-getopts('b:d:fFhi:o:O:ps:S:', \%opts);
-
-&print_help if ($opts{'h'});
-
-# Name and existance of the image
-$image_name = ($opts{'i'} ? $opts{'i'} : 'fimage');
-die "Could not find the image $image_name!\n" unless (-s $image_name);
-
-if ($opts{'f'} || $opts{'F'})
-{
-  $image_size = -s $image_name;
-
-  $offset = ($opts{'f'} ? 0x10000 : 0);
-
-  $offset = &convert_size($opts{'o'}) if (defined($opts{'o'}));
-
-  die("$my_name: Invalid destination offset\n") if ($offset !~ /^\d+$/);
-
-  my $base_name = basename($image_name);
-  if ($base_name eq 'timage' || $base_name eq 'flash1.img')
-  {
-    $source_offset = 0;
-  }
-  else
-  {
-    $source_offset = $offset;
-  }
-
-  $source_offset = &convert_size($opts{'O'}) if (defined($opts{'O'}));
-
-  die("$my_name: Invalid source offset\n") if ($source_offset !~ /^\d+$/);
-  die("$my_name: Source offset > image size\n") if ($source_offset > $image_size);
-
-  if (defined($opts{'S'}))
-  {
-    # Backwards compatibility to allow specifying the flash size in MB
-    # without using an M suffix
-    $opts{'S'} .= 'M' if ($opts{'S'} =~ /^\d+$/ && $opts{'S'} <= 16);
-
-    $flash_size = &convert_size($opts{'S'});
-  }
-  else
-  {
-    # Calculate a flash size large enough for the image without the checksum
-    # and HWID.
-    $flash_size = ($image_size - $source_offset + $offset) & 0xFFFF0000;
-  }
-
-  die("$my_name: Invalid flash size\n") if ($flash_size !~ /^\d+$/);
-  die("$my_name: Destination offset > flash size\n") if ($offset > $flash_size);
-  if (defined($opts{'s'}))
-  {
-    $flashing_size = &convert_size($opts{'s'});
-  }
-  else
-  {
-    $flashing_size = $flash_size - $offset;
-  }
-
-  die("$my_name: Invalid size to flash\n") if ($flashing_size !~ /^\d+$/);
-
-  if ($flashing_size > $flash_size - $offset)
-  {
-    $flashing_size = $flash_size - $offset;
-    printf("Warning: Flashing size limited to 0x%lx due to the offset (0x%lx) and flash size (0x%lx).\n", $flashing_size, $offset, $flash_size);
-  }
-
-  if ($flashing_size > $image_size - $source_offset)
-  {
-    $flashing_size = $image_size - $source_offset;
-    printf("Warning: Flashing size limited to 0x%lx due to the offset (0x%lx) and image size (0x%lx).\n", $flashing_size, $source_offset, $image_size);
-  }
-}
-
-# Create the command line to boot the image
-if (system('./etrax100boot --help > /dev/null') == 0)
-{
-  $cmd = './etrax100boot';
-}
-elsif (system('svinto_boot --help > /dev/null') == 0)
-{
-  $cmd = 'svinto_boot';
-}
-else
-{
-  die("Cannot find e100boot program in your PATH!\n");
-}
-
-$cmd .= " --device $opts{'d'}" if ($opts{'d'});
-
-$cmd .= &extract_hw_settings;
-
-$cmd .= " --bootfile $opts{'b'}" if ($opts{'b'});
-$cmd .= " --file $image_name $text_start";
-
-if ($opts{'f'} || $opts{'F'})
-{
-  $cmd .= sprintf(" --flash %lx %lx %lx --jump 0",
-                 hex($text_start) + $source_offset, $offset, $flashing_size);
-}
-else
-{
-  $cmd .= " --jump $text_start";
-}
-
-if ($opts{'p'})
-{
-  print "Command:\n$cmd\n";
-}
-else
-{
-  system($cmd);
-}
-
-exit 0;
-
-#****************** FUNCTION DEFINITION SECTION ******************************
-
-#*****************************************************************************
-##
-## FUNCTION NAME: convert_size
-##
-##****************************************************************************
-
-sub convert_size
-{
-  my($arg) = @_;
-  my $size;
-
-  if ($arg =~ /^0x([\da-fA-F]+)([kM])?$/)
-  {
-    $size = hex($1);
-  }
-  elsif ($arg =~ /^(\d+)([kM])?$/)
-  {
-    $size = $1;
-  }
-  else
-  {
-    return -1;
-  }
-
-  if (!defined($2))
-  {
-    return $size;
-  }
-  elsif ($2 eq 'k')
-  {
-    return $size * 1024;
-  }
-  elsif ($2 eq 'M')
-  {
-    return $size * 1048576;
-  }
-}
-
-#*****************************************************************************
-##
-## FUNCTION NAME: extract_hw_settings
-##
-##****************************************************************************
-
-sub extract_hw_settings
-{
-  my $data;
-  my $dbg_port;
-  my $sdram_enabled;
-  my $return_value = "";
-  my $sdram_config;
-
-  # The hw information table has the following format
-  #
-  # "HW_PARAM_MAGIC"
-  # text_start (dword)
-  # serial debg port (dword)
-  # sdram enabled (dword)
-  # register address (dword)
-  # register value (dword)
-  # ...
-  # 0
-
-  open(FILE, "$image_name") || die("Could not open '$image_name'");
-
-  while (<FILE>)
-  {
-    if (m/HW_PARAM_MAGIC/g)
-    {
-      # Seek to first byte after magic
-      seek(FILE, -length($_) + pos($_), 1);
-      last;
-    }
-  }
-
-  $text_start = &get_dword;
-  $dbg_port = &get_dword;
-  $sdram_enabled = int(&get_dword);
-
-  while (1)
-  {
-    my $register = &get_dword;
-    my $value = &get_dword;
-
-    last if ($register eq "00000000");
-
-    if ($sdram_enabled)
-    {
-      if ($register eq $sdram_config_address)
-      {
-       $sdram_config = $value;
-      }
-      elsif ($register eq $sdram_timing_address)
-      {
-       $return_value .= &calculate_sdram_init($value, $sdram_config);
-       next;
-      }
-    }
-
-    $return_value .= " --setreg $register $value";
-  }
-
-  close(FILE);
-
-  return $return_value;
-}
-
-#*****************************************************************************
-##
-## FUNCTION NAME: get_dword
-##
-##****************************************************************************
-
-sub get_dword
-{
-  my $data;
-
-  read(FILE, $data, 4);
-  return unpack("H8", pack("V", unpack("N", $data)));
-}
-
-#*****************************************************************************
-##
-## FUNCTION NAME: calculate_sdram_init
-##
-##****************************************************************************
-
-sub calculate_sdram_init
-{
-  # Refer to ETRAX 100LX Designers Reference for a description of SDRAM
-  # initialization
-  my $sdram_init_val = hex($_[0]);
-  my $sdram_config_val = hex($_[1]);
-  my $bus_width = $sdram_config_val & 0x00800000;
-  my $speed;
-  my $cas_latency;
-  my $mrs_data;
-  my $temp;
-  my $return_value;
-  my $value;
-
-  $mrs_data = ($sdram_init_val & 0x00ff0000) >> 16;
-  $sdram_init_val &= 0x8000ffff; # Make sure mrs data is 0
-  $sdram_init_val |= 0x80000000; # Make sure sdram is enabled
-  $speed = $sdram_init_val & 0x1000;
-  $cas_latency = $sdram_init_val & 0x3;
-  if ($speed) # 100 MHz
-  {
-    $cas_latency += 2;
-  }
-  else # 50 MHz
-  {
-    $cas_latency += 1;
-  }
-
-  # Calculate value of mrs_data
-  # CAS latency = 2 && bus_width = 32 => 0x40
-  # CAS latency = 3 && bus_width = 32 => 0x60
-  # CAS latency = 2 && bus_width = 16 => 0x20
-  # CAS latency = 3 && bus_width = 16 => 0x30
-  if ($mrs_data == 0)
-  {
-    if ($bus_width == 0) # 16 bits
-    {
-      $mrs_data = $cas_latency == 2 ? 0x20 : 0x30;
-    }
-    else # 32 bits
-    {
-      $mrs_data = $cas_latency == 2 ? 0x40 : 0x60;
-    }
-  }
-
-  $temp = $sdram_init_val | 0x0000c000; # Disable refresh
-  $return_value .= &sdram_command($temp);
-  $return_value .= " --pause 20000";
-
-  $return_value .= &sdram_command($temp, $sdram_precharge);
-  $return_value .= &sdram_command($temp, $sdram_nop);
-
-  $return_value .= " --setreg +0 7";
-  $return_value .= " --label label1";
-  $return_value .= &sdram_command($temp, $sdram_refresh);
-  $return_value .= &sdram_command($temp, $sdram_nop);
-  $return_value .= " --loop +0 label1";
-
-  $return_value .= &sdram_command($temp, $sdram_mrs, $mrs_data);
-  $return_value .= &sdram_command($temp, $sdram_nop);
-
-  $return_value .= &sdram_command($sdram_init_val);
-
-  return $return_value;
-}
-
-#*****************************************************************************
-##
-## FUNCTION NAME: sdram_command
-##
-##****************************************************************************
-
-sub sdram_command
-{
-  my($temp, $value, $mrs_data) = @_;
-
-  $value ||= 0;
-  if ($value == $sdram_mrs)
-  {
-    $value = sprintf("%lx", $temp | ($value << 9) | ($mrs_data << 16));
-  }
-  else
-  {
-    $value = sprintf("%lx", $temp | ($value << 9));
-  }
-
-  return " --setreg $sdram_timing_address $value";
-}
-
-#*****************************************************************************
-##
-## FUNCTION NAME: print_help
-##
-##****************************************************************************
-
-sub print_help
-{
-  print "\nAXIS $my_name, ", '$Revision: 1.16 $ $Date: 2004/11/01 16:32:27 $ ', "\n";
-  die <<EOT;
-Copyright (C) 2001-2002 Axis Communications AB
-
-DESCRIPTION:
-  This program is used to boot (and flash) a linux image to a box.
-  It tries to extract the required ETRAX 100 settings from the image file.
-
-SYNTAX:
-  $my_name [options]
-
-OPTIONS:
-  -b <bootfile>           : The boot image to use.
-  -d <device>             : The network interface to use, default is eth0.
-  -f                      : Save the image in the flash memory starting at
-                            address 0x10000.
-  -F                      : Save the image in the flash memory starting at
-                            address 0.
-  -h                      : Print this help text.
-  -i <image>              : The path and name of the image to use, default
-                            is fimage.
-  -o <offset>             : The offset in the flash where the flashing starts.
-  -O <offset>             : The offset in the image file where the flashing
-                            starts from.
-  -p                      : Print the resulting etrax100boot command instead
-                            of executing it.
-  -s <size>               : How much to flash (default is the size of the
-                           flash minus the offset specified using -o or -f).
-  -S <size>               : The size of the flash.
-
-  All sizes and offsets above can be specified as decimal numbers, or as
-  hexadecimal numbers by prefixing them with 0x. It is also possible to use
-  the suffixes k and M to specify kilo (1024) or mega (1048576).
-
-EOT
-}
-
-#****************** END OF FILE boot_linux ***********************************
diff --git a/target/linux/etrax/image/e100boot/Makefile b/target/linux/etrax/image/e100boot/Makefile
deleted file mode 100644 (file)
index ebc9ef3..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-# $Id$
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=e100boot
-PKG_VERSION:=0.1
-PKG_RELEASE:=1
-
-PKG_SOURCE:=e100boot.tar.bz2
-PKG_SOURCE_URL:=http://www.acmesystems.it/download/owrt
-PKG_MD5SUM:=
-
-PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
-
-CRLF_WORKAROUND=1
-
-include $(INCLUDE_DIR)/package.mk
-
-define Build/Compile
-       make -C $(PKG_BUILD_DIR) STRIP=true 
-endef
-
-define Build/InstallDev
-       $(INSTALL_BIN) $(PKG_BUILD_DIR)/sbl/e100boot $(BIN_DIR)/etrax100boot
-endef
-
-$(eval $(call Build/DefaultTargets))
diff --git a/target/linux/etrax/image/mkfimage/Makefile b/target/linux/etrax/image/mkfimage/Makefile
deleted file mode 100644 (file)
index f97d098..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-# $Id$
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=mkfimage
-PKG_VERSION:=0.1
-PKG_RELEASE:=1
-
-PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
-
-include $(INCLUDE_DIR)/package.mk
-
-define Build/Compile
-       mkdir -p $(PKG_BUILD_DIR)
-       cp -r ./src/* $(PKG_BUILD_DIR)
-       make -C $(PKG_BUILD_DIR)
-endef
-
-define Build/InstallDev
-       $(INSTALL_BIN) $(PKG_BUILD_DIR)/mkfimage $(STAGING_DIR_HOST)/bin/mkfimage
-endef
-
-$(eval $(call Build/DefaultTargets))
diff --git a/target/linux/etrax/image/mkfimage/src/Makefile b/target/linux/etrax/image/mkfimage/src/Makefile
deleted file mode 100644 (file)
index 3e0b79c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-
-all: mkfimage 
-       gcc mkfimage.c -o mkfimage
-
diff --git a/target/linux/etrax/image/mkfimage/src/mkfimage.c b/target/linux/etrax/image/mkfimage/src/mkfimage.c
deleted file mode 100644 (file)
index 6904170..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-
-int main(int argc, char **argv){
-       unsigned char *buffer = malloc(64 * 1024);
-       struct stat s;
-       unsigned int size_vmlinux = 0, real_size_vmlinux = 0;
-       const unsigned char *magic_str = "ACME_PART_MAGIC";
-       unsigned int loop;
-       unsigned char *magic;
-
-       if(argc != 3){
-               printf("%s in out\n", argv[0]);
-               return 1;
-       }
-
-       printf("Generating image\n");
-
-       FILE *vmlinux = fopen(argv[1], "r");
-       FILE *vmlinux_out = fopen(argv[2], "w");
-       if((!vmlinux) || (!vmlinux_out)){
-               printf("Error opening a file\n");
-               return 1;
-       }
-
-       stat(argv[1], &s);
-       size_vmlinux = s.st_size;
-       real_size_vmlinux = (size_vmlinux & 0xffff0000) + 0x10000;
-
-       printf("vmlinux = 0x%.08X / 0x%.08X\n", size_vmlinux, real_size_vmlinux);
-
-       unsigned int t = fread(buffer, 1, 64 * 1024, vmlinux);
-       for(loop = 0; loop < (64 * 1024) - sizeof(magic_str); loop++){
-               if(buffer[loop] == magic_str[0]){
-                       if((magic = strstr(&buffer[loop], magic_str))){
-                               printf("Magic at 0x%.08X %p %p\n", magic - buffer, magic, buffer);
-                               printf("Found Magic %X%X%X%X\n",
-                                       buffer[loop + strlen(magic_str)],
-                                       buffer[loop + strlen(magic_str) + 2],
-                                       buffer[loop + strlen(magic_str) + 1],
-                                       buffer[loop + strlen(magic_str) + 3]);
-
-                               buffer[loop + strlen(magic_str)] = real_size_vmlinux >> 24;
-                               buffer[loop + strlen(magic_str) + 2] = (real_size_vmlinux >> 16) & 0xff;
-                               buffer[loop + strlen(magic_str) + 1] = (real_size_vmlinux >> 8) & 0xff;
-                               buffer[loop + strlen(magic_str) + 3] = (real_size_vmlinux) & 0xff;
-
-                               printf("Replaced with %.02X%.02X%.02X%.02X\n",
-                                       buffer[loop + strlen(magic_str)],
-                                       buffer[loop + strlen(magic_str) + 2],
-                                       buffer[loop + strlen(magic_str) + 1],
-                                       buffer[loop + strlen(magic_str) + 3]);
-
-                       }
-               }
-       }
-
-       fwrite(buffer, 1, 64 * 1024, vmlinux_out);
-       real_size_vmlinux -= 64 * 1024;
-       do {
-               real_size_vmlinux -= 64 * 1024;
-               memset(buffer, 0, 64 * 1024);
-               fread(buffer, 1, 64 * 1024, vmlinux);
-               fwrite(buffer, 1, 64 * 1024, vmlinux_out);
-       } while (real_size_vmlinux);
-
-       return 0;
-}
diff --git a/target/linux/etrax/patches/100-compile_fixes.patch b/target/linux/etrax/patches/100-compile_fixes.patch
deleted file mode 100644 (file)
index ea6d08e..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
---- a/arch/cris/Makefile
-+++ b/arch/cris/Makefile
-@@ -33,7 +33,7 @@
- LD = $(CROSS_COMPILE)ld -mcrislinux
--OBJCOPYFLAGS := -O binary -R .note -R .comment -S
-+OBJCOPYFLAGS := -O binary -R .bss -R .note -R .note.gnu.build-id -R .comment -S
- CPPFLAGS_vmlinux.lds = -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE)
---- a/arch/cris/arch-v10/boot/Makefile
-+++ b/arch/cris/arch-v10/boot/Makefile
-@@ -2,9 +2,6 @@
- # arch/cris/arch-v10/boot/Makefile
- #
--OBJCOPY = objcopy-cris
--OBJCOPYFLAGS = -O binary --remove-section=.bss
--
- subdir- := compressed rescue
- targets := Image
-@@ -14,7 +11,6 @@
- $(obj)/compressed/vmlinux: $(obj)/Image FORCE
-       $(Q)$(MAKE) $(build)=$(obj)/compressed $@
--      $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
- $(obj)/zImage:  $(obj)/compressed/vmlinux
-       @cp $< $@
---- a/arch/cris/arch-v10/boot/compressed/Makefile
-+++ b/arch/cris/arch-v10/boot/compressed/Makefile
-@@ -2,13 +2,9 @@
- # arch/cris/arch-v10/boot/compressed/Makefile
- #
--CC = gcc-cris -melf $(LINUXINCLUDE)
- ccflags-y += -O2
--LD = ld-cris
- ldflags-y += -T $(obj)/decompress.ld
- OBJECTS = $(obj)/head.o $(obj)/misc.o
--OBJCOPY = objcopy-cris
--OBJCOPYFLAGS = -O binary --remove-section=.bss
- quiet_cmd_image = BUILD   $@
- cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
-@@ -22,10 +18,10 @@
-       $(call if_changed,objcopy)
- $(obj)/head.o: $(obj)/head.S .config
--      @$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
-+      @$(CC) -Iinclude  -D__ASSEMBLY__ -traditional -Wa,--em=criself -c $< -o $@
- $(obj)/misc.o: $(obj)/misc.c .config
--      @$(CC) -D__KERNEL__ -c $< -o $@
-+      @$(CC) -Iinclude -D__KERNEL__ -Wa,--em=criself -c $< -o $@
- $(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
-       $(call if_changed,image)
---- a/arch/cris/arch-v10/boot/compressed/decompress.ld
-+++ b/arch/cris/arch-v10/boot/compressed/decompress.ld
-@@ -1,4 +1,4 @@
--OUTPUT_FORMAT(elf32-us-cris)
-+OUTPUT_FORMAT(elf32-cris)
- MEMORY 
-       {
---- a/arch/cris/arch-v10/boot/compressed/head.S
-+++ b/arch/cris/arch-v10/boot/compressed/head.S
-@@ -10,13 +10,14 @@
- #define ASSEMBLER_MACROS_ONLY
- #include <asm/arch/sv_addr_ag.h>
-+#include <linux/autoconf.h>
- #define RAM_INIT_MAGIC 0x56902387
- #define COMMAND_LINE_MAGIC 0x87109563
-       ;; Exported symbols
-       
--      .globl  _input_data
-+      .globl  input_data
-       
-       .text
-@@ -26,7 +27,7 @@
- ;; We need to initialze DRAM registers before we start using the DRAM
-       
--      cmp.d   RAM_INIT_MAGIC, r8      ; Already initialized?
-+      cmp.d   RAM_INIT_MAGIC, $r8     ; Already initialized?
-       beq     dram_init_finished
-       nop
-       
-@@ -36,91 +37,91 @@
-               
-       ;; Initiate the PA and PB ports
--      move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
--      move.b   r0, [R_PORT_PA_DATA]
-+      move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
-+      move.b   $r0, [R_PORT_PA_DATA]
--      move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
--      move.b   r0, [R_PORT_PA_DIR]
-+      move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
-+      move.b   $r0, [R_PORT_PA_DIR]
--      move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
--      move.b   r0, [R_PORT_PB_DATA]
-+      move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
-+      move.b   $r0, [R_PORT_PB_DATA]
--      move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
--      move.b   r0, [R_PORT_PB_DIR]
-+      move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
-+      move.b   $r0, [R_PORT_PB_DIR]
-       ;; Setup the stack to a suitably high address.
-       ;; We assume 8 MB is the minimum DRAM in an eLinux
-       ;; product and put the sp at the top for now.
--      move.d  0x40800000, sp
-+      move.d  0x40800000, $sp
-       ;; Figure out where the compressed piggyback image is
-       ;; in the flash (since we wont try to copy it to DRAM
-       ;; before unpacking). It is at _edata, but in flash.
-       ;; Use (_edata - basse) as offset to the current PC.
-       
--basse:        move.d  pc, r5
--      and.d   0x7fffffff, r5  ; strip any non-cache bit
--      subq    2, r5           ; compensate for the move.d pc instr
--      move.d  r5, r0          ; save for later - flash address of 'basse'
--      add.d   _edata, r5
--      sub.d   basse, r5       ; r5 = flash address of '_edata'
-+basse:        move.d  $pc, $r5
-+      and.d   0x7fffffff, $r5 ; strip any non-cache bit
-+      subq    2, $r5          ; compensate for the move.d pc instr
-+      move.d  $r5, $r0                ; save for later - flash address of 'basse'
-+      add.d   _edata, $r5
-+      sub.d   basse, $r5      ; r5 = flash address of '_edata'
-       
-       ;; Copy text+data to DRAM
-       
--      move.d  basse, r1       ; destination
--      move.d  _edata, r2      ; end destination
--1:    move.w  [r0+], r3
--      move.w  r3, [r1+]
--      cmp.d   r2, r1
-+      move.d  basse, $r1      ; destination
-+      move.d  _edata, $r2     ; end destination
-+1:    move.w  [$r0+], $r3
-+      move.w  $r3, [$r1+]
-+      cmp.d   $r2, $r1
-       bcs     1b
-       nop
--      move.d  r5, [_input_data] ; for the decompressor
-+      move.d  $r5, [input_data] ; for the decompressor
-       ;; Clear the decompressors BSS (between _edata and _end)
-       
--      moveq   0, r0
--      move.d  _edata, r1
--      move.d  _end, r2
--1:    move.w  r0, [r1+]
--      cmp.d   r2, r1
-+      moveq   0, $r0
-+      move.d  _edata, $r1
-+      move.d  _end, $r2
-+1:    move.w  $r0, [$r1+]
-+      cmp.d   $r2, $r1
-       bcs     1b
-       nop
-       ;;  Save command line magic and address.
--      move.d  _cmd_line_magic, $r12
-+      move.d  cmd_line_magic, $r12
-       move.d  $r10, [$r12]
--      move.d  _cmd_line_addr, $r12
-+      move.d  cmd_line_addr, $r12
-       move.d  $r11, [$r12]
-       
-       ;; Do the decompression and save compressed size in _inptr
--      jsr     _decompress_kernel
-+      jsr     decompress_kernel
-       
-       ;; Put start address of root partition in r9 so the kernel can use it
-       ;; when mounting from flash
--      move.d  [_input_data], r9       ; flash address of compressed kernel
--      add.d   [_inptr], r9            ; size of compressed kernel
-+      move.d  [input_data], $r9       ; flash address of compressed kernel
-+      add.d   [inptr], $r9            ; size of compressed kernel
-       ;; Restore command line magic and address.
--      move.d  _cmd_line_magic, $r10
-+      move.d  cmd_line_magic, $r10
-       move.d  [$r10], $r10
--      move.d  _cmd_line_addr, $r11
-+      move.d  cmd_line_addr, $r11
-       move.d  [$r11], $r11
-       ;; Enter the decompressed kernel
--      move.d  RAM_INIT_MAGIC, r8      ; Tell kernel that DRAM is initialized
-+      move.d  RAM_INIT_MAGIC, $r8     ; Tell kernel that DRAM is initialized
-       jump    0x40004000      ; kernel is linked to this address
-       
-       .data
--_input_data:
-+input_data:
-       .dword  0               ; used by the decompressor
--_cmd_line_magic:
-+cmd_line_magic:
-       .dword 0
--_cmd_line_addr:
-+cmd_line_addr:
-       .dword 0
- #include "../../lib/hw_settings.S"
---- a/arch/cris/arch-v10/boot/compressed/misc.c
-+++ b/arch/cris/arch-v10/boot/compressed/misc.c
-@@ -5,7 +5,7 @@
-  * adapted for Linux.
-  *
-  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
-- * puts by Nick Holloway 1993, better puts by Martin Mares 1995
-+ * putstr by Nick Holloway 1993, better putstr by Martin Mares 1995
-  * adaptation for Linux/CRIS Axis Communications AB, 1999
-  *
-  */
-@@ -99,12 +99,12 @@
- static void gzip_mark(void **);
- static void gzip_release(void **);
-  
--static void puts(const char *);
-+static void putstr(const char *);
- /* the "heap" is put directly after the BSS ends, at end */
-   
--extern int end;
--static long free_mem_ptr = (long)&end;
-+extern int _end;
-+static long free_mem_ptr = (long)&_end;
-  
- #include "../../../../../lib/inflate.c"
-@@ -139,7 +139,7 @@
- /* decompressor info and error messages to serial console */
- static void
--puts(const char *s)
-+putstr(const char *s)
- {
- #ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
-       while(*s) {
-@@ -209,9 +209,9 @@
- static void
- error(char *x)
- {
--      puts("\n\n");
--      puts(x);
--      puts("\n\n -- System halted\n");
-+      putstr("\n\n");
-+      putstr(x);
-+      putstr("\n\n -- System halted\n");
-       while(1);       /* Halt */
- }
-@@ -257,14 +257,7 @@
-       makecrc();
--      __asm__ volatile ("move vr,%0" : "=rm" (revision));
--      if (revision < 10)
--      {
--              puts("You need an ETRAX 100LX to run linux 2.6\n");
--              while(1);
--      }
--
--      puts("Uncompressing Linux...\n");
-+      putstr("Uncompressing Linux...\n");
-       gunzip();
--      puts("Done. Now booting the kernel.\n");
-+      putstr("Done. Now booting the kernel.\n");
- }
---- a/arch/cris/arch-v10/mm/init.c
-+++ b/arch/cris/arch-v10/mm/init.c
-@@ -184,6 +184,9 @@
-       free_area_init_node(0, &contig_page_data, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0);
- }
-+void free_initrd_mem(unsigned long start, unsigned long end)
-+{
-+}
- /* Initialize remaps of some I/O-ports. It is important that this
-  * is called before any driver is initialized.
diff --git a/target/linux/etrax/patches/101-cris-eth-driver.patch b/target/linux/etrax/patches/101-cris-eth-driver.patch
deleted file mode 100644 (file)
index f73b379..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/drivers/net/cris/eth_v10.c
-+++ b/drivers/net/cris/eth_v10.c
-@@ -1707,7 +1707,7 @@
- static void
- e100_netpoll(struct net_device* netdev)
- {
--      e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL);
-+      e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev);
- }
- #endif
diff --git a/target/linux/etrax/patches/102-missing_arch_include.patch b/target/linux/etrax/patches/102-missing_arch_include.patch
deleted file mode 100644 (file)
index 8955712..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/include/asm-cris/Kbuild
-+++ b/include/asm-cris/Kbuild
-@@ -1,7 +1,6 @@
- include include/asm-generic/Kbuild.asm
--header-$(CONFIG_ETRAX_ARCH_V10) += arch-v10/
--header-$(CONFIG_ETRAX_ARCH_V32) += arch-v32/
-+header-y += arch-v10/ arch-v32/
- header-y += ethernet.h
- header-y += rtc.h
diff --git a/target/linux/etrax/patches/200-samsung_flash.patch b/target/linux/etrax/patches/200-samsung_flash.patch
deleted file mode 100644 (file)
index ac4ac67..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -297,8 +297,8 @@
-                       return NULL;
-               }
--              if (extp->MajorVersion != '1' ||
--                  (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
-+              if (extp->MajorVersion < '0' || extp->MajorVersion > '3' ||
-+                      (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
-                       if (cfi->mfr == MANUFACTURER_SAMSUNG &&
-                           (extp->MajorVersion == '3' && extp->MinorVersion == '3')) {
-                           printk(KERN_NOTICE "  Newer Samsung flash detected, "
diff --git a/target/linux/etrax/patches/201-flashsize.patch b/target/linux/etrax/patches/201-flashsize.patch
deleted file mode 100644 (file)
index 859bb46..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
---- a/arch/cris/arch-v10/lib/hw_settings.S
-+++ b/arch/cris/arch-v10/lib/hw_settings.S
-@@ -60,3 +60,5 @@
-       .dword R_PORT_PB_SET
-       .dword PB_SET_VALUE
-       .dword 0 ; No more register values
-+      .ascii "ACME_PART_MAGIC" 
-+      .dword 0xdeadc0de
---- a/arch/cris/arch-v10/drivers/axisflashmap.c
-+++ b/arch/cris/arch-v10/drivers/axisflashmap.c
-@@ -113,7 +113,7 @@
- /* If no partition-table was found, we use this default-set. */
- #define MAX_PARTITIONS         7
--#define NUM_DEFAULT_PARTITIONS 3
-+#define NUM_DEFAULT_PARTITIONS 2
- /*
-  * Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
-@@ -122,19 +122,14 @@
-  */
- static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
-       {
--              .name = "boot firmware",
--              .size = CONFIG_ETRAX_PTABLE_SECTOR,
--              .offset = 0
--      },
--      {
-               .name = "kernel",
--              .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
--              .offset = CONFIG_ETRAX_PTABLE_SECTOR
-+              .size = 0x00,
-+              .offset = 0
-       },
-       {
--              .name = "filesystem",
--              .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR,
--              .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
-+              .name = "rootfs",
-+              .size = 0x200000 ,
-+              .offset = 0x200000
-       }
- };
-@@ -281,6 +276,11 @@
-       struct partitiontable_entry *ptable;
-       int use_default_ptable = 1; /* Until proven otherwise. */
-       const char pmsg[] = "  /dev/flash%d at 0x%08x, size 0x%08x\n";
-+      unsigned int kernel_part_size = 0;
-+      unsigned char *flash_mem = (unsigned char*)(FLASH_CACHED_ADDR);
-+      unsigned int flash_scan_count = 0;
-+      const char *part_magic = "ACME_PART_MAGIC";
-+      unsigned int magic_len = strlen(part_magic);
-       if (!(mymtd = flash_probe())) {
-               /* There's no reason to use this module if no flash chip can
-@@ -292,6 +292,31 @@
-                      mymtd->name, mymtd->size);
-               axisflash_mtd = mymtd;
-       }
-+      /* scan flash to findout where out partition starts */
-+
-+      printk(KERN_INFO "Scanning flash for end of kernel magic\n");
-+      for(flash_scan_count = 0; flash_scan_count < 100000; flash_scan_count++){
-+              if(strncmp(&flash_mem[flash_scan_count], part_magic, magic_len - 1) == 0)
-+              {
-+                      kernel_part_size = flash_mem[flash_scan_count + magic_len ];
-+                      kernel_part_size <<= 8;
-+                      kernel_part_size += flash_mem[flash_scan_count + magic_len + 2];
-+                      kernel_part_size <<= 8;
-+                      kernel_part_size += flash_mem[flash_scan_count + magic_len + 1];
-+                      kernel_part_size <<= 8;
-+                      kernel_part_size += flash_mem[flash_scan_count + magic_len + 3];
-+                      printk(KERN_INFO "Kernel ends at 0x%.08X\n", kernel_part_size);
-+                      flash_scan_count = 1100000;
-+              }
-+      }
-+
-+
-+      if(kernel_part_size){
-+              kernel_part_size = (kernel_part_size & 0xffff0000);
-+              axis_default_partitions[0].size = kernel_part_size;
-+              axis_default_partitions[1].size =  mymtd->size - axis_default_partitions[0].size;
-+              axis_default_partitions[1].offset = axis_default_partitions[0].size;
-+      }
-       if (mymtd) {
-               mymtd->owner = THIS_MODULE;
diff --git a/target/linux/etrax/patches/300-sysfs.patch b/target/linux/etrax/patches/300-sysfs.patch
deleted file mode 100644 (file)
index 3b03784..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
---- a/drivers/serial/crisv10.c
-+++ b/drivers/serial/crisv10.c
-@@ -27,6 +27,7 @@
- #include <linux/kernel.h>
- #include <linux/mutex.h>
- #include <linux/bitops.h>
-+#include <linux/device.h>
- #include <asm/io.h>
- #include <asm/irq.h>
-@@ -4384,6 +4385,7 @@
-       .tiocmset = rs_tiocmset
- };
-+static struct class *rs_class;
- static int __init
- rs_init(void)
- {
-@@ -4518,6 +4520,24 @@
- #endif
- #endif /* CONFIG_SVINTO_SIM */
-+      rs_class = class_create(THIS_MODULE, "rs_tty");
-+#ifdef CONFIG_ETRAX_SERIAL_PORT0 
-+      class_device_create(rs_class, NULL,
-+              MKDEV(TTY_MAJOR, 64), NULL, "ttyS0");
-+#endif
-+#ifdef CONFIG_ETRAX_SERIAL_PORT1 
-+      class_device_create(rs_class, NULL,
-+              MKDEV(TTY_MAJOR, 65), NULL, "ttyS1");
-+#endif
-+#ifdef CONFIG_ETRAX_SERIAL_PORT2 
-+      class_device_create(rs_class, NULL,
-+              MKDEV(TTY_MAJOR, 66), NULL, "ttyS2");
-+#endif
-+#ifdef CONFIG_ETRAX_SERIAL_PORT3 
-+      class_device_create(rs_class, NULL,
-+              MKDEV(TTY_MAJOR, 67), NULL, "ttyS3");
-+#endif
-+
-       return 0;
- }
diff --git a/target/linux/etrax/patches/301-usb_support.patch b/target/linux/etrax/patches/301-usb_support.patch
deleted file mode 100644 (file)
index 5b443d4..0000000
+++ /dev/null
@@ -1,5301 +0,0 @@
---- a/drivers/usb/Makefile
-+++ b/drivers/usb/Makefile
-@@ -16,6 +16,7 @@
- obj-$(CONFIG_USB_SL811_HCD)   += host/
- obj-$(CONFIG_USB_U132_HCD)    += host/
- obj-$(CONFIG_USB_R8A66597_HCD)        += host/
-+obj-$(CONFIG_ETRAX_USB_HOST)  += host/
- obj-$(CONFIG_USB_ACM)         += class/
- obj-$(CONFIG_USB_PRINTER)     += class/
---- a/drivers/usb/host/Makefile
-+++ b/drivers/usb/host/Makefile
-@@ -17,3 +17,5 @@
- obj-$(CONFIG_USB_U132_HCD)    += u132-hcd.o
- obj-$(CONFIG_USB_R8A66597_HCD)        += r8a66597-hcd.o
-+#obj-$(CONFIG_USB_CARNEOL)    += hc-crisv10.o
-+obj-$(CONFIG_ETRAX_USB_HOST)  += hc-crisv10.o
---- /dev/null
-+++ b/drivers/usb/host/hc-cris-dbg.h
-@@ -0,0 +1,143 @@
-+
-+/* macros for debug output */
-+
-+#define hcd_dbg(hcd, fmt, args...) \
-+      dev_info(hcd->self.controller, fmt, ## args)
-+#define hcd_err(hcd, fmt, args...) \
-+      dev_err(hcd->self.controller, fmt, ## args)
-+#define hcd_info(hcd, fmt, args...) \
-+      dev_info(hcd->self.controller, fmt, ## args)
-+#define hcd_warn(hcd, fmt, args...) \
-+      dev_warn(hcd->self.controller, fmt, ## args)
-+
-+/*
-+#define devdrv_dbg(fmt, args...) \
-+        printk(KERN_INFO "usb_devdrv dbg: ");printk(fmt, ## args)
-+*/
-+#define devdrv_dbg(fmt, args...) {}
-+
-+#define devdrv_err(fmt, args...) \
-+        printk(KERN_ERR "usb_devdrv error: ");printk(fmt, ## args)
-+#define devdrv_info(fmt, args...) \
-+        printk(KERN_INFO "usb_devdrv: ");printk(fmt, ## args)
-+
-+#define irq_dbg(fmt, args...) \
-+        printk(KERN_INFO "crisv10_irq dbg: ");printk(fmt, ## args)
-+#define irq_err(fmt, args...) \
-+        printk(KERN_ERR "crisv10_irq error: ");printk(fmt, ## args)
-+#define irq_warn(fmt, args...) \
-+        printk(KERN_INFO "crisv10_irq warn: ");printk(fmt, ## args)
-+#define irq_info(fmt, args...) \
-+        printk(KERN_INFO "crisv10_hcd: ");printk(fmt, ## args)
-+
-+/*
-+#define rh_dbg(fmt, args...) \
-+  printk(KERN_DEBUG "crisv10_rh dbg: ");printk(fmt, ## args)
-+*/
-+#define rh_dbg(fmt, args...) {}
-+
-+#define rh_err(fmt, args...) \
-+        printk(KERN_ERR "crisv10_rh error: ");printk(fmt, ## args)
-+#define rh_warn(fmt, args...) \
-+        printk(KERN_INFO "crisv10_rh warning: ");printk(fmt, ## args)
-+#define rh_info(fmt, args...) \
-+        printk(KERN_INFO "crisv10_rh: ");printk(fmt, ## args)
-+
-+/*
-+#define tc_dbg(fmt, args...) \
-+        printk(KERN_INFO "crisv10_tc dbg: ");printk(fmt, ## args)
-+*/
-+#define tc_dbg(fmt, args...) {while(0){}}
-+
-+#define tc_err(fmt, args...) \
-+        printk(KERN_ERR "crisv10_tc error: ");printk(fmt, ## args)
-+/*
-+#define tc_warn(fmt, args...) \
-+        printk(KERN_INFO "crisv10_tc warning: ");printk(fmt, ## args)
-+*/
-+#define tc_warn(fmt, args...) {while(0){}}
-+
-+#define tc_info(fmt, args...) \
-+        printk(KERN_INFO "crisv10_tc: ");printk(fmt, ## args)
-+
-+
-+/* Debug print-outs for various traffic types */
-+
-+#define intr_warn(fmt, args...) \
-+        printk(KERN_INFO "crisv10_intr warning: ");printk(fmt, ## args)
-+
-+#define intr_dbg(fmt, args...) \
-+        printk(KERN_DEBUG "crisv10_intr dbg: ");printk(fmt, ## args)
-+/*
-+#define intr_dbg(fmt, args...) {while(0){}}
-+*/
-+
-+
-+#define isoc_err(fmt, args...) \
-+        printk(KERN_ERR "crisv10_isoc error: ");printk(fmt, ## args)
-+/*
-+#define isoc_warn(fmt, args...) \
-+        printk(KERN_INFO "crisv10_isoc warning: ");printk(fmt, ## args)
-+*/
-+#define isoc_warn(fmt, args...) {while(0){}}
-+
-+/*
-+#define isoc_dbg(fmt, args...) \
-+        printk(KERN_INFO "crisv10_isoc dbg: ");printk(fmt, ## args)
-+*/
-+#define isoc_dbg(fmt, args...) {while(0){}}
-+
-+/*
-+#define timer_warn(fmt, args...) \
-+        printk(KERN_INFO "crisv10_timer warning: ");printk(fmt, ## args)
-+*/
-+#define timer_warn(fmt, args...) {while(0){}}
-+
-+/*
-+#define timer_dbg(fmt, args...) \
-+        printk(KERN_INFO "crisv10_timer dbg: ");printk(fmt, ## args)
-+*/
-+#define timer_dbg(fmt, args...) {while(0){}}
-+
-+
-+/* Debug printouts for events related to late finishing of URBs */
-+
-+#define late_dbg(fmt, args...) \
-+        printk(KERN_INFO "crisv10_late dbg: ");printk(fmt, ## args)
-+/*
-+#define late_dbg(fmt, args...) {while(0){}}
-+*/
-+
-+#define late_warn(fmt, args...) \
-+        printk(KERN_INFO "crisv10_late warning: ");printk(fmt, ## args)
-+/*
-+#define errno_dbg(fmt, args...) \
-+        printk(KERN_INFO "crisv10_errno dbg: ");printk(fmt, ## args)
-+*/
-+#define errno_dbg(fmt, args...) {while(0){}}
-+
-+
-+#define dma_dbg(fmt, args...) \
-+        printk(KERN_INFO "crisv10_dma dbg: ");printk(fmt, ## args)
-+#define dma_err(fmt, args...) \
-+        printk(KERN_ERR "crisv10_dma error: ");printk(fmt, ## args)
-+#define dma_warn(fmt, args...) \
-+        printk(KERN_INFO "crisv10_dma warning: ");printk(fmt, ## args)
-+#define dma_info(fmt, args...) \
-+        printk(KERN_INFO "crisv10_dma: ");printk(fmt, ## args)
-+
-+
-+
-+#define str_dir(pipe) \
-+      (usb_pipeout(pipe) ? "out" : "in")
-+#define str_type(pipe) \
-+      ({                                                              \
-+              char *s = "?";                                          \
-+              switch (usb_pipetype(pipe)) {                           \
-+              case PIPE_ISOCHRONOUS:  s = "iso";  break;              \
-+              case PIPE_INTERRUPT:    s = "intr"; break;              \
-+              case PIPE_CONTROL:      s = "ctrl"; break;              \
-+              case PIPE_BULK:         s = "bulk"; break;              \
-+              };                                                      \
-+              s;                                                      \
-+      })
---- /dev/null
-+++ b/drivers/usb/host/hc-crisv10.c
-@@ -0,0 +1,4800 @@
-+/*
-+ *
-+ * ETRAX 100LX USB Host Controller Driver
-+ *
-+ * Copyright (C) 2005, 2006  Axis Communications AB
-+ *
-+ * Author: Konrad Eriksson <konrad.eriksson@axis.se>
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/moduleparam.h>
-+#include <linux/spinlock.h>
-+#include <linux/usb.h>
-+#include <linux/platform_device.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/arch/dma.h>
-+#include <asm/arch/io_interface_mux.h>
-+
-+#include "../core/hcd.h"
-+#include "../core/hub.h"
-+#include "hc-crisv10.h"
-+#include "hc-cris-dbg.h"
-+
-+
-+/***************************************************************************/
-+/***************************************************************************/
-+/* Host Controller settings                                                */
-+/***************************************************************************/
-+/***************************************************************************/
-+
-+#define VERSION                       "1.00 hinko.4"
-+#define COPYRIGHT             "(c) 2005, 2006 Axis Communications AB"
-+#define DESCRIPTION     "ETRAX 100LX USB Host Controller (2.6.25-rc9 port)"
-+
-+#define ETRAX_USB_HC_IRQ USB_HC_IRQ_NBR
-+#define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR
-+#define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR
-+
-+/* Number of physical ports in Etrax 100LX */
-+#define USB_ROOT_HUB_PORTS 2
-+
-+const char hc_name[] = "hc-crisv10";
-+const char product_desc[] = DESCRIPTION;
-+
-+/* The number of epids is, among other things, used for pre-allocating
-+   ctrl, bulk and isoc EP descriptors (one for each epid).
-+   Assumed to be > 1 when initiating the DMA lists. */
-+#define NBR_OF_EPIDS       32
-+
-+/* Support interrupt traffic intervals up to 128 ms. */
-+#define MAX_INTR_INTERVAL  128
-+
-+/* If periodic traffic (intr or isoc) is to be used, then one entry in the EP
-+   table must be "invalid". By this we mean that we shouldn't care about epid
-+   attentions for this epid, or at least handle them differently from epid
-+   attentions for "valid" epids. This define determines which one to use
-+   (don't change it). */
-+#define INVALID_EPID       31
-+/* A special epid for the bulk dummys. */
-+#define DUMMY_EPID         30
-+
-+/* Module settings */
-+
-+MODULE_DESCRIPTION(DESCRIPTION);
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Konrad Eriksson <konrad.eriksson@axis.se>");
-+
-+
-+/* Module parameters */
-+
-+/* 0 = No ports enabled
-+   1 = Only port 1 enabled (on board ethernet on devboard)
-+   2 = Only port 2 enabled (external connector on devboard)
-+   3 = Both ports enabled
-+*/
-+static unsigned int ports = 3;
-+module_param(ports, uint, S_IRUGO);
-+MODULE_PARM_DESC(ports, "Bitmask indicating USB ports to use");
-+
-+
-+/***************************************************************************/
-+/***************************************************************************/
-+/* Shared global variables for this module                                 */
-+/***************************************************************************/
-+/***************************************************************************/
-+
-+/* EP descriptor lists for non period transfers. Must be 32-bit aligned. */
-+static volatile struct USB_EP_Desc TxBulkEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4)));
-+
-+static volatile struct USB_EP_Desc TxCtrlEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4)));
-+
-+/* EP descriptor lists for period transfers. Must be 32-bit aligned. */
-+static volatile struct USB_EP_Desc TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4)));
-+static volatile struct USB_SB_Desc TxIntrSB_zout __attribute__ ((aligned (4)));
-+
-+static volatile struct USB_EP_Desc TxIsocEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4)));
-+static volatile struct USB_SB_Desc TxIsocSB_zout __attribute__ ((aligned (4)));
-+
-+//static volatile struct USB_SB_Desc TxIsocSBList[NBR_OF_EPIDS] __attribute__ ((aligned (4))); 
-+
-+/* After each enabled bulk EP IN we put two disabled EP descriptors with the eol flag set,
-+   causing the DMA to stop the DMA channel. The first of these two has the intr flag set, which
-+   gives us a dma8_sub0_descr interrupt. When we receive this, we advance the DMA one step in the
-+   EP list and then restart the bulk channel, thus forcing a switch between bulk EP descriptors
-+   in each frame. */
-+static volatile struct USB_EP_Desc TxBulkDummyEPList[NBR_OF_EPIDS][2] __attribute__ ((aligned (4)));
-+
-+/* List of URB pointers, where each points to the active URB for a epid.
-+   For Bulk, Ctrl and Intr this means which URB that currently is added to
-+   DMA lists (Isoc URBs are all directly added to DMA lists). As soon as
-+   URB has completed is the queue examined and the first URB in queue is
-+   removed and moved to the activeUrbList while its state change to STARTED and
-+   its transfer(s) gets added to DMA list (exception Isoc where URBs enter
-+   state STARTED directly and added transfers added to DMA lists). */
-+static struct urb *activeUrbList[NBR_OF_EPIDS];
-+
-+/* Additional software state info for each epid */
-+static struct etrax_epid epid_state[NBR_OF_EPIDS];
-+
-+/* Timer handles for bulk traffic timer used to avoid DMA bug where DMA stops
-+   even if there is new data waiting to be processed */
-+static struct timer_list bulk_start_timer = TIMER_INITIALIZER(NULL, 0, 0);
-+static struct timer_list bulk_eot_timer = TIMER_INITIALIZER(NULL, 0, 0);
-+
-+/* We want the start timer to expire before the eot timer, because the former
-+   might start traffic, thus making it unnecessary for the latter to time
-+   out. */
-+#define BULK_START_TIMER_INTERVAL (HZ/50) /* 20 ms */
-+#define BULK_EOT_TIMER_INTERVAL (HZ/16) /* 60 ms */
-+
-+/* Delay before a URB completion happen when it's scheduled to be delayed */
-+#define LATER_TIMER_DELAY (HZ/50) /* 20 ms */
-+
-+/* Simplifying macros for checking software state info of a epid */
-+/* ----------------------------------------------------------------------- */
-+#define epid_inuse(epid)       epid_state[epid].inuse
-+#define epid_out_traffic(epid) epid_state[epid].out_traffic
-+#define epid_isoc(epid)   (epid_state[epid].type == PIPE_ISOCHRONOUS ? 1 : 0)
-+#define epid_intr(epid)   (epid_state[epid].type == PIPE_INTERRUPT ? 1 : 0)
-+
-+
-+/***************************************************************************/
-+/***************************************************************************/
-+/* DEBUG FUNCTIONS                                                         */
-+/***************************************************************************/
-+/***************************************************************************/
-+/* Note that these functions are always available in their "__" variants,
-+   for use in error situations. The "__" missing variants are controlled by
-+   the USB_DEBUG_DESC/USB_DEBUG_URB macros. */
-+static void __dump_urb(struct urb* purb)
-+{
-+  struct crisv10_urb_priv *urb_priv = purb->hcpriv;
-+  int urb_num = -1;
-+  if(urb_priv) {
-+    urb_num = urb_priv->urb_num;
-+  }
-+  printk("\nURB:0x%x[%d]\n", (unsigned int)purb, urb_num);
-+  printk("dev                   :0x%08lx\n", (unsigned long)purb->dev);
-+  printk("pipe                  :0x%08x\n", purb->pipe);
-+  printk("status                :%d\n", purb->status);
-+  printk("transfer_flags        :0x%08x\n", purb->transfer_flags);
-+  printk("transfer_buffer       :0x%08lx\n", (unsigned long)purb->transfer_buffer);
-+  printk("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-+  printk("actual_length         :%d\n", purb->actual_length);
-+  printk("setup_packet          :0x%08lx\n", (unsigned long)purb->setup_packet);
-+  printk("start_frame           :%d\n", purb->start_frame);
-+  printk("number_of_packets     :%d\n", purb->number_of_packets);
-+  printk("interval              :%d\n", purb->interval);
-+  printk("error_count           :%d\n", purb->error_count);
-+  printk("context               :0x%08lx\n", (unsigned long)purb->context);
-+  printk("complete              :0x%08lx\n\n", (unsigned long)purb->complete);
-+}
-+
-+static void __dump_in_desc(volatile struct USB_IN_Desc *in)
-+{
-+  printk("\nUSB_IN_Desc at 0x%08lx\n", (unsigned long)in);
-+  printk("  sw_len  : 0x%04x (%d)\n", in->sw_len, in->sw_len);
-+  printk("  command : 0x%04x\n", in->command);
-+  printk("  next    : 0x%08lx\n", in->next);
-+  printk("  buf     : 0x%08lx\n", in->buf);
-+  printk("  hw_len  : 0x%04x (%d)\n", in->hw_len, in->hw_len);
-+  printk("  status  : 0x%04x\n\n", in->status);
-+}
-+
-+static void __dump_sb_desc(volatile struct USB_SB_Desc *sb)
-+{
-+  char tt = (sb->command & 0x30) >> 4;
-+  char *tt_string;
-+
-+  switch (tt) {
-+  case 0:
-+    tt_string = "zout";
-+    break;
-+  case 1:
-+    tt_string = "in";
-+    break;
-+  case 2:
-+    tt_string = "out";
-+    break;
-+  case 3:
-+    tt_string = "setup";
-+    break;
-+  default:
-+    tt_string = "unknown (weird)";
-+  }
-+
-+  printk(" USB_SB_Desc at 0x%08lx ", (unsigned long)sb);
-+  printk(" command:0x%04x (", sb->command);
-+  printk("rem:%d ", (sb->command & 0x3f00) >> 8);
-+  printk("full:%d ", (sb->command & 0x40) >> 6);
-+  printk("tt:%d(%s) ", tt, tt_string);
-+  printk("intr:%d ", (sb->command & 0x8) >> 3);
-+  printk("eot:%d ", (sb->command & 0x2) >> 1);
-+  printk("eol:%d)", sb->command & 0x1);
-+  printk(" sw_len:0x%04x(%d)", sb->sw_len, sb->sw_len);
-+  printk(" next:0x%08lx", sb->next);
-+  printk(" buf:0x%08lx\n", sb->buf);
-+}
-+
-+
-+static void __dump_ep_desc(volatile struct USB_EP_Desc *ep)
-+{
-+  printk("USB_EP_Desc at 0x%08lx ", (unsigned long)ep);
-+  printk(" command:0x%04x (", ep->command);
-+  printk("ep_id:%d ", (ep->command & 0x1f00) >> 8);
-+  printk("enable:%d ", (ep->command & 0x10) >> 4);
-+  printk("intr:%d ", (ep->command & 0x8) >> 3);
-+  printk("eof:%d ", (ep->command & 0x2) >> 1);
-+  printk("eol:%d)", ep->command & 0x1);
-+  printk(" hw_len:0x%04x(%d)", ep->hw_len, ep->hw_len);
-+  printk(" next:0x%08lx", ep->next);
-+  printk(" sub:0x%08lx\n", ep->sub);
-+}
-+
-+static inline void __dump_ep_list(int pipe_type)
-+{
-+  volatile struct USB_EP_Desc *ep;
-+  volatile struct USB_EP_Desc *first_ep;
-+  volatile struct USB_SB_Desc *sb;
-+
-+  switch (pipe_type)
-+    {
-+    case PIPE_BULK:
-+      first_ep = &TxBulkEPList[0];
-+      break;
-+    case PIPE_CONTROL:
-+      first_ep = &TxCtrlEPList[0];
-+      break;
-+    case PIPE_INTERRUPT:
-+      first_ep = &TxIntrEPList[0];
-+      break;
-+    case PIPE_ISOCHRONOUS:
-+      first_ep = &TxIsocEPList[0];
-+      break;
-+    default:
-+      warn("Cannot dump unknown traffic type");
-+      return;
-+    }
-+  ep = first_ep;
-+
-+  printk("\n\nDumping EP list...\n\n");
-+
-+  do {
-+    __dump_ep_desc(ep);
-+    /* Cannot phys_to_virt on 0 as it turns into 80000000, which is != 0. */
-+    sb = ep->sub ? phys_to_virt(ep->sub) : 0;
-+    while (sb) {
-+      __dump_sb_desc(sb);
-+      sb = sb->next ? phys_to_virt(sb->next) : 0;
-+    }
-+    ep = (volatile struct USB_EP_Desc *)(phys_to_virt(ep->next));
-+
-+  } while (ep != first_ep);
-+}
-+
-+static inline void __dump_ept_data(int epid)
-+{
-+  unsigned long flags;
-+  __u32 r_usb_ept_data;
-+
-+  if (epid < 0 || epid > 31) {
-+    printk("Cannot dump ept data for invalid epid %d\n", epid);
-+    return;
-+  }
-+
-+  local_irq_save(flags);
-+  *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-+  nop();
-+  r_usb_ept_data = *R_USB_EPT_DATA;
-+  local_irq_restore(flags);
-+
-+  printk(" R_USB_EPT_DATA = 0x%x for epid %d :\n", r_usb_ept_data, epid);
-+  if (r_usb_ept_data == 0) {
-+    /* No need for more detailed printing. */
-+    return;
-+  }
-+  printk("  valid           : %d\n", (r_usb_ept_data & 0x80000000) >> 31);
-+  printk("  hold            : %d\n", (r_usb_ept_data & 0x40000000) >> 30);
-+  printk("  error_count_in  : %d\n", (r_usb_ept_data & 0x30000000) >> 28);
-+  printk("  t_in            : %d\n", (r_usb_ept_data & 0x08000000) >> 27);
-+  printk("  low_speed       : %d\n", (r_usb_ept_data & 0x04000000) >> 26);
-+  printk("  port            : %d\n", (r_usb_ept_data & 0x03000000) >> 24);
-+  printk("  error_code      : %d\n", (r_usb_ept_data & 0x00c00000) >> 22);
-+  printk("  t_out           : %d\n", (r_usb_ept_data & 0x00200000) >> 21);
-+  printk("  error_count_out : %d\n", (r_usb_ept_data & 0x00180000) >> 19);
-+  printk("  max_len         : %d\n", (r_usb_ept_data & 0x0003f800) >> 11);
-+  printk("  ep              : %d\n", (r_usb_ept_data & 0x00000780) >> 7);
-+  printk("  dev             : %d\n", (r_usb_ept_data & 0x0000003f));
-+}
-+
-+static inline void __dump_ept_data_iso(int epid)
-+{
-+  unsigned long flags;
-+  __u32 ept_data;
-+
-+  if (epid < 0 || epid > 31) {
-+    printk("Cannot dump ept data for invalid epid %d\n", epid);
-+    return;
-+  }
-+
-+  local_irq_save(flags);
-+  *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-+  nop();
-+  ept_data = *R_USB_EPT_DATA_ISO;
-+  local_irq_restore(flags);
-+
-+  printk(" R_USB_EPT_DATA = 0x%x for epid %d :\n", ept_data, epid);
-+  if (ept_data == 0) {
-+    /* No need for more detailed printing. */
-+    return;
-+  }
-+  printk("  valid           : %d\n", IO_EXTRACT(R_USB_EPT_DATA_ISO, valid,
-+                                              ept_data));
-+  printk("  port            : %d\n", IO_EXTRACT(R_USB_EPT_DATA_ISO, port,
-+                                              ept_data));
-+  printk("  error_code      : %d\n", IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code,
-+                                              ept_data));
-+  printk("  max_len         : %d\n", IO_EXTRACT(R_USB_EPT_DATA_ISO, max_len,
-+                                              ept_data));
-+  printk("  ep              : %d\n", IO_EXTRACT(R_USB_EPT_DATA_ISO, ep,
-+                                              ept_data));
-+  printk("  dev             : %d\n", IO_EXTRACT(R_USB_EPT_DATA_ISO, dev,
-+                                              ept_data));
-+}
-+
-+static inline void __dump_ept_data_list(void)
-+{
-+  int i;
-+
-+  printk("Dumping the whole R_USB_EPT_DATA list\n");
-+
-+  for (i = 0; i < 32; i++) {
-+    __dump_ept_data(i);
-+  }
-+}
-+
-+static void debug_epid(int epid) {
-+  int i;
-+  
-+  if(epid_isoc(epid)) {
-+    __dump_ept_data_iso(epid);
-+  } else {
-+    __dump_ept_data(epid);
-+  }
-+
-+  printk("Bulk:\n");
-+  for(i = 0; i < 32; i++) {
-+    if(IO_EXTRACT(USB_EP_command, epid, TxBulkEPList[i].command) ==
-+       epid) {
-+      printk("%d: ", i); __dump_ep_desc(&(TxBulkEPList[i]));
-+    }
-+  }
-+
-+  printk("Ctrl:\n");
-+  for(i = 0; i < 32; i++) {
-+    if(IO_EXTRACT(USB_EP_command, epid, TxCtrlEPList[i].command) ==
-+       epid) {
-+      printk("%d: ", i); __dump_ep_desc(&(TxCtrlEPList[i]));
-+    }
-+  }
-+
-+  printk("Intr:\n");
-+  for(i = 0; i < MAX_INTR_INTERVAL; i++) {
-+    if(IO_EXTRACT(USB_EP_command, epid, TxIntrEPList[i].command) ==
-+       epid) {
-+      printk("%d: ", i); __dump_ep_desc(&(TxIntrEPList[i]));
-+    }
-+  }
-+  
-+  printk("Isoc:\n");
-+  for(i = 0; i < 32; i++) {
-+    if(IO_EXTRACT(USB_EP_command, epid, TxIsocEPList[i].command) ==
-+       epid) {
-+      printk("%d: ", i); __dump_ep_desc(&(TxIsocEPList[i]));
-+    }
-+  }
-+
-+  __dump_ept_data_list();
-+  __dump_ep_list(PIPE_INTERRUPT);
-+  printk("\n\n");
-+}
-+
-+
-+
-+char* hcd_status_to_str(__u8 bUsbStatus) {
-+  static char hcd_status_str[128];
-+  hcd_status_str[0] = '\0';
-+  if(bUsbStatus & IO_STATE(R_USB_STATUS, ourun, yes)) {
-+    strcat(hcd_status_str, "ourun ");
-+  }
-+  if(bUsbStatus & IO_STATE(R_USB_STATUS, perror, yes)) {
-+    strcat(hcd_status_str, "perror ");
-+  }
-+  if(bUsbStatus & IO_STATE(R_USB_STATUS, device_mode, yes)) {
-+    strcat(hcd_status_str, "device_mode ");
-+  }
-+  if(bUsbStatus & IO_STATE(R_USB_STATUS, host_mode, yes)) {
-+    strcat(hcd_status_str, "host_mode ");
-+  }
-+  if(bUsbStatus & IO_STATE(R_USB_STATUS, started, yes)) {
-+    strcat(hcd_status_str, "started ");
-+  }
-+  if(bUsbStatus & IO_STATE(R_USB_STATUS, running, yes)) {
-+    strcat(hcd_status_str, "running ");
-+  }
-+  return hcd_status_str;
-+}
-+
-+
-+char* sblist_to_str(struct USB_SB_Desc* sb_desc) {
-+  static char sblist_to_str_buff[128];
-+  char tmp[32], tmp2[32];
-+  sblist_to_str_buff[0] = '\0';
-+  while(sb_desc != NULL) {
-+    switch(IO_EXTRACT(USB_SB_command, tt, sb_desc->command)) {
-+    case 0: sprintf(tmp, "zout");  break;
-+    case 1: sprintf(tmp, "in");    break;
-+    case 2: sprintf(tmp, "out");   break;
-+    case 3: sprintf(tmp, "setup"); break;
-+    }
-+    sprintf(tmp2, "(%s %d)", tmp, sb_desc->sw_len);
-+    strcat(sblist_to_str_buff, tmp2);
-+    if(sb_desc->next != 0) {
-+      sb_desc = phys_to_virt(sb_desc->next);
-+    } else {
-+      sb_desc = NULL;
-+    }
-+  }
-+  return sblist_to_str_buff;
-+}
-+
-+char* port_status_to_str(__u16 wPortStatus) {
-+  static char port_status_str[128];
-+  port_status_str[0] = '\0';
-+  if(wPortStatus & IO_STATE(R_USB_RH_PORT_STATUS_1, connected, yes)) {
-+    strcat(port_status_str, "connected ");
-+  }
-+  if(wPortStatus & IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes)) {
-+    strcat(port_status_str, "enabled ");
-+  }
-+  if(wPortStatus & IO_STATE(R_USB_RH_PORT_STATUS_1, suspended, yes)) {
-+    strcat(port_status_str, "suspended ");
-+  }
-+  if(wPortStatus & IO_STATE(R_USB_RH_PORT_STATUS_1, reset, yes)) {
-+    strcat(port_status_str, "reset ");
-+  }
-+  if(wPortStatus & IO_STATE(R_USB_RH_PORT_STATUS_1, speed, full)) {
-+    strcat(port_status_str, "full-speed ");
-+  } else {
-+    strcat(port_status_str, "low-speed ");
-+  }
-+  return port_status_str;
-+}
-+
-+
-+char* endpoint_to_str(struct usb_endpoint_descriptor *ed) {
-+  static char endpoint_to_str_buff[128];
-+  char tmp[32];
-+  int epnum = ed->bEndpointAddress & 0x0F;
-+  int dir = ed->bEndpointAddress & 0x80;
-+  int type = ed->bmAttributes & 0x03;
-+  endpoint_to_str_buff[0] = '\0';
-+  sprintf(endpoint_to_str_buff, "ep:%d ", epnum);
-+  switch(type) {
-+  case 0:
-+    sprintf(tmp, " ctrl");
-+    break;
-+  case 1:
-+    sprintf(tmp, " isoc");
-+    break;
-+  case 2:
-+    sprintf(tmp, " bulk");
-+    break;
-+  case 3:
-+    sprintf(tmp, " intr");
-+    break;
-+  }
-+  strcat(endpoint_to_str_buff, tmp);
-+  if(dir) {
-+    sprintf(tmp, " in");
-+  } else {
-+    sprintf(tmp, " out");
-+  }
-+  strcat(endpoint_to_str_buff, tmp);
-+
-+  return endpoint_to_str_buff;
-+}
-+
-+/* Debug helper functions for Transfer Controller */
-+char* pipe_to_str(unsigned int pipe) {
-+  static char pipe_to_str_buff[128];
-+  char tmp[64];
-+  sprintf(pipe_to_str_buff, "dir:%s", str_dir(pipe));
-+  sprintf(tmp, " type:%s", str_type(pipe));
-+  strcat(pipe_to_str_buff, tmp);
-+
-+  sprintf(tmp, " dev:%d", usb_pipedevice(pipe));
-+  strcat(pipe_to_str_buff, tmp);
-+  sprintf(tmp, " ep:%d", usb_pipeendpoint(pipe));
-+  strcat(pipe_to_str_buff, tmp);
-+  return pipe_to_str_buff;
-+}
-+
-+
-+#define USB_DEBUG_DESC 1
-+
-+#ifdef USB_DEBUG_DESC
-+#define dump_in_desc(x) __dump_in_desc(x)
-+#define dump_sb_desc(...) __dump_sb_desc(...)
-+#define dump_ep_desc(x) __dump_ep_desc(x)
-+#define dump_ept_data(x) __dump_ept_data(x)
-+#else
-+#define dump_in_desc(...) do {} while (0)
-+#define dump_sb_desc(...) do {} while (0)
-+#define dump_ep_desc(...) do {} while (0)
-+#endif
-+
-+
-+/* Uncomment this to enable massive function call trace
-+   #define USB_DEBUG_TRACE */
-+//#define USB_DEBUG_TRACE 1
-+
-+#ifdef USB_DEBUG_TRACE
-+#define DBFENTER (printk(": Entering: %s\n", __FUNCTION__))
-+#define DBFEXIT  (printk(": Exiting:  %s\n", __FUNCTION__))
-+#else
-+#define DBFENTER do {} while (0)
-+#define DBFEXIT  do {} while (0)
-+#endif
-+
-+#define CHECK_ALIGN(x) if (((__u32)(x)) & 0x00000003) \
-+{panic("Alignment check (DWORD) failed at %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);}
-+
-+/* Most helpful debugging aid */
-+#define ASSERT(expr) ((void) ((expr) ? 0 : (err("assert failed at: %s %d",__FUNCTION__, __LINE__))))
-+
-+
-+/***************************************************************************/
-+/***************************************************************************/
-+/* Forward declarations                                                    */
-+/***************************************************************************/
-+/***************************************************************************/
-+void crisv10_hcd_epid_attn_irq(struct crisv10_irq_reg *reg);
-+void crisv10_hcd_port_status_irq(struct crisv10_irq_reg *reg);
-+void crisv10_hcd_ctl_status_irq(struct crisv10_irq_reg *reg);
-+void crisv10_hcd_isoc_eof_irq(struct crisv10_irq_reg *reg);
-+
-+void rh_port_status_change(__u16[]);
-+int  rh_clear_port_feature(__u8, __u16);
-+int  rh_set_port_feature(__u8, __u16);
-+static void rh_disable_port(unsigned int port);
-+
-+static void check_finished_bulk_tx_epids(struct usb_hcd *hcd,
-+                                       int timer);
-+
-+//static int  tc_setup_epid(struct usb_host_endpoint *ep, struct urb *urb,
-+//                     int mem_flags);
-+static int tc_setup_epid(struct urb *urb, int mem_flags);
-+static void tc_free_epid(struct usb_host_endpoint *ep);
-+static int  tc_allocate_epid(void);
-+static void tc_finish_urb(struct usb_hcd *hcd, struct urb *urb, int status);
-+static void tc_finish_urb_later(struct usb_hcd *hcd, struct urb *urb,
-+                              int status);
-+
-+static int  urb_priv_create(struct usb_hcd *hcd, struct urb *urb, int epid,
-+                         int mem_flags);
-+static void urb_priv_free(struct usb_hcd *hcd, struct urb *urb);
-+
-+static inline struct urb *urb_list_first(int epid);
-+static inline void        urb_list_add(struct urb *urb, int epid,
-+                                    int mem_flags);
-+static inline urb_entry_t *urb_list_entry(struct urb *urb, int epid);
-+static inline void        urb_list_del(struct urb *urb, int epid);
-+static inline void        urb_list_move_last(struct urb *urb, int epid);
-+static inline struct urb *urb_list_next(struct urb *urb, int epid);
-+
-+int create_sb_for_urb(struct urb *urb, int mem_flags);
-+int init_intr_urb(struct urb *urb, int mem_flags);
-+
-+static inline void  etrax_epid_set(__u8 index, __u32 data);
-+static inline void  etrax_epid_clear_error(__u8 index);
-+static inline void  etrax_epid_set_toggle(__u8 index, __u8 dirout,
-+                                            __u8 toggle);
-+static inline __u8  etrax_epid_get_toggle(__u8 index, __u8 dirout);
-+static inline __u32 etrax_epid_get(__u8 index);
-+
-+/* We're accessing the same register position in Etrax so
-+   when we do full access the internal difference doesn't matter */
-+#define etrax_epid_iso_set(index, data) etrax_epid_set(index, data)
-+#define etrax_epid_iso_get(index) etrax_epid_get(index)
-+
-+
-+//static void        tc_dma_process_isoc_urb(struct urb *urb);
-+static void        tc_dma_process_queue(int epid);
-+static void        tc_dma_unlink_intr_urb(struct urb *urb);
-+static irqreturn_t tc_dma_tx_interrupt(int irq, void *vhc);
-+static irqreturn_t tc_dma_rx_interrupt(int irq, void *vhc);
-+
-+static void tc_bulk_start_timer_func(unsigned long dummy);
-+static void tc_bulk_eot_timer_func(unsigned long dummy);
-+
-+
-+/*************************************************************/
-+/*************************************************************/
-+/* Host Controler Driver block                               */
-+/*************************************************************/
-+/*************************************************************/
-+
-+/* HCD operations */
-+static irqreturn_t crisv10_hcd_top_irq(int irq, void*);
-+static int crisv10_hcd_reset(struct usb_hcd *);
-+static int crisv10_hcd_start(struct usb_hcd *);
-+static void crisv10_hcd_stop(struct usb_hcd *);
-+#ifdef CONFIG_PM
-+static int crisv10_hcd_suspend(struct device *, u32, u32);
-+static int crisv10_hcd_resume(struct device *, u32);
-+#endif /* CONFIG_PM */
-+static int crisv10_hcd_get_frame(struct usb_hcd *);
-+
-+//static int  tc_urb_enqueue(struct usb_hcd *, struct usb_host_endpoint *ep, struct urb *, gfp_t mem_flags);
-+static int tc_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
-+//static int  tc_urb_dequeue(struct usb_hcd *, struct urb *);
-+static int tc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
-+static void tc_endpoint_disable(struct usb_hcd *, struct usb_host_endpoint *ep);
-+
-+static int rh_status_data_request(struct usb_hcd *, char *);
-+static int rh_control_request(struct usb_hcd *, u16, u16, u16, char*, u16);
-+
-+#ifdef CONFIG_PM
-+static int crisv10_hcd_hub_suspend(struct usb_hcd *);
-+static int crisv10_hcd_hub_resume(struct usb_hcd *);
-+#endif /* CONFIG_PM */
-+#ifdef CONFIG_USB_OTG
-+static int crisv10_hcd_start_port_reset(struct usb_hcd *, unsigned);
-+#endif /* CONFIG_USB_OTG */
-+
-+/* host controller driver interface */
-+static const struct hc_driver crisv10_hc_driver = 
-+  {
-+    .description =    hc_name,
-+    .product_desc =   product_desc,
-+    .hcd_priv_size =  sizeof(struct crisv10_hcd),
-+
-+    /* Attaching IRQ handler manualy in probe() */
-+    /* .irq =         crisv10_hcd_irq, */
-+
-+    .flags =          HCD_USB11,
-+
-+    /* called to init HCD and root hub */
-+    .reset =          crisv10_hcd_reset,
-+    .start =          crisv10_hcd_start,      
-+
-+    /* cleanly make HCD stop writing memory and doing I/O */
-+    .stop =           crisv10_hcd_stop,
-+
-+    /* return current frame number */
-+    .get_frame_number =       crisv10_hcd_get_frame,
-+
-+
-+    /* Manage i/o requests via the Transfer Controller */
-+    .urb_enqueue =    tc_urb_enqueue,
-+    .urb_dequeue =    tc_urb_dequeue,
-+
-+    /* hw synch, freeing endpoint resources that urb_dequeue can't */
-+    .endpoint_disable = tc_endpoint_disable,
-+
-+
-+    /* Root Hub support */
-+    .hub_status_data =        rh_status_data_request,
-+    .hub_control =    rh_control_request,
-+#ifdef CONFIG_PM
-+    .hub_suspend =    rh_suspend_request,
-+    .hub_resume =     rh_resume_request,
-+#endif /* CONFIG_PM */
-+#ifdef        CONFIG_USB_OTG
-+    .start_port_reset =       crisv10_hcd_start_port_reset,
-+#endif /* CONFIG_USB_OTG */
-+  };
-+
-+
-+/*
-+ * conversion between pointers to a hcd and the corresponding
-+ * crisv10_hcd 
-+ */
-+
-+static inline struct crisv10_hcd *hcd_to_crisv10_hcd(struct usb_hcd *hcd)
-+{
-+      return (struct crisv10_hcd *) hcd->hcd_priv;
-+}
-+
-+static inline struct usb_hcd *crisv10_hcd_to_hcd(struct crisv10_hcd *hcd)
-+{
-+      return container_of((void *) hcd, struct usb_hcd, hcd_priv);
-+}
-+
-+/* check if specified port is in use */
-+static inline int port_in_use(unsigned int port)
-+{
-+      return ports & (1 << port);
-+}
-+
-+/* number of ports in use */
-+static inline unsigned int num_ports(void)
-+{
-+      unsigned int i, num = 0;
-+      for (i = 0; i < USB_ROOT_HUB_PORTS; i++)
-+              if (port_in_use(i))
-+                      num++;
-+      return num;
-+}
-+
-+/* map hub port number to the port number used internally by the HC */
-+static inline unsigned int map_port(unsigned int port)
-+{
-+  unsigned int i, num = 0;
-+  for (i = 0; i < USB_ROOT_HUB_PORTS; i++)
-+    if (port_in_use(i))
-+      if (++num == port)
-+      return i;
-+  return -1;
-+}
-+
-+/* size of descriptors in slab cache */
-+#ifndef MAX
-+#define MAX(x, y)             ((x) > (y) ? (x) : (y))
-+#endif
-+
-+
-+/******************************************************************/
-+/* Hardware Interrupt functions                                   */
-+/******************************************************************/
-+
-+/* Fast interrupt handler for HC */
-+static irqreturn_t crisv10_hcd_top_irq(int irq, void *vcd)
-+{
-+  struct usb_hcd *hcd = vcd;
-+  struct crisv10_irq_reg reg;
-+  __u32 irq_mask;
-+  unsigned long flags;
-+
-+  DBFENTER;
-+
-+  ASSERT(hcd != NULL);
-+  reg.hcd = hcd;
-+
-+  /* Turn of other interrupts while handling these sensitive cases */
-+  local_irq_save(flags);
-+  
-+  /* Read out which interrupts that are flaged */
-+  irq_mask = *R_USB_IRQ_MASK_READ;
-+  reg.r_usb_irq_mask_read = irq_mask;
-+
-+  /* Reading R_USB_STATUS clears the ctl_status interrupt. Note that
-+     R_USB_STATUS must be read before R_USB_EPID_ATTN since reading the latter
-+     clears the ourun and perror fields of R_USB_STATUS. */
-+  reg.r_usb_status = *R_USB_STATUS;
-+  
-+  /* Reading R_USB_EPID_ATTN clears the iso_eof, bulk_eot and epid_attn
-+     interrupts. */
-+  reg.r_usb_epid_attn = *R_USB_EPID_ATTN;
-+  
-+  /* Reading R_USB_RH_PORT_STATUS_1 and R_USB_RH_PORT_STATUS_2 clears the
-+     port_status interrupt. */
-+  reg.r_usb_rh_port_status_1 = *R_USB_RH_PORT_STATUS_1;
-+  reg.r_usb_rh_port_status_2 = *R_USB_RH_PORT_STATUS_2;
-+  
-+  /* Reading R_USB_FM_NUMBER clears the sof interrupt. */
-+  /* Note: the lower 11 bits contain the actual frame number, sent with each
-+     sof. */
-+  reg.r_usb_fm_number = *R_USB_FM_NUMBER;
-+
-+  /* Interrupts are handled in order of priority. */
-+  if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, port_status)) {
-+    crisv10_hcd_port_status_irq(&reg);
-+  }
-+  if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, epid_attn)) {
-+    crisv10_hcd_epid_attn_irq(&reg);
-+  }
-+  if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, ctl_status)) {
-+    crisv10_hcd_ctl_status_irq(&reg);
-+  }
-+  if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, iso_eof)) {
-+    crisv10_hcd_isoc_eof_irq(&reg);
-+  }
-+  if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, bulk_eot)) {
-+    /* Update/restart the bulk start timer since obviously the channel is
-+       running. */
-+    mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL);
-+    /* Update/restart the bulk eot timer since we just received an bulk eot
-+       interrupt. */
-+    mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL);
-+
-+    /* Check for finished bulk transfers on epids */
-+    check_finished_bulk_tx_epids(hcd, 0);
-+  }
-+  local_irq_restore(flags);
-+
-+  DBFEXIT;
-+  return IRQ_HANDLED;
-+}
-+
-+
-+void crisv10_hcd_epid_attn_irq(struct crisv10_irq_reg *reg) {
-+  struct usb_hcd *hcd = reg->hcd;
-+  struct crisv10_urb_priv *urb_priv;
-+  int epid;
-+  DBFENTER;
-+
-+  for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
-+    if (test_bit(epid, (void *)&reg->r_usb_epid_attn)) {
-+      struct urb *urb;
-+      __u32 ept_data;
-+      int error_code;
-+
-+      if (epid == DUMMY_EPID || epid == INVALID_EPID) {
-+      /* We definitely don't care about these ones. Besides, they are
-+         always disabled, so any possible disabling caused by the
-+         epid attention interrupt is irrelevant. */
-+      warn("Got epid_attn for INVALID_EPID or DUMMY_EPID (%d).", epid);
-+      continue;
-+      }
-+
-+      if(!epid_inuse(epid)) {
-+      irq_err("Epid attention on epid:%d that isn't in use\n", epid);
-+      printk("R_USB_STATUS: 0x%x\n", reg->r_usb_status);
-+      debug_epid(epid);
-+      continue;
-+      }
-+
-+      /* Note that although there are separate R_USB_EPT_DATA and
-+       R_USB_EPT_DATA_ISO registers, they are located at the same address and
-+       are of the same size. In other words, this read should be ok for isoc
-+       also. */
-+      ept_data = etrax_epid_get(epid);
-+      error_code = IO_EXTRACT(R_USB_EPT_DATA, error_code, ept_data);
-+
-+      /* Get the active URB for this epid. We blatantly assume
-+       that only this URB could have caused the epid attention. */
-+      urb = activeUrbList[epid];
-+      if (urb == NULL) {
-+      irq_err("Attention on epid:%d error:%d with no active URB.\n",
-+              epid, error_code);
-+      printk("R_USB_STATUS: 0x%x\n", reg->r_usb_status);
-+      debug_epid(epid);
-+      continue;
-+      }
-+
-+      urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+      ASSERT(urb_priv);
-+
-+      /* Using IO_STATE_VALUE on R_USB_EPT_DATA should be ok for isoc also. */
-+      if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-+
-+      /* Isoc traffic doesn't have error_count_in/error_count_out. */
-+      if ((usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) &&
-+          (IO_EXTRACT(R_USB_EPT_DATA, error_count_in, ept_data) == 3 ||
-+           IO_EXTRACT(R_USB_EPT_DATA, error_count_out, ept_data) == 3)) {
-+        /* Check if URB allready is marked for late-finish, we can get
-+           several 3rd error for Intr traffic when a device is unplugged */
-+        if(urb_priv->later_data == NULL) {
-+          /* 3rd error. */
-+          irq_warn("3rd error for epid:%d (%s %s) URB:0x%x[%d]\n", epid,
-+                   str_dir(urb->pipe), str_type(urb->pipe),
-+                   (unsigned int)urb, urb_priv->urb_num);
-+        
-+          tc_finish_urb_later(hcd, urb, -EPROTO);
-+        }
-+
-+      } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
-+        irq_warn("Perror for epid:%d\n", epid);
-+        printk("FM_NUMBER: %d\n", reg->r_usb_fm_number & 0x7ff);
-+        printk("R_USB_STATUS: 0x%x\n", reg->r_usb_status);
-+        __dump_urb(urb);
-+        debug_epid(epid);
-+
-+        if (!(ept_data & IO_MASK(R_USB_EPT_DATA, valid))) {
-+          /* invalid ep_id */
-+          panic("Perror because of invalid epid."
-+                " Deconfigured too early?");
-+        } else {
-+          /* past eof1, near eof, zout transfer, setup transfer */
-+          /* Dump the urb and the relevant EP descriptor. */
-+          panic("Something wrong with DMA descriptor contents."
-+                " Too much traffic inserted?");
-+        }
-+      } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
-+        /* buffer ourun */
-+        printk("FM_NUMBER: %d\n", reg->r_usb_fm_number & 0x7ff);
-+        printk("R_USB_STATUS: 0x%x\n", reg->r_usb_status);
-+        __dump_urb(urb);
-+        debug_epid(epid);
-+
-+        panic("Buffer overrun/underrun for epid:%d. DMA too busy?", epid);
-+      } else {
-+        irq_warn("Attention on epid:%d (%s %s) with no error code\n", epid,
-+                 str_dir(urb->pipe), str_type(urb->pipe));
-+        printk("R_USB_STATUS: 0x%x\n", reg->r_usb_status);
-+        __dump_urb(urb);
-+        debug_epid(epid);
-+      }
-+
-+      } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code,
-+                                            stall)) {
-+      /* Not really a protocol error, just says that the endpoint gave
-+         a stall response. Note that error_code cannot be stall for isoc. */
-+      if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-+        panic("Isoc traffic cannot stall");
-+      }
-+
-+      tc_dbg("Stall for epid:%d (%s %s) URB:0x%x\n", epid,
-+             str_dir(urb->pipe), str_type(urb->pipe), (unsigned int)urb);
-+      tc_finish_urb(hcd, urb, -EPIPE);
-+
-+      } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code,
-+                                            bus_error)) {
-+      /* Two devices responded to a transaction request. Must be resolved
-+         by software. FIXME: Reset ports? */
-+      panic("Bus error for epid %d."
-+            " Two devices responded to transaction request\n",
-+            epid);
-+
-+      } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code,
-+                                            buffer_error)) {
-+      /* DMA overrun or underrun. */
-+      irq_warn("Buffer overrun/underrun for epid:%d (%s %s)\n", epid,
-+               str_dir(urb->pipe), str_type(urb->pipe));
-+
-+      /* It seems that error_code = buffer_error in
-+         R_USB_EPT_DATA/R_USB_EPT_DATA_ISO and ourun = yes in R_USB_STATUS
-+         are the same error. */
-+      tc_finish_urb(hcd, urb, -EPROTO);
-+      } else {
-+        irq_warn("Unknown attention on epid:%d (%s %s)\n", epid,
-+                 str_dir(urb->pipe), str_type(urb->pipe));
-+        dump_ept_data(epid);
-+      }
-+    }
-+  }
-+  DBFEXIT;
-+}
-+
-+void crisv10_hcd_port_status_irq(struct crisv10_irq_reg *reg)
-+{
-+  __u16 port_reg[USB_ROOT_HUB_PORTS];
-+  DBFENTER;
-+  port_reg[0] = reg->r_usb_rh_port_status_1;
-+  port_reg[1] = reg->r_usb_rh_port_status_2;
-+  rh_port_status_change(port_reg);
-+  DBFEXIT;
-+}
-+
-+void crisv10_hcd_isoc_eof_irq(struct crisv10_irq_reg *reg)
-+{
-+  int epid;
-+  struct urb *urb;
-+  struct crisv10_urb_priv *urb_priv;
-+
-+  DBFENTER;
-+
-+  for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) {
-+
-+    /* Only check epids that are in use, is valid and has SB list */
-+    if (!epid_inuse(epid) || epid == INVALID_EPID ||
-+      TxIsocEPList[epid].sub == 0 || epid == DUMMY_EPID) {
-+      /* Nothing here to see. */
-+      continue;
-+    }
-+    ASSERT(epid_isoc(epid));
-+
-+    /* Get the active URB for this epid (if any). */
-+    urb = activeUrbList[epid];
-+    if (urb == 0) {
-+      isoc_warn("Ignoring NULL urb for epid:%d\n", epid);
-+      continue;
-+    }
-+    if(!epid_out_traffic(epid)) {
-+      /* Sanity check. */
-+      ASSERT(usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS);
-+
-+      urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+      ASSERT(urb_priv);
-+
-+      if (urb_priv->urb_state == NOT_STARTED) {
-+      /* If ASAP is not set and urb->start_frame is the current frame,
-+         start the transfer. */
-+      if (!(urb->transfer_flags & URB_ISO_ASAP) &&
-+          (urb->start_frame == (*R_USB_FM_NUMBER & 0x7ff))) {
-+        /* EP should not be enabled if we're waiting for start_frame */
-+        ASSERT((TxIsocEPList[epid].command &
-+                IO_STATE(USB_EP_command, enable, yes)) == 0);
-+
-+        isoc_warn("Enabling isoc IN EP descr for epid %d\n", epid);
-+        TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-+
-+        /* This urb is now active. */
-+        urb_priv->urb_state = STARTED;
-+        continue;
-+      }
-+      }
-+    }
-+  }
-+
-+  DBFEXIT;
-+}
-+
-+void crisv10_hcd_ctl_status_irq(struct crisv10_irq_reg *reg)
-+{
-+  struct crisv10_hcd* crisv10_hcd = hcd_to_crisv10_hcd(reg->hcd);
-+
-+  DBFENTER;
-+  ASSERT(crisv10_hcd);
-+
-+  irq_dbg("ctr_status_irq, controller status: %s\n",
-+        hcd_status_to_str(reg->r_usb_status));
-+  
-+  /* FIXME: What should we do if we get ourun or perror? Dump the EP and SB
-+     list for the corresponding epid? */
-+  if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
-+    panic("USB controller got ourun.");
-+  }
-+  if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
-+    
-+    /* Before, etrax_usb_do_intr_recover was called on this epid if it was
-+       an interrupt pipe. I don't see how re-enabling all EP descriptors
-+       will help if there was a programming error. */
-+    panic("USB controller got perror.");
-+  }
-+
-+  /* Keep track of USB Controller, if it's running or not */
-+  if(reg->r_usb_status & IO_STATE(R_USB_STATUS, running, yes)) {
-+    crisv10_hcd->running = 1;
-+  } else {
-+    crisv10_hcd->running = 0;
-+  }
-+  
-+  if (reg->r_usb_status & IO_MASK(R_USB_STATUS, device_mode)) {
-+    /* We should never operate in device mode. */
-+    panic("USB controller in device mode.");
-+  }
-+
-+  /* Set the flag to avoid getting "Unlink after no-IRQ? Controller is probably
-+     using the wrong IRQ" from hcd_unlink_urb() in drivers/usb/core/hcd.c */
-+  set_bit(HCD_FLAG_SAW_IRQ, &reg->hcd->flags);
-+  
-+  DBFEXIT;
-+}
-+
-+
-+/******************************************************************/
-+/* Host Controller interface functions                            */
-+/******************************************************************/
-+
-+static inline void crisv10_ready_wait(void) {
-+  volatile int timeout = 10000;
-+  /* Check the busy bit of USB controller in Etrax */
-+  while((*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)) &&
-+      (timeout-- > 0));
-+  if(timeout == 0) {
-+    warn("Timeout while waiting for USB controller to be idle\n");
-+  }
-+}
-+
-+/* reset host controller */
-+static int crisv10_hcd_reset(struct usb_hcd *hcd)
-+{
-+  DBFENTER;
-+  hcd_dbg(hcd, "reset\n");
-+
-+
-+  /* Reset the USB interface. */
-+  /*
-+  *R_USB_COMMAND =
-+    IO_STATE(R_USB_COMMAND, port_sel, nop) |
-+    IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-+    IO_STATE(R_USB_COMMAND, ctrl_cmd, reset);
-+  nop();
-+  */
-+  DBFEXIT;
-+  return 0;
-+}
-+
-+/* start host controller */
-+static int crisv10_hcd_start(struct usb_hcd *hcd)
-+{
-+  DBFENTER;
-+  hcd_dbg(hcd, "start\n");
-+
-+  crisv10_ready_wait();
-+
-+  /* Start processing of USB traffic. */
-+  *R_USB_COMMAND =
-+    IO_STATE(R_USB_COMMAND, port_sel, nop) |
-+    IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-+    IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
-+
-+  nop();
-+
-+  hcd->state = HC_STATE_RUNNING;
-+
-+  DBFEXIT;
-+  return 0;
-+}
-+
-+/* stop host controller */
-+static void crisv10_hcd_stop(struct usb_hcd *hcd)
-+{
-+  DBFENTER;
-+  hcd_dbg(hcd, "stop\n");
-+  crisv10_hcd_reset(hcd);
-+  DBFEXIT;
-+}
-+
-+/* return the current frame number */
-+static int crisv10_hcd_get_frame(struct usb_hcd *hcd)
-+{
-+  DBFENTER;
-+  DBFEXIT;
-+  return (*R_USB_FM_NUMBER & 0x7ff);
-+}
-+
-+#ifdef        CONFIG_USB_OTG
-+
-+static int crisv10_hcd_start_port_reset(struct usb_hcd *hcd, unsigned port)
-+{
-+  return 0; /* no-op for now */
-+}
-+
-+#endif /* CONFIG_USB_OTG */
-+
-+
-+/******************************************************************/
-+/* Root Hub functions                                             */
-+/******************************************************************/
-+
-+/* root hub status */
-+static const struct usb_hub_status rh_hub_status = 
-+  {
-+    .wHubStatus =             0,
-+    .wHubChange =             0,
-+  };
-+
-+/* root hub descriptor */
-+static const u8 rh_hub_descr[] =
-+  {
-+    0x09,                     /* bDescLength         */
-+    0x29,                     /* bDescriptorType     */
-+    USB_ROOT_HUB_PORTS,         /* bNbrPorts         */
-+    0x00,                     /* wHubCharacteristics */
-+    0x00,              
-+    0x01,                     /* bPwrOn2pwrGood      */
-+    0x00,                     /* bHubContrCurrent    */
-+    0x00,                     /* DeviceRemovable     */
-+    0xff                      /* PortPwrCtrlMask     */
-+  };
-+
-+/* Actual holder of root hub status*/
-+struct crisv10_rh rh;
-+
-+/* Initialize root hub data structures (called from dvdrv_hcd_probe()) */
-+int rh_init(void) {
-+  int i;
-+  /* Reset port status flags */
-+  for (i = 0; i < USB_ROOT_HUB_PORTS; i++) {
-+    rh.wPortChange[i] = 0;
-+    rh.wPortStatusPrev[i] = 0;
-+  }
-+  return 0;
-+}
-+
-+#define RH_FEAT_MASK ((1<<USB_PORT_FEAT_CONNECTION)|\
-+                    (1<<USB_PORT_FEAT_ENABLE)|\
-+                    (1<<USB_PORT_FEAT_SUSPEND)|\
-+                    (1<<USB_PORT_FEAT_RESET))
-+
-+/* Handle port status change interrupt (called from bottom part interrupt) */
-+void rh_port_status_change(__u16 port_reg[]) {
-+  int i;
-+  __u16 wChange;
-+
-+  for(i = 0; i < USB_ROOT_HUB_PORTS; i++) {
-+    /* Xor out changes since last read, masked for important flags */
-+    wChange = (port_reg[i] & RH_FEAT_MASK) ^ rh.wPortStatusPrev[i];
-+    /* Or changes together with (if any) saved changes */
-+    rh.wPortChange[i] |= wChange;
-+    /* Save new status */
-+    rh.wPortStatusPrev[i] = port_reg[i];
-+
-+    if(wChange) {
-+      rh_dbg("Interrupt port_status change port%d: %s  Current-status:%s\n", i+1,
-+           port_status_to_str(wChange),
-+           port_status_to_str(port_reg[i]));
-+    }
-+  }
-+}
-+
-+/* Construct port status change bitmap for the root hub */
-+static int rh_status_data_request(struct usb_hcd *hcd, char *buf)
-+{
-+  struct crisv10_hcd* crisv10_hcd = hcd_to_crisv10_hcd(hcd);
-+  unsigned int i;
-+
-+//  DBFENTER;
-+  
-+  /*
-+   * corresponds to hub status change EP (USB 2.0 spec section 11.13.4)
-+   * return bitmap indicating ports with status change
-+   */
-+  *buf = 0;
-+  spin_lock(&crisv10_hcd->lock);
-+  for (i = 1; i <= crisv10_hcd->num_ports; i++) {
-+    if (rh.wPortChange[map_port(i)]) {
-+      *buf |= (1 << i);
-+      rh_dbg("rh_status_data_request, change on port %d: %s  Current Status: %s\n", i,
-+           port_status_to_str(rh.wPortChange[map_port(i)]),
-+           port_status_to_str(rh.wPortStatusPrev[map_port(i)]));
-+    }
-+  }
-+  spin_unlock(&crisv10_hcd->lock);
-+
-+// DBFEXIT;
-+
-+  return *buf == 0 ? 0 : 1;
-+}
-+
-+/* Handle a control request for the root hub (called from hcd_driver) */
-+static int rh_control_request(struct usb_hcd *hcd, 
-+                            u16 typeReq, 
-+                            u16 wValue, 
-+                            u16 wIndex,
-+                            char *buf, 
-+                            u16 wLength) {
-+
-+  struct crisv10_hcd *crisv10_hcd = hcd_to_crisv10_hcd(hcd);
-+  int retval = 0;
-+  int len;
-+  DBFENTER;
-+
-+  switch (typeReq) {
-+  case GetHubDescriptor:
-+    rh_dbg("GetHubDescriptor\n");
-+    len = min_t(unsigned int, sizeof rh_hub_descr, wLength);
-+    memcpy(buf, rh_hub_descr, len);
-+    buf[2] = crisv10_hcd->num_ports;
-+    break;
-+  case GetHubStatus:
-+    rh_dbg("GetHubStatus\n");
-+    len = min_t(unsigned int, sizeof rh_hub_status, wLength);
-+    memcpy(buf, &rh_hub_status, len);
-+    break;
-+  case GetPortStatus:
-+    if (!wIndex || wIndex > crisv10_hcd->num_ports)
-+      goto error;
-+    rh_dbg("GetportStatus, port:%d change:%s  status:%s\n", wIndex,
-+         port_status_to_str(rh.wPortChange[map_port(wIndex)]),
-+         port_status_to_str(rh.wPortStatusPrev[map_port(wIndex)]));
-+    *(u16 *) buf = cpu_to_le16(rh.wPortStatusPrev[map_port(wIndex)]);
-+    *(u16 *) (buf + 2) = cpu_to_le16(rh.wPortChange[map_port(wIndex)]);
-+    break;
-+  case SetHubFeature:
-+    rh_dbg("SetHubFeature\n");
-+  case ClearHubFeature:
-+    rh_dbg("ClearHubFeature\n");
-+    switch (wValue) {
-+    case C_HUB_OVER_CURRENT:
-+    case C_HUB_LOCAL_POWER:
-+      rh_warn("Not implemented hub request:%d \n", typeReq);
-+      /* not implemented */
-+      break;
-+    default:
-+      goto error;
-+    }
-+    break;
-+  case SetPortFeature:
-+    if (!wIndex || wIndex > crisv10_hcd->num_ports)
-+      goto error;
-+    if(rh_set_port_feature(map_port(wIndex), wValue))
-+      goto error;
-+    break;
-+  case ClearPortFeature:
-+    if (!wIndex || wIndex > crisv10_hcd->num_ports)
-+      goto error;
-+    if(rh_clear_port_feature(map_port(wIndex), wValue))
-+      goto error;
-+    break;
-+  default:
-+    rh_warn("Unknown hub request: %d\n", typeReq);
-+  error:
-+    retval = -EPIPE;
-+  }
-+  DBFEXIT;
-+  return retval;
-+}
-+
-+int rh_set_port_feature(__u8 bPort, __u16 wFeature) {
-+  __u8 bUsbCommand = 0;
-+  switch(wFeature) {
-+  case USB_PORT_FEAT_RESET:
-+    rh_dbg("SetPortFeature: reset\n");
-+    bUsbCommand |= IO_STATE(R_USB_COMMAND, port_cmd, reset);
-+    goto set;
-+    break;
-+  case USB_PORT_FEAT_SUSPEND:
-+    rh_dbg("SetPortFeature: suspend\n");
-+    bUsbCommand |= IO_STATE(R_USB_COMMAND, port_cmd, suspend);
-+    goto set;
-+    break;
-+  case USB_PORT_FEAT_POWER:
-+    rh_dbg("SetPortFeature: power\n");
-+    break;
-+  case USB_PORT_FEAT_C_CONNECTION:
-+    rh_dbg("SetPortFeature: c_connection\n");
-+    break;
-+  case USB_PORT_FEAT_C_RESET:
-+    rh_dbg("SetPortFeature: c_reset\n");
-+    break;
-+  case USB_PORT_FEAT_C_OVER_CURRENT:
-+    rh_dbg("SetPortFeature: c_over_current\n");
-+    break;
-+
-+  set:
-+    /* Select which port via the port_sel field */
-+    bUsbCommand |= IO_FIELD(R_USB_COMMAND, port_sel, bPort+1);
-+
-+    /* Make sure the controller isn't busy. */
-+    crisv10_ready_wait();
-+    /* Send out the actual command to the USB controller */
-+    *R_USB_COMMAND = bUsbCommand;
-+
-+    /* If port reset then also bring USB controller into running state */
-+    if(wFeature == USB_PORT_FEAT_RESET) {
-+      /* Wait a while for controller to first become started after port reset */
-+      udelay(12000); /* 12ms blocking wait */
-+      
-+      /* Make sure the controller isn't busy. */
-+      crisv10_ready_wait();
-+
-+      /* If all enabled ports were disabled the host controller goes down into
-+       started mode, so we need to bring it back into the running state.
-+       (This is safe even if it's already in the running state.) */
-+      *R_USB_COMMAND =
-+      IO_STATE(R_USB_COMMAND, port_sel, nop) |
-+      IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-+      IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
-+    }
-+
-+    break;
-+  default:
-+    rh_dbg("SetPortFeature: unknown feature\n");
-+    return -1;
-+  }
-+  return 0;
-+}
-+
-+int rh_clear_port_feature(__u8 bPort, __u16 wFeature) {
-+  switch(wFeature) {
-+  case USB_PORT_FEAT_ENABLE:
-+    rh_dbg("ClearPortFeature: enable\n");
-+    rh_disable_port(bPort);
-+    break;
-+  case USB_PORT_FEAT_SUSPEND:
-+    rh_dbg("ClearPortFeature: suspend\n");
-+    break;
-+  case USB_PORT_FEAT_POWER:
-+    rh_dbg("ClearPortFeature: power\n");
-+    break;
-+
-+  case USB_PORT_FEAT_C_ENABLE:
-+    rh_dbg("ClearPortFeature: c_enable\n");
-+    goto clear;
-+  case USB_PORT_FEAT_C_SUSPEND:
-+    rh_dbg("ClearPortFeature: c_suspend\n");
-+    goto clear;
-+  case USB_PORT_FEAT_C_CONNECTION:
-+    rh_dbg("ClearPortFeature: c_connection\n");
-+    goto clear;
-+  case USB_PORT_FEAT_C_OVER_CURRENT:
-+    rh_dbg("ClearPortFeature: c_over_current\n");
-+    goto clear;
-+  case USB_PORT_FEAT_C_RESET:
-+    rh_dbg("ClearPortFeature: c_reset\n");
-+    goto clear;
-+  clear:
-+    rh.wPortChange[bPort] &= ~(1 << (wFeature - 16));
-+    break;
-+  default:
-+    rh_dbg("ClearPortFeature: unknown feature\n");
-+    return -1;
-+  }
-+  return 0;
-+}
-+
-+
-+#ifdef        CONFIG_PM
-+/* Handle a suspend request for the root hub (called from hcd_driver) */
-+static int rh_suspend_request(struct usb_hcd *hcd)
-+{
-+  return 0; /* no-op for now */
-+}
-+
-+/* Handle a resume request for the root hub (called from hcd_driver) */
-+static int rh_resume_request(struct usb_hcd *hcd)
-+{
-+  return 0; /* no-op for now */
-+}
-+#endif /* CONFIG_PM */
-+
-+
-+
-+/* Wrapper function for workaround port disable registers in USB controller  */
-+static void rh_disable_port(unsigned int port) {
-+  volatile int timeout = 10000;
-+  volatile char* usb_portx_disable;
-+  switch(port) {
-+  case 0:
-+    usb_portx_disable = R_USB_PORT1_DISABLE;
-+    break;
-+  case 1:
-+    usb_portx_disable = R_USB_PORT2_DISABLE;
-+    break;
-+  default:
-+    /* Invalid port index */
-+    return;
-+  }
-+  /* Set disable flag in special register  */
-+  *usb_portx_disable = IO_STATE(R_USB_PORT1_DISABLE, disable, yes);
-+  /* Wait until not enabled anymore */
-+  while((rh.wPortStatusPrev[port] &
-+      IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes)) &&
-+      (timeout-- > 0));
-+  if(timeout == 0) {
-+    warn("Timeout while waiting for port %d to become disabled\n", port);
-+  }
-+  /* clear disable flag in special register  */
-+  *usb_portx_disable = IO_STATE(R_USB_PORT1_DISABLE, disable, no);
-+  rh_info("Physical port %d disabled\n", port+1);
-+}
-+
-+
-+/******************************************************************/
-+/* Transfer Controller (TC) functions                             */
-+/******************************************************************/
-+
-+/* FIXME: Should RX_BUF_SIZE be a config option, or maybe we should adjust it
-+   dynamically?
-+   To adjust it dynamically we would have to get an interrupt when we reach
-+   the end of the rx descriptor list, or when we get close to the end, and
-+   then allocate more descriptors. */
-+#define NBR_OF_RX_DESC     512
-+#define RX_DESC_BUF_SIZE   1024
-+#define RX_BUF_SIZE        (NBR_OF_RX_DESC * RX_DESC_BUF_SIZE)
-+
-+
-+/* Local variables for Transfer Controller */
-+/* --------------------------------------- */
-+
-+/* This is a circular (double-linked) list of the active urbs for each epid.
-+   The head is never removed, and new urbs are linked onto the list as
-+   urb_entry_t elements. Don't reference urb_list directly; use the wrapper
-+   functions instead (which includes spin_locks) */
-+static struct list_head urb_list[NBR_OF_EPIDS];
-+
-+/* Read about the need and usage of this lock in submit_ctrl_urb. */
-+/* Lock for URB lists for each EPID */
-+static spinlock_t urb_list_lock;
-+
-+/* Lock for EPID array register (R_USB_EPT_x) in Etrax */
-+static spinlock_t etrax_epid_lock;
-+
-+/* Lock for dma8 sub0 handling */
-+static spinlock_t etrax_dma8_sub0_lock;
-+
-+/* DMA IN cache bug. Align the DMA IN buffers to 32 bytes, i.e. a cache line.
-+   Since RX_DESC_BUF_SIZE is 1024 is a multiple of 32, all rx buffers will be
-+   cache aligned. */
-+static volatile unsigned char RxBuf[RX_BUF_SIZE] __attribute__ ((aligned (32)));
-+static volatile struct USB_IN_Desc RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned (4)));
-+
-+/* Pointers into RxDescList. */
-+static volatile struct USB_IN_Desc *myNextRxDesc;
-+static volatile struct USB_IN_Desc *myLastRxDesc;
-+
-+/* A zout transfer makes a memory access at the address of its buf pointer,
-+   which means that setting this buf pointer to 0 will cause an access to the
-+   flash. In addition to this, setting sw_len to 0 results in a 16/32 bytes
-+   (depending on DMA burst size) transfer.
-+   Instead, we set it to 1, and point it to this buffer. */
-+static int zout_buffer[4] __attribute__ ((aligned (4)));
-+
-+/* Cache for allocating new EP and SB descriptors. */
-+//static kmem_cache_t *usb_desc_cache;
-+static struct kmem_cache *usb_desc_cache;
-+
-+/* Cache for the data allocated in the isoc descr top half. */
-+//static kmem_cache_t *isoc_compl_cache;
-+static struct kmem_cache *isoc_compl_cache;
-+
-+/* Cache for the data allocated when delayed finishing of URBs */
-+//static kmem_cache_t *later_data_cache;
-+static struct kmem_cache *later_data_cache;
-+
-+/* Counter to keep track of how many Isoc EP we have sat up. Used to enable
-+   and disable iso_eof interrupt. We only need these interrupts when we have
-+   Isoc data endpoints (consumes CPU cycles).
-+   FIXME: This could be more fine granular, so this interrupt is only enabled
-+   when we have a In Isoc URB not URB_ISO_ASAP flaged queued. */
-+static int isoc_epid_counter;
-+
-+/* Protecting wrapper functions for R_USB_EPT_x */
-+/* -------------------------------------------- */
-+static inline void etrax_epid_set(__u8 index, __u32 data) {
-+  unsigned long flags;
-+  spin_lock_irqsave(&etrax_epid_lock, flags);
-+  *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, index);
-+  nop();
-+  *R_USB_EPT_DATA = data;
-+  spin_unlock_irqrestore(&etrax_epid_lock, flags);
-+}
-+
-+static inline void etrax_epid_clear_error(__u8 index) {
-+  unsigned long flags;
-+  spin_lock_irqsave(&etrax_epid_lock, flags);
-+  *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, index);
-+  nop();
-+  *R_USB_EPT_DATA &=
-+    ~(IO_MASK(R_USB_EPT_DATA, error_count_in) |
-+      IO_MASK(R_USB_EPT_DATA, error_count_out) |
-+      IO_MASK(R_USB_EPT_DATA, error_code));
-+  spin_unlock_irqrestore(&etrax_epid_lock, flags);
-+}
-+
-+static inline void etrax_epid_set_toggle(__u8 index, __u8 dirout,
-+                                             __u8 toggle) {
-+  unsigned long flags;
-+  spin_lock_irqsave(&etrax_epid_lock, flags);
-+  *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, index);
-+  nop();
-+  if(dirout) {
-+    *R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_out);
-+    *R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_out, toggle);
-+  } else {
-+    *R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_in);
-+    *R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_in, toggle);
-+  }
-+  spin_unlock_irqrestore(&etrax_epid_lock, flags);
-+}
-+
-+static inline __u8 etrax_epid_get_toggle(__u8 index, __u8 dirout) {
-+  unsigned long flags;
-+  __u8 toggle;
-+  spin_lock_irqsave(&etrax_epid_lock, flags);
-+  *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, index);
-+  nop();
-+  if (dirout) {
-+    toggle = IO_EXTRACT(R_USB_EPT_DATA, t_out, *R_USB_EPT_DATA);
-+  } else {
-+    toggle = IO_EXTRACT(R_USB_EPT_DATA, t_in, *R_USB_EPT_DATA);
-+  }
-+  spin_unlock_irqrestore(&etrax_epid_lock, flags);
-+  return toggle;
-+}
-+
-+
-+static inline __u32 etrax_epid_get(__u8 index) {
-+  unsigned long flags;
-+  __u32 data;
-+  spin_lock_irqsave(&etrax_epid_lock, flags);
-+  *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, index);
-+  nop();
-+  data = *R_USB_EPT_DATA;
-+  spin_unlock_irqrestore(&etrax_epid_lock, flags);
-+  return data;
-+}
-+
-+
-+
-+
-+/* Main functions for Transfer Controller */
-+/* -------------------------------------- */
-+
-+/* Init structs, memories and lists used by Transfer Controller */
-+int tc_init(struct usb_hcd *hcd) {
-+  int i;
-+  /* Clear software state info for all epids */
-+  memset(epid_state, 0, sizeof(struct etrax_epid) * NBR_OF_EPIDS);
-+
-+  /* Set Invalid and Dummy as being in use and disabled */
-+  epid_state[INVALID_EPID].inuse = 1;
-+  epid_state[DUMMY_EPID].inuse = 1;
-+  epid_state[INVALID_EPID].disabled = 1;
-+  epid_state[DUMMY_EPID].disabled = 1;
-+
-+  /* Clear counter for how many Isoc epids we have sat up */
-+  isoc_epid_counter = 0;
-+
-+  /* Initialize the urb list by initiating a head for each list.
-+     Also reset list hodling active URB for each epid */
-+  for (i = 0; i < NBR_OF_EPIDS; i++) {
-+    INIT_LIST_HEAD(&urb_list[i]);
-+    activeUrbList[i] = NULL;
-+  }
-+
-+  /* Init lock for URB lists */
-+  spin_lock_init(&urb_list_lock);
-+  /* Init lock for Etrax R_USB_EPT register */
-+  spin_lock_init(&etrax_epid_lock);
-+  /* Init lock for Etrax dma8 sub0 handling */
-+  spin_lock_init(&etrax_dma8_sub0_lock);
-+
-+  /* We use kmem_cache_* to make sure that all DMA desc. are dword aligned */
-+
-+  /* Note that we specify sizeof(struct USB_EP_Desc) as the size, but also
-+     allocate SB descriptors from this cache. This is ok since
-+     sizeof(struct USB_EP_Desc) == sizeof(struct USB_SB_Desc). */
-+//  usb_desc_cache = kmem_cache_create("usb_desc_cache",
-+//                                 sizeof(struct USB_EP_Desc), 0,
-+//                                 SLAB_HWCACHE_ALIGN, 0, 0);
-+  usb_desc_cache = kmem_cache_create(
-+                                "usb_desc_cache",
-+                                sizeof(struct USB_EP_Desc),
-+                                0,
-+                                SLAB_HWCACHE_ALIGN,
-+                                NULL);
-+  if(usb_desc_cache == NULL) {
-+    return -ENOMEM;
-+  }
-+
-+  /* Create slab cache for speedy allocation of memory for isoc bottom-half
-+     interrupt handling */
-+//  isoc_compl_cache =
-+//    kmem_cache_create("isoc_compl_cache",
-+//                  sizeof(struct crisv10_isoc_complete_data),
-+//                  0, SLAB_HWCACHE_ALIGN, 0, 0);
-+  isoc_compl_cache = kmem_cache_create(
-+                                "isoc_compl_cache",
-+                                sizeof(struct crisv10_isoc_complete_data),
-+                                0,
-+                                SLAB_HWCACHE_ALIGN,
-+                                NULL
-+                                );
-+
-+  if(isoc_compl_cache == NULL) {
-+    return -ENOMEM;
-+  }
-+
-+  /* Create slab cache for speedy allocation of memory for later URB finish
-+     struct */
-+//  later_data_cache =
-+//    kmem_cache_create("later_data_cache",
-+//                  sizeof(struct urb_later_data),
-+//                  0, SLAB_HWCACHE_ALIGN, 0, 0);
-+
-+  later_data_cache = kmem_cache_create(
-+                                "later_data_cache",
-+                                sizeof(struct urb_later_data),
-+                                0,
-+                                SLAB_HWCACHE_ALIGN,
-+                                NULL
-+                                );
-+  
-+  if(later_data_cache == NULL) {
-+    return -ENOMEM;
-+  }
-+
-+
-+  /* Initiate the bulk start timer. */
-+  init_timer(&bulk_start_timer);
-+  bulk_start_timer.expires = jiffies + BULK_START_TIMER_INTERVAL;
-+  bulk_start_timer.function = tc_bulk_start_timer_func;
-+  add_timer(&bulk_start_timer);
-+
-+
-+  /* Initiate the bulk eot timer. */
-+  init_timer(&bulk_eot_timer);
-+  bulk_eot_timer.expires = jiffies + BULK_EOT_TIMER_INTERVAL;
-+  bulk_eot_timer.function = tc_bulk_eot_timer_func;
-+  bulk_eot_timer.data = (unsigned long)hcd;
-+  add_timer(&bulk_eot_timer);
-+
-+  return 0;
-+}
-+
-+/* Uninitialize all resources used by Transfer Controller */
-+void tc_destroy(void) {
-+
-+  /* Destroy all slab cache */
-+  kmem_cache_destroy(usb_desc_cache);
-+  kmem_cache_destroy(isoc_compl_cache);
-+  kmem_cache_destroy(later_data_cache);
-+
-+  /* Remove timers */
-+  del_timer(&bulk_start_timer);
-+  del_timer(&bulk_eot_timer);
-+}
-+
-+static void restart_dma8_sub0(void) {
-+  unsigned long flags;
-+  spin_lock_irqsave(&etrax_dma8_sub0_lock, flags);
-+  /* Verify that the dma is not running */
-+  if ((*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd)) == 0) {
-+    struct USB_EP_Desc *ep = (struct USB_EP_Desc *)phys_to_virt(*R_DMA_CH8_SUB0_EP);
-+    while (DUMMY_EPID == IO_EXTRACT(USB_EP_command, epid, ep->command)) {
-+      ep = (struct USB_EP_Desc *)phys_to_virt(ep->next);
-+    }
-+    /* Advance the DMA to the next EP descriptor that is not a DUMMY_EPID.
-+       * ep->next is already a physical address. virt_to_phys is needed, see
-+       * http://mhonarc.axis.se/dev-etrax/msg08630.html
-+       */
-+    //*R_DMA_CH8_SUB0_EP = ep->next;
-+      *R_DMA_CH8_SUB0_EP = virt_to_phys(ep);
-+    /* Restart the DMA */
-+    *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
-+  }
-+  spin_unlock_irqrestore(&etrax_dma8_sub0_lock, flags);
-+}
-+
-+/* queue an URB with the transfer controller (called from hcd_driver) */
-+//static int tc_urb_enqueue(struct usb_hcd *hcd, 
-+//                      struct usb_host_endpoint *ep,
-+//                      struct urb *urb, 
-+//                      gfp_t mem_flags) {
-+static int tc_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
-+{
-+  int epid;
-+  int retval;
-+//  int bustime = 0;
-+  int maxpacket;
-+  unsigned long flags;
-+  struct crisv10_urb_priv *urb_priv;
-+  struct crisv10_hcd* crisv10_hcd = hcd_to_crisv10_hcd(hcd);
-+  DBFENTER;
-+
-+  if(!(crisv10_hcd->running)) {
-+    /* The USB Controller is not running, probably because no device is 
-+       attached. No idea to enqueue URBs then */
-+    tc_warn("Rejected enqueueing of URB:0x%x because no dev attached\n",
-+          (unsigned int)urb);
-+    return -ENOENT;
-+  }
-+
-+  maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-+  
-+  /* hinko ignore usb_pipeisoc */
-+#if 0
-+  /* Special case check for In Isoc transfers. Specification states that each
-+     In Isoc transfer consists of one packet and therefore it should fit into
-+     the transfer-buffer of an URB.
-+     We do the check here to be sure (an invalid scenario can be produced with
-+     parameters to the usbtest suite) */
-+  if(usb_pipeisoc(urb->pipe) && usb_pipein(urb->pipe) &&
-+     (urb->transfer_buffer_length < maxpacket)) {
-+    tc_err("Submit In Isoc URB with buffer length:%d to pipe with maxpacketlen: %d\n", urb->transfer_buffer_length, maxpacket);
-+    return -EMSGSIZE;
-+  }
-+
-+  /* Check if there is enough bandwidth for periodic transfer  */
-+  if(usb_pipeint(urb->pipe) || usb_pipeisoc(urb->pipe)) {
-+    /* only check (and later claim) if not already claimed */
-+    if (urb->bandwidth == 0) {
-+      bustime = usb_check_bandwidth(urb->dev, urb);
-+      if (bustime < 0) {
-+      tc_err("Not enough periodic bandwidth\n");
-+      return -ENOSPC;
-+      }
-+    }
-+  }
-+#endif
-+  
-+  /* Check if there is a epid for URBs destination, if not this function
-+     set up one. */
-+  //epid = tc_setup_epid(ep, urb, mem_flags);
-+  epid = tc_setup_epid(urb, mem_flags);
-+  if (epid < 0) {
-+    tc_err("Failed setup epid:%d for URB:0x%x\n", epid, (unsigned int)urb);
-+    DBFEXIT;
-+    return -ENOMEM;
-+  }
-+
-+  if(urb == activeUrbList[epid]) {
-+    tc_err("Resubmition of allready active URB:0x%x\n", (unsigned int)urb);
-+    return -ENXIO;
-+  }
-+
-+  if(urb_list_entry(urb, epid)) {
-+    tc_err("Resubmition of allready queued URB:0x%x\n", (unsigned int)urb);
-+    return -ENXIO;
-+  }
-+
-+  /* If we actively have flaged endpoint as disabled then refuse submition */
-+  if(epid_state[epid].disabled) {
-+    return -ENOENT;
-+  }
-+
-+  /* Allocate and init HC-private data for URB */
-+  if(urb_priv_create(hcd, urb, epid, mem_flags) != 0) {
-+    DBFEXIT;
-+    return -ENOMEM;
-+  }
-+  urb_priv = urb->hcpriv;
-+
-+  tc_dbg("Enqueue URB:0x%x[%d] epid:%d (%s) bufflen:%d\n",
-+       (unsigned int)urb, urb_priv->urb_num, epid,
-+       pipe_to_str(urb->pipe), urb->transfer_buffer_length);
-+
-+  /* Create and link SBs required for this URB */
-+  retval = create_sb_for_urb(urb, mem_flags);
-+  if(retval != 0) {
-+    tc_err("Failed to create SBs for URB:0x%x[%d]\n", (unsigned int)urb,
-+         urb_priv->urb_num);
-+    urb_priv_free(hcd, urb);
-+    DBFEXIT;
-+    return retval;
-+  }
-+
-+  /* Init intr EP pool if this URB is a INTR transfer. This pool is later
-+     used when inserting EPs in the TxIntrEPList. We do the alloc here
-+     so we can't run out of memory later */
-+  if(usb_pipeint(urb->pipe)) {
-+    retval = init_intr_urb(urb, mem_flags);
-+    if(retval != 0) {
-+      tc_warn("Failed to init Intr URB\n");
-+      urb_priv_free(hcd, urb);
-+      DBFEXIT;
-+      return retval;
-+    }
-+  }
-+
-+  /* Disable other access when inserting USB */
-+
-+  /* BUG on sleeping inside int disabled if using local_irq_save/local_irq_restore
-+   * her - because urb_list_add() and tc_dma_process_queue() save irqs again !??!
-+   */
-+//  local_irq_save(flags);
-+
-+  /* hinko ignore usb_pipeisoc */
-+#if 0
-+  /* Claim bandwidth, if needed */
-+  if(bustime) {
-+    usb_claim_bandwidth(urb->dev, urb, bustime, 0);
-+  }
-+  
-+  /* Add URB to EP queue */
-+  urb_list_add(urb, epid, mem_flags);
-+
-+  if(usb_pipeisoc(urb->pipe)) {
-+    /* Special processing of Isoc URBs. */
-+    tc_dma_process_isoc_urb(urb);
-+  } else {
-+    /* Process EP queue for rest of the URB types (Bulk, Ctrl, Intr) */
-+    tc_dma_process_queue(epid);
-+  }
-+#endif
-+  /* Add URB to EP queue */
-+  urb_list_add(urb, epid, mem_flags);
-+
-+  /*hinko link/unlink urb -> ep */
-+  spin_lock_irqsave(&crisv10_hcd->lock, flags);
-+  //spin_lock(&crisv10_hcd->lock);
-+  retval = usb_hcd_link_urb_to_ep(hcd, urb);
-+  if (retval) {
-+    spin_unlock_irqrestore(&crisv10_hcd->lock, flags);
-+    tc_warn("Failed to link urb to ep\n");
-+    urb_priv_free(hcd, urb);
-+    DBFEXIT;
-+    return retval;
-+  }
-+  spin_unlock_irqrestore(&crisv10_hcd->lock, flags);
-+  //spin_unlock(&crisv10_hcd->lock);
-+  
-+  /* Process EP queue for rest of the URB types (Bulk, Ctrl, Intr) */
-+  tc_dma_process_queue(epid);
-+
-+//  local_irq_restore(flags);
-+
-+  DBFEXIT;
-+  return 0;
-+}
-+
-+/* remove an URB from the transfer controller queues (called from hcd_driver)*/
-+//static int tc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
-+static int tc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
-+{
-+  struct crisv10_urb_priv *urb_priv;
-+  unsigned long flags;
-+  int epid;
-+
-+  DBFENTER;
-+  /* Disable interrupts here since a descriptor interrupt for the isoc epid
-+     will modify the sb list.  This could possibly be done more granular, but
-+     urb_dequeue should not be used frequently anyway.
-+  */
-+  local_irq_save(flags);
-+
-+  urb_priv = urb->hcpriv;
-+
-+  if (!urb_priv) {
-+    /* This happens if a device driver calls unlink on an urb that
-+       was never submitted (lazy driver) or if the urb was completed
-+       while dequeue was being called. */
-+    tc_warn("Dequeing of not enqueued URB:0x%x\n", (unsigned int)urb);
-+    local_irq_restore(flags);
-+    return 0;
-+  }
-+  epid = urb_priv->epid;
-+
-+  tc_warn("Dequeing %s URB:0x%x[%d] (%s %s epid:%d) status:%d %s\n",
-+        (urb == activeUrbList[epid]) ? "active" : "queued",
-+        (unsigned int)urb, urb_priv->urb_num, str_dir(urb->pipe),
-+        str_type(urb->pipe), epid, urb->status,
-+        (urb_priv->later_data) ? "later-sched" : "");
-+
-+  /* For Bulk, Ctrl and Intr are only one URB active at a time. So any URB
-+     that isn't active can be dequeued by just removing it from the queue */
-+  if(usb_pipebulk(urb->pipe) || usb_pipecontrol(urb->pipe) ||
-+     usb_pipeint(urb->pipe)) {
-+
-+    /* Check if URB haven't gone further than the queue */
-+    if(urb != activeUrbList[epid]) {
-+      ASSERT(urb_priv->later_data == NULL);
-+      tc_warn("Dequeing URB:0x%x[%d] (%s %s epid:%d) from queue"
-+            " (not active)\n", (unsigned int)urb, urb_priv->urb_num,
-+            str_dir(urb->pipe), str_type(urb->pipe), epid);
-+      
-+      /* Finish the URB with error status from USB core */
-+      tc_finish_urb(hcd, urb, urb->status);
-+      local_irq_restore(flags);
-+      return 0;
-+    }
-+  }
-+
-+  /* Set URB status to Unlink for handling when interrupt comes. */
-+  urb_priv->urb_state = UNLINK;
-+
-+  /* Differentiate dequeing of Bulk and Ctrl from Isoc and Intr */
-+  switch(usb_pipetype(urb->pipe)) {
-+  case PIPE_BULK:
-+    /* Check if EP still is enabled */
-+    if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-+      /* The EP was enabled, disable it. */
-+      TxBulkEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-+    }
-+    /* Kicking dummy list out of the party. */
-+    TxBulkEPList[epid].next = virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]);
-+    break;
-+  case PIPE_CONTROL:
-+    /* Check if EP still is enabled */
-+    if (TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-+      /* The EP was enabled, disable it. */
-+      TxCtrlEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-+    }
-+    break;
-+  case PIPE_ISOCHRONOUS:
-+    /* Disabling, busy-wait and unlinking of Isoc SBs will be done in
-+       finish_isoc_urb(). Because there might the case when URB is dequeued
-+       but there are other valid URBs waiting */
-+
-+    /* Check if In Isoc EP still is enabled */
-+    if (TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-+      /* The EP was enabled, disable it. */
-+      TxIsocEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-+    }
-+    break;
-+  case PIPE_INTERRUPT:
-+    /* Special care is taken for interrupt URBs. EPs are unlinked in
-+       tc_finish_urb */
-+    break;
-+  default:
-+    break;
-+  }
-+
-+  /* Asynchronous unlink, finish the URB later from scheduled or other
-+     event (data finished, error) */
-+  tc_finish_urb_later(hcd, urb, urb->status);
-+
-+  local_irq_restore(flags);
-+  DBFEXIT;
-+  return 0;
-+}
-+
-+
-+static void tc_sync_finish_epid(struct usb_hcd *hcd, int epid) {
-+  volatile int timeout = 10000;
-+  struct urb* urb;
-+  struct crisv10_urb_priv* urb_priv;
-+  unsigned long flags;
-+  
-+  volatile struct USB_EP_Desc *first_ep;  /* First EP in the list. */
-+  volatile struct USB_EP_Desc *curr_ep;   /* Current EP, the iterator. */
-+  volatile struct USB_EP_Desc *next_ep;   /* The EP after current. */
-+
-+  int type = epid_state[epid].type;
-+
-+  /* Setting this flag will cause enqueue() to return -ENOENT for new
-+     submitions on this endpoint and finish_urb() wont process queue further */
-+  epid_state[epid].disabled = 1;
-+
-+  switch(type) {
-+  case PIPE_BULK:
-+    /* Check if EP still is enabled */
-+    if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-+      /* The EP was enabled, disable it. */
-+      TxBulkEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-+      tc_warn("sync_finish: Disabling EP for epid:%d\n", epid);
-+
-+      /* Do busy-wait until DMA not using this EP descriptor anymore */
-+      while((*R_DMA_CH8_SUB0_EP ==
-+           virt_to_phys(&TxBulkEPList[epid])) &&
-+          (timeout-- > 0));
-+      if(timeout == 0) {
-+      warn("Timeout while waiting for DMA-TX-Bulk to leave EP for"
-+           " epid:%d\n", epid);
-+      }
-+    }
-+    break;
-+
-+  case PIPE_CONTROL:
-+    /* Check if EP still is enabled */
-+    if (TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-+      /* The EP was enabled, disable it. */
-+      TxCtrlEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-+      tc_warn("sync_finish: Disabling EP for epid:%d\n", epid);
-+
-+      /* Do busy-wait until DMA not using this EP descriptor anymore */
-+      while((*R_DMA_CH8_SUB1_EP ==
-+           virt_to_phys(&TxCtrlEPList[epid])) &&
-+          (timeout-- > 0));
-+      if(timeout == 0) {
-+      warn("Timeout while waiting for DMA-TX-Ctrl to leave EP for"
-+           " epid:%d\n", epid);
-+      }
-+    }
-+    break;
-+
-+  case PIPE_INTERRUPT:
-+    local_irq_save(flags);
-+    /* Disable all Intr EPs belonging to epid */
-+    first_ep = &TxIntrEPList[0];
-+    curr_ep = first_ep;
-+    do {
-+      next_ep = (struct USB_EP_Desc *)phys_to_virt(curr_ep->next);
-+      if (IO_EXTRACT(USB_EP_command, epid, next_ep->command) == epid) {
-+      /* Disable EP */
-+      next_ep->command &= ~IO_MASK(USB_EP_command, enable);
-+      }
-+      curr_ep = phys_to_virt(curr_ep->next);
-+    } while (curr_ep != first_ep);
-+
-+    local_irq_restore(flags);
-+    break;
-+
-+  case PIPE_ISOCHRONOUS:
-+    /* Check if EP still is enabled */
-+    if (TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-+      tc_warn("sync_finish: Disabling Isoc EP for epid:%d\n", epid);
-+      /* The EP was enabled, disable it. */
-+      TxIsocEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-+      
-+      while((*R_DMA_CH8_SUB3_EP == virt_to_phys(&TxIsocEPList[epid])) &&
-+          (timeout-- > 0));
-+      if(timeout == 0) {
-+      warn("Timeout while waiting for DMA-TX-Isoc to leave EP for"
-+           " epid:%d\n", epid);
-+      }
-+    }
-+    break;
-+  }
-+
-+  local_irq_save(flags);
-+
-+  /* Finish if there is active URB for this endpoint */
-+  if(activeUrbList[epid] != NULL) {
-+    urb = activeUrbList[epid];
-+    urb_priv = urb->hcpriv;
-+    ASSERT(urb_priv);
-+    tc_warn("Sync finish %s URB:0x%x[%d] (%s %s epid:%d) status:%d %s\n",
-+          (urb == activeUrbList[epid]) ? "active" : "queued",
-+          (unsigned int)urb, urb_priv->urb_num, str_dir(urb->pipe),
-+          str_type(urb->pipe), epid, urb->status,
-+          (urb_priv->later_data) ? "later-sched" : "");
-+
-+    tc_finish_urb(hcd, activeUrbList[epid], -ENOENT);
-+    ASSERT(activeUrbList[epid] == NULL);
-+  }
-+
-+  /* Finish any queued URBs for this endpoint. There won't be any resubmitions
-+     because epid_disabled causes enqueue() to fail for this endpoint */
-+  while((urb = urb_list_first(epid)) != NULL) {
-+    urb_priv = urb->hcpriv;
-+    ASSERT(urb_priv);
-+
-+    tc_warn("Sync finish %s URB:0x%x[%d] (%s %s epid:%d) status:%d %s\n",
-+          (urb == activeUrbList[epid]) ? "active" : "queued",
-+          (unsigned int)urb, urb_priv->urb_num, str_dir(urb->pipe),
-+          str_type(urb->pipe), epid, urb->status,
-+          (urb_priv->later_data) ? "later-sched" : "");
-+
-+    tc_finish_urb(hcd, urb, -ENOENT);
-+  }
-+  epid_state[epid].disabled = 0;
-+  local_irq_restore(flags);
-+}
-+
-+/* free resources associated with an endpoint (called from hcd_driver) */
-+static void tc_endpoint_disable(struct usb_hcd *hcd, 
-+                              struct usb_host_endpoint *ep) {
-+  DBFENTER;
-+  /* Only free epid if it has been allocated. We get two endpoint_disable
-+     requests for ctrl endpoints so ignore the second one */
-+  if(ep->hcpriv != NULL) {
-+    struct crisv10_ep_priv *ep_priv = ep->hcpriv;
-+    int epid = ep_priv->epid;
-+    tc_warn("endpoint_disable ep:0x%x ep-priv:0x%x (%s) (epid:%d freed)\n",
-+         (unsigned int)ep, (unsigned int)ep->hcpriv,
-+         endpoint_to_str(&(ep->desc)), epid);
-+
-+    tc_sync_finish_epid(hcd, epid);
-+
-+    ASSERT(activeUrbList[epid] == NULL);
-+    ASSERT(list_empty(&urb_list[epid]));
-+
-+    tc_free_epid(ep);
-+  } else {
-+    tc_dbg("endpoint_disable ep:0x%x ep-priv:0x%x (%s)\n", (unsigned int)ep,
-+         (unsigned int)ep->hcpriv, endpoint_to_str(&(ep->desc)));
-+  }
-+  DBFEXIT;
-+}
-+
-+//static void tc_finish_urb_later_proc(void *data) {
-+static void tc_finish_urb_later_proc(struct work_struct *work) {
-+  unsigned long flags;
-+  //struct urb_later_data* uld = (struct urb_later_data*)data;
-+  struct urb_later_data* uld = container_of(work, struct urb_later_data, ws.work);
-+  local_irq_save(flags);
-+  if(uld->urb == NULL) {
-+    late_dbg("Later finish of URB = NULL (allready finished)\n");
-+  } else {
-+    struct crisv10_urb_priv* urb_priv = uld->urb->hcpriv;
-+    ASSERT(urb_priv);
-+    if(urb_priv->urb_num == uld->urb_num) {
-+      late_dbg("Later finish of URB:0x%x[%d]\n", (unsigned int)(uld->urb),
-+             urb_priv->urb_num);
-+      if(uld->status != uld->urb->status) {
-+      errno_dbg("Later-finish URB with status:%d, later-status:%d\n",
-+                uld->urb->status, uld->status);
-+      }
-+      if(uld != urb_priv->later_data) {
-+      panic("Scheduled uld not same as URBs uld\n");
-+      }
-+      tc_finish_urb(uld->hcd, uld->urb, uld->status);
-+    } else {
-+      late_warn("Ignoring later finish of URB:0x%x[%d]"
-+              ", urb_num doesn't match current URB:0x%x[%d]",
-+              (unsigned int)(uld->urb), uld->urb_num,
-+              (unsigned int)(uld->urb), urb_priv->urb_num);
-+    }
-+  }
-+  local_irq_restore(flags);
-+  kmem_cache_free(later_data_cache, uld);
-+}
-+
-+static void tc_finish_urb_later(struct usb_hcd *hcd, struct urb *urb,
-+                              int status) {
-+  struct crisv10_urb_priv *urb_priv = urb->hcpriv;
-+  struct urb_later_data* uld;
-+
-+  ASSERT(urb_priv);
-+
-+  if(urb_priv->later_data != NULL) {
-+    /* Later-finish allready scheduled for this URB, just update status to
-+       return when finishing later */
-+    errno_dbg("Later-finish schedule change URB status:%d with new"
-+            " status:%d\n", urb_priv->later_data->status, status);
-+    
-+    urb_priv->later_data->status = status;
-+    return;
-+  }
-+
-+  uld = kmem_cache_alloc(later_data_cache, GFP_ATOMIC);
-+  ASSERT(uld);
-+
-+  uld->hcd = hcd;
-+  uld->urb = urb;
-+  uld->urb_num = urb_priv->urb_num;
-+  uld->status = status;
-+
-+  //INIT_WORK(&uld->ws, tc_finish_urb_later_proc, uld);
-+  INIT_DELAYED_WORK(&uld->ws, tc_finish_urb_later_proc);
-+  urb_priv->later_data = uld;
-+
-+  /* Schedule the finishing of the URB to happen later */
-+  schedule_delayed_work(&uld->ws, LATER_TIMER_DELAY);
-+}
-+
-+  /* hinko ignore usb_pipeisoc */
-+#if 0
-+static void tc_finish_isoc_urb(struct usb_hcd *hcd, struct urb *urb,
-+                             int status);
-+#endif
-+
-+static void tc_finish_urb(struct usb_hcd *hcd, struct urb *urb, int status) {
-+  struct crisv10_hcd* crisv10_hcd = hcd_to_crisv10_hcd(hcd);
-+  struct crisv10_urb_priv *urb_priv = urb->hcpriv;
-+  int epid;
-+  char toggle;
-+  int urb_num;
-+
-+  DBFENTER;
-+  ASSERT(urb_priv != NULL);
-+  epid = urb_priv->epid;
-+  urb_num = urb_priv->urb_num;
-+
-+  if(urb != activeUrbList[epid]) {
-+    if(urb_list_entry(urb, epid)) {
-+      /* Remove this URB from the list. Only happens when URB are finished
-+       before having been processed (dequeing) */
-+      urb_list_del(urb, epid);
-+    } else {
-+      tc_warn("Finishing of URB:0x%x[%d] neither active or in queue for"
-+            " epid:%d\n", (unsigned int)urb, urb_num, epid);
-+    }
-+  }
-+
-+  /* Cancel any pending later-finish of this URB */
-+  if(urb_priv->later_data) {
-+    urb_priv->later_data->urb = NULL;
-+  }
-+
-+  /* For an IN pipe, we always set the actual length, regardless of whether
-+     there was an error or not (which means the device driver can use the data
-+     if it wants to). */
-+  if(usb_pipein(urb->pipe)) {
-+    urb->actual_length = urb_priv->rx_offset;
-+  } else {
-+    /* Set actual_length for OUT urbs also; the USB mass storage driver seems
-+       to want that. */
-+    if (status == 0 && urb->status == -EINPROGRESS) {
-+      urb->actual_length = urb->transfer_buffer_length;
-+    } else {
-+      /*  We wouldn't know of any partial writes if there was an error. */
-+      urb->actual_length = 0;
-+    }
-+  }
-+
-+
-+  /* URB status mangling */
-+  if(urb->status == -EINPROGRESS) {
-+    /* The USB core hasn't changed the status, let's set our finish status */
-+    urb->status = status;
-+
-+    if ((status == 0) && (urb->transfer_flags & URB_SHORT_NOT_OK) &&
-+      usb_pipein(urb->pipe) &&
-+      (urb->actual_length != urb->transfer_buffer_length)) {
-+      /* URB_SHORT_NOT_OK means that short reads (shorter than the endpoint's
-+       max length) is to be treated as an error. */
-+      errno_dbg("Finishing URB:0x%x[%d] with SHORT_NOT_OK flag and short"
-+              " data:%d\n", (unsigned int)urb, urb_num,
-+              urb->actual_length);
-+      urb->status = -EREMOTEIO;
-+    }
-+
-+    if(urb_priv->urb_state == UNLINK) {
-+      /* URB has been requested to be unlinked asynchronously */
-+      urb->status = -ECONNRESET;
-+      errno_dbg("Fixing unlink status of URB:0x%x[%d] to:%d\n",
-+              (unsigned int)urb, urb_num, urb->status);
-+    }
-+  } else {
-+    /* The USB Core wants to signal some error via the URB, pass it through */
-+  }
-+
-+  /* hinko ignore usb_pipeisoc */
-+#if 0
-+  /* use completely different finish function for Isoc URBs */
-+  if(usb_pipeisoc(urb->pipe)) {
-+    tc_finish_isoc_urb(hcd, urb, status);
-+    return;
-+  }
-+#endif
-+
-+  /* Do special unlinking of EPs for Intr traffic */
-+  if(usb_pipeint(urb->pipe)) {
-+    tc_dma_unlink_intr_urb(urb);
-+  }
-+
-+  /* hinko ignore usb_pipeisoc */
-+#if 0
-+  /* Release allocated bandwidth for periodic transfers */
-+  if(usb_pipeint(urb->pipe) || usb_pipeisoc(urb->pipe))
-+    usb_release_bandwidth(urb->dev, urb, 0);
-+#endif
-+  
-+  /* This URB is active on EP */
-+  if(urb == activeUrbList[epid]) {
-+    /* We need to fiddle with the toggle bits because the hardware doesn't do
-+       it for us. */
-+    toggle = etrax_epid_get_toggle(epid, usb_pipeout(urb->pipe));
-+    usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-+                usb_pipeout(urb->pipe), toggle);
-+
-+    /* Checks for Ctrl and Bulk EPs */
-+    switch(usb_pipetype(urb->pipe)) {
-+    case PIPE_BULK:
-+      /* Check so Bulk EP realy is disabled before finishing active URB  */
-+      ASSERT((TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) ==
-+           IO_STATE(USB_EP_command, enable, no));
-+      /* Disable sub-pointer for EP to avoid next tx_interrupt() to
-+       process Bulk EP. */
-+      TxBulkEPList[epid].sub = 0;
-+      /* No need to wait for the DMA before changing the next pointer.
-+       The modulo NBR_OF_EPIDS isn't actually necessary, since we will never use
-+       the last one (INVALID_EPID) for actual traffic. */
-+      TxBulkEPList[epid].next = 
-+      virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]);
-+      break;
-+    case PIPE_CONTROL:
-+      /* Check so Ctrl EP realy is disabled before finishing active URB  */
-+      ASSERT((TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) ==
-+           IO_STATE(USB_EP_command, enable, no));
-+      /* Disable sub-pointer for EP to avoid next tx_interrupt() to
-+       process Ctrl EP. */
-+      TxCtrlEPList[epid].sub = 0;
-+      break;
-+    }
-+  }
-+
-+  /* Free HC-private URB data*/
-+  urb_priv_free(hcd, urb);
-+
-+  if(urb->status) {
-+    errno_dbg("finish_urb (URB:0x%x[%d] %s %s) (data:%d) status:%d\n",
-+            (unsigned int)urb, urb_num, str_dir(urb->pipe),
-+            str_type(urb->pipe), urb->actual_length, urb->status);
-+  } else {
-+    tc_dbg("finish_urb (URB:0x%x[%d] %s %s) (data:%d) status:%d\n",
-+         (unsigned int)urb, urb_num, str_dir(urb->pipe),
-+         str_type(urb->pipe), urb->actual_length, urb->status);
-+  }
-+
-+  /* If we just finished an active URB, clear active pointer. */
-+  if (urb == activeUrbList[epid]) {
-+    /* Make URB not active on EP anymore */
-+    activeUrbList[epid] = NULL;
-+
-+    if(urb->status == 0) {
-+      /* URB finished sucessfully, process queue to see if there are any more
-+       URBs waiting before we call completion function.*/
-+      if(crisv10_hcd->running) {
-+      /* Only process queue if USB controller is running */
-+      tc_dma_process_queue(epid);
-+      } else {
-+      tc_warn("No processing of queue for epid:%d, USB Controller not"
-+              " running\n", epid);
-+      }
-+    }
-+  }
-+
-+  /*  Hand the URB from HCD to its USB device driver, using its completion
-+      functions */
-+//  usb_hcd_giveback_urb (hcd, urb);
-+      /**
-+       * usb_hcd_unlink_urb_from_ep - remove an URB from its endpoint queue
-+       * @hcd: host controller to which @urb was submitted
-+       * @urb: URB being unlinked
-+       *
-+       * Host controller drivers should call this routine before calling
-+       * usb_hcd_giveback_urb().  The HCD's private spinlock must be held and
-+       * interrupts must be disabled.  The actions carried out here are required
-+       * for URB completion.
-+       */
-+  
-+  /*hinko link/unlink urb -> ep */
-+  //spin_lock(&crisv10_hcd->lock);
-+  unsigned long flags;
-+  spin_lock_irqsave(&crisv10_hcd->lock, flags);
-+  usb_hcd_unlink_urb_from_ep(hcd, urb);
-+  usb_hcd_giveback_urb(hcd, urb, status);
-+  //spin_unlock(&crisv10_hcd->lock);
-+  spin_unlock_irqrestore(&crisv10_hcd->lock, flags);
-+
-+  /* Check the queue once more if the URB returned with error, because we
-+     didn't do it before the completion function because the specification
-+     states that the queue should not restart until all it's unlinked
-+     URBs have been fully retired, with the completion functions run */
-+  if(crisv10_hcd->running) {
-+    /* Only process queue if USB controller is running */
-+    tc_dma_process_queue(epid);
-+  } else {
-+    tc_warn("No processing of queue for epid:%d, USB Controller not running\n",
-+          epid);
-+  }
-+
-+  DBFEXIT;
-+}
-+
-+  /* hinko ignore usb_pipeisoc */
-+#if 0
-+static void tc_finish_isoc_urb(struct usb_hcd *hcd, struct urb *urb,
-+                             int status) {
-+  struct crisv10_urb_priv *urb_priv = urb->hcpriv;
-+  int epid, i;
-+  volatile int timeout = 10000;
-+
-+  ASSERT(urb_priv);
-+  epid = urb_priv->epid;
-+
-+  ASSERT(usb_pipeisoc(urb->pipe));
-+
-+  /* Set that all isoc packets have status and length set before
-+     completing the urb. */
-+  for (i = urb_priv->isoc_packet_counter; i < urb->number_of_packets; i++){
-+    urb->iso_frame_desc[i].actual_length = 0;
-+    urb->iso_frame_desc[i].status = -EPROTO;
-+  }
-+
-+  /* Check if the URB is currently active (done or error) */
-+  if(urb == activeUrbList[epid]) {
-+    /* Check if there are another In Isoc URB queued for this epid */
-+    if (!list_empty(&urb_list[epid])&& !epid_state[epid].disabled) {
-+      /* Move it from queue to active and mark it started so Isoc transfers
-+       won't be interrupted.
-+       All Isoc URBs data transfers are already added to DMA lists so we
-+       don't have to insert anything in DMA lists here. */
-+      activeUrbList[epid] = urb_list_first(epid);
-+      ((struct crisv10_urb_priv *)(activeUrbList[epid]->hcpriv))->urb_state =
-+      STARTED;
-+      urb_list_del(activeUrbList[epid], epid);
-+
-+      if(urb->status) {
-+      errno_dbg("finish_isoc_urb (URB:0x%x[%d] %s %s) (%d of %d packets)"
-+                " status:%d, new waiting URB:0x%x[%d]\n",
-+                (unsigned int)urb, urb_priv->urb_num, str_dir(urb->pipe),
-+                str_type(urb->pipe), urb_priv->isoc_packet_counter,
-+                urb->number_of_packets, urb->status,
-+                (unsigned int)activeUrbList[epid],
-+                ((struct crisv10_urb_priv *)(activeUrbList[epid]->hcpriv))->urb_num);
-+      }
-+
-+    } else { /* No other URB queued for this epid */
-+      if(urb->status) {
-+      errno_dbg("finish_isoc_urb (URB:0x%x[%d] %s %s) (%d of %d packets)"
-+                " status:%d, no new URB waiting\n",
-+                (unsigned int)urb, urb_priv->urb_num, str_dir(urb->pipe),
-+                str_type(urb->pipe), urb_priv->isoc_packet_counter,
-+                urb->number_of_packets, urb->status);
-+      }
-+
-+      /* Check if EP is still enabled, then shut it down. */
-+      if (TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-+      isoc_dbg("Isoc EP enabled for epid:%d, disabling it\n", epid);
-+
-+      /* Should only occur for In Isoc EPs where SB isn't consumed. */
-+      ASSERT(usb_pipein(urb->pipe));
-+
-+      /* Disable it and wait for it to stop */
-+      TxIsocEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-+      
-+      /* Ah, the luxury of busy-wait. */
-+      while((*R_DMA_CH8_SUB3_EP == virt_to_phys(&TxIsocEPList[epid])) &&
-+            (timeout-- > 0));
-+      if(timeout == 0) {
-+        warn("Timeout while waiting for DMA-TX-Isoc to leave EP for epid:%d\n", epid);
-+      }
-+      }
-+
-+      /* Unlink SB to say that epid is finished. */
-+      TxIsocEPList[epid].sub = 0;
-+      TxIsocEPList[epid].hw_len = 0;
-+
-+      /* No URB active for EP anymore */
-+      activeUrbList[epid] = NULL;
-+    }
-+  } else { /* Finishing of not active URB (queued up with SBs thought) */
-+    isoc_warn("finish_isoc_urb (URB:0x%x %s) (%d of %d packets) status:%d,"
-+            " SB queued but not active\n",
-+            (unsigned int)urb, str_dir(urb->pipe),
-+            urb_priv->isoc_packet_counter, urb->number_of_packets,
-+            urb->status);
-+    if(usb_pipeout(urb->pipe)) {
-+      /* Finishing of not yet active Out Isoc URB needs unlinking of SBs. */
-+      struct USB_SB_Desc *iter_sb, *prev_sb, *next_sb;
-+
-+      iter_sb = TxIsocEPList[epid].sub ?
-+      phys_to_virt(TxIsocEPList[epid].sub) : 0;
-+      prev_sb = 0;
-+
-+      /* SB that is linked before this URBs first SB */
-+      while (iter_sb && (iter_sb != urb_priv->first_sb)) {
-+      prev_sb = iter_sb;
-+      iter_sb = iter_sb->next ? phys_to_virt(iter_sb->next) : 0;
-+      }
-+
-+      if (iter_sb == 0) {
-+      /* Unlink of the URB currently being transmitted. */
-+      prev_sb = 0;
-+      iter_sb = TxIsocEPList[epid].sub ? phys_to_virt(TxIsocEPList[epid].sub) : 0;
-+      }
-+
-+      while (iter_sb && (iter_sb != urb_priv->last_sb)) {
-+      iter_sb = iter_sb->next ? phys_to_virt(iter_sb->next) : 0;
-+      }
-+
-+      if (iter_sb) {
-+      next_sb = iter_sb->next ? phys_to_virt(iter_sb->next) : 0;
-+      } else {
-+      /* This should only happen if the DMA has completed
-+         processing the SB list for this EP while interrupts
-+         are disabled. */
-+      isoc_dbg("Isoc urb not found, already sent?\n");
-+      next_sb = 0;
-+      }
-+      if (prev_sb) {
-+      prev_sb->next = next_sb ? virt_to_phys(next_sb) : 0;
-+      } else {
-+      TxIsocEPList[epid].sub = next_sb ? virt_to_phys(next_sb) : 0;
-+      }
-+    }
-+  }
-+
-+  /* Free HC-private URB data*/
-+  urb_priv_free(hcd, urb);
-+
-+  usb_release_bandwidth(urb->dev, urb, 0);
-+
-+  /*  Hand the URB from HCD to its USB device driver, using its completion
-+      functions */
-+  usb_hcd_giveback_urb (hcd, urb);
-+}
-+#endif
-+
-+static __u32 urb_num = 0;
-+
-+/* allocate and initialize URB private data */
-+static int urb_priv_create(struct usb_hcd *hcd, struct urb *urb, int epid,
-+                         int mem_flags) {
-+  struct crisv10_urb_priv *urb_priv;
-+  
-+  urb_priv = kmalloc(sizeof *urb_priv, mem_flags);
-+  if (!urb_priv)
-+    return -ENOMEM;
-+  memset(urb_priv, 0, sizeof *urb_priv);
-+
-+  urb_priv->epid = epid;
-+  urb_priv->urb_state = NOT_STARTED;
-+
-+  urb->hcpriv = urb_priv;
-+  /* Assign URB a sequence number, and increment counter */
-+  urb_priv->urb_num = urb_num;
-+  urb_num++;
-+  return 0;
-+}
-+
-+/* free URB private data */
-+static void urb_priv_free(struct usb_hcd *hcd, struct urb *urb) {
-+  int i;
-+  struct crisv10_urb_priv *urb_priv = urb->hcpriv;
-+  ASSERT(urb_priv != 0);
-+
-+  /* Check it has any SBs linked that needs to be freed*/
-+  if(urb_priv->first_sb != NULL) {
-+    struct USB_SB_Desc *next_sb, *first_sb, *last_sb;
-+    int i = 0;
-+    first_sb = urb_priv->first_sb;
-+    last_sb = urb_priv->last_sb;
-+    ASSERT(last_sb);
-+    while(first_sb != last_sb) {
-+      next_sb = (struct USB_SB_Desc *)phys_to_virt(first_sb->next);
-+      kmem_cache_free(usb_desc_cache, first_sb);
-+      first_sb = next_sb;
-+      i++;
-+    }
-+    kmem_cache_free(usb_desc_cache, last_sb);
-+    i++;
-+  }
-+
-+  /* Check if it has any EPs in its Intr pool that also needs to be freed */
-+  if(urb_priv->intr_ep_pool_length > 0) {
-+    for(i = 0; i < urb_priv->intr_ep_pool_length; i++) {
-+      kfree(urb_priv->intr_ep_pool[i]);
-+    }
-+    /*
-+    tc_dbg("Freed %d EPs from URB:0x%x EP pool\n",
-+           urb_priv->intr_ep_pool_length, (unsigned int)urb);
-+    */
-+  }
-+
-+  kfree(urb_priv);
-+  urb->hcpriv = NULL;
-+}
-+
-+static int ep_priv_create(struct usb_host_endpoint *ep, int mem_flags) {
-+  struct crisv10_ep_priv *ep_priv;
-+  
-+  ep_priv = kmalloc(sizeof *ep_priv, mem_flags);
-+  if (!ep_priv)
-+    return -ENOMEM;
-+  memset(ep_priv, 0, sizeof *ep_priv);
-+
-+  ep->hcpriv = ep_priv;
-+  return 0;
-+}
-+
-+static void ep_priv_free(struct usb_host_endpoint *ep) {
-+  struct crisv10_ep_priv *ep_priv = ep->hcpriv;
-+  ASSERT(ep_priv);
-+  kfree(ep_priv);
-+  ep->hcpriv = NULL;
-+}
-+
-+/* EPID handling functions, managing EP-list in Etrax through wrappers */
-+/* ------------------------------------------------------------------- */
-+
-+/* Sets up a new EPID for an endpoint or returns existing if found */
-+//static int tc_setup_epid(struct usb_host_endpoint *ep, struct urb *urb,
-+//                     int mem_flags) {
-+static int tc_setup_epid(struct urb *urb, int mem_flags)
-+{
-+  int epid;
-+  char devnum, endpoint, out_traffic, slow;
-+  int maxlen;
-+  __u32 epid_data;
-+  struct usb_host_endpoint *ep = urb->ep;
-+  struct crisv10_ep_priv *ep_priv = ep->hcpriv;
-+  
-+  DBFENTER;
-+  
-+  /* Check if a valid epid already is setup for this endpoint */
-+  if(ep_priv != NULL) {
-+    return ep_priv->epid;
-+  }
-+
-+  /* We must find and initiate a new epid for this urb. */
-+  epid = tc_allocate_epid();
-+  
-+  if (epid == -1) {
-+    /* Failed to allocate a new epid. */
-+    DBFEXIT;
-+    return epid;
-+  }
-+  
-+  /* We now have a new epid to use. Claim it. */
-+  epid_state[epid].inuse = 1;
-+  
-+  /* Init private data for new endpoint */
-+  if(ep_priv_create(ep, mem_flags) != 0) {
-+    return -ENOMEM;
-+  }
-+  ep_priv = ep->hcpriv;
-+  ep_priv->epid = epid;
-+
-+  devnum = usb_pipedevice(urb->pipe);
-+  endpoint = usb_pipeendpoint(urb->pipe);
-+  slow = (urb->dev->speed == USB_SPEED_LOW);
-+  maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-+
-+  if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
-+    /* We want both IN and OUT control traffic to be put on the same
-+       EP/SB list. */
-+    out_traffic = 1;
-+  } else {
-+    out_traffic = usb_pipeout(urb->pipe);
-+  }
-+    
-+  if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-+    epid_data = IO_STATE(R_USB_EPT_DATA_ISO, valid, yes) |
-+      /* FIXME: Change any to the actual port? */
-+      IO_STATE(R_USB_EPT_DATA_ISO, port, any) |
-+      IO_FIELD(R_USB_EPT_DATA_ISO, max_len, maxlen) |
-+      IO_FIELD(R_USB_EPT_DATA_ISO, ep, endpoint) |
-+      IO_FIELD(R_USB_EPT_DATA_ISO, dev, devnum);
-+    etrax_epid_iso_set(epid, epid_data);
-+  } else {
-+    epid_data = IO_STATE(R_USB_EPT_DATA, valid, yes) |
-+      IO_FIELD(R_USB_EPT_DATA, low_speed, slow) |
-+      /* FIXME: Change any to the actual port? */
-+      IO_STATE(R_USB_EPT_DATA, port, any) |
-+      IO_FIELD(R_USB_EPT_DATA, max_len, maxlen) |
-+      IO_FIELD(R_USB_EPT_DATA, ep, endpoint) |
-+      IO_FIELD(R_USB_EPT_DATA, dev, devnum);
-+    etrax_epid_set(epid, epid_data);
-+  }
-+  
-+  epid_state[epid].out_traffic = out_traffic;
-+  epid_state[epid].type = usb_pipetype(urb->pipe);
-+
-+  tc_warn("Setting up ep:0x%x epid:%d (addr:%d endp:%d max_len:%d %s %s %s)\n",
-+        (unsigned int)ep, epid, devnum, endpoint, maxlen,
-+        str_type(urb->pipe), out_traffic ? "out" : "in",
-+        slow ? "low" : "full");
-+
-+  /* Enable Isoc eof interrupt if we set up the first Isoc epid */
-+  if(usb_pipeisoc(urb->pipe)) {
-+    isoc_epid_counter++;
-+    if(isoc_epid_counter == 1) {
-+      isoc_warn("Enabled Isoc eof interrupt\n");
-+      *R_USB_IRQ_MASK_SET |= IO_STATE(R_USB_IRQ_MASK_SET, iso_eof, set);
-+    }
-+  }
-+
-+  DBFEXIT;
-+  return epid;
-+}
-+
-+static void tc_free_epid(struct usb_host_endpoint *ep) {
-+  unsigned long flags;
-+  struct crisv10_ep_priv *ep_priv = ep->hcpriv;
-+  int epid;
-+  volatile int timeout = 10000;
-+
-+  DBFENTER;
-+
-+  if (ep_priv == NULL) {
-+    tc_warn("Trying to free unused epid on ep:0x%x\n", (unsigned int)ep);
-+    DBFEXIT;
-+    return;
-+  }
-+
-+  epid = ep_priv->epid;
-+
-+  /* Disable Isoc eof interrupt if we free the last Isoc epid */
-+  if(epid_isoc(epid)) {
-+    ASSERT(isoc_epid_counter > 0);
-+    isoc_epid_counter--;
-+    if(isoc_epid_counter == 0) {
-+      *R_USB_IRQ_MASK_SET &= ~IO_STATE(R_USB_IRQ_MASK_SET, iso_eof, set);
-+      isoc_warn("Disabled Isoc eof interrupt\n");
-+    }
-+  }
-+
-+  /* Take lock manualy instead of in epid_x_x wrappers,
-+     because we need to be polling here */
-+  spin_lock_irqsave(&etrax_epid_lock, flags);
-+  
-+  *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
-+  nop();
-+  while((*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) &&
-+      (timeout-- > 0));
-+  if(timeout == 0) {
-+    warn("Timeout while waiting for epid:%d to drop hold\n", epid);
-+  }
-+  /* This will, among other things, set the valid field to 0. */
-+  *R_USB_EPT_DATA = 0;
-+  spin_unlock_irqrestore(&etrax_epid_lock, flags);
-+  
-+  /* Free resource in software state info list */
-+  epid_state[epid].inuse = 0;
-+
-+  /* Free private endpoint data */
-+  ep_priv_free(ep);
-+  
-+  DBFEXIT;
-+}
-+
-+static int tc_allocate_epid(void) {
-+  int i;
-+  DBFENTER;
-+  for (i = 0; i < NBR_OF_EPIDS; i++) {
-+    if (!epid_inuse(i)) {
-+      DBFEXIT;
-+      return i;
-+    }
-+  }
-+  
-+  tc_warn("Found no free epids\n");
-+  DBFEXIT;
-+  return -1;
-+}
-+
-+
-+/* Wrappers around the list functions (include/linux/list.h). */
-+/* ---------------------------------------------------------- */
-+static inline int __urb_list_empty(int epid) {
-+  int retval;
-+  retval = list_empty(&urb_list[epid]);
-+  return retval;
-+}
-+
-+/* Returns first urb for this epid, or NULL if list is empty. */
-+static inline struct urb *urb_list_first(int epid) {
-+  unsigned long flags;
-+  struct urb *first_urb = 0;
-+  spin_lock_irqsave(&urb_list_lock, flags);
-+  if (!__urb_list_empty(epid)) {
-+    /* Get the first urb (i.e. head->next). */
-+    urb_entry_t *urb_entry = list_entry((&urb_list[epid])->next, urb_entry_t, list);
-+    first_urb = urb_entry->urb;
-+  }
-+  spin_unlock_irqrestore(&urb_list_lock, flags);
-+  return first_urb;
-+}
-+
-+/* Adds an urb_entry last in the list for this epid. */
-+static inline void urb_list_add(struct urb *urb, int epid, int mem_flags) {
-+  unsigned long flags;
-+  urb_entry_t *urb_entry = (urb_entry_t *)kmalloc(sizeof(urb_entry_t), mem_flags);
-+  ASSERT(urb_entry);
-+  
-+  urb_entry->urb = urb;
-+  spin_lock_irqsave(&urb_list_lock, flags);
-+  list_add_tail(&urb_entry->list, &urb_list[epid]);
-+  spin_unlock_irqrestore(&urb_list_lock, flags);
-+}
-+
-+/* Search through the list for an element that contains this urb. (The list
-+   is expected to be short and the one we are about to delete will often be
-+   the first in the list.)
-+   Should be protected by spin_locks in calling function */
-+static inline urb_entry_t *__urb_list_entry(struct urb *urb, int epid) {
-+  struct list_head *entry;
-+  struct list_head *tmp;
-+  urb_entry_t *urb_entry;
-+  
-+  list_for_each_safe(entry, tmp, &urb_list[epid]) {
-+    urb_entry = list_entry(entry, urb_entry_t, list);
-+    ASSERT(urb_entry);
-+    ASSERT(urb_entry->urb);
-+    
-+    if (urb_entry->urb == urb) {
-+      return urb_entry;
-+    }
-+  }
-+  return 0;
-+}
-+
-+/* Same function as above but for global use. Protects list by spinlock */
-+static inline urb_entry_t *urb_list_entry(struct urb *urb, int epid) {
-+  unsigned long flags;
-+  urb_entry_t *urb_entry;
-+  spin_lock_irqsave(&urb_list_lock, flags);
-+  urb_entry = __urb_list_entry(urb, epid);
-+  spin_unlock_irqrestore(&urb_list_lock, flags);
-+  return (urb_entry);
-+}
-+
-+/* Delete an urb from the list. */
-+static inline void urb_list_del(struct urb *urb, int epid) {
-+  unsigned long flags;
-+  urb_entry_t *urb_entry;
-+
-+  /* Delete entry and free. */
-+  spin_lock_irqsave(&urb_list_lock, flags);
-+  urb_entry = __urb_list_entry(urb, epid);
-+  ASSERT(urb_entry);
-+
-+  list_del(&urb_entry->list);
-+  spin_unlock_irqrestore(&urb_list_lock, flags);
-+  kfree(urb_entry);
-+}
-+
-+/* Move an urb to the end of the list. */
-+static inline void urb_list_move_last(struct urb *urb, int epid) {
-+  unsigned long flags;
-+  urb_entry_t *urb_entry;
-+  
-+  spin_lock_irqsave(&urb_list_lock, flags);
-+  urb_entry = __urb_list_entry(urb, epid);
-+  ASSERT(urb_entry);
-+
-+  list_del(&urb_entry->list);
-+  list_add_tail(&urb_entry->list, &urb_list[epid]);
-+  spin_unlock_irqrestore(&urb_list_lock, flags);
-+}
-+
-+/* Get the next urb in the list. */
-+static inline struct urb *urb_list_next(struct urb *urb, int epid) {
-+  unsigned long flags;
-+  urb_entry_t *urb_entry;
-+
-+  spin_lock_irqsave(&urb_list_lock, flags);
-+  urb_entry = __urb_list_entry(urb, epid);
-+  ASSERT(urb_entry);
-+
-+  if (urb_entry->list.next != &urb_list[epid]) {
-+    struct list_head *elem = urb_entry->list.next;
-+    urb_entry = list_entry(elem, urb_entry_t, list);
-+    spin_unlock_irqrestore(&urb_list_lock, flags);
-+    return urb_entry->urb;
-+  } else {
-+    spin_unlock_irqrestore(&urb_list_lock, flags);
-+    return NULL;
-+  }
-+}
-+
-+struct USB_EP_Desc* create_ep(int epid, struct USB_SB_Desc* sb_desc,
-+                            int mem_flags) {
-+  struct USB_EP_Desc *ep_desc;
-+  ep_desc = (struct USB_EP_Desc *) kmem_cache_alloc(usb_desc_cache, mem_flags);
-+  if(ep_desc == NULL)
-+    return NULL;
-+  memset(ep_desc, 0, sizeof(struct USB_EP_Desc));
-+
-+  ep_desc->hw_len = 0;
-+  ep_desc->command = (IO_FIELD(USB_EP_command, epid, epid) |
-+                    IO_STATE(USB_EP_command, enable, yes));
-+  if(sb_desc == NULL) {
-+    ep_desc->sub = 0;
-+  } else {
-+    ep_desc->sub = virt_to_phys(sb_desc);
-+  }
-+  return ep_desc;
-+}
-+
-+#define TT_ZOUT  0
-+#define TT_IN    1
-+#define TT_OUT   2
-+#define TT_SETUP 3
-+
-+#define CMD_EOL  IO_STATE(USB_SB_command, eol, yes)
-+#define CMD_INTR IO_STATE(USB_SB_command, intr, yes)
-+#define CMD_FULL IO_STATE(USB_SB_command, full, yes)
-+
-+/* Allocation and setup of a generic SB. Used to create SETUP, OUT and ZOUT
-+   SBs. Also used by create_sb_in() to avoid same allocation procedure at two
-+   places */
-+struct USB_SB_Desc* create_sb(struct USB_SB_Desc* sb_prev, int tt, void* data,
-+                            int datalen, int mem_flags) {
-+  struct USB_SB_Desc *sb_desc;
-+  sb_desc = (struct USB_SB_Desc*)kmem_cache_alloc(usb_desc_cache, mem_flags);
-+  if(sb_desc == NULL)
-+    return NULL;
-+  memset(sb_desc, 0, sizeof(struct USB_SB_Desc));
-+
-+  sb_desc->command = IO_FIELD(USB_SB_command, tt, tt) |
-+                     IO_STATE(USB_SB_command, eot, yes);
-+
-+  sb_desc->sw_len = datalen;
-+  if(data != NULL) {
-+    sb_desc->buf = virt_to_phys(data);
-+  } else {
-+    sb_desc->buf = 0;
-+  }
-+  if(sb_prev != NULL) {
-+    sb_prev->next = virt_to_phys(sb_desc);
-+  }
-+  return sb_desc;
-+}
-+
-+/* Creates a copy of an existing SB by allocation space for it and copy
-+   settings */
-+struct USB_SB_Desc* create_sb_copy(struct USB_SB_Desc* sb_orig, int mem_flags) {
-+  struct USB_SB_Desc *sb_desc;
-+  sb_desc = (struct USB_SB_Desc*)kmem_cache_alloc(usb_desc_cache, mem_flags);
-+  if(sb_desc == NULL)
-+    return NULL;
-+
-+  memcpy(sb_desc, sb_orig, sizeof(struct USB_SB_Desc));
-+  return sb_desc;
-+}
-+
-+/* A specific create_sb function for creation of in SBs. This is due to
-+   that datalen in In SBs shows how many packets we are expecting. It also
-+   sets up the rem field to show if how many bytes we expect in last packet
-+   if it's not a full one */
-+struct USB_SB_Desc* create_sb_in(struct USB_SB_Desc* sb_prev, int datalen,
-+                               int maxlen, int mem_flags) {
-+  struct USB_SB_Desc *sb_desc;
-+  sb_desc = create_sb(sb_prev, TT_IN, NULL,
-+                    datalen ? (datalen - 1) / maxlen + 1 : 0, mem_flags);
-+  if(sb_desc == NULL)
-+    return NULL;
-+  sb_desc->command |= IO_FIELD(USB_SB_command, rem, datalen % maxlen);
-+  return sb_desc;
-+}
-+
-+void set_sb_cmds(struct USB_SB_Desc *sb_desc, __u16 flags) {
-+  sb_desc->command |= flags;
-+}
-+
-+int create_sb_for_urb(struct urb *urb, int mem_flags) {
-+  int is_out = !usb_pipein(urb->pipe);
-+  int type = usb_pipetype(urb->pipe);
-+  int maxlen = usb_maxpacket(urb->dev, urb->pipe, is_out);
-+  int buf_len = urb->transfer_buffer_length;
-+  void *buf = buf_len > 0 ? urb->transfer_buffer : NULL;
-+  struct USB_SB_Desc *sb_desc = NULL;
-+
-+  struct crisv10_urb_priv *urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+  ASSERT(urb_priv != NULL);
-+
-+  switch(type) {
-+  case PIPE_CONTROL:
-+    /* Setup stage */
-+    sb_desc = create_sb(NULL, TT_SETUP, urb->setup_packet, 8, mem_flags);
-+    if(sb_desc == NULL)
-+      return -ENOMEM;
-+    set_sb_cmds(sb_desc, CMD_FULL);
-+
-+    /* Attach first SB to URB */
-+    urb_priv->first_sb = sb_desc;    
-+
-+    if (is_out) { /* Out Control URB */
-+      /* If this Control OUT transfer has an optional data stage we add
-+       an OUT token before the mandatory IN (status) token */
-+      if ((buf_len > 0) && buf) {
-+      sb_desc = create_sb(sb_desc, TT_OUT, buf, buf_len, mem_flags);
-+      if(sb_desc == NULL)
-+        return -ENOMEM;
-+      set_sb_cmds(sb_desc, CMD_FULL);
-+      }
-+
-+      /* Status stage */
-+      /* The data length has to be exactly 1. This is due to a requirement
-+         of the USB specification that a host must be prepared to receive
-+         data in the status phase */
-+      sb_desc = create_sb(sb_desc, TT_IN, NULL, 1, mem_flags);
-+      if(sb_desc == NULL)
-+      return -ENOMEM;
-+    } else { /* In control URB */
-+      /* Data stage */
-+      sb_desc = create_sb_in(sb_desc, buf_len, maxlen, mem_flags);
-+      if(sb_desc == NULL)
-+      return -ENOMEM;
-+
-+      /* Status stage */
-+      /* Read comment at zout_buffer declaration for an explanation to this. */
-+      sb_desc = create_sb(sb_desc, TT_ZOUT, &zout_buffer[0], 1, mem_flags);
-+      if(sb_desc == NULL)
-+      return -ENOMEM;
-+      /* Set descriptor interrupt flag for in URBs so we can finish URB after
-+         zout-packet has been sent */
-+      set_sb_cmds(sb_desc, CMD_INTR | CMD_FULL);
-+    }
-+    /* Set end-of-list flag in last SB */
-+    set_sb_cmds(sb_desc, CMD_EOL);
-+    /* Attach last SB to URB */
-+    urb_priv->last_sb = sb_desc;
-+    break;
-+
-+  case PIPE_BULK:
-+    if (is_out) { /* Out Bulk URB */
-+      sb_desc = create_sb(NULL, TT_OUT, buf, buf_len, mem_flags);
-+      if(sb_desc == NULL)
-+      return -ENOMEM;
-+      /* The full field is set to yes, even if we don't actually check that
-+       this is a full-length transfer (i.e., that transfer_buffer_length %
-+       maxlen = 0).
-+       Setting full prevents the USB controller from sending an empty packet
-+       in that case.  However, if URB_ZERO_PACKET was set we want that. */
-+      if (!(urb->transfer_flags & URB_ZERO_PACKET)) {
-+      set_sb_cmds(sb_desc, CMD_FULL);
-+      }
-+    } else { /* In Bulk URB */
-+      sb_desc = create_sb_in(NULL, buf_len, maxlen, mem_flags);
-+      if(sb_desc == NULL)
-+      return -ENOMEM;
-+    }
-+    /* Set end-of-list flag for last SB */
-+    set_sb_cmds(sb_desc, CMD_EOL);
-+
-+    /* Attach SB to URB */
-+    urb_priv->first_sb = sb_desc;
-+    urb_priv->last_sb = sb_desc;
-+    break;
-+
-+  case PIPE_INTERRUPT:
-+    if(is_out) { /* Out Intr URB */
-+      sb_desc = create_sb(NULL, TT_OUT, buf, buf_len, mem_flags);
-+      if(sb_desc == NULL)
-+      return -ENOMEM;
-+
-+      /* The full field is set to yes, even if we don't actually check that
-+       this is a full-length transfer (i.e., that transfer_buffer_length %
-+       maxlen = 0).
-+       Setting full prevents the USB controller from sending an empty packet
-+       in that case.  However, if URB_ZERO_PACKET was set we want that. */
-+      if (!(urb->transfer_flags & URB_ZERO_PACKET)) {
-+      set_sb_cmds(sb_desc, CMD_FULL);
-+      }
-+      /* Only generate TX interrupt if it's a Out URB*/
-+      set_sb_cmds(sb_desc, CMD_INTR);
-+
-+    } else { /* In Intr URB */
-+      sb_desc = create_sb_in(NULL, buf_len, maxlen, mem_flags);
-+      if(sb_desc == NULL)
-+      return -ENOMEM;
-+    }
-+    /* Set end-of-list flag for last SB */
-+    set_sb_cmds(sb_desc, CMD_EOL);
-+
-+    /* Attach SB to URB */
-+    urb_priv->first_sb = sb_desc;
-+    urb_priv->last_sb = sb_desc;
-+
-+    break;
-+  case PIPE_ISOCHRONOUS:
-+    if(is_out) { /* Out Isoc URB */
-+      int i;
-+      if(urb->number_of_packets == 0) {
-+      tc_err("Can't create SBs for Isoc URB with zero packets\n");
-+      return -EPIPE;
-+      }
-+      /* Create one SB descriptor for each packet and link them together. */
-+      for(i = 0; i < urb->number_of_packets; i++) {
-+      if (urb->iso_frame_desc[i].length > 0) {
-+
-+        sb_desc = create_sb(sb_desc, TT_OUT, urb->transfer_buffer +
-+                            urb->iso_frame_desc[i].offset,
-+                            urb->iso_frame_desc[i].length, mem_flags);
-+        if(sb_desc == NULL)
-+          return -ENOMEM;
-+
-+        /* Check if it's a full length packet */
-+        if (urb->iso_frame_desc[i].length ==
-+            usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) {
-+          set_sb_cmds(sb_desc, CMD_FULL);
-+        }
-+        
-+      } else { /* zero length packet */
-+        sb_desc = create_sb(sb_desc, TT_ZOUT, &zout_buffer[0], 1, mem_flags);
-+        if(sb_desc == NULL)
-+          return -ENOMEM;
-+        set_sb_cmds(sb_desc, CMD_FULL);
-+      }
-+      /* Attach first SB descriptor to URB */
-+      if (i == 0) {
-+        urb_priv->first_sb = sb_desc;
-+      }
-+      }
-+      /* Set interrupt and end-of-list flags in last SB */
-+      set_sb_cmds(sb_desc, CMD_INTR | CMD_EOL);
-+      /* Attach last SB descriptor to URB */
-+      urb_priv->last_sb = sb_desc;
-+      tc_dbg("Created %d out SBs for Isoc URB:0x%x\n",
-+             urb->number_of_packets, (unsigned int)urb);
-+    } else { /* In Isoc URB */
-+      /* Actual number of packets is not relevant for periodic in traffic as
-+       long as it is more than zero.  Set to 1 always. */
-+      sb_desc = create_sb(sb_desc, TT_IN, NULL, 1, mem_flags);
-+      if(sb_desc == NULL)
-+      return -ENOMEM;
-+      /* Set end-of-list flags for SB */
-+      set_sb_cmds(sb_desc, CMD_EOL);
-+
-+      /* Attach SB to URB */
-+      urb_priv->first_sb = sb_desc;
-+      urb_priv->last_sb = sb_desc;
-+    }
-+    break;
-+  default:
-+    tc_err("Unknown pipe-type\n");
-+    return -EPIPE;
-+    break;
-+  }
-+  return 0;
-+}
-+
-+int init_intr_urb(struct urb *urb, int mem_flags) {
-+  struct crisv10_urb_priv *urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+  struct USB_EP_Desc* ep_desc;
-+  int interval;
-+  int i;
-+  int ep_count;
-+
-+  ASSERT(urb_priv != NULL);
-+  ASSERT(usb_pipeint(urb->pipe));
-+  /* We can't support interval longer than amount of eof descriptors in
-+     TxIntrEPList */
-+  if(urb->interval > MAX_INTR_INTERVAL) {
-+    tc_err("Interrupt interval %dms too big (max: %dms)\n", urb->interval,
-+         MAX_INTR_INTERVAL);
-+    return -EINVAL;
-+  }
-+
-+  /* We assume that the SB descriptors already have been setup */
-+  ASSERT(urb_priv->first_sb != NULL);
-+
-+  /* Round of the interval to 2^n, it is obvious that this code favours
-+     smaller numbers, but that is actually a good thing */
-+  /* FIXME: The "rounding error" for larger intervals will be quite
-+     large. For in traffic this shouldn't be a problem since it will only
-+     mean that we "poll" more often. */
-+  interval = urb->interval;
-+  for (i = 0; interval; i++) {
-+    interval = interval >> 1;
-+  }
-+  urb_priv->interval = 1 << (i - 1);
-+
-+  /* We can only have max interval for Out Interrupt due to that we can only
-+     handle one linked in EP for a certain epid in the Intr descr array at the
-+     time. The USB Controller in the Etrax 100LX continues to process Intr EPs
-+     so we have no way of knowing which one that caused the actual transfer if
-+     we have several linked in. */
-+  if(usb_pipeout(urb->pipe)) {
-+    urb_priv->interval = MAX_INTR_INTERVAL;
-+  }
-+
-+  /* Calculate amount of EPs needed */
-+  ep_count = MAX_INTR_INTERVAL / urb_priv->interval;
-+
-+  for(i = 0; i < ep_count; i++) {
-+    ep_desc = create_ep(urb_priv->epid, urb_priv->first_sb, mem_flags);
-+    if(ep_desc == NULL) {
-+      /* Free any descriptors that we may have allocated before failure */
-+      while(i > 0) {
-+      i--;
-+      kfree(urb_priv->intr_ep_pool[i]);
-+      }
-+      return -ENOMEM;
-+    }
-+    urb_priv->intr_ep_pool[i] = ep_desc;
-+  }
-+  urb_priv->intr_ep_pool_length = ep_count;
-+  return 0;
-+}
-+
-+/* DMA RX/TX functions */
-+/* ----------------------- */
-+
-+static void tc_dma_init_rx_list(void) {
-+  int i;
-+
-+  /* Setup descriptor list except last one */
-+  for (i = 0; i < (NBR_OF_RX_DESC - 1); i++) {
-+    RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
-+    RxDescList[i].command = 0;
-+    RxDescList[i].next = virt_to_phys(&RxDescList[i + 1]);
-+    RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE));
-+    RxDescList[i].hw_len = 0;
-+    RxDescList[i].status = 0;
-+    
-+    /* DMA IN cache bug. (struct etrax_dma_descr has the same layout as
-+       USB_IN_Desc for the relevant fields.) */
-+    prepare_rx_descriptor((struct etrax_dma_descr*)&RxDescList[i]);
-+    
-+  }
-+  /* Special handling of last descriptor */
-+  RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
-+  RxDescList[i].command = IO_STATE(USB_IN_command, eol, yes);
-+  RxDescList[i].next = virt_to_phys(&RxDescList[0]);
-+  RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE));
-+  RxDescList[i].hw_len = 0;
-+  RxDescList[i].status = 0;
-+  
-+  /* Setup list pointers that show progress in list */
-+  myNextRxDesc = &RxDescList[0];
-+  myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
-+  
-+  flush_etrax_cache();
-+  /* Point DMA to first descriptor in list and start it */
-+  *R_DMA_CH9_FIRST = virt_to_phys(myNextRxDesc);
-+  *R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, start);
-+}
-+
-+
-+static void tc_dma_init_tx_bulk_list(void) {
-+  int i;
-+  volatile struct USB_EP_Desc *epDescr;
-+
-+  for (i = 0; i < (NBR_OF_EPIDS - 1); i++) {
-+    epDescr = &(TxBulkEPList[i]);
-+    CHECK_ALIGN(epDescr);
-+    epDescr->hw_len = 0;
-+    epDescr->command = IO_FIELD(USB_EP_command, epid, i);
-+    epDescr->sub = 0;
-+    epDescr->next = virt_to_phys(&TxBulkEPList[i + 1]);
-+
-+    /* Initiate two EPs, disabled and with the eol flag set. No need for any
-+       preserved epid. */
-+    
-+    /* The first one has the intr flag set so we get an interrupt when the DMA
-+       channel is about to become disabled. */
-+    CHECK_ALIGN(&TxBulkDummyEPList[i][0]);
-+    TxBulkDummyEPList[i][0].hw_len = 0;
-+    TxBulkDummyEPList[i][0].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) |
-+                                     IO_STATE(USB_EP_command, eol, yes) |
-+                                     IO_STATE(USB_EP_command, intr, yes));
-+    TxBulkDummyEPList[i][0].sub = 0;
-+    TxBulkDummyEPList[i][0].next = virt_to_phys(&TxBulkDummyEPList[i][1]);
-+    
-+    /* The second one. */
-+    CHECK_ALIGN(&TxBulkDummyEPList[i][1]);
-+    TxBulkDummyEPList[i][1].hw_len = 0;
-+    TxBulkDummyEPList[i][1].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) |
-+                                     IO_STATE(USB_EP_command, eol, yes));
-+    TxBulkDummyEPList[i][1].sub = 0;
-+    /* The last dummy's next pointer is the same as the current EP's next pointer. */
-+    TxBulkDummyEPList[i][1].next = virt_to_phys(&TxBulkEPList[i + 1]);
-+  }
-+
-+  /* Special handling of last descr in list, make list circular */
-+  epDescr = &TxBulkEPList[i];
-+  CHECK_ALIGN(epDescr);
-+  epDescr->hw_len = 0;
-+  epDescr->command = IO_STATE(USB_EP_command, eol, yes) |
-+    IO_FIELD(USB_EP_command, epid, i);
-+  epDescr->sub = 0;
-+  epDescr->next = virt_to_phys(&TxBulkEPList[0]);
-+  
-+  /* Init DMA sub-channel pointers to last item in each list */
-+  *R_DMA_CH8_SUB0_EP = virt_to_phys(&TxBulkEPList[i]);
-+  /* No point in starting the bulk channel yet.
-+   *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); */
-+}
-+
-+static void tc_dma_init_tx_ctrl_list(void) {
-+  int i;
-+  volatile struct USB_EP_Desc *epDescr;
-+
-+  for (i = 0; i < (NBR_OF_EPIDS - 1); i++) {
-+    epDescr = &(TxCtrlEPList[i]);
-+    CHECK_ALIGN(epDescr);
-+    epDescr->hw_len = 0;
-+    epDescr->command = IO_FIELD(USB_EP_command, epid, i);
-+    epDescr->sub = 0;
-+    epDescr->next = virt_to_phys(&TxCtrlEPList[i + 1]);
-+  }
-+  /* Special handling of last descr in list, make list circular */
-+  epDescr = &TxCtrlEPList[i];
-+  CHECK_ALIGN(epDescr);
-+  epDescr->hw_len = 0;
-+  epDescr->command = IO_STATE(USB_EP_command, eol, yes) |
-+    IO_FIELD(USB_EP_command, epid, i);
-+  epDescr->sub = 0;
-+  epDescr->next = virt_to_phys(&TxCtrlEPList[0]);
-+  
-+  /* Init DMA sub-channel pointers to last item in each list */
-+  *R_DMA_CH8_SUB1_EP = virt_to_phys(&TxCtrlEPList[i]);
-+  /* No point in starting the ctrl channel yet.
-+   *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); */
-+}
-+
-+
-+static void tc_dma_init_tx_intr_list(void) {
-+  int i;
-+
-+  TxIntrSB_zout.sw_len = 1;
-+  TxIntrSB_zout.next = 0;
-+  TxIntrSB_zout.buf = virt_to_phys(&zout_buffer[0]);
-+  TxIntrSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) |
-+                         IO_STATE(USB_SB_command, tt, zout) |
-+                         IO_STATE(USB_SB_command, full, yes) |
-+                         IO_STATE(USB_SB_command, eot, yes) |
-+                         IO_STATE(USB_SB_command, eol, yes));
-+  
-+  for (i = 0; i < (MAX_INTR_INTERVAL - 1); i++) {
-+    CHECK_ALIGN(&TxIntrEPList[i]);
-+    TxIntrEPList[i].hw_len = 0;
-+    TxIntrEPList[i].command =
-+      (IO_STATE(USB_EP_command, eof, yes) |
-+       IO_STATE(USB_EP_command, enable, yes) |
-+       IO_FIELD(USB_EP_command, epid, INVALID_EPID));
-+    TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout);
-+    TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[i + 1]);
-+  }
-+
-+  /* Special handling of last descr in list, make list circular */
-+  CHECK_ALIGN(&TxIntrEPList[i]);
-+  TxIntrEPList[i].hw_len = 0;
-+  TxIntrEPList[i].command =
-+    (IO_STATE(USB_EP_command, eof, yes) |
-+     IO_STATE(USB_EP_command, eol, yes) |
-+     IO_STATE(USB_EP_command, enable, yes) |
-+     IO_FIELD(USB_EP_command, epid, INVALID_EPID));
-+  TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout);
-+  TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[0]);
-+
-+  intr_dbg("Initiated Intr EP descriptor list\n");
-+
-+
-+  /* Connect DMA 8 sub-channel 2 to first in list */
-+  *R_DMA_CH8_SUB2_EP = virt_to_phys(&TxIntrEPList[0]);
-+}
-+
-+static void tc_dma_init_tx_isoc_list(void) {
-+  int i;
-+
-+  DBFENTER;
-+
-+  /* Read comment at zout_buffer declaration for an explanation to this. */
-+  TxIsocSB_zout.sw_len = 1;
-+  TxIsocSB_zout.next = 0;
-+  TxIsocSB_zout.buf = virt_to_phys(&zout_buffer[0]);
-+  TxIsocSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) |
-+                         IO_STATE(USB_SB_command, tt, zout) |
-+                         IO_STATE(USB_SB_command, full, yes) |
-+                         IO_STATE(USB_SB_command, eot, yes) |
-+                         IO_STATE(USB_SB_command, eol, yes));
-+
-+  /* The last isochronous EP descriptor is a dummy. */
-+  for (i = 0; i < (NBR_OF_EPIDS - 1); i++) {
-+    CHECK_ALIGN(&TxIsocEPList[i]);
-+    TxIsocEPList[i].hw_len = 0;
-+    TxIsocEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
-+    TxIsocEPList[i].sub = 0;
-+    TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[i + 1]);
-+  }
-+
-+  CHECK_ALIGN(&TxIsocEPList[i]);
-+  TxIsocEPList[i].hw_len = 0;
-+
-+  /* Must enable the last EP descr to get eof interrupt. */
-+  TxIsocEPList[i].command = (IO_STATE(USB_EP_command, enable, yes) |
-+                           IO_STATE(USB_EP_command, eof, yes) |
-+                           IO_STATE(USB_EP_command, eol, yes) |
-+                           IO_FIELD(USB_EP_command, epid, INVALID_EPID));
-+  TxIsocEPList[i].sub = virt_to_phys(&TxIsocSB_zout);
-+  TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[0]);
-+
-+  *R_DMA_CH8_SUB3_EP = virt_to_phys(&TxIsocEPList[0]);
-+  *R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start);
-+}
-+
-+static int tc_dma_init(struct usb_hcd *hcd) {
-+  tc_dma_init_rx_list();
-+  tc_dma_init_tx_bulk_list();
-+  tc_dma_init_tx_ctrl_list();
-+  tc_dma_init_tx_intr_list();
-+  tc_dma_init_tx_isoc_list();
-+
-+  if (cris_request_dma(USB_TX_DMA_NBR,
-+                     "ETRAX 100LX built-in USB (Tx)",
-+                     DMA_VERBOSE_ON_ERROR,
-+                     dma_usb)) {
-+    err("Could not allocate DMA ch 8 for USB");
-+    return -EBUSY;
-+  }
-+      
-+  if (cris_request_dma(USB_RX_DMA_NBR,
-+                     "ETRAX 100LX built-in USB (Rx)",
-+                     DMA_VERBOSE_ON_ERROR,
-+                     dma_usb)) {
-+    err("Could not allocate DMA ch 9 for USB");
-+    return -EBUSY;
-+  }
-+
-+  *R_IRQ_MASK2_SET =
-+    /* Note that these interrupts are not used. */
-+    IO_STATE(R_IRQ_MASK2_SET, dma8_sub0_descr, set) |
-+    /* Sub channel 1 (ctrl) descr. interrupts are used. */
-+    IO_STATE(R_IRQ_MASK2_SET, dma8_sub1_descr, set) |
-+    IO_STATE(R_IRQ_MASK2_SET, dma8_sub2_descr, set) |
-+    /* Sub channel 3 (isoc) descr. interrupts are used. */
-+    IO_STATE(R_IRQ_MASK2_SET, dma8_sub3_descr, set);
-+  
-+  /* Note that the dma9_descr interrupt is not used. */
-+  *R_IRQ_MASK2_SET =
-+    IO_STATE(R_IRQ_MASK2_SET, dma9_eop, set) |
-+    IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
-+
-+  if (request_irq(ETRAX_USB_RX_IRQ, tc_dma_rx_interrupt, 0,
-+                "ETRAX 100LX built-in USB (Rx)", hcd)) {
-+    err("Could not allocate IRQ %d for USB", ETRAX_USB_RX_IRQ);
-+    return -EBUSY;
-+  }
-+  
-+  if (request_irq(ETRAX_USB_TX_IRQ, tc_dma_tx_interrupt, 0,
-+                "ETRAX 100LX built-in USB (Tx)", hcd)) {
-+    err("Could not allocate IRQ %d for USB", ETRAX_USB_TX_IRQ);
-+    return -EBUSY;
-+  }
-+
-+  return 0;
-+}
-+
-+static void tc_dma_destroy(void) {
-+  free_irq(ETRAX_USB_RX_IRQ, NULL);
-+  free_irq(ETRAX_USB_TX_IRQ, NULL);
-+
-+  cris_free_dma(USB_TX_DMA_NBR, "ETRAX 100LX built-in USB (Tx)");
-+  cris_free_dma(USB_RX_DMA_NBR, "ETRAX 100LX built-in USB (Rx)");
-+
-+}
-+
-+static void tc_dma_link_intr_urb(struct urb *urb);
-+
-+/* Handle processing of Bulk, Ctrl and Intr queues */
-+static void tc_dma_process_queue(int epid) {
-+  struct urb *urb;
-+  struct crisv10_urb_priv *urb_priv = urb->hcpriv;
-+  unsigned long flags;
-+  char toggle;
-+
-+  if(epid_state[epid].disabled) {
-+    /* Don't process any URBs on a disabled endpoint */
-+    return;
-+  }
-+
-+  /* Do not disturb us while fiddling with EPs and epids */
-+  local_irq_save(flags);
-+
-+  /* For bulk, Ctrl and Intr can we only have one URB active at a time for
-+     a specific EP. */
-+  if(activeUrbList[epid] != NULL) {
-+    /* An URB is already active on EP, skip checking queue */
-+    local_irq_restore(flags);
-+    return;
-+  }
-+
-+  urb = urb_list_first(epid);
-+  if(urb == NULL) {
-+    /* No URB waiting in EP queue. Nothing do to */
-+    local_irq_restore(flags);
-+    return;
-+  }
-+
-+  urb_priv = urb->hcpriv;
-+  ASSERT(urb_priv != NULL);
-+  ASSERT(urb_priv->urb_state == NOT_STARTED);
-+  ASSERT(!usb_pipeisoc(urb->pipe));
-+
-+  /* Remove this URB from the queue and move it to active */
-+  activeUrbList[epid] = urb;
-+  urb_list_del(urb, epid);
-+
-+  urb_priv->urb_state = STARTED;
-+
-+  /* Reset error counters (regardless of which direction this traffic is). */
-+  etrax_epid_clear_error(epid);
-+
-+  /* Special handling of Intr EP lists */
-+  if(usb_pipeint(urb->pipe)) {
-+    tc_dma_link_intr_urb(urb);
-+    local_irq_restore(flags);
-+    return;
-+  }
-+
-+  /* Software must preset the toggle bits for Bulk and Ctrl */
-+  if(usb_pipecontrol(urb->pipe)) {
-+    /* Toggle bits are initialized only during setup transaction in a
-+       CTRL transfer */
-+    etrax_epid_set_toggle(epid, 0, 0);
-+    etrax_epid_set_toggle(epid, 1, 0);
-+  } else {
-+    toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-+                         usb_pipeout(urb->pipe));
-+    etrax_epid_set_toggle(epid, usb_pipeout(urb->pipe), toggle);
-+  }
-+
-+  tc_dbg("Added SBs from (URB:0x%x %s %s) to epid %d: %s\n",
-+       (unsigned int)urb, str_dir(urb->pipe), str_type(urb->pipe), epid,
-+       sblist_to_str(urb_priv->first_sb));
-+
-+  /* We start the DMA sub channel without checking if it's running or not,
-+     because:
-+     1) If it's already running, issuing the start command is a nop.
-+     2) We avoid a test-and-set race condition. */
-+  switch(usb_pipetype(urb->pipe)) {
-+  case PIPE_BULK:
-+    /* Assert that the EP descriptor is disabled. */
-+    ASSERT(!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)));
-+
-+    /* Set up and enable the EP descriptor. */
-+    TxBulkEPList[epid].sub = virt_to_phys(urb_priv->first_sb);
-+    TxBulkEPList[epid].hw_len = 0;
-+    TxBulkEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-+
-+    /* Check if the dummy list is already with us (if several urbs were queued). */
-+    if (usb_pipein(urb->pipe) && (TxBulkEPList[epid].next != virt_to_phys(&TxBulkDummyEPList[epid][0]))) {
-+      tc_dbg("Inviting dummy list to the party for urb 0x%lx, epid %d", 
-+           (unsigned long)urb, epid);
-+      
-+      /* We don't need to check if the DMA is at this EP or not before changing the
-+       next pointer, since we will do it in one 32-bit write (EP descriptors are
-+       32-bit aligned). */
-+      TxBulkEPList[epid].next = virt_to_phys(&TxBulkDummyEPList[epid][0]);
-+    }
-+
-+    restart_dma8_sub0();
-+
-+    /* Update/restart the bulk start timer since we just started the channel.*/
-+    mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL);
-+    /* Update/restart the bulk eot timer since we just inserted traffic. */
-+    mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL);
-+    break;
-+  case PIPE_CONTROL:
-+    /* Assert that the EP descriptor is disabled. */
-+    ASSERT(!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)));
-+
-+    /* Set up and enable the EP descriptor. */
-+    TxCtrlEPList[epid].sub = virt_to_phys(urb_priv->first_sb);
-+    TxCtrlEPList[epid].hw_len = 0;
-+    TxCtrlEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-+
-+    *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start);
-+    break;
-+  }
-+  local_irq_restore(flags);
-+}
-+
-+static void tc_dma_link_intr_urb(struct urb *urb) {
-+  struct crisv10_urb_priv *urb_priv = urb->hcpriv;
-+  volatile struct USB_EP_Desc *tmp_ep;
-+  struct USB_EP_Desc *ep_desc;
-+  int i = 0, epid;
-+  int pool_idx = 0;
-+
-+  ASSERT(urb_priv != NULL);
-+  epid = urb_priv->epid;
-+  ASSERT(urb_priv->interval > 0);
-+  ASSERT(urb_priv->intr_ep_pool_length > 0);
-+
-+  tmp_ep = &TxIntrEPList[0];
-+
-+  /* Only insert one EP descriptor in list for Out Intr URBs.
-+     We can only handle Out Intr with interval of 128ms because
-+     it's not possible to insert several Out Intr EPs because they
-+     are not consumed by the DMA. */
-+  if(usb_pipeout(urb->pipe)) {
-+    ep_desc = urb_priv->intr_ep_pool[0];
-+    ASSERT(ep_desc);
-+    ep_desc->next = tmp_ep->next;
-+    tmp_ep->next = virt_to_phys(ep_desc);
-+    i++;
-+  } else {
-+    /* Loop through Intr EP descriptor list and insert EP for URB at
-+       specified interval */
-+    do {
-+      /* Each EP descriptor with eof flag sat signals a new frame */
-+      if (tmp_ep->command & IO_MASK(USB_EP_command, eof)) {
-+      /* Insert a EP from URBs EP pool at correct interval */
-+      if ((i % urb_priv->interval) == 0) {
-+        ep_desc = urb_priv->intr_ep_pool[pool_idx];
-+        ASSERT(ep_desc);
-+        ep_desc->next = tmp_ep->next;
-+        tmp_ep->next = virt_to_phys(ep_desc);
-+        pool_idx++;
-+        ASSERT(pool_idx <= urb_priv->intr_ep_pool_length);
-+      }
-+      i++;
-+      }
-+      tmp_ep = (struct USB_EP_Desc *)phys_to_virt(tmp_ep->next);
-+    } while(tmp_ep != &TxIntrEPList[0]);
-+  }
-+
-+  intr_dbg("Added SBs to intr epid %d: %s interval:%d (%d EP)\n", epid,
-+         sblist_to_str(urb_priv->first_sb), urb_priv->interval, pool_idx);
-+
-+  /* We start the DMA sub channel without checking if it's running or not,
-+     because:
-+     1) If it's already running, issuing the start command is a nop.
-+     2) We avoid a test-and-set race condition. */
-+  *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
-+}
-+
-+  /* hinko ignore usb_pipeisoc */
-+#if 0
-+static void tc_dma_process_isoc_urb(struct urb *urb) {
-+  unsigned long flags;
-+  struct crisv10_urb_priv *urb_priv = urb->hcpriv;
-+  int epid;
-+
-+  /* Do not disturb us while fiddling with EPs and epids */
-+  local_irq_save(flags);
-+
-+  ASSERT(urb_priv);
-+  ASSERT(urb_priv->first_sb);
-+  epid = urb_priv->epid;
-+
-+  if(activeUrbList[epid] == NULL) {
-+    /* EP is idle, so make this URB active */
-+    activeUrbList[epid] = urb;
-+    urb_list_del(urb, epid);
-+    ASSERT(TxIsocEPList[epid].sub == 0);
-+    ASSERT(!(TxIsocEPList[epid].command &
-+           IO_STATE(USB_EP_command, enable, yes)));
-+
-+    /* Differentiate between In and Out Isoc. Because In SBs are not consumed*/
-+    if(usb_pipein(urb->pipe)) {
-+    /* Each EP for In Isoc will have only one SB descriptor, setup when
-+       submitting the first active urb. We do it here by copying from URBs
-+       pre-allocated SB. */
-+      memcpy((void *)&(TxIsocSBList[epid]), urb_priv->first_sb,
-+           sizeof(TxIsocSBList[epid]));
-+      TxIsocEPList[epid].hw_len = 0;
-+      TxIsocEPList[epid].sub = virt_to_phys(&(TxIsocSBList[epid]));
-+    } else {
-+      /* For Out Isoc we attach the pre-allocated list of SBs for the URB */
-+      TxIsocEPList[epid].hw_len = 0;
-+      TxIsocEPList[epid].sub = virt_to_phys(urb_priv->first_sb);
-+
-+      isoc_dbg("Attached first URB:0x%x[%d] to epid:%d first_sb:0x%x"
-+             " last_sb::0x%x\n",
-+             (unsigned int)urb, urb_priv->urb_num, epid,
-+             (unsigned int)(urb_priv->first_sb),
-+             (unsigned int)(urb_priv->last_sb));
-+    }
-+
-+    if (urb->transfer_flags & URB_ISO_ASAP) {
-+      /* The isoc transfer should be started as soon as possible. The
-+       start_frame field is a return value if URB_ISO_ASAP was set. Comparing
-+       R_USB_FM_NUMBER with a USB Chief trace shows that the first isoc IN
-+       token is sent 2 frames later. I'm not sure how this affects usage of
-+       the start_frame field by the device driver, or how it affects things
-+       when USB_ISO_ASAP is not set, so therefore there's no compensation for
-+       the 2 frame "lag" here. */
-+      urb->start_frame = (*R_USB_FM_NUMBER & 0x7ff);
-+      TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
-+      urb_priv->urb_state = STARTED;
-+      isoc_dbg("URB_ISO_ASAP set, urb->start_frame set to %d\n",
-+             urb->start_frame);
-+    } else {
-+      /* Not started yet. */
-+      urb_priv->urb_state = NOT_STARTED;
-+      isoc_warn("urb_priv->urb_state set to NOT_STARTED for URB:0x%x\n",
-+              (unsigned int)urb);
-+    }
-+
-+  } else {
-+    /* An URB is already active on the EP. Leave URB in queue and let
-+       finish_isoc_urb process it after current active URB */
-+    ASSERT(TxIsocEPList[epid].sub != 0);
-+
-+    if(usb_pipein(urb->pipe)) {
-+      /* Because there already is a active In URB on this epid we do nothing
-+         and the finish_isoc_urb() function will handle switching to next URB*/
-+
-+    } else { /* For Out Isoc, insert new URBs traffic last in SB-list. */
-+      struct USB_SB_Desc *temp_sb_desc;
-+
-+      /* Set state STARTED to all Out Isoc URBs added to SB list because we
-+         don't know how many of them that are finished before descr interrupt*/
-+      urb_priv->urb_state = STARTED;
-+
-+      /* Find end of current SB list by looking for SB with eol flag sat */
-+      temp_sb_desc = phys_to_virt(TxIsocEPList[epid].sub);
-+      while ((temp_sb_desc->command & IO_MASK(USB_SB_command, eol)) !=
-+           IO_STATE(USB_SB_command, eol, yes)) {
-+      ASSERT(temp_sb_desc->next);
-+      temp_sb_desc = phys_to_virt(temp_sb_desc->next);
-+      }
-+
-+      isoc_dbg("Appended URB:0x%x[%d] (first:0x%x last:0x%x) to epid:%d"
-+             " sub:0x%x eol:0x%x\n",
-+             (unsigned int)urb, urb_priv->urb_num,
-+             (unsigned int)(urb_priv->first_sb),
-+             (unsigned int)(urb_priv->last_sb), epid,
-+             (unsigned int)phys_to_virt(TxIsocEPList[epid].sub),
-+             (unsigned int)temp_sb_desc);
-+
-+      /* Next pointer must be set before eol is removed. */
-+      temp_sb_desc->next = virt_to_phys(urb_priv->first_sb);
-+      /* Clear the previous end of list flag since there is a new in the
-+       added SB descriptor list. */
-+      temp_sb_desc->command &= ~IO_MASK(USB_SB_command, eol);
-+
-+      if (!(TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable))) {
-+      __u32 epid_data;
-+      /* 8.8.5 in Designer's Reference says we should check for and correct
-+         any errors in the EP here.  That should not be necessary if
-+         epid_attn is handled correctly, so we assume all is ok. */
-+      epid_data = etrax_epid_iso_get(epid);
-+      if (IO_EXTRACT(R_USB_EPT_DATA, error_code, epid_data) !=
-+          IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-+        isoc_err("Disabled Isoc EP with error:%d on epid:%d when appending"
-+                 " URB:0x%x[%d]\n",
-+                 IO_EXTRACT(R_USB_EPT_DATA, error_code, epid_data), epid,
-+                 (unsigned int)urb, urb_priv->urb_num);
-+      }
-+
-+      /* The SB list was exhausted. */
-+      if (virt_to_phys(urb_priv->last_sb) != TxIsocEPList[epid].sub) {
-+        /* The new sublist did not get processed before the EP was
-+           disabled.  Setup the EP again. */
-+
-+        if(virt_to_phys(temp_sb_desc) == TxIsocEPList[epid].sub) {
-+          isoc_dbg("EP for epid:%d stoped at SB:0x%x before newly inserted"
-+                   ", restarting from this URBs SB:0x%x\n",
-+                   epid, (unsigned int)temp_sb_desc,
-+                   (unsigned int)(urb_priv->first_sb));
-+          TxIsocEPList[epid].hw_len = 0;
-+          TxIsocEPList[epid].sub = virt_to_phys(urb_priv->first_sb);
-+          urb->start_frame = (*R_USB_FM_NUMBER & 0x7ff);
-+          /* Enable the EP again so data gets processed this time */
-+          TxIsocEPList[epid].command |=
-+            IO_STATE(USB_EP_command, enable, yes);
-+
-+        } else {
-+          /* The EP has been disabled but not at end this URB (god knows
-+             where). This should generate an epid_attn so we should not be
-+             here */
-+          isoc_warn("EP was disabled on sb:0x%x before SB list for"
-+                   " URB:0x%x[%d] got processed\n",
-+                   (unsigned int)phys_to_virt(TxIsocEPList[epid].sub),
-+                   (unsigned int)urb, urb_priv->urb_num);
-+        }
-+      } else {
-+        /* This might happend if we are slow on this function and isn't
-+           an error. */
-+        isoc_dbg("EP was disabled and finished with SBs from appended"
-+                 " URB:0x%x[%d]\n", (unsigned int)urb, urb_priv->urb_num);
-+      }
-+      }
-+    }
-+  }
-+  
-+  /* Start the DMA sub channel */
-+  *R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start);
-+
-+  local_irq_restore(flags);
-+}
-+#endif
-+
-+static void tc_dma_unlink_intr_urb(struct urb *urb) {
-+  struct crisv10_urb_priv *urb_priv = urb->hcpriv;
-+  volatile struct USB_EP_Desc *first_ep;  /* First EP in the list. */
-+  volatile struct USB_EP_Desc *curr_ep;   /* Current EP, the iterator. */
-+  volatile struct USB_EP_Desc *next_ep;   /* The EP after current. */
-+  volatile struct USB_EP_Desc *unlink_ep; /* The one we should remove from
-+                                           the list. */
-+  int count = 0;
-+  volatile int timeout = 10000;
-+  int epid;
-+
-+  /* Read 8.8.4 in Designer's Reference, "Removing an EP Descriptor from the
-+     List". */
-+  ASSERT(urb_priv);
-+  ASSERT(urb_priv->intr_ep_pool_length > 0);
-+  epid = urb_priv->epid;
-+
-+  /* First disable all Intr EPs belonging to epid for this URB */
-+  first_ep = &TxIntrEPList[0];
-+  curr_ep = first_ep;
-+  do {
-+    next_ep = (struct USB_EP_Desc *)phys_to_virt(curr_ep->next);
-+    if (IO_EXTRACT(USB_EP_command, epid, next_ep->command) == epid) {
-+      /* Disable EP */
-+      next_ep->command &= ~IO_MASK(USB_EP_command, enable);
-+    }
-+    curr_ep = phys_to_virt(curr_ep->next);
-+  } while (curr_ep != first_ep);
-+
-+
-+  /* Now unlink all EPs belonging to this epid from Descr list */
-+  first_ep = &TxIntrEPList[0];
-+  curr_ep = first_ep;
-+  do {
-+    next_ep = (struct USB_EP_Desc *)phys_to_virt(curr_ep->next);
-+    if (IO_EXTRACT(USB_EP_command, epid, next_ep->command) == epid) {
-+      /* This is the one we should unlink. */
-+      unlink_ep = next_ep;
-+
-+      /* Actually unlink the EP from the DMA list. */
-+      curr_ep->next = unlink_ep->next;
-+
-+      /* Wait until the DMA is no longer at this descriptor. */
-+      while((*R_DMA_CH8_SUB2_EP == virt_to_phys(unlink_ep)) &&
-+          (timeout-- > 0));
-+      if(timeout == 0) {
-+      warn("Timeout while waiting for DMA-TX-Intr to leave unlink EP\n");
-+      }
-+      
-+      count++;
-+    }
-+    curr_ep = phys_to_virt(curr_ep->next);
-+  } while (curr_ep != first_ep);
-+
-+  if(count != urb_priv->intr_ep_pool_length) {
-+    intr_warn("Unlinked %d of %d Intr EPs for URB:0x%x[%d]\n", count,
-+            urb_priv->intr_ep_pool_length, (unsigned int)urb,
-+            urb_priv->urb_num);
-+  } else {
-+    intr_dbg("Unlinked %d of %d interrupt EPs for URB:0x%x\n", count,
-+           urb_priv->intr_ep_pool_length, (unsigned int)urb);
-+  }
-+}
-+
-+static void check_finished_bulk_tx_epids(struct usb_hcd *hcd,
-+                                                  int timer) {
-+  unsigned long flags;
-+  int epid;
-+  struct urb *urb;
-+  struct crisv10_urb_priv * urb_priv;
-+  __u32 epid_data;
-+
-+  /* Protect TxEPList */
-+  local_irq_save(flags);
-+
-+  for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
-+    /* A finished EP descriptor is disabled and has a valid sub pointer */
-+    if (!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) &&
-+      (TxBulkEPList[epid].sub != 0)) {
-+
-+      /* Get the active URB for this epid */
-+      urb = activeUrbList[epid];
-+      /* Sanity checks */
-+      ASSERT(urb);
-+      urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+      ASSERT(urb_priv);
-+      
-+      /* Only handle finished out Bulk EPs here,
-+       and let RX interrupt take care of the rest */
-+      if(!epid_out_traffic(epid)) {
-+      continue;
-+      }
-+
-+      if(timer) {
-+      tc_warn("Found finished %s Bulk epid:%d URB:0x%x[%d] from timeout\n",
-+              epid_out_traffic(epid) ? "Out" : "In", epid, (unsigned int)urb,
-+              urb_priv->urb_num);
-+      } else {
-+      tc_dbg("Found finished %s Bulk epid:%d URB:0x%x[%d] from interrupt\n",
-+             epid_out_traffic(epid) ? "Out" : "In", epid, (unsigned int)urb,
-+             urb_priv->urb_num);
-+      }
-+
-+      if(urb_priv->urb_state == UNLINK) {
-+      /* This Bulk URB is requested to be unlinked, that means that the EP
-+         has been disabled and we might not have sent all data */
-+      tc_finish_urb(hcd, urb, urb->status);
-+      continue;
-+      }
-+
-+      ASSERT(urb_priv->urb_state == STARTED);
-+      if (phys_to_virt(TxBulkEPList[epid].sub) != urb_priv->last_sb) {
-+      tc_err("Endpoint got disabled before reaching last sb\n");
-+      }
-+      
-+      epid_data = etrax_epid_get(epid);
-+      if (IO_EXTRACT(R_USB_EPT_DATA, error_code, epid_data) ==
-+        IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-+      /* This means that the endpoint has no error, is disabled
-+         and had inserted traffic, i.e. transfer successfully completed. */
-+      tc_finish_urb(hcd, urb, 0);
-+      } else {
-+      /* Shouldn't happen. We expect errors to be caught by epid
-+         attention. */
-+      tc_err("Found disabled bulk EP desc (epid:%d error:%d)\n",
-+             epid, IO_EXTRACT(R_USB_EPT_DATA, error_code, epid_data));
-+      }
-+    } else {
-+      tc_dbg("Ignoring In Bulk epid:%d, let RX interrupt handle it\n", epid);
-+    }
-+  }
-+
-+  local_irq_restore(flags);
-+}
-+
-+static void check_finished_ctrl_tx_epids(struct usb_hcd *hcd) {
-+  unsigned long flags;
-+  int epid;
-+  struct urb *urb;
-+  struct crisv10_urb_priv * urb_priv;
-+  __u32 epid_data;
-+
-+  /* Protect TxEPList */
-+  local_irq_save(flags);
-+
-+  for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
-+    if(epid == DUMMY_EPID)
-+      continue;
-+
-+    /* A finished EP descriptor is disabled and has a valid sub pointer */
-+    if (!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) &&
-+      (TxCtrlEPList[epid].sub != 0)) {
-+      
-+      /* Get the active URB for this epid */
-+      urb = activeUrbList[epid];
-+
-+      if(urb == NULL) {
-+      tc_warn("Found finished Ctrl epid:%d with no active URB\n", epid);
-+      continue;
-+      }
-+      
-+      /* Sanity checks */
-+      ASSERT(usb_pipein(urb->pipe));
-+      urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+      ASSERT(urb_priv);
-+      if (phys_to_virt(TxCtrlEPList[epid].sub) != urb_priv->last_sb) {
-+      tc_err("Endpoint got disabled before reaching last sb\n");
-+      }
-+
-+      epid_data = etrax_epid_get(epid);
-+      if (IO_EXTRACT(R_USB_EPT_DATA, error_code, epid_data) ==
-+        IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-+      /* This means that the endpoint has no error, is disabled
-+         and had inserted traffic, i.e. transfer successfully completed. */
-+
-+      /* Check if RX-interrupt for In Ctrl has been processed before
-+         finishing the URB */
-+      if(urb_priv->ctrl_rx_done) {
-+        tc_dbg("Finishing In Ctrl URB:0x%x[%d] in tx_interrupt\n",
-+               (unsigned int)urb, urb_priv->urb_num);
-+        tc_finish_urb(hcd, urb, 0);
-+      } else {
-+        /* If we get zout descriptor interrupt before RX was done for a
-+           In Ctrl transfer, then we flag that and it will be finished
-+           in the RX-Interrupt */
-+        urb_priv->ctrl_zout_done = 1;
-+        tc_dbg("Got zout descr interrupt before RX interrupt\n");
-+      }
-+      } else {
-+      /* Shouldn't happen. We expect errors to be caught by epid
-+         attention. */
-+      tc_err("Found disabled Ctrl EP desc (epid:%d URB:0x%x[%d]) error_code:%d\n", epid, (unsigned int)urb, urb_priv->urb_num, IO_EXTRACT(R_USB_EPT_DATA, error_code, epid_data));
-+      __dump_ep_desc(&(TxCtrlEPList[epid]));
-+      __dump_ept_data(epid);
-+      }      
-+    }
-+  }
-+  local_irq_restore(flags);
-+}
-+
-+  /* hinko ignore usb_pipeisoc */
-+#if 0
-+/* This function goes through all epids that are setup for Out Isoc transfers
-+   and marks (isoc_out_done) all queued URBs that the DMA has finished
-+   transfer for.
-+   No URB completetion is done here to make interrupt routine return quickly.
-+   URBs are completed later with help of complete_isoc_bottom_half() that
-+   becomes schedules when this functions is finished. */
-+static void check_finished_isoc_tx_epids(void) {
-+  unsigned long flags;
-+  int epid;
-+  struct urb *urb;
-+  struct crisv10_urb_priv * urb_priv;
-+  struct USB_SB_Desc* sb_desc;
-+  int epid_done;
-+
-+  /* Protect TxIsocEPList */
-+  local_irq_save(flags);
-+
-+  for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
-+    if (TxIsocEPList[epid].sub == 0 || epid == INVALID_EPID ||
-+      !epid_out_traffic(epid)) {
-+      /* Nothing here to see. */
-+      continue;
-+    }
-+    ASSERT(epid_inuse(epid));
-+    ASSERT(epid_isoc(epid));
-+
-+    sb_desc = phys_to_virt(TxIsocEPList[epid].sub);
-+    /* Find the last descriptor of the currently active URB for this ep.
-+       This is the first descriptor in the sub list marked for a descriptor
-+       interrupt. */
-+    while (sb_desc && !IO_EXTRACT(USB_SB_command, intr, sb_desc->command)) {
-+      sb_desc = sb_desc->next ? phys_to_virt(sb_desc->next) : 0;
-+    }
-+    ASSERT(sb_desc);
-+
-+    isoc_dbg("Descr IRQ checking epid:%d sub:0x%x intr:0x%x\n",
-+           epid, (unsigned int)phys_to_virt(TxIsocEPList[epid].sub),
-+           (unsigned int)sb_desc);
-+
-+    urb = activeUrbList[epid];
-+    if(urb == NULL) {
-+      isoc_err("Isoc Descr irq on epid:%d with no active URB\n", epid);
-+      continue;
-+    }
-+
-+    epid_done = 0;
-+    while(urb && !epid_done) {
-+      /* Sanity check. */
-+      ASSERT(usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS);
-+      ASSERT(usb_pipeout(urb->pipe));
-+      
-+      urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+      ASSERT(urb_priv);
-+      ASSERT(urb_priv->urb_state == STARTED ||
-+           urb_priv->urb_state == UNLINK);
-+      
-+      if (sb_desc != urb_priv->last_sb) {
-+      /* This urb has been sent. */
-+      urb_priv->isoc_out_done = 1;
-+
-+      } else { /* Found URB that has last_sb as the interrupt reason */
-+
-+      /* Check if EP has been disabled, meaning that all transfers are done*/
-+      if(!(TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable))) {
-+        ASSERT((sb_desc->command & IO_MASK(USB_SB_command, eol)) ==
-+               IO_STATE(USB_SB_command, eol, yes));
-+        ASSERT(sb_desc->next == 0);
-+        urb_priv->isoc_out_done = 1;
-+      } else {
-+        isoc_dbg("Skipping URB:0x%x[%d] because EP not disabled yet\n",
-+                 (unsigned int)urb, urb_priv->urb_num);
-+      }
-+      /* Stop looking any further in queue */
-+      epid_done = 1;  
-+      }
-+
-+      if (!epid_done) {
-+      if(urb == activeUrbList[epid]) {
-+        urb = urb_list_first(epid);
-+      } else {
-+        urb = urb_list_next(urb, epid);
-+      }
-+      }
-+    } /* END: while(urb && !epid_done) */
-+  }
-+
-+  local_irq_restore(flags);
-+}
-+
-+
-+/* This is where the Out Isoc URBs are realy completed. This function is
-+   scheduled from tc_dma_tx_interrupt() when one or more Out Isoc transfers
-+   are done. This functions completes all URBs earlier marked with
-+   isoc_out_done by fast interrupt routine check_finished_isoc_tx_epids() */
-+
-+static void complete_isoc_bottom_half(void *data) {
-+  struct crisv10_isoc_complete_data *comp_data;
-+  struct usb_iso_packet_descriptor *packet;
-+  struct crisv10_urb_priv * urb_priv;
-+  unsigned long flags;
-+  struct urb* urb;
-+  int epid_done;
-+  int epid;
-+  int i;
-+
-+  comp_data = (struct crisv10_isoc_complete_data*)data;
-+
-+  local_irq_save(flags);
-+
-+  for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) {
-+    if(!epid_inuse(epid) || !epid_isoc(epid) || !epid_out_traffic(epid) || epid == DUMMY_EPID) {
-+      /* Only check valid Out Isoc epids */
-+      continue;
-+    }
-+
-+    isoc_dbg("Isoc bottom-half checking epid:%d, sub:0x%x\n", epid,
-+           (unsigned int)phys_to_virt(TxIsocEPList[epid].sub));
-+
-+    /* The descriptor interrupt handler has marked all transmitted Out Isoc
-+       URBs with isoc_out_done.  Now we traverse all epids and for all that
-+       have out Isoc traffic we traverse its URB list and complete the
-+       transmitted URBs. */
-+    epid_done = 0;
-+    while (!epid_done) {
-+
-+      /* Get the active urb (if any) */
-+      urb = activeUrbList[epid];
-+      if (urb == 0) {
-+      isoc_dbg("No active URB on epid:%d anymore\n", epid);
-+      epid_done = 1;
-+      continue;
-+      }
-+
-+      /* Sanity check. */
-+      ASSERT(usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS);
-+      ASSERT(usb_pipeout(urb->pipe));
-+
-+      urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+      ASSERT(urb_priv);
-+
-+      if (!(urb_priv->isoc_out_done)) {
-+      /* We have reached URB that isn't flaged done yet, stop traversing. */
-+      isoc_dbg("Stoped traversing Out Isoc URBs on epid:%d"
-+               " before not yet flaged URB:0x%x[%d]\n",
-+               epid, (unsigned int)urb, urb_priv->urb_num);
-+      epid_done = 1;
-+      continue;
-+      }
-+
-+      /* This urb has been sent. */
-+      isoc_dbg("Found URB:0x%x[%d] that is flaged isoc_out_done\n",
-+             (unsigned int)urb, urb_priv->urb_num);
-+
-+      /* Set ok on transfered packets for this URB and finish it */
-+      for (i = 0; i < urb->number_of_packets; i++) {
-+      packet = &urb->iso_frame_desc[i];
-+      packet->status = 0;
-+      packet->actual_length = packet->length;
-+      }
-+      urb_priv->isoc_packet_counter = urb->number_of_packets;
-+      tc_finish_urb(comp_data->hcd, urb, 0);
-+
-+    } /* END: while(!epid_done) */
-+  } /* END: for(epid...) */
-+
-+  local_irq_restore(flags);
-+  kmem_cache_free(isoc_compl_cache, comp_data);
-+}
-+#endif
-+
-+static void check_finished_intr_tx_epids(struct usb_hcd *hcd) {
-+  unsigned long flags;
-+  int epid;
-+  struct urb *urb;
-+  struct crisv10_urb_priv * urb_priv;
-+  volatile struct USB_EP_Desc *curr_ep;   /* Current EP, the iterator. */
-+  volatile struct USB_EP_Desc *next_ep;   /* The EP after current. */
-+
-+  /* Protect TxintrEPList */
-+  local_irq_save(flags);
-+
-+  for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
-+    if(!epid_inuse(epid) || !epid_intr(epid) || !epid_out_traffic(epid)) {
-+      /* Nothing to see on this epid. Only check valid Out Intr epids */
-+      continue;
-+    }
-+
-+    urb = activeUrbList[epid];
-+    if(urb == 0) {
-+      intr_warn("Found Out Intr epid:%d with no active URB\n", epid);
-+      continue;
-+    }
-+
-+    /* Sanity check. */
-+    ASSERT(usb_pipetype(urb->pipe) == PIPE_INTERRUPT);
-+    ASSERT(usb_pipeout(urb->pipe));
-+    
-+    urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+    ASSERT(urb_priv);
-+
-+    /* Go through EPs between first and second sof-EP. It's here Out Intr EPs
-+       are inserted.*/
-+    curr_ep = &TxIntrEPList[0];
-+    do {
-+      next_ep = (struct USB_EP_Desc *)phys_to_virt(curr_ep->next);
-+      if(next_ep == urb_priv->intr_ep_pool[0]) {
-+      /* We found the Out Intr EP for this epid */
-+      
-+      /* Disable it so it doesn't get processed again */
-+      next_ep->command &= ~IO_MASK(USB_EP_command, enable);
-+
-+      /* Finish the active Out Intr URB with status OK */
-+      tc_finish_urb(hcd, urb, 0);
-+      }
-+      curr_ep = phys_to_virt(curr_ep->next);
-+    } while (curr_ep != &TxIntrEPList[1]);
-+
-+  }
-+  local_irq_restore(flags);
-+}
-+
-+/* Interrupt handler for DMA8/IRQ24 with subchannels (called from hardware intr) */
-+static irqreturn_t tc_dma_tx_interrupt(int irq, void *vhc) {
-+  struct usb_hcd *hcd = (struct usb_hcd*)vhc;
-+  ASSERT(hcd);
-+
-+  if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub0_descr)) {
-+    /* Clear this interrupt */
-+    *R_DMA_CH8_SUB0_CLR_INTR = IO_STATE(R_DMA_CH8_SUB0_CLR_INTR, clr_descr, do);
-+    restart_dma8_sub0();
-+  }
-+
-+  if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub1_descr)) {
-+    /* Clear this interrupt */
-+    *R_DMA_CH8_SUB1_CLR_INTR = IO_STATE(R_DMA_CH8_SUB1_CLR_INTR, clr_descr, do);
-+    check_finished_ctrl_tx_epids(hcd);
-+  }
-+
-+  if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub2_descr)) {
-+    /* Clear this interrupt */
-+    *R_DMA_CH8_SUB2_CLR_INTR = IO_STATE(R_DMA_CH8_SUB2_CLR_INTR, clr_descr, do);
-+    check_finished_intr_tx_epids(hcd);
-+  }
-+
-+  /* hinko ignore usb_pipeisoc */
-+#if 0
-+  if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub3_descr)) {
-+    struct crisv10_isoc_complete_data* comp_data;
-+
-+    /* Flag done Out Isoc for later completion */
-+    check_finished_isoc_tx_epids();
-+
-+    /* Clear this interrupt */
-+    *R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do);
-+    /* Schedule bottom half of Out Isoc completion function. This function
-+       finishes the URBs marked with isoc_out_done */
-+    comp_data = (struct crisv10_isoc_complete_data*)
-+      kmem_cache_alloc(isoc_compl_cache, GFP_ATOMIC);
-+    ASSERT(comp_data != NULL);
-+    comp_data ->hcd = hcd;
-+
-+    //INIT_WORK(&comp_data->usb_bh, complete_isoc_bottom_half, comp_data);
-+    INIT_WORK(&comp_data->usb_bh, complete_isoc_bottom_half);
-+    schedule_work(&comp_data->usb_bh);
-+  }
-+#endif
-+
-+  return IRQ_HANDLED;
-+}
-+
-+/* Interrupt handler for DMA9/IRQ25 (called from hardware intr) */
-+static irqreturn_t tc_dma_rx_interrupt(int irq, void *vhc) {
-+  unsigned long flags;
-+  struct urb *urb;
-+  struct usb_hcd *hcd = (struct usb_hcd*)vhc;
-+  struct crisv10_urb_priv *urb_priv;
-+  int epid = 0;
-+  int real_error;
-+
-+  ASSERT(hcd);
-+
-+  /* Clear this interrupt. */
-+  *R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do);
-+
-+  /* Custom clear interrupt for this interrupt */
-+  /* The reason we cli here is that we call the driver's callback functions. */
-+  local_irq_save(flags);
-+
-+  /* Note that this while loop assumes that all packets span only
-+     one rx descriptor. */
-+  while(myNextRxDesc->status & IO_MASK(USB_IN_status, eop)) {
-+    epid = IO_EXTRACT(USB_IN_status, epid, myNextRxDesc->status);
-+    /* Get the active URB for this epid */
-+    urb = activeUrbList[epid];
-+
-+    ASSERT(epid_inuse(epid));
-+    if (!urb) {
-+      dma_err("No urb for epid %d in rx interrupt\n", epid);
-+      goto skip_out;
-+    }
-+
-+    /* Check if any errors on epid */
-+    real_error = 0;
-+    if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) {
-+      __u32 r_usb_ept_data;
-+
-+      if (usb_pipeisoc(urb->pipe)) {
-+      r_usb_ept_data = etrax_epid_iso_get(epid);
-+      if((r_usb_ept_data & IO_MASK(R_USB_EPT_DATA_ISO, valid)) &&
-+         (IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code, r_usb_ept_data) == 0) &&
-+         (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata))) {
-+        /* Not an error, just a failure to receive an expected iso
-+           in packet in this frame.  This is not documented
-+           in the designers reference. Continue processing.
-+        */
-+      } else real_error = 1;
-+      } else real_error = 1;
-+    }
-+
-+    if(real_error) {
-+      dma_err("Error in RX descr on epid:%d for URB 0x%x",
-+            epid, (unsigned int)urb);
-+      dump_ept_data(epid);
-+      dump_in_desc(myNextRxDesc);
-+      goto skip_out;
-+    }
-+
-+    urb_priv = (struct crisv10_urb_priv *)urb->hcpriv;
-+    ASSERT(urb_priv);
-+    ASSERT(urb_priv->urb_state == STARTED ||
-+         urb_priv->urb_state == UNLINK);
-+
-+    if ((usb_pipetype(urb->pipe) == PIPE_BULK) ||
-+      (usb_pipetype(urb->pipe) == PIPE_CONTROL) ||
-+      (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
-+
-+      /* We get nodata for empty data transactions, and the rx descriptor's
-+       hw_len field is not valid in that case. No data to copy in other
-+       words. */
-+      if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) {
-+      /* No data to copy */
-+      } else {
-+      /*
-+      dma_dbg("Processing RX for URB:0x%x epid:%d (data:%d ofs:%d)\n",
-+              (unsigned int)urb, epid, myNextRxDesc->hw_len,
-+              urb_priv->rx_offset);
-+      */
-+      /* Only copy data if URB isn't flaged to be unlinked*/
-+      if(urb_priv->urb_state != UNLINK) {
-+        /* Make sure the data fits in the buffer. */
-+        if(urb_priv->rx_offset + myNextRxDesc->hw_len
-+           <= urb->transfer_buffer_length) {
-+
-+          /* Copy the data to URBs buffer */
-+          memcpy(urb->transfer_buffer + urb_priv->rx_offset,
-+                 phys_to_virt(myNextRxDesc->buf), myNextRxDesc->hw_len);
-+          urb_priv->rx_offset += myNextRxDesc->hw_len;
-+        } else {
-+          /* Signal overflow when returning URB */
-+          urb->status = -EOVERFLOW;
-+          tc_finish_urb_later(hcd, urb, urb->status);
-+        }
-+      }
-+      }
-+
-+      /* Check if it was the last packet in the transfer */
-+      if (myNextRxDesc->status & IO_MASK(USB_IN_status, eot)) {
-+      /* Special handling for In Ctrl URBs. */
-+      if(usb_pipecontrol(urb->pipe) && usb_pipein(urb->pipe) &&
-+         !(urb_priv->ctrl_zout_done)) {
-+        /* Flag that RX part of Ctrl transfer is done. Because zout descr
-+           interrupt hasn't happend yet will the URB be finished in the
-+           TX-Interrupt. */
-+        urb_priv->ctrl_rx_done = 1;
-+        tc_dbg("Not finishing In Ctrl URB:0x%x from rx_interrupt, waiting"
-+               " for zout\n", (unsigned int)urb);
-+      } else {
-+        tc_finish_urb(hcd, urb, 0);
-+      }
-+      }
-+    } else { /* ISOC RX */
-+      /*
-+      isoc_dbg("Processing RX for epid:%d (URB:0x%x) ISOC pipe\n",
-+             epid, (unsigned int)urb);
-+      */
-+
-+      struct usb_iso_packet_descriptor *packet;
-+
-+      if (urb_priv->urb_state == UNLINK) {
-+      isoc_warn("Ignoring Isoc Rx data for urb being unlinked.\n");
-+      goto skip_out;
-+      } else if (urb_priv->urb_state == NOT_STARTED) {
-+      isoc_err("What? Got Rx data for Isoc urb that isn't started?\n");
-+      goto skip_out;
-+      }
-+
-+      packet = &urb->iso_frame_desc[urb_priv->isoc_packet_counter];
-+      ASSERT(packet);
-+      packet->status = 0;
-+
-+      if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) {
-+      /* We get nodata for empty data transactions, and the rx descriptor's
-+         hw_len field is not valid in that case. We copy 0 bytes however to
-+         stay in synch. */
-+      packet->actual_length = 0;
-+      } else {
-+      packet->actual_length = myNextRxDesc->hw_len;
-+      /* Make sure the data fits in the buffer. */
-+      ASSERT(packet->actual_length <= packet->length);
-+      memcpy(urb->transfer_buffer + packet->offset,
-+             phys_to_virt(myNextRxDesc->buf), packet->actual_length);
-+      if(packet->actual_length > 0)
-+        isoc_dbg("Copied %d bytes, packet %d for URB:0x%x[%d]\n",
-+                 packet->actual_length, urb_priv->isoc_packet_counter,
-+                 (unsigned int)urb, urb_priv->urb_num);
-+      }
-+
-+      /* Increment the packet counter. */
-+      urb_priv->isoc_packet_counter++;
-+
-+      /* Note that we don't care about the eot field in the rx descriptor's
-+       status. It will always be set for isoc traffic. */
-+      if (urb->number_of_packets == urb_priv->isoc_packet_counter) {
-+      /* Complete the urb with status OK. */
-+      tc_finish_urb(hcd, urb, 0);
-+      }
-+    }
-+
-+  skip_out:
-+    myNextRxDesc->status = 0;
-+    myNextRxDesc->command |= IO_MASK(USB_IN_command, eol);
-+    myLastRxDesc->command &= ~IO_MASK(USB_IN_command, eol);
-+    myLastRxDesc = myNextRxDesc;
-+    myNextRxDesc = phys_to_virt(myNextRxDesc->next);
-+    flush_etrax_cache();
-+    *R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, restart);
-+  }
-+
-+  local_irq_restore(flags);
-+
-+  return IRQ_HANDLED;
-+}
-+
-+static void tc_bulk_start_timer_func(unsigned long dummy) {
-+  /* We might enable an EP descriptor behind the current DMA position when
-+     it's about to decide that there are no more bulk traffic and it should
-+     stop the bulk channel.
-+     Therefore we periodically check if the bulk channel is stopped and there
-+     is an enabled bulk EP descriptor, in which case we start the bulk
-+     channel. */
-+  
-+  if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) {
-+    int epid;
-+
-+    timer_dbg("bulk_start_timer: Bulk DMA channel not running.\n");
-+
-+    for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
-+      if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-+      timer_warn("Found enabled EP for epid %d, starting bulk channel.\n",
-+                 epid);
-+      restart_dma8_sub0();
-+
-+      /* Restart the bulk eot timer since we just started the bulk channel.*/
-+      mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL);
-+
-+      /* No need to search any further. */
-+      break;
-+      }
-+    }
-+  } else {
-+    timer_dbg("bulk_start_timer: Bulk DMA channel running.\n");
-+  }
-+}
-+
-+static void tc_bulk_eot_timer_func(unsigned long dummy) {
-+  struct usb_hcd *hcd = (struct usb_hcd*)dummy;
-+  ASSERT(hcd);
-+  /* Because of a race condition in the top half, we might miss a bulk eot.
-+     This timer "simulates" a bulk eot if we don't get one for a while,
-+     hopefully correcting the situation. */
-+  timer_dbg("bulk_eot_timer timed out.\n");
-+  check_finished_bulk_tx_epids(hcd, 1);
-+}
-+
-+
-+/*************************************************************/
-+/*************************************************************/
-+/* Device driver block                                       */
-+/*************************************************************/
-+/*************************************************************/
-+
-+/* Forward declarations for device driver functions */
-+static int devdrv_hcd_probe(struct device *);
-+static int devdrv_hcd_remove(struct device *);
-+#ifdef CONFIG_PM
-+static int devdrv_hcd_suspend(struct device *, u32, u32);
-+static int devdrv_hcd_resume(struct device *, u32);
-+#endif /* CONFIG_PM */
-+
-+/* the device */
-+static struct platform_device *devdrv_hc_platform_device;
-+
-+/* device driver interface */
-+static struct device_driver devdrv_hc_device_driver = {
-+  .name =                     (char *) hc_name,
-+  .bus =                      &platform_bus_type,
-+
-+  .probe =            devdrv_hcd_probe,
-+  .remove =           devdrv_hcd_remove,
-+
-+#ifdef CONFIG_PM
-+  .suspend =          devdrv_hcd_suspend,
-+  .resume =           devdrv_hcd_resume,
-+#endif /* CONFIG_PM */
-+};
-+
-+/* initialize the host controller and driver  */
-+static int __init_or_module devdrv_hcd_probe(struct device *dev)
-+{
-+  struct usb_hcd *hcd;
-+  struct crisv10_hcd *crisv10_hcd;
-+  int retval;
-+
-+  /* Check DMA burst length */
-+  if(IO_EXTRACT(R_BUS_CONFIG, dma_burst, *R_BUS_CONFIG) !=
-+     IO_STATE(R_BUS_CONFIG, dma_burst, burst32)) {
-+    devdrv_err("Invalid DMA burst length in Etrax 100LX,"
-+             " needs to be 32\n");
-+    return -EPERM;
-+  }
-+
-+  hcd = usb_create_hcd(&crisv10_hc_driver, dev, dev->bus_id);
-+  if (!hcd)
-+    return -ENOMEM;
-+
-+  crisv10_hcd = hcd_to_crisv10_hcd(hcd);
-+  spin_lock_init(&crisv10_hcd->lock);
-+  crisv10_hcd->num_ports = num_ports();
-+  crisv10_hcd->running = 0;
-+
-+  dev_set_drvdata(dev, crisv10_hcd);
-+
-+  devdrv_dbg("ETRAX USB IRQs HC:%d  RX:%d  TX:%d\n", ETRAX_USB_HC_IRQ,
-+        ETRAX_USB_RX_IRQ, ETRAX_USB_TX_IRQ);
-+
-+  /* Print out chip version read from registers */
-+  int rev_maj = *R_USB_REVISION & IO_MASK(R_USB_REVISION, major);
-+  int rev_min = *R_USB_REVISION & IO_MASK(R_USB_REVISION, minor);
-+  if(rev_min == 0) {
-+    devdrv_info("Etrax 100LX USB Revision %d v1,2\n", rev_maj);
-+  } else {
-+    devdrv_info("Etrax 100LX USB Revision %d v%d\n", rev_maj, rev_min);
-+  }
-+
-+  devdrv_info("Bulk timer interval, start:%d eot:%d\n",
-+            BULK_START_TIMER_INTERVAL,
-+            BULK_EOT_TIMER_INTERVAL);
-+
-+
-+  /* Init root hub data structures */
-+  if(rh_init()) {
-+    devdrv_err("Failed init data for Root Hub\n");
-+    retval = -ENOMEM;
-+  }
-+
-+  if(port_in_use(0)) {
-+    if (cris_request_io_interface(if_usb_1, "ETRAX100LX USB-HCD")) {
-+      printk(KERN_CRIT "usb-host: request IO interface usb1 failed");
-+      retval = -EBUSY;
-+      goto out;
-+    }
-+    devdrv_info("Claimed interface for USB physical port 1\n");
-+  }
-+  if(port_in_use(1)) {
-+    if (cris_request_io_interface(if_usb_2, "ETRAX100LX USB-HCD")) {
-+      /* Free first interface if second failed to be claimed */
-+      if(port_in_use(0)) {
-+      cris_free_io_interface(if_usb_1);
-+      }
-+      printk(KERN_CRIT "usb-host: request IO interface usb2 failed");
-+      retval = -EBUSY;
-+      goto out;
-+    }
-+    devdrv_info("Claimed interface for USB physical port 2\n");
-+  }
-+  
-+  /* Init transfer controller structs and locks */
-+  if((retval = tc_init(hcd)) != 0) {
-+    goto out;
-+  }
-+
-+  /* Attach interrupt functions for DMA and init DMA controller */
-+  if((retval = tc_dma_init(hcd)) != 0) {
-+    goto out;
-+  }
-+
-+  /* Attach the top IRQ handler for USB controller interrupts */
-+  if (request_irq(ETRAX_USB_HC_IRQ, crisv10_hcd_top_irq, 0,
-+                "ETRAX 100LX built-in USB (HC)", hcd)) {
-+    err("Could not allocate IRQ %d for USB", ETRAX_USB_HC_IRQ);
-+    retval = -EBUSY;
-+    goto out;
-+  }
-+
-+  /* iso_eof is only enabled when isoc traffic is running. */
-+  *R_USB_IRQ_MASK_SET =
-+    /* IO_STATE(R_USB_IRQ_MASK_SET, iso_eof, set) | */
-+    IO_STATE(R_USB_IRQ_MASK_SET, bulk_eot, set) |
-+    IO_STATE(R_USB_IRQ_MASK_SET, epid_attn, set) |
-+    IO_STATE(R_USB_IRQ_MASK_SET, port_status, set) |
-+    IO_STATE(R_USB_IRQ_MASK_SET, ctl_status, set);
-+
-+
-+  crisv10_ready_wait();
-+  /* Reset the USB interface. */
-+  *R_USB_COMMAND =
-+    IO_STATE(R_USB_COMMAND, port_sel, nop) |
-+    IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-+    IO_STATE(R_USB_COMMAND, ctrl_cmd, reset);
-+
-+  /* Designer's Reference, p. 8 - 10 says we should Initate R_USB_FM_PSTART to
-+     0x2A30 (10800), to guarantee that control traffic gets 10% of the
-+     bandwidth, and periodic transfer may allocate the rest (90%).
-+     This doesn't work though.
-+     The value 11960 is chosen to be just after the SOF token, with a couple
-+     of bit times extra for possible bit stuffing. */
-+  *R_USB_FM_PSTART = IO_FIELD(R_USB_FM_PSTART, value, 11960);
-+
-+  crisv10_ready_wait();
-+  /* Configure the USB interface as a host controller. */
-+  *R_USB_COMMAND =
-+    IO_STATE(R_USB_COMMAND, port_sel, nop) |
-+    IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-+    IO_STATE(R_USB_COMMAND, ctrl_cmd, host_config);
-+
-+
-+  /* Check so controller not busy before enabling ports */
-+  crisv10_ready_wait();
-+
-+  /* Enable selected USB ports */
-+  if(port_in_use(0)) {
-+    *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no);
-+  } else {
-+    *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, yes);
-+  }
-+  if(port_in_use(1)) {
-+    *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no);
-+  } else {
-+    *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, yes);
-+  }
-+
-+  crisv10_ready_wait();
-+  /* Start processing of USB traffic. */
-+  *R_USB_COMMAND =
-+    IO_STATE(R_USB_COMMAND, port_sel, nop) |
-+    IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-+    IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
-+
-+  /* Do not continue probing initialization before USB interface is done */
-+  crisv10_ready_wait();
-+
-+  /* Register our Host Controller to USB Core
-+   * Finish the remaining parts of generic HCD initialization: allocate the
-+   * buffers of consistent memory, register the bus
-+   * and call the driver's reset() and start() routines. */
-+  retval = usb_add_hcd(hcd, ETRAX_USB_HC_IRQ, IRQF_DISABLED);
-+  if (retval != 0) {
-+    devdrv_err("Failed registering HCD driver\n");
-+    goto out;
-+  }
-+
-+  return 0;
-+
-+ out:
-+  devdrv_hcd_remove(dev);
-+  return retval;
-+}
-+
-+
-+/* cleanup after the host controller and driver */
-+static int __init_or_module devdrv_hcd_remove(struct device *dev)
-+{
-+  struct crisv10_hcd *crisv10_hcd = dev_get_drvdata(dev);
-+  struct usb_hcd *hcd;
-+
-+  if (!crisv10_hcd)
-+    return 0;
-+  hcd = crisv10_hcd_to_hcd(crisv10_hcd);
-+
-+
-+  /* Stop USB Controller in Etrax 100LX */
-+  crisv10_hcd_reset(hcd);
-+
-+  usb_remove_hcd(hcd);
-+  devdrv_dbg("Removed HCD from USB Core\n");
-+
-+  /* Free USB Controller IRQ */
-+  free_irq(ETRAX_USB_HC_IRQ, NULL);
-+
-+  /* Free resources */
-+  tc_dma_destroy();
-+  tc_destroy();
-+
-+
-+  if(port_in_use(0)) {
-+    cris_free_io_interface(if_usb_1);
-+  }
-+  if(port_in_use(1)) {
-+    cris_free_io_interface(if_usb_2);
-+  }
-+
-+  devdrv_dbg("Freed all claimed resources\n");
-+
-+  return 0;
-+}
-+
-+
-+#ifdef        CONFIG_PM
-+
-+static int devdrv_hcd_suspend(struct usb_hcd *hcd, u32 state, u32 level)
-+{
-+  return 0; /* no-op for now */
-+}
-+
-+static int devdrv_hcd_resume(struct usb_hcd *hcd, u32 level)
-+{
-+  return 0; /* no-op for now */
-+}
-+
-+#endif /* CONFIG_PM */
-+
-+
-+
-+/*************************************************************/
-+/*************************************************************/
-+/* Module block                                              */
-+/*************************************************************/
-+/*************************************************************/
-+ 
-+/* register driver */
-+static int __init module_hcd_init(void) 
-+{
-+  
-+  if (usb_disabled())
-+    return -ENODEV;
-+
-+  /* Here we select enabled ports by following defines created from
-+     menuconfig */
-+#ifndef CONFIG_ETRAX_USB_HOST_PORT1
-+  ports &= ~(1<<0);
-+#endif
-+#ifndef CONFIG_ETRAX_USB_HOST_PORT2
-+  ports &= ~(1<<1);
-+#endif
-+
-+  printk(KERN_INFO "%s version "VERSION" "COPYRIGHT"\n", product_desc);
-+
-+  devdrv_hc_platform_device =
-+    platform_device_register_simple((char *) hc_name, 0, NULL, 0);
-+
-+  if (IS_ERR(devdrv_hc_platform_device))
-+    return PTR_ERR(devdrv_hc_platform_device);
-+  return driver_register(&devdrv_hc_device_driver);
-+  /* 
-+   * Note that we do not set the DMA mask for the device,
-+   * i.e. we pretend that we will use PIO, since no specific
-+   * allocation routines are needed for DMA buffers. This will
-+   * cause the HCD buffer allocation routines to fall back to
-+   * kmalloc().
-+   */
-+}
-+
-+/* unregister driver */
-+static void __exit module_hcd_exit(void) 
-+{     
-+  driver_unregister(&devdrv_hc_device_driver);
-+}
-+
-+
-+/* Module hooks */
-+module_init(module_hcd_init);
-+module_exit(module_hcd_exit);
---- /dev/null
-+++ b/drivers/usb/host/hc-crisv10.h
-@@ -0,0 +1,331 @@
-+#ifndef __LINUX_ETRAX_USB_H
-+#define __LINUX_ETRAX_USB_H
-+
-+#include <linux/types.h>
-+#include <linux/list.h>
-+
-+struct USB_IN_Desc {
-+  volatile __u16 sw_len;
-+  volatile __u16 command;
-+  volatile unsigned long next;
-+  volatile unsigned long buf;
-+  volatile __u16 hw_len;
-+  volatile __u16 status;
-+};
-+
-+struct USB_SB_Desc {
-+  volatile __u16 sw_len;
-+  volatile __u16 command;
-+  volatile unsigned long next;
-+  volatile unsigned long buf;
-+};
-+
-+struct USB_EP_Desc {
-+  volatile __u16 hw_len;
-+  volatile __u16 command;
-+  volatile unsigned long sub;
-+  volatile unsigned long next;
-+};
-+
-+
-+/* Root Hub port status struct */
-+struct crisv10_rh {
-+  volatile __u16 wPortChange[2];
-+  volatile __u16 wPortStatusPrev[2];
-+};
-+
-+/* HCD description */
-+struct crisv10_hcd {
-+  spinlock_t          lock;
-+  __u8                        num_ports;
-+  __u8                  running;
-+};
-+
-+
-+/* Endpoint HC private data description */
-+struct crisv10_ep_priv {
-+  int epid;
-+};
-+
-+/* Additional software state info for a USB Controller epid */
-+struct etrax_epid {
-+  __u8 inuse;       /* !0 = setup in Etrax and used for a endpoint */
-+  __u8 disabled;    /* !0 = Temporarly disabled to avoid resubmission */
-+  __u8 type;        /* Setup as: PIPE_BULK, PIPE_CONTROL ... */
-+  __u8 out_traffic; /* !0 = This epid is for out traffic */
-+};
-+
-+/* Struct to hold information of scheduled later URB completion */
-+struct urb_later_data {
-+//  struct work_struct ws;
-+  struct delayed_work ws;
-+  struct usb_hcd *hcd;
-+  struct urb *urb;
-+  int urb_num;
-+  int status;
-+};
-+
-+
-+typedef enum {
-+  STARTED,
-+  NOT_STARTED,
-+  UNLINK,
-+} crisv10_urb_state_t;
-+
-+
-+struct crisv10_urb_priv {
-+  /* Sequence number for this URB. Every new submited URB gets this from
-+     a incrementing counter. Used when a URB is scheduled for later finish to
-+     be sure that the intended URB hasn't already been completed (device
-+     drivers has a tendency to reuse URBs once they are completed, causing us
-+     to not be able to single old ones out only based on the URB pointer.) */
-+  __u32 urb_num;
-+
-+  /* The first_sb field is used for freeing all SB descriptors belonging
-+     to an urb. The corresponding ep descriptor's sub pointer cannot be
-+     used for this since the DMA advances the sub pointer as it processes
-+     the sb list. */
-+  struct USB_SB_Desc *first_sb;
-+
-+  /* The last_sb field referes to the last SB descriptor that belongs to
-+     this urb. This is important to know so we can free the SB descriptors
-+     that ranges between first_sb and last_sb. */
-+  struct USB_SB_Desc *last_sb;
-+  
-+  /* The rx_offset field is used in ctrl and bulk traffic to keep track
-+     of the offset in the urb's transfer_buffer where incoming data should be
-+     copied to. */
-+  __u32 rx_offset;
-+  
-+  /* Counter used in isochronous transfers to keep track of the
-+     number of packets received/transmitted.  */
-+  __u32 isoc_packet_counter;
-+
-+  /* Flag that marks if this Isoc Out URB has finished it's transfer. Used
-+     because several URBs can be finished before list is processed */
-+  __u8  isoc_out_done;
-+  
-+  /* This field is used to pass information about the urb's current state
-+     between the various interrupt handlers (thus marked volatile). */
-+  volatile crisv10_urb_state_t urb_state;
-+  
-+  /* In Ctrl transfers consist of (at least) 3 packets: SETUP, IN and ZOUT.
-+     When DMA8 sub-channel 2 has processed the SB list for this sequence we
-+     get a interrupt. We also get a interrupt for In transfers and which
-+     one of these interrupts that comes first depends of data size and device.
-+     To be sure that we have got both interrupts before we complete the URB
-+     we have these to flags that shows which part that has completed.
-+     We can then check when we get one of the interrupts that if the other has
-+     occured it's safe for us to complete the URB, otherwise we set appropriate
-+     flag and do the completion when we get the other interrupt. */
-+  volatile unsigned char ctrl_zout_done;
-+  volatile unsigned char ctrl_rx_done;
-+
-+  /* Connection between the submitted urb and ETRAX epid number */
-+  __u8 epid;
-+  
-+  /* The rx_data_list field is used for periodic traffic, to hold
-+     received data for later processing in the the complete_urb functions,
-+     where the data us copied to the urb's transfer_buffer. Basically, we
-+     use this intermediate storage because we don't know when it's safe to
-+     reuse the transfer_buffer (FIXME?). */
-+  struct list_head rx_data_list;
-+
-+
-+  /* The interval time rounded up to closest 2^N */
-+  int interval;
-+
-+  /* Pool of EP descriptors needed if it's a INTR transfer.
-+     Amount of EPs in pool correspons to how many INTR that should
-+     be inserted in TxIntrEPList (max 128, defined by MAX_INTR_INTERVAL) */
-+  struct USB_EP_Desc* intr_ep_pool[128];
-+
-+  /* The mount of EPs allocated for this INTR URB */
-+  int intr_ep_pool_length;
-+
-+  /* Pointer to info struct if URB is scheduled to be finished later */
-+  struct urb_later_data* later_data;
-+};
-+
-+
-+/* This struct is for passing data from the top half to the bottom half irq
-+   handlers */
-+struct crisv10_irq_reg {
-+  struct usb_hcd* hcd;
-+  __u32 r_usb_epid_attn;
-+  __u8 r_usb_status;
-+  __u16 r_usb_rh_port_status_1;
-+  __u16 r_usb_rh_port_status_2;
-+  __u32 r_usb_irq_mask_read;
-+  __u32 r_usb_fm_number;
-+  struct work_struct usb_bh;
-+};
-+
-+
-+/* This struct is for passing data from the isoc top half to the isoc bottom
-+   half. */
-+struct crisv10_isoc_complete_data {
-+  struct usb_hcd *hcd;
-+  struct urb *urb;
-+  struct work_struct usb_bh;
-+};
-+
-+/* Entry item for URB lists for each endpint */
-+typedef struct urb_entry
-+{
-+      struct urb *urb;
-+      struct list_head list;
-+} urb_entry_t;
-+
-+/* ---------------------------------------------------------------------------
-+   Virtual Root HUB
-+   ------------------------------------------------------------------------- */
-+/* 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
-+
-+/* Our Vendor Specific feature */
-+#define RH_REMOVE_EP               0x00
-+
-+
-+#define RH_ACK                     0x01
-+#define RH_REQ_ERR                 -1
-+#define RH_NACK                    0x00
-+
-+/* Field definitions for */
-+
-+#define USB_IN_command__eol__BITNR      0 /* command macros */
-+#define USB_IN_command__eol__WIDTH      1
-+#define USB_IN_command__eol__no         0
-+#define USB_IN_command__eol__yes        1
-+
-+#define USB_IN_command__intr__BITNR     3
-+#define USB_IN_command__intr__WIDTH     1
-+#define USB_IN_command__intr__no        0
-+#define USB_IN_command__intr__yes       1
-+
-+#define USB_IN_status__eop__BITNR       1 /* status macros. */
-+#define USB_IN_status__eop__WIDTH       1
-+#define USB_IN_status__eop__no          0
-+#define USB_IN_status__eop__yes         1
-+
-+#define USB_IN_status__eot__BITNR       5
-+#define USB_IN_status__eot__WIDTH       1
-+#define USB_IN_status__eot__no          0
-+#define USB_IN_status__eot__yes         1
-+
-+#define USB_IN_status__error__BITNR     6
-+#define USB_IN_status__error__WIDTH     1
-+#define USB_IN_status__error__no        0
-+#define USB_IN_status__error__yes       1
-+
-+#define USB_IN_status__nodata__BITNR    7
-+#define USB_IN_status__nodata__WIDTH    1
-+#define USB_IN_status__nodata__no       0
-+#define USB_IN_status__nodata__yes      1
-+
-+#define USB_IN_status__epid__BITNR      8
-+#define USB_IN_status__epid__WIDTH      5
-+
-+#define USB_EP_command__eol__BITNR      0
-+#define USB_EP_command__eol__WIDTH      1
-+#define USB_EP_command__eol__no         0
-+#define USB_EP_command__eol__yes        1
-+
-+#define USB_EP_command__eof__BITNR      1
-+#define USB_EP_command__eof__WIDTH      1
-+#define USB_EP_command__eof__no         0
-+#define USB_EP_command__eof__yes        1
-+
-+#define USB_EP_command__intr__BITNR     3
-+#define USB_EP_command__intr__WIDTH     1
-+#define USB_EP_command__intr__no        0
-+#define USB_EP_command__intr__yes       1
-+
-+#define USB_EP_command__enable__BITNR   4
-+#define USB_EP_command__enable__WIDTH   1
-+#define USB_EP_command__enable__no      0
-+#define USB_EP_command__enable__yes     1
-+
-+#define USB_EP_command__hw_valid__BITNR 5
-+#define USB_EP_command__hw_valid__WIDTH 1
-+#define USB_EP_command__hw_valid__no    0
-+#define USB_EP_command__hw_valid__yes   1
-+
-+#define USB_EP_command__epid__BITNR     8
-+#define USB_EP_command__epid__WIDTH     5
-+
-+#define USB_SB_command__eol__BITNR      0 /* command macros. */
-+#define USB_SB_command__eol__WIDTH      1
-+#define USB_SB_command__eol__no         0
-+#define USB_SB_command__eol__yes        1
-+
-+#define USB_SB_command__eot__BITNR      1
-+#define USB_SB_command__eot__WIDTH      1
-+#define USB_SB_command__eot__no         0
-+#define USB_SB_command__eot__yes        1
-+
-+#define USB_SB_command__intr__BITNR     3
-+#define USB_SB_command__intr__WIDTH     1
-+#define USB_SB_command__intr__no        0
-+#define USB_SB_command__intr__yes       1
-+
-+#define USB_SB_command__tt__BITNR       4
-+#define USB_SB_command__tt__WIDTH       2
-+#define USB_SB_command__tt__zout        0
-+#define USB_SB_command__tt__in          1
-+#define USB_SB_command__tt__out         2
-+#define USB_SB_command__tt__setup       3
-+
-+
-+#define USB_SB_command__rem__BITNR      8
-+#define USB_SB_command__rem__WIDTH      6
-+
-+#define USB_SB_command__full__BITNR     6
-+#define USB_SB_command__full__WIDTH     1
-+#define USB_SB_command__full__no        0
-+#define USB_SB_command__full__yes       1
-+
-+#endif
diff --git a/target/linux/etrax/profiles/100-generic.mk b/target/linux/etrax/profiles/100-generic.mk
deleted file mode 100644 (file)
index 9d0fc72..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-define Profile/default
-  NAME:=Normal (default)
-endef
-
-define Profile/default/Description
-       Normal Foxboard setup (no vhdl)
-endef
-$(eval $(call Profile,default))
-
diff --git a/target/linux/etrax/profiles/101-vhdl-nofb.mk b/target/linux/etrax/profiles/101-vhdl-nofb.mk
deleted file mode 100644 (file)
index 620db42..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-define Profile/vhdl_no_fb
-  NAME:=FOXVHDL no fb
-#  PACKAGES:=kmod-madwifi
-endef
-
-define Profile/vhdl_no_fb/Description
-       Setup the Foxboard for FOXVHDL support with no framebuffer
-endef
-$(eval $(call Profile,vhdl_no_fb))
-
diff --git a/target/linux/ifxmips/Makefile b/target/linux/ifxmips/Makefile
new file mode 100644 (file)
index 0000000..de982ab
--- /dev/null
@@ -0,0 +1,22 @@
+# 
+# Copyright (C) 2007 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+ARCH:=mips
+BOARD:=ifxmips
+BOARDNAME:=Infineon Mips
+FEATURES:=squashfs jffs2
+LINUX_VERSION:=2.6.26.5
+
+include $(INCLUDE_DIR)/target.mk
+DEFAULT_PACKAGES+=uboot-ifxmips
+
+define Target/Description
+       Build firmware images for Infineon Mips Controllers
+endef
+
+$(eval $(call BuildTarget))
diff --git a/target/linux/ifxmips/base-files/etc/hotplug.d/button/00-reset b/target/linux/ifxmips/base-files/etc/hotplug.d/button/00-reset
new file mode 100644 (file)
index 0000000..ef70cd4
--- /dev/null
@@ -0,0 +1,3 @@
+[ "$ACTION" = "released" -a "$BUTTON" = reset ] && {
+       reboot
+}
diff --git a/target/linux/ifxmips/base-files/etc/inittab b/target/linux/ifxmips/base-files/etc/inittab
new file mode 100644 (file)
index 0000000..7989a7f
--- /dev/null
@@ -0,0 +1,4 @@
+::sysinit:/etc/init.d/rcS S boot
+::shutdown:/etc/init.d/rcS K stop
+ttyS0::askfirst:/bin/ash --login
+ttyS1::askfirst:/bin/ash --login
diff --git a/target/linux/ifxmips/config-2.6.26 b/target/linux/ifxmips/config-2.6.26
new file mode 100644 (file)
index 0000000..9b50667
--- /dev/null
@@ -0,0 +1,236 @@
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+# CONFIG_8139TOO is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_ATM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_BCM47XX is not set
+CONFIG_BITREVERSE=y
+# CONFIG_BT is not set
+CONFIG_CEVT_R4K=y
+CONFIG_CLASSIC_RCU=y
+CONFIG_CMDLINE="console=ttyS0,9600 rootfstype=squashfs,jffs2 init=/etc/preinit"
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_CPU_LOONGSON2 is not set
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+CONFIG_CPU_MIPSR1=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_VR41XX is not set
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CSRC_R4K=y
+CONFIG_DEVPORT=y
+# CONFIG_DM9000 is not set
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_E1000E_ENABLED is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GPIO_DEVICE=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_HAVE_KPROBES is not set
+# CONFIG_HAVE_KRETPROBES is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+# CONFIG_HIGH_RES_TIMERS is not set
+# CONFIG_HOSTAP is not set
+CONFIG_HW_HAS_PCI=y
+CONFIG_HW_RANDOM=y
+# CONFIG_I2C is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IDE is not set
+CONFIG_IFXMIPS=y
+CONFIG_IFXMIPS_EEPROM=y
+CONFIG_IFXMIPS_GPIO_RST_BTN=y
+# CONFIG_IFXMIPS_MEI is not set
+CONFIG_IFXMIPS_MII0=y
+# CONFIG_IFXMIPS_PROM_ASC0 is not set
+CONFIG_IFXMIPS_PROM_ASC1=y
+CONFIG_IFXMIPS_SSC=y
+CONFIG_IFXMIPS_WDT=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IRQ_CPU=y
+# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_KALLSYMS=y
+# CONFIG_LEDS_ALIX is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_IFXMIPS=y
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+CONFIG_MIPS=y
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_COBALT is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_MALTA is not set
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+CONFIG_MTD=y
+# CONFIG_MTD_ABSENT is not set
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_MTD_BLOCK2MTD is not set
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_IFXMIPS=y
+# CONFIG_MTD_JEDECPROBE is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_START=0x0
+# CONFIG_MTD_PLATRAM is not set
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NO_IOPORT is not set
+# CONFIG_OCF_OCF is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+# CONFIG_PAGE_SIZE_16KB is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_PAGE_SIZE_8KB is not set
+CONFIG_PCI=y
+# CONFIG_PCIPCWATCHDOG is not set
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCSPKR_PLATFORM=y
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_R6040 is not set
+CONFIG_RFKILL_LEDS=y
+CONFIG_RTC_LIB=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCSI_WAIT_SCAN=m
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_IFXMIPS=y
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SSB_POSSIBLE=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+# CONFIG_TC35815 is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+CONFIG_TRAD_SIGNALS=y
+CONFIG_USB=m
+# CONFIG_USB_DWC_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIA_RHINE is not set
+CONFIG_VIDEO_MEDIA=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/Kconfig b/target/linux/ifxmips/files/arch/mips/ifxmips/Kconfig
new file mode 100644 (file)
index 0000000..621020f
--- /dev/null
@@ -0,0 +1,40 @@
+# copyright 2007 john crispin <blogic@openwrt.org>
+
+menu "IFXMips built-in"
+
+config MTD_IFXMIPS
+       bool "IFXMips flash map"
+       default y
+
+config IFXMIPS_SSC
+       bool "IFXMips ssc"
+       default y
+
+config IFXMIPS_EEPROM
+       bool "IFXMips eeprom"
+       default y
+
+config IFXMIPS_MEI
+       bool "IFXMips mei"
+       default y
+
+config IFXMIPS_GPIO_RST_BTN
+       bool "Reset Button"
+       default y
+
+choice
+       prompt "prom_printf ASC"
+       help
+         Choose which serial port is used, until the console driver is loaded
+
+config IFXMIPS_PROM_ASC0
+       bool "ASC0"
+
+config IFXMIPS_PROM_ASC1
+       bool "ASC1"
+
+endchoice
+
+
+endmenu
+
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/Makefile b/target/linux/ifxmips/files/arch/mips/ifxmips/Makefile
new file mode 100644 (file)
index 0000000..eb9a77e
--- /dev/null
@@ -0,0 +1 @@
+obj-y := reset.o prom.o setup.o interrupt.o dma-core.o pmu.o board.o clock.o timer.o gpio.o
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/board.c b/target/linux/ifxmips/files/arch/mips/ifxmips/board.c
new file mode 100644 (file)
index 0000000..86a2595
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+
+#include <linux/autoconf.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mtd/physmap.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/etherdevice.h>
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/ifxmips/ifxmips.h>
+
+#define MAX_BOARD_NAME_LEN             32
+#define MAX_IFXMIPS_DEVS               9
+
+#define SYSTEM_DANUBE                  "Danube"
+#define SYSTEM_DANUBE_CHIPID1  0x10129083
+#define SYSTEM_DANUBE_CHIPID2  0x3012B083
+
+#define SYSTEM_TWINPASS                        "Twinpass"
+#define SYSTEM_TWINPASS_CHIPID 0x3012D083
+
+enum {
+       EASY50712,
+       EASY4010,
+       ARV4519,
+};
+
+extern int ifxmips_pci_external_clock;
+
+static unsigned int chiprev;
+static int cmdline_mac = 0;
+char board_name[MAX_BOARD_NAME_LEN + 1] = { 0 };
+
+struct ifxmips_board {
+       int type;
+       char name[32];
+       unsigned int system_type;
+       struct platform_device **devs;
+       struct resource reset_resource;
+       struct resource gpiodev_resource;
+       struct gpio_led *ifxmips_leds;
+       struct gpio_led *gpio_leds;
+       int pci_external_clock;
+       int num_devs;
+};
+
+spinlock_t ebu_lock = SPIN_LOCK_UNLOCKED;
+EXPORT_SYMBOL_GPL(ebu_lock);
+
+static unsigned char ifxmips_mii_mac[6];
+static int ifxmips_brn = 0;
+
+static struct gpio_led_platform_data ifxmips_led_data;
+
+static struct platform_device
+ifxmips_led =
+{
+       .id = 0,
+       .name = "ifxmips_led",
+       .dev = {
+               .platform_data = (void *) &ifxmips_led_data,
+       }
+};
+
+static struct platform_device
+ifxmips_gpio =
+{
+       .id = 0,
+       .name = "ifxmips_gpio",
+       .num_resources = 1,
+};
+
+static struct platform_device
+ifxmips_mii =
+{
+       .id = 0,
+       .name = "ifxmips_mii0",
+       .dev = {
+               .platform_data = ifxmips_mii_mac,
+       }
+};
+
+static struct platform_device
+ifxmips_wdt =
+{
+       .id = 0,
+       .name = "ifxmips_wdt",
+};
+
+static struct resource
+ifxmips_mtd_resource = {
+       .start  = IFXMIPS_FLASH_START,
+       .end    = IFXMIPS_FLASH_START + IFXMIPS_FLASH_MAX - 1,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct platform_device
+ifxmips_mtd =
+{
+       .id = 0,
+       .name = "ifxmips_mtd",
+       .num_resources  = 1,
+       .resource   = &ifxmips_mtd_resource,
+};
+
+static struct platform_device
+ifxmips_gpio_dev = {
+       .name     = "GPIODEV",
+       .id     = -1,
+       .num_resources    =     1,
+};
+
+#ifdef CONFIG_LEDS_GPIO
+static struct gpio_led arv4519_gpio_leds[] = {
+       { .name = "ifx:green:power", .gpio = 3, .active_low = 1, },
+       { .name = "ifx:red:power", .gpio = 7, .active_low = 1, },
+       { .name = "ifx:green:adsl", .gpio = 4, .active_low = 1, },
+       { .name = "ifx:green:internet", .gpio = 5, .active_low = 1, },
+       { .name = "ifx:red:internet", .gpio = 8, .active_low = 1, },
+       { .name = "ifx:green:wlan", .gpio = 6, .active_low = 1, },
+       { .name = "ifx:green:usb", .gpio = 19, .active_low = 1, },
+};
+
+static struct gpio_led_platform_data ifxmips_gpio_led_data;
+
+static struct platform_device ifxmips_gpio_leds = {
+       .name = "leds-gpio",
+       .id = -1,
+       .dev = {
+               .platform_data = (void *) &ifxmips_gpio_led_data,
+        }
+};
+#endif
+
+struct platform_device *easy50712_devs[] = {
+       &ifxmips_led, &ifxmips_gpio, &ifxmips_mii,
+       &ifxmips_mtd, &ifxmips_wdt, &ifxmips_gpio_dev
+};
+
+struct platform_device *easy4010_devs[] = {
+       &ifxmips_led, &ifxmips_gpio, &ifxmips_mii,
+       &ifxmips_mtd, &ifxmips_wdt, &ifxmips_gpio_dev
+};
+
+struct platform_device *arv5419_devs[] = {
+       &ifxmips_gpio, &ifxmips_mii, &ifxmips_mtd, &ifxmips_wdt,
+#ifdef CONFIG_LEDS_GPIO
+       &ifxmips_gpio_leds,
+#endif
+};
+
+static struct gpio_led easy50712_leds[] = {
+       { .name = "ifx:green:test0", .gpio = 0,},
+       { .name = "ifx:green:test1", .gpio = 1,},
+       { .name = "ifx:green:test2", .gpio = 2,},
+       { .name = "ifx:green:test3", .gpio = 3,},
+};
+
+static struct gpio_led easy4010_leds[] = {
+       { .name = "ifx:green:test0", .gpio = 0,},
+       { .name = "ifx:green:test1", .gpio = 1,},
+       { .name = "ifx:green:test2", .gpio = 2,},
+       { .name = "ifx:green:test3", .gpio = 3,},
+};
+
+static struct ifxmips_board boards[] =
+{
+       {
+               .type = EASY50712,
+               .name = "EASY50712",
+               .system_type = SYSTEM_DANUBE_CHIPID1,
+               .devs = easy50712_devs,
+               .reset_resource = {.name = "reset", .start = 1, .end = 15,},
+               .gpiodev_resource =     {.name = "gpio", .start = (1 << 0) | (1 << 1),
+                       .end = (1 << 0) | (1 << 1)},
+               .ifxmips_leds = easy50712_leds,
+       }, {
+               .type = EASY4010,
+               .name = "EASY4010",
+               .system_type = SYSTEM_TWINPASS_CHIPID,
+               .devs = easy4010_devs,
+               .reset_resource = {.name = "reset", .start = 1, .end = 15},
+               .gpiodev_resource =     {.name = "gpio", .start = (1 << 0) | (1 << 1),
+                       .end = (1 << 0) | (1 << 1)},
+               .ifxmips_leds = easy4010_leds,
+       }, {
+               .type = ARV4519,
+               .name = "ARV4519",
+               .system_type = SYSTEM_DANUBE_CHIPID2,
+               .devs = arv5419_devs,
+               .reset_resource = {.name = "reset", .start = 1, .end = 14},
+               .pci_external_clock = 1,
+               .gpio_leds = arv4519_gpio_leds,
+       },
+};
+
+const char*
+get_system_type(void)
+{
+       chiprev = ifxmips_r32(IFXMIPS_MPS_CHIPID);
+       switch(chiprev)
+       {
+       case SYSTEM_DANUBE_CHIPID1:
+       case SYSTEM_DANUBE_CHIPID2:
+               return SYSTEM_DANUBE;
+
+       case SYSTEM_TWINPASS_CHIPID:
+               return SYSTEM_TWINPASS;
+       }
+
+       return BOARD_SYSTEM_TYPE;
+}
+
+static int __init
+ifxmips_set_board_type(char *str)
+{
+       str = strchr(str, '=');
+       if(!str)
+               goto out;
+       str++;
+       if(strlen(str) > MAX_BOARD_NAME_LEN)
+               goto out;
+       strncpy(board_name, str, MAX_BOARD_NAME_LEN);
+       printk("bootloader told us, that this is a %s board\n", board_name);
+out:
+       return 1;
+}
+__setup("ifxmips_board", ifxmips_set_board_type);
+
+static int __init
+ifxmips_set_mii0_mac(char *str)
+{
+#define IS_HEX(x) \
+       (((x >='0' && x <= '9') || (x >='a' && x <= 'f') || (x >='A' && x <= 'F'))?(1):(0))
+       int i;
+       str = strchr(str, '=');
+       if(!str)
+               goto out;
+       str++;
+       if(strlen(str) != 17)
+               goto out;
+       for(i = 0; i < 6; i++)
+       {
+               if(!IS_HEX(str[3 * i]) || !IS_HEX(str[(3 * i) + 1]))
+                       goto out;
+               if((i != 5) && (str[(3 * i) + 2] != ':'))
+                       goto out;
+               ifxmips_mii_mac[i] = simple_strtoul(&str[3 * i], NULL, 16);
+       }
+       if(is_valid_ether_addr(ifxmips_mii_mac))
+               cmdline_mac = 1;
+out:
+       return 1;
+}
+__setup("mii0_mac", ifxmips_set_mii0_mac);
+
+int
+ifxmips_find_brn_block(void){
+       unsigned char temp[8];
+       memcpy_fromio(temp, (void*)KSEG1ADDR(IFXMIPS_FLASH_START + 0x800000 - 0x10000), 8);
+       if(memcmp(temp, "BRN-BOOT", 8) == 0)
+       {
+               if(!cmdline_mac)
+                       memcpy_fromio(ifxmips_mii_mac, (void*)KSEG1ADDR(IFXMIPS_FLASH_START + 0x800000 - 0x10000 + 0x16), 6);
+               cmdline_mac = 1;
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+int
+ifxmips_has_brn_block(void)
+{
+       return ifxmips_brn;
+}
+EXPORT_SYMBOL(ifxmips_has_brn_block);
+
+struct ifxmips_board*
+ifxmips_find_board(void)
+{
+       int i;
+       if(!*board_name)
+               return 0;
+       for(i = 0; i < ARRAY_SIZE(boards); i++)
+               if((boards[i].system_type == chiprev) && (!strcmp(boards[i].name, board_name)))
+                       return &boards[i];
+       return 0;
+}
+
+int __init
+ifxmips_init_devices(void)
+{
+       struct ifxmips_board *board = ifxmips_find_board();
+
+       chiprev = ifxmips_r32(IFXMIPS_MPS_CHIPID);
+       ifxmips_brn = ifxmips_find_brn_block();
+
+       if(!cmdline_mac)
+               random_ether_addr(ifxmips_mii_mac);
+
+       if(!board)
+       {
+               switch(chiprev)
+               {
+               case SYSTEM_DANUBE_CHIPID1:
+               case SYSTEM_DANUBE_CHIPID2:
+                       board = &boards[0];
+                       break;
+               case SYSTEM_TWINPASS_CHIPID:
+                       board = &boards[1];
+                       break;
+               }
+       }
+
+       switch(board->type)
+       {
+       case EASY50712:
+               board->num_devs = ARRAY_SIZE(easy50712_devs);
+               ifxmips_led_data.num_leds = ARRAY_SIZE(easy50712_leds);
+               break;
+       case EASY4010:
+               board->num_devs = ARRAY_SIZE(easy4010_devs);
+               ifxmips_led_data.num_leds = ARRAY_SIZE(easy4010_leds);
+               break;
+       case ARV4519:
+               gpio_set_value(3, 0);
+               gpio_set_value(4, 0);
+               gpio_set_value(5, 0);
+               gpio_set_value(6, 0);
+               gpio_set_value(7, 1);
+               gpio_set_value(8, 1);
+               gpio_set_value(19, 0);
+               board->num_devs = ARRAY_SIZE(arv5419_devs);
+#ifdef CONFIG_LEDS_GPIO
+               ifxmips_gpio_led_data.num_leds = ARRAY_SIZE(arv4519_gpio_leds);
+#endif
+               break;
+       }
+#ifdef CONFIG_LEDS_GPIO
+       ifxmips_gpio_led_data.leds = board->gpio_leds;
+#endif
+       ifxmips_led_data.leds = board->ifxmips_leds;
+
+       printk("%s:%s[%d]adding %d devs\n", __FILE__, __func__, __LINE__, board->num_devs);
+
+       ifxmips_gpio.resource = &board->reset_resource;
+       ifxmips_gpio_dev.resource = &board->gpiodev_resource;
+       if(board->pci_external_clock)
+               ifxmips_pci_external_clock = 1;
+       printk("using board definition %s\n", board->name);
+       return platform_add_devices(board->devs, board->num_devs);
+}
+
+arch_initcall(ifxmips_init_devices);
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/clock.c b/target/linux/ifxmips/files/arch/mips/ifxmips/clock.c
new file mode 100644 (file)
index 0000000..fc3658b
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2007 Xu Liang, infineon
+ *   Copyright (C) 2008 John Crispin <blogic@openwrt.org> 
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+#include <linux/errno.h>
+#include <asm/ifxmips/ifxmips.h>
+
+#define BASIC_INPUT_CLOCK_FREQUENCY_1   35328000
+#define BASIC_INPUT_CLOCK_FREQUENCY_2   36000000
+
+#define BASIS_INPUT_CRYSTAL_USB         12000000
+
+#define GET_BITS(x, msb, lsb)           (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
+
+
+#define CGU_PLL0_PHASE_DIVIDER_ENABLE   (ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & (1 << 31))
+#define CGU_PLL0_BYPASS                 (ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & (1 << 30))
+#define CGU_PLL0_CFG_DSMSEL             (ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & (1 << 28))
+#define CGU_PLL0_CFG_FRAC_EN            (ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & (1 << 27))
+#define CGU_PLL1_SRC                    (ifxmips_r32(IFXMIPS_CGU_PLL1_CFG) & (1 << 31))
+#define CGU_PLL1_BYPASS                 (ifxmips_r32(IFXMIPS_CGU_PLL1_CFG) & (1 << 30))
+#define CGU_PLL1_CFG_DSMSEL             (ifxmips_r32(IFXMIPS_CGU_PLL1_CFG) & (1 << 28))
+#define CGU_PLL1_CFG_FRAC_EN            (ifxmips_r32(IFXMIPS_CGU_PLL1_CFG) & (1 << 27))
+#define CGU_PLL2_PHASE_DIVIDER_ENABLE   (ifxmips_r32(IFXMIPS_CGU_PLL2_CFG) & (1 << 20))
+#define CGU_PLL2_BYPASS                 (ifxmips_r32(IFXMIPS_CGU_PLL2_CFG) & (1 << 19))
+#define CGU_SYS_FPI_SEL                 (1 << 6)
+#define CGU_SYS_DDR_SEL                 0x3
+#define CGU_PLL0_SRC                    (1 << 29)
+
+#define CGU_PLL0_CFG_PLLK               GET_BITS(*IFXMIPS_CGU_PLL0_CFG, 26, 17)
+#define CGU_PLL0_CFG_PLLN               GET_BITS(*IFXMIPS_CGU_PLL0_CFG, 12, 6)
+#define CGU_PLL0_CFG_PLLM               GET_BITS(*IFXMIPS_CGU_PLL0_CFG, 5, 2)
+#define CGU_PLL1_CFG_PLLK               GET_BITS(*IFXMIPS_CGU_PLL1_CFG, 26, 17)
+#define CGU_PLL1_CFG_PLLN               GET_BITS(*IFXMIPS_CGU_PLL1_CFG, 12, 6)
+#define CGU_PLL1_CFG_PLLM               GET_BITS(*IFXMIPS_CGU_PLL1_CFG, 5, 2)
+#define CGU_PLL2_SRC                    GET_BITS(*IFXMIPS_CGU_PLL2_CFG, 18, 17)
+#define CGU_PLL2_CFG_INPUT_DIV          GET_BITS(*IFXMIPS_CGU_PLL2_CFG, 16, 13)
+#define CGU_PLL2_CFG_PLLN               GET_BITS(*IFXMIPS_CGU_PLL2_CFG, 12, 6)
+#define CGU_PLL2_CFG_PLLM               GET_BITS(*IFXMIPS_CGU_PLL2_CFG, 5, 2)
+#define CGU_IF_CLK_PCI_CLK              GET_BITS(*IFXMIPS_CGU_IF_CLK, 23, 20)
+
+static unsigned int cgu_get_pll0_fdiv(void);
+unsigned int ifxmips_clocks[] = {CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
+
+#define DDR_HZ ifxmips_clocks[ifxmips_r32(IFXMIPS_CGU_SYS) & 0x3]
+
+
+static inline unsigned int
+get_input_clock(int pll)
+{
+       switch(pll)
+       {
+       case 0:
+               if(ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & CGU_PLL0_SRC)
+                       return BASIS_INPUT_CRYSTAL_USB;
+               else if(CGU_PLL0_PHASE_DIVIDER_ENABLE)
+                       return BASIC_INPUT_CLOCK_FREQUENCY_1;
+               else
+                       return BASIC_INPUT_CLOCK_FREQUENCY_2;
+       case 1:
+               if(CGU_PLL1_SRC)
+                       return BASIS_INPUT_CRYSTAL_USB;
+               else if(CGU_PLL0_PHASE_DIVIDER_ENABLE)
+                       return BASIC_INPUT_CLOCK_FREQUENCY_1;
+               else
+                       return BASIC_INPUT_CLOCK_FREQUENCY_2;
+       case 2:
+               switch(CGU_PLL2_SRC)
+               {
+               case 0:
+                       return cgu_get_pll0_fdiv();
+               case 1:
+                       return CGU_PLL2_PHASE_DIVIDER_ENABLE ? BASIC_INPUT_CLOCK_FREQUENCY_1 : BASIC_INPUT_CLOCK_FREQUENCY_2;
+               case 2:
+                       return BASIS_INPUT_CRYSTAL_USB;
+               }
+       default:
+               return 0;
+       }
+}
+
+static inline unsigned int
+cal_dsm(int pll, unsigned int num, unsigned int den)
+{
+       u64 res, clock = get_input_clock(pll);
+
+       res = num * clock;
+       do_div(res, den);
+       return res;
+}
+
+static inline unsigned int
+mash_dsm(int pll, unsigned int M, unsigned int N, unsigned int K)
+{
+       unsigned int num = ((N + 1) << 10) + K;
+       unsigned int den = (M + 1) << 10;
+
+       return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int
+ssff_dsm_1(int pll, unsigned int M,    unsigned int N, unsigned int K)
+{
+       unsigned int num = ((N + 1) << 11) + K + 512;
+       unsigned int den = (M + 1) << 11;
+
+       return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int
+ssff_dsm_2(int pll, unsigned int M,    unsigned int N, unsigned int K)
+{
+       unsigned int num = K >= 512 ?
+               ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
+       unsigned int den = (M + 1) << 12;
+
+       return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int
+dsm(int pll, unsigned int M, unsigned int N, unsigned int K,
+       unsigned int dsmsel, unsigned int phase_div_en)
+{
+       if(!dsmsel)
+               return mash_dsm(pll, M, N, K);
+       else if(!phase_div_en)
+               return mash_dsm(pll, M, N, K);
+       else
+               return ssff_dsm_2(pll, M, N, K);
+}
+
+static inline unsigned int
+cgu_get_pll0_fosc(void)
+{
+       if(CGU_PLL0_BYPASS)
+               return get_input_clock(0);
+       else
+               return !CGU_PLL0_CFG_FRAC_EN
+                       ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0, CGU_PLL0_CFG_DSMSEL,
+                               CGU_PLL0_PHASE_DIVIDER_ENABLE)
+                       : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, CGU_PLL0_CFG_PLLK,
+                               CGU_PLL0_CFG_DSMSEL, CGU_PLL0_PHASE_DIVIDER_ENABLE);
+}
+
+static unsigned int
+cgu_get_pll0_fdiv(void)
+{
+       register unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
+       return (cgu_get_pll0_fosc() + (div >> 1)) / div;
+}
+
+unsigned int
+cgu_get_io_region_clock(void)
+{
+       register unsigned int ret = cgu_get_pll0_fosc();
+       switch(ifxmips_r32(IFXMIPS_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL)
+       {
+       default:
+       case 0:
+               return (ret + 1) / 2;
+       case 1:
+               return (ret * 2 + 2) / 5;
+       case 2:
+               return (ret + 1) / 3;
+       case 3:
+               return (ret + 2) / 4;
+       }
+}
+
+unsigned int
+cgu_get_fpi_bus_clock(int fpi)
+{
+       register unsigned int ret = cgu_get_io_region_clock();
+       if((fpi == 2) && (ifxmips_r32(IFXMIPS_CGU_SYS) & CGU_SYS_FPI_SEL))
+               ret >>= 1;
+       return ret;
+}
+
+void cgu_setup_pci_clk(int external_clock)
+{
+       //set clock to 33Mhz 
+       ifxmips_w32(ifxmips_r32(IFXMIPS_CGU_IFCCR) & ~0xf00000, IFXMIPS_CGU_IFCCR);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_CGU_IFCCR) | 0x800000, IFXMIPS_CGU_IFCCR);
+       if(external_clock)
+       {
+               ifxmips_w32(ifxmips_r32(IFXMIPS_CGU_IFCCR) & ~ (1 << 16), IFXMIPS_CGU_IFCCR);
+               ifxmips_w32((1 << 30), IFXMIPS_CGU_PCICR);
+       } else {
+               ifxmips_w32(ifxmips_r32(IFXMIPS_CGU_IFCCR) | (1 << 16), IFXMIPS_CGU_IFCCR);
+               ifxmips_w32((1 << 31) | (1 << 30), IFXMIPS_CGU_PCICR);
+       }
+}
+
+unsigned int
+ifxmips_get_cpu_hz(void)
+{
+       unsigned int ddr_clock = DDR_HZ;
+       switch(ifxmips_r32(IFXMIPS_CGU_SYS) & 0xc)
+       {
+       case 0:
+               return CLOCK_333M;
+       case 4:
+               return ddr_clock;
+       }
+       return ddr_clock << 1;
+}
+EXPORT_SYMBOL(ifxmips_get_cpu_hz);
+
+unsigned int
+ifxmips_get_fpi_hz(void)
+{
+       unsigned int ddr_clock = DDR_HZ;
+       if(ifxmips_r32(IFXMIPS_CGU_SYS) & 0x40)
+               return ddr_clock >> 1;
+       return ddr_clock;
+}
+EXPORT_SYMBOL(ifxmips_get_fpi_hz);
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/dma-core.c b/target/linux/ifxmips/files/arch/mips/ifxmips/dma-core.c
new file mode 100644 (file)
index 0000000..a57b803
--- /dev/null
@@ -0,0 +1,758 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/stat.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/selection.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <linux/errno.h>
+#include <asm/io.h>
+
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+#include <asm/ifxmips/ifxmips_dma.h>
+#include <asm/ifxmips/ifxmips_pmu.h>
+
+/*25 descriptors for each dma channel,4096/8/20=25.xx*/
+#define IFXMIPS_DMA_DESCRIPTOR_OFFSET 25
+
+#define MAX_DMA_DEVICE_NUM  6  /*max ports connecting to dma */
+#define MAX_DMA_CHANNEL_NUM 20 /*max dma channels */
+#define DMA_INT_BUDGET      100        /*budget for interrupt handling */
+#define DMA_POLL_COUNTER    4  /*fix me, set the correct counter value here! */
+
+extern void ifxmips_mask_and_ack_irq (unsigned int irq_nr);
+extern void ifxmips_enable_irq (unsigned int irq_nr);
+extern void ifxmips_disable_irq (unsigned int irq_nr);
+
+u64 *g_desc_list;
+_dma_device_info dma_devs[MAX_DMA_DEVICE_NUM];
+_dma_channel_info dma_chan[MAX_DMA_CHANNEL_NUM];
+
+char global_device_name[MAX_DMA_DEVICE_NUM][20] =
+       { {"PPE"}, {"DEU"}, {"SPI"}, {"SDIO"}, {"MCTRL0"}, {"MCTRL1"} };
+
+_dma_chan_map default_dma_map[MAX_DMA_CHANNEL_NUM] = {
+       {"PPE", IFXMIPS_DMA_RX, 0, IFXMIPS_DMA_CH0_INT, 0},
+       {"PPE", IFXMIPS_DMA_TX, 0, IFXMIPS_DMA_CH1_INT, 0},
+       {"PPE", IFXMIPS_DMA_RX, 1, IFXMIPS_DMA_CH2_INT, 1},
+       {"PPE", IFXMIPS_DMA_TX, 1, IFXMIPS_DMA_CH3_INT, 1},
+       {"PPE", IFXMIPS_DMA_RX, 2, IFXMIPS_DMA_CH4_INT, 2},
+       {"PPE", IFXMIPS_DMA_TX, 2, IFXMIPS_DMA_CH5_INT, 2},
+       {"PPE", IFXMIPS_DMA_RX, 3, IFXMIPS_DMA_CH6_INT, 3},
+       {"PPE", IFXMIPS_DMA_TX, 3, IFXMIPS_DMA_CH7_INT, 3},
+       {"DEU", IFXMIPS_DMA_RX, 0, IFXMIPS_DMA_CH8_INT, 0},
+       {"DEU", IFXMIPS_DMA_TX, 0, IFXMIPS_DMA_CH9_INT, 0},
+       {"DEU", IFXMIPS_DMA_RX, 1, IFXMIPS_DMA_CH10_INT, 1},
+       {"DEU", IFXMIPS_DMA_TX, 1, IFXMIPS_DMA_CH11_INT, 1},
+       {"SPI", IFXMIPS_DMA_RX, 0, IFXMIPS_DMA_CH12_INT, 0},
+       {"SPI", IFXMIPS_DMA_TX, 0, IFXMIPS_DMA_CH13_INT, 0},
+       {"SDIO", IFXMIPS_DMA_RX, 0, IFXMIPS_DMA_CH14_INT, 0},
+       {"SDIO", IFXMIPS_DMA_TX, 0, IFXMIPS_DMA_CH15_INT, 0},
+       {"MCTRL0", IFXMIPS_DMA_RX, 0, IFXMIPS_DMA_CH16_INT, 0},
+       {"MCTRL0", IFXMIPS_DMA_TX, 0, IFXMIPS_DMA_CH17_INT, 0},
+       {"MCTRL1", IFXMIPS_DMA_RX, 1, IFXMIPS_DMA_CH18_INT, 1},
+       {"MCTRL1", IFXMIPS_DMA_TX, 1, IFXMIPS_DMA_CH19_INT, 1}
+};
+
+_dma_chan_map *chan_map = default_dma_map;
+volatile u32 g_ifxmips_dma_int_status = 0;
+volatile int g_ifxmips_dma_in_process = 0;/*0=not in process,1=in process*/
+
+void do_dma_tasklet (unsigned long);
+DECLARE_TASKLET (dma_tasklet, do_dma_tasklet, 0);
+
+u8*
+common_buffer_alloc (int len, int *byte_offset, void **opt)
+{
+       u8 *buffer = (u8 *) kmalloc (len * sizeof (u8), GFP_KERNEL);
+
+       *byte_offset = 0;
+
+       return buffer;
+}
+
+void
+common_buffer_free (u8 *dataptr, void *opt)
+{
+       if (dataptr)
+               kfree(dataptr);
+}
+
+void
+enable_ch_irq (_dma_channel_info *pCh)
+{
+       int chan_no = (int)(pCh - dma_chan);
+       int flag;
+
+       local_irq_save(flag);
+       ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+       ifxmips_w32(0x4a, IFXMIPS_DMA_CIE);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_IRNEN) | (1 << chan_no), IFXMIPS_DMA_IRNEN);
+       local_irq_restore(flag);
+       ifxmips_enable_irq(pCh->irq);
+}
+
+void
+disable_ch_irq (_dma_channel_info *pCh)
+{
+       int flag;
+       int chan_no = (int) (pCh - dma_chan);
+
+       local_irq_save(flag);
+       g_ifxmips_dma_int_status &= ~(1 << chan_no);
+       ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+       ifxmips_w32(0, IFXMIPS_DMA_CIE);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_IRNEN) & ~(1 << chan_no), IFXMIPS_DMA_IRNEN);
+       local_irq_restore(flag);
+       ifxmips_mask_and_ack_irq(pCh->irq);
+}
+
+void
+open_chan (_dma_channel_info *pCh)
+{
+       int flag;
+       int chan_no = (int)(pCh - dma_chan);
+
+       local_irq_save(flag);
+       ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) | 1, IFXMIPS_DMA_CCTRL);
+       if(pCh->dir == IFXMIPS_DMA_RX)
+               enable_ch_irq(pCh);
+       local_irq_restore(flag);
+}
+
+void
+close_chan(_dma_channel_info *pCh)
+{
+       int flag;
+       int chan_no = (int) (pCh - dma_chan);
+
+       local_irq_save(flag);
+       ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) & ~1, IFXMIPS_DMA_CCTRL);
+       disable_ch_irq(pCh);
+       local_irq_restore(flag);
+}
+
+void
+reset_chan (_dma_channel_info *pCh)
+{
+       int chan_no = (int) (pCh - dma_chan);
+
+       ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) | 2, IFXMIPS_DMA_CCTRL);
+}
+
+void
+rx_chan_intr_handler (int chan_no)
+{
+       _dma_device_info *pDev = (_dma_device_info *)dma_chan[chan_no].dma_dev;
+       _dma_channel_info *pCh = &dma_chan[chan_no];
+       struct rx_desc *rx_desc_p;
+       int tmp;
+       int flag;
+
+       /*handle command complete interrupt */
+       rx_desc_p = (struct rx_desc*)pCh->desc_base + pCh->curr_desc;
+       if (rx_desc_p->status.field.OWN == CPU_OWN
+           && rx_desc_p->status.field.C
+           && rx_desc_p->status.field.data_length < 1536){
+               /*Every thing is correct, then we inform the upper layer */
+               pDev->current_rx_chan = pCh->rel_chan_no;
+               if(pDev->intr_handler)
+                       pDev->intr_handler(pDev, RCV_INT);
+               pCh->weight--;
+       } else {
+               local_irq_save(flag);
+               tmp = ifxmips_r32(IFXMIPS_DMA_CS);
+               ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+               ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CIS) | 0x7e, IFXMIPS_DMA_CIS);
+               ifxmips_w32(tmp, IFXMIPS_DMA_CS);
+               g_ifxmips_dma_int_status &= ~(1 << chan_no);
+               local_irq_restore(flag);
+               ifxmips_enable_irq(dma_chan[chan_no].irq);
+       }
+}
+
+inline void
+tx_chan_intr_handler (int chan_no)
+{
+       _dma_device_info *pDev = (_dma_device_info*)dma_chan[chan_no].dma_dev;
+       _dma_channel_info *pCh = &dma_chan[chan_no];
+    int tmp;
+    int flag;
+
+    local_irq_save(flag);
+    tmp = ifxmips_r32(IFXMIPS_DMA_CS);
+    ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+    ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CIS) | 0x7e, IFXMIPS_DMA_CIS);
+    ifxmips_w32(tmp, IFXMIPS_DMA_CS);
+    g_ifxmips_dma_int_status &= ~(1 << chan_no);
+    local_irq_restore(flag);
+       pDev->current_tx_chan = pCh->rel_chan_no;
+       if (pDev->intr_handler)
+               pDev->intr_handler(pDev, TRANSMIT_CPT_INT);
+}
+
+void
+do_dma_tasklet (unsigned long unused)
+{
+       int i;
+       int chan_no = 0;
+       int budget = DMA_INT_BUDGET;
+       int weight = 0;
+    int flag;
+
+       while (g_ifxmips_dma_int_status)
+       {
+               if (budget-- < 0)
+               {
+                       tasklet_schedule(&dma_tasklet);
+                       return;
+               }
+               chan_no = -1;
+               weight = 0;
+               for (i = 0; i < MAX_DMA_CHANNEL_NUM; i++)
+               {
+                       if ((g_ifxmips_dma_int_status & (1 << i)) && dma_chan[i].weight > 0)
+                       {
+                               if (dma_chan[i].weight > weight)
+                               {
+                                       chan_no = i;
+                    weight = dma_chan[chan_no].weight;
+                }
+                       }
+               }
+
+               if (chan_no >= 0)
+               {
+                       if (chan_map[chan_no].dir == IFXMIPS_DMA_RX)
+                               rx_chan_intr_handler(chan_no);
+                       else
+                               tx_chan_intr_handler(chan_no);
+               } else {
+                       for (i = 0; i < MAX_DMA_CHANNEL_NUM; i++)
+                       {
+                               dma_chan[i].weight = dma_chan[i].default_weight;
+                       }
+               }
+       }
+
+    local_irq_save(flag);
+       g_ifxmips_dma_in_process = 0;
+    if (g_ifxmips_dma_int_status)
+       {
+        g_ifxmips_dma_in_process = 1;
+        tasklet_schedule(&dma_tasklet);
+    }
+    local_irq_restore(flag);
+}
+
+irqreturn_t
+dma_interrupt (int irq, void *dev_id)
+{
+       _dma_channel_info *pCh;
+       int chan_no = 0;
+       int tmp;
+
+       pCh = (_dma_channel_info*)dev_id;
+       chan_no = (int)(pCh - dma_chan);
+       if (chan_no < 0 || chan_no > 19)
+               BUG();
+
+       tmp = ifxmips_r32(IFXMIPS_DMA_IRNEN);
+       ifxmips_w32(0, IFXMIPS_DMA_IRNEN);
+       g_ifxmips_dma_int_status |= 1 << chan_no;
+       ifxmips_w32(tmp, IFXMIPS_DMA_IRNEN);
+       ifxmips_mask_and_ack_irq(irq);
+
+    if (!g_ifxmips_dma_in_process)
+       {
+        g_ifxmips_dma_in_process = 1;
+        tasklet_schedule(&dma_tasklet);
+    }
+
+       return IRQ_HANDLED;
+}
+
+_dma_device_info*
+dma_device_reserve (char *dev_name)
+{
+       int i;
+
+       for (i = 0; i < MAX_DMA_DEVICE_NUM; i++)
+       {
+               if (strcmp(dev_name, dma_devs[i].device_name) == 0)
+               {
+                       if (dma_devs[i].reserved)
+                               return NULL;
+                       dma_devs[i].reserved = 1;
+                       break;
+               }
+       }
+
+       return &dma_devs[i];
+}
+
+void
+dma_device_release (_dma_device_info *dev)
+{
+       dev->reserved = 0;
+}
+
+void
+dma_device_register(_dma_device_info *dev)
+{
+       int i, j;
+       int chan_no = 0;
+       u8 *buffer;
+       int byte_offset;
+       int flag;
+       _dma_device_info *pDev;
+       _dma_channel_info *pCh;
+       struct rx_desc *rx_desc_p;
+       struct tx_desc *tx_desc_p;
+
+       for (i = 0; i < dev->max_tx_chan_num; i++)
+       {
+               pCh = dev->tx_chan[i];
+               if (pCh->control == IFXMIPS_DMA_CH_ON)
+               {
+                       chan_no = (int)(pCh - dma_chan);
+                       for (j = 0; j < pCh->desc_len; j++)
+                       {
+                               tx_desc_p = (struct tx_desc*)pCh->desc_base + j;
+                               memset(tx_desc_p, 0, sizeof(struct tx_desc));
+                       }
+                       local_irq_save(flag);
+                       ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+                       /*check if the descriptor length is changed */
+                       if (ifxmips_r32(IFXMIPS_DMA_CDLEN) != pCh->desc_len)
+                               ifxmips_w32(pCh->desc_len, IFXMIPS_DMA_CDLEN);
+
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) & ~1, IFXMIPS_DMA_CCTRL);
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) | 2, IFXMIPS_DMA_CCTRL);
+                       while (ifxmips_r32(IFXMIPS_DMA_CCTRL) & 2){};
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_IRNEN) | (1 << chan_no), IFXMIPS_DMA_IRNEN);
+                       ifxmips_w32(0x30100, IFXMIPS_DMA_CCTRL);        /*reset and enable channel,enable channel later */
+                       local_irq_restore(flag);
+               }
+       }
+
+       for (i = 0; i < dev->max_rx_chan_num; i++)
+       {
+               pCh = dev->rx_chan[i];
+               if (pCh->control == IFXMIPS_DMA_CH_ON)
+               {
+                       chan_no = (int)(pCh - dma_chan);
+
+                       for (j = 0; j < pCh->desc_len; j++)
+                       {
+                               rx_desc_p = (struct rx_desc*)pCh->desc_base + j;
+                               pDev = (_dma_device_info*)(pCh->dma_dev);
+                               buffer = pDev->buffer_alloc(pCh->packet_size, &byte_offset, (void*)&(pCh->opt[j]));
+                               if (!buffer)
+                                       break;
+
+                               dma_cache_inv((unsigned long) buffer, pCh->packet_size);
+
+                               rx_desc_p->Data_Pointer = (u32)CPHYSADDR((u32)buffer);
+                               rx_desc_p->status.word = 0;
+                               rx_desc_p->status.field.byte_offset = byte_offset;
+                               rx_desc_p->status.field.OWN = DMA_OWN;
+                               rx_desc_p->status.field.data_length = pCh->packet_size;
+                       }
+
+                       local_irq_save(flag);
+                       ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+                       /*check if the descriptor length is changed */
+                       if (ifxmips_r32(IFXMIPS_DMA_CDLEN) != pCh->desc_len)
+                               ifxmips_w32(pCh->desc_len, IFXMIPS_DMA_CDLEN);
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) & ~1, IFXMIPS_DMA_CCTRL);
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) | 2, IFXMIPS_DMA_CCTRL);
+                       while (ifxmips_r32(IFXMIPS_DMA_CCTRL) & 2){};
+                       ifxmips_w32(0x0a, IFXMIPS_DMA_CIE);     /*fix me, should enable all the interrupts here? */
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_IRNEN) | (1 << chan_no), IFXMIPS_DMA_IRNEN);
+                       ifxmips_w32(0x30000, IFXMIPS_DMA_CCTRL);
+                       local_irq_restore(flag);
+                       ifxmips_enable_irq(dma_chan[chan_no].irq);
+               }
+       }
+}
+
+void
+dma_device_unregister (_dma_device_info *dev)
+{
+       int i, j;
+       int chan_no;
+       _dma_channel_info *pCh;
+       struct rx_desc *rx_desc_p;
+       struct tx_desc *tx_desc_p;
+       int flag;
+
+       for (i = 0; i < dev->max_tx_chan_num; i++)
+       {
+               pCh = dev->tx_chan[i];
+               if (pCh->control == IFXMIPS_DMA_CH_ON)
+               {
+                       chan_no = (int)(dev->tx_chan[i] - dma_chan);
+                       local_irq_save (flag);
+                       ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+                       pCh->curr_desc = 0;
+                       pCh->prev_desc = 0;
+                       pCh->control = IFXMIPS_DMA_CH_OFF;
+                       ifxmips_w32(0, IFXMIPS_DMA_CIE);        /*fix me, should disable all the interrupts here? */
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_IRNEN) & ~(1 << chan_no), IFXMIPS_DMA_IRNEN);       /*disable interrupts */
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) & ~1, IFXMIPS_DMA_CCTRL);
+                       while (ifxmips_r32(IFXMIPS_DMA_CCTRL) & 1) {};
+                       local_irq_restore (flag);
+
+                       for (j = 0; j < pCh->desc_len; j++)
+                       {
+                               tx_desc_p = (struct tx_desc*)pCh->desc_base + j;
+                               if ((tx_desc_p->status.field.OWN == CPU_OWN && tx_desc_p->status.field.C)
+                                               || (tx_desc_p->status.field.OWN == DMA_OWN && tx_desc_p->status.field.data_length > 0))
+                               {
+                                       dev->buffer_free ((u8 *) __va (tx_desc_p->Data_Pointer), (void*)pCh->opt[j]);
+                               }
+                               tx_desc_p->status.field.OWN = CPU_OWN;
+                               memset (tx_desc_p, 0, sizeof (struct tx_desc));
+                       }
+                       //TODO should free buffer that is not transferred by dma
+               }
+       }
+
+       for (i = 0; i < dev->max_rx_chan_num; i++)
+       {
+               pCh = dev->rx_chan[i];
+               chan_no = (int)(dev->rx_chan[i] - dma_chan);
+               ifxmips_disable_irq(pCh->irq);
+
+               local_irq_save(flag);
+               g_ifxmips_dma_int_status &= ~(1 << chan_no);
+               pCh->curr_desc = 0;
+               pCh->prev_desc = 0;
+               pCh->control = IFXMIPS_DMA_CH_OFF;
+
+               ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+               ifxmips_w32(0, IFXMIPS_DMA_CIE); /*fix me, should disable all the interrupts here? */
+               ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_IRNEN) & ~(1 << chan_no), IFXMIPS_DMA_IRNEN);       /*disable interrupts */
+               ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) & ~1, IFXMIPS_DMA_CCTRL);
+               while (ifxmips_r32(IFXMIPS_DMA_CCTRL) & 1) {};
+
+               local_irq_restore (flag);
+               for (j = 0; j < pCh->desc_len; j++)
+               {
+                       rx_desc_p = (struct rx_desc *) pCh->desc_base + j;
+                       if ((rx_desc_p->status.field.OWN == CPU_OWN 
+                            && rx_desc_p->status.field.C)
+                           || (rx_desc_p->status.field.OWN == DMA_OWN
+                               && rx_desc_p->status.field.data_length > 0)) {
+                               dev->buffer_free ((u8 *)
+                                                 __va (rx_desc_p->
+                                                       Data_Pointer),
+                                                 (void *) pCh->opt[j]);
+                       }
+               }
+       }
+}
+
+int
+dma_device_read (struct dma_device_info *dma_dev, u8 ** dataptr, void **opt)
+{
+       u8 *buf;
+       int len;
+       int byte_offset = 0;
+       void *p = NULL;
+       _dma_channel_info *pCh = dma_dev->rx_chan[dma_dev->current_rx_chan];
+       struct rx_desc *rx_desc_p;
+
+       /*get the rx data first */
+       rx_desc_p = (struct rx_desc *) pCh->desc_base + pCh->curr_desc;
+       if (!(rx_desc_p->status.field.OWN == CPU_OWN && rx_desc_p->status.field.C))
+       {
+               return 0;
+       }
+
+       buf = (u8 *) __va (rx_desc_p->Data_Pointer);
+       *(u32*)dataptr = (u32)buf;
+       len = rx_desc_p->status.field.data_length;
+
+       if (opt)
+       {
+               *(int*)opt = (int)pCh->opt[pCh->curr_desc];
+       }
+
+       /*replace with a new allocated buffer */
+       buf = dma_dev->buffer_alloc(pCh->packet_size, &byte_offset, &p);
+
+       if (buf)
+       {
+               dma_cache_inv ((unsigned long) buf,
+               pCh->packet_size);
+               pCh->opt[pCh->curr_desc] = p;
+               wmb ();
+
+               rx_desc_p->Data_Pointer = (u32) CPHYSADDR ((u32) buf);
+               rx_desc_p->status.word = (DMA_OWN << 31) | ((byte_offset) << 23) | pCh->packet_size;
+               wmb ();
+       } else {
+               *(u32 *) dataptr = 0;
+               if (opt)
+                       *(int *) opt = 0;
+               len = 0;
+       }
+
+       /*increase the curr_desc pointer */
+       pCh->curr_desc++;
+       if (pCh->curr_desc == pCh->desc_len)
+               pCh->curr_desc = 0;
+
+       return len;
+}
+
+int
+dma_device_write (struct dma_device_info *dma_dev, u8 * dataptr, int len, void *opt)
+{
+       int flag;
+       u32 tmp, byte_offset;
+       _dma_channel_info *pCh;
+       int chan_no;
+       struct tx_desc *tx_desc_p;
+       local_irq_save (flag);
+
+       pCh = dma_dev->tx_chan[dma_dev->current_tx_chan];
+       chan_no = (int)(pCh - (_dma_channel_info *) dma_chan);
+
+       tx_desc_p = (struct tx_desc*)pCh->desc_base + pCh->prev_desc;
+       while (tx_desc_p->status.field.OWN == CPU_OWN && tx_desc_p->status.field.C)
+       {
+               dma_dev->buffer_free((u8 *) __va (tx_desc_p->Data_Pointer), pCh->opt[pCh->prev_desc]);
+               memset(tx_desc_p, 0, sizeof (struct tx_desc));
+               pCh->prev_desc = (pCh->prev_desc + 1) % (pCh->desc_len);
+               tx_desc_p = (struct tx_desc*)pCh->desc_base + pCh->prev_desc;
+       }
+       tx_desc_p = (struct tx_desc*)pCh->desc_base + pCh->curr_desc;
+       /*Check whether this descriptor is available */
+       if (tx_desc_p->status.field.OWN == DMA_OWN || tx_desc_p->status.field.C)
+       {
+               /*if not , the tell the upper layer device */
+               dma_dev->intr_handler (dma_dev, TX_BUF_FULL_INT);
+               local_irq_restore(flag);
+               printk (KERN_INFO "%s %d: failed to write!\n", __func__, __LINE__);
+
+               return 0;
+       }
+       pCh->opt[pCh->curr_desc] = opt;
+       /*byte offset----to adjust the starting address of the data buffer, should be multiple of the burst length. */
+       byte_offset = ((u32) CPHYSADDR ((u32) dataptr)) % ((dma_dev->tx_burst_len) * 4);
+       dma_cache_wback ((unsigned long) dataptr, len);
+       wmb ();
+       tx_desc_p->Data_Pointer = (u32) CPHYSADDR ((u32) dataptr) - byte_offset;
+       wmb ();
+       tx_desc_p->status.word = (DMA_OWN << 31) | DMA_DESC_SOP_SET | DMA_DESC_EOP_SET | ((byte_offset) << 23) | len;
+       wmb ();
+
+       pCh->curr_desc++;
+       if (pCh->curr_desc == pCh->desc_len)
+               pCh->curr_desc = 0;
+
+       /*Check whether this descriptor is available */
+       tx_desc_p = (struct tx_desc *) pCh->desc_base + pCh->curr_desc;
+       if (tx_desc_p->status.field.OWN == DMA_OWN)
+       {
+               /*if not , the tell the upper layer device */
+               dma_dev->intr_handler (dma_dev, TX_BUF_FULL_INT);
+       }
+
+       ifxmips_w32(chan_no, IFXMIPS_DMA_CS);
+       tmp = ifxmips_r32(IFXMIPS_DMA_CCTRL);
+
+       if (!(tmp & 1))
+               pCh->open (pCh);
+
+       local_irq_restore (flag);
+
+       return len;
+}
+
+int
+map_dma_chan(_dma_chan_map *map)
+{
+       int i, j;
+       int result;
+
+       for (i = 0; i < MAX_DMA_DEVICE_NUM; i++)
+       {
+               strcpy(dma_devs[i].device_name, global_device_name[i]);
+       }
+
+       for (i = 0; i < MAX_DMA_CHANNEL_NUM; i++)
+       {
+               dma_chan[i].irq = map[i].irq;
+               result = request_irq(dma_chan[i].irq, dma_interrupt, IRQF_DISABLED, "dma-core", (void*)&dma_chan[i]);
+               if (result)
+               {
+                       printk("error, cannot get dma_irq!\n");
+                       free_irq(dma_chan[i].irq, (void *) &dma_interrupt);
+
+                       return -EFAULT;
+               }
+       }
+
+       for (i = 0; i < MAX_DMA_DEVICE_NUM; i++)
+       {
+               dma_devs[i].num_tx_chan = 0;    /*set default tx channel number to be one */
+               dma_devs[i].num_rx_chan = 0;    /*set default rx channel number to be one */
+               dma_devs[i].max_rx_chan_num = 0;
+               dma_devs[i].max_tx_chan_num = 0;
+               dma_devs[i].buffer_alloc = &common_buffer_alloc;
+               dma_devs[i].buffer_free = &common_buffer_free;
+               dma_devs[i].intr_handler = NULL;
+               dma_devs[i].tx_burst_len = 4;
+               dma_devs[i].rx_burst_len = 4;
+               if (i == 0)
+               {
+                       ifxmips_w32(0, IFXMIPS_DMA_PS);
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_PCTRL) | ((0xf << 8) | (1 << 6)), IFXMIPS_DMA_PCTRL);       /*enable dma drop */
+               }
+
+               if (i == 1)
+               {
+                       ifxmips_w32(1, IFXMIPS_DMA_PS);
+                       ifxmips_w32(0x14, IFXMIPS_DMA_PCTRL);   /*deu port setting */
+               }
+
+               for (j = 0; j < MAX_DMA_CHANNEL_NUM; j++)
+               {
+                       dma_chan[j].byte_offset = 0;
+                       dma_chan[j].open = &open_chan;
+                       dma_chan[j].close = &close_chan;
+                       dma_chan[j].reset = &reset_chan;
+                       dma_chan[j].enable_irq = &enable_ch_irq;
+                       dma_chan[j].disable_irq = &disable_ch_irq;
+                       dma_chan[j].rel_chan_no = map[j].rel_chan_no;
+                       dma_chan[j].control = IFXMIPS_DMA_CH_OFF;
+                       dma_chan[j].default_weight = IFXMIPS_DMA_CH_DEFAULT_WEIGHT;
+                       dma_chan[j].weight = dma_chan[j].default_weight;
+                       dma_chan[j].curr_desc = 0;
+                       dma_chan[j].prev_desc = 0;
+               }
+
+               for (j = 0; j < MAX_DMA_CHANNEL_NUM; j++)
+               {
+                       if (strcmp(dma_devs[i].device_name, map[j].dev_name) == 0)
+                       {
+                               if (map[j].dir == IFXMIPS_DMA_RX)
+                               {
+                                       dma_chan[j].dir = IFXMIPS_DMA_RX;
+                                       dma_devs[i].max_rx_chan_num++;
+                                       dma_devs[i].rx_chan[dma_devs[i].max_rx_chan_num - 1] = &dma_chan[j];
+                                       dma_devs[i].rx_chan[dma_devs[i].max_rx_chan_num - 1]->pri = map[j].pri;
+                                       dma_chan[j].dma_dev = (void*)&dma_devs[i];
+                               } else if(map[j].dir == IFXMIPS_DMA_TX)
+                               { /*TX direction */
+                                       dma_chan[j].dir = IFXMIPS_DMA_TX;
+                                       dma_devs[i].max_tx_chan_num++;
+                                       dma_devs[i].tx_chan[dma_devs[i].max_tx_chan_num - 1] = &dma_chan[j];
+                                       dma_devs[i].tx_chan[dma_devs[i].max_tx_chan_num - 1]->pri = map[j].pri;
+                                       dma_chan[j].dma_dev = (void*)&dma_devs[i];
+                               } else {
+                                       printk ("WRONG DMA MAP!\n");
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+
+void
+dma_chip_init(void)
+{
+       int i;
+
+       // enable DMA from PMU
+       ifxmips_pmu_enable(IFXMIPS_PMU_PWDCR_DMA);
+
+       // reset DMA
+       ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CTRL) | 1, IFXMIPS_DMA_CTRL);
+
+       // diable all interrupts
+       ifxmips_w32(0, IFXMIPS_DMA_IRNEN);
+
+       for (i = 0; i < MAX_DMA_CHANNEL_NUM; i++)
+       {
+               ifxmips_w32(i, IFXMIPS_DMA_CS);
+               ifxmips_w32(0x2, IFXMIPS_DMA_CCTRL);
+               ifxmips_w32(0x80000040, IFXMIPS_DMA_CPOLL);
+               ifxmips_w32(ifxmips_r32(IFXMIPS_DMA_CCTRL) & ~0x1, IFXMIPS_DMA_CCTRL);
+
+       }
+}
+
+int
+ifxmips_dma_init (void)
+{
+       int i;
+
+       dma_chip_init();
+       if (map_dma_chan(default_dma_map))
+               BUG();
+
+       g_desc_list = (u64*)KSEG1ADDR(__get_free_page(GFP_DMA));
+
+       if (g_desc_list == NULL)
+       {
+               printk("no memory for desriptor\n");
+               return -ENOMEM;
+       }
+
+       memset(g_desc_list, 0, PAGE_SIZE);
+
+       for (i = 0; i < MAX_DMA_CHANNEL_NUM; i++)
+       {
+               dma_chan[i].desc_base = (u32)g_desc_list + i * IFXMIPS_DMA_DESCRIPTOR_OFFSET * 8;
+               dma_chan[i].curr_desc = 0;
+               dma_chan[i].desc_len = IFXMIPS_DMA_DESCRIPTOR_OFFSET;
+
+               ifxmips_w32(i, IFXMIPS_DMA_CS);
+               ifxmips_w32((u32)CPHYSADDR(dma_chan[i].desc_base), IFXMIPS_DMA_CDBA);
+               ifxmips_w32(dma_chan[i].desc_len, IFXMIPS_DMA_CDLEN);
+       }
+
+       return 0;
+}
+
+arch_initcall(ifxmips_dma_init);
+
+void
+dma_cleanup(void)
+{
+       int i;
+
+       free_page(KSEG0ADDR((unsigned long) g_desc_list));
+       for (i = 0; i < MAX_DMA_CHANNEL_NUM; i++)
+               free_irq(dma_chan[i].irq, (void*)&dma_interrupt);
+}
+
+EXPORT_SYMBOL (dma_device_reserve);
+EXPORT_SYMBOL (dma_device_release);
+EXPORT_SYMBOL (dma_device_register);
+EXPORT_SYMBOL (dma_device_unregister);
+EXPORT_SYMBOL (dma_device_read);
+EXPORT_SYMBOL (dma_device_write);
+
+MODULE_LICENSE ("GPL");
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/gpio.c b/target/linux/ifxmips/files/arch/mips/ifxmips/gpio.c
new file mode 100644 (file)
index 0000000..eef5146
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2004 btxu Generate from INCA-IP project
+ *   Copyright (C) 2005 Jin-Sze.Sow Comments edited
+ *   Copyright (C) 2006 Huang Xiaogang Modification & verification on Danube chip
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/timer.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/kobject.h>
+#include <linux/workqueue.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/platform_device.h>
+#include <net/sock.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+#include <asm/ifxmips/ifxmips.h>
+
+#define MAX_PORTS                      2
+#define PINS_PER_PORT          16
+
+#ifdef CONFIG_IFXMIPS_GPIO_RST_BTN
+
+unsigned int rst_port = 1;
+unsigned int rst_pin = 15;
+static struct timer_list rst_button_timer;
+
+extern struct sock *uevent_sock;
+extern u64 uevent_next_seqnum(void);
+static unsigned long seen;
+static int pressed = 0;
+
+struct event_t {
+       struct work_struct wq;
+       int set;
+       unsigned long jiffies;
+};
+#endif
+
+#define IFXMIPS_GPIO_SANITY            {if (port > MAX_PORTS || pin > PINS_PER_PORT) return -EINVAL; }
+int
+ifxmips_port_reserve_pin(unsigned int port, unsigned int pin)
+{
+       IFXMIPS_GPIO_SANITY;
+       printk("%s : call to obseleted function\n", __func__);
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_reserve_pin);
+
+int
+ifxmips_port_free_pin(unsigned int port, unsigned int pin)
+{
+       IFXMIPS_GPIO_SANITY;
+       printk("%s : call to obseleted function\n", __func__);
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_free_pin);
+
+int
+ifxmips_port_set_open_drain(unsigned int port, unsigned int pin)
+{
+       IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_OD + (port * 0xC)) | (1 << pin),
+               IFXMIPS_GPIO_P0_OD + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_set_open_drain);
+
+int
+ifxmips_port_clear_open_drain(unsigned int port, unsigned int pin)
+{
+       IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_OD + (port * 0xC)) & ~(1 << pin),
+               IFXMIPS_GPIO_P0_OD + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_clear_open_drain);
+
+int
+ifxmips_port_set_pudsel(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_PUDSEL + (port * 0xC)) | (1 << pin),
+               IFXMIPS_GPIO_P0_PUDSEL + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_set_pudsel);
+
+int
+ifxmips_port_clear_pudsel (unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_PUDSEL + (port * 0xC)) & ~(1 << pin),
+               IFXMIPS_GPIO_P0_PUDSEL + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_clear_pudsel);
+
+int
+ifxmips_port_set_puden(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_PUDEN + (port * 0xC)) | (1 << pin),
+               IFXMIPS_GPIO_P0_PUDEN + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_set_puden);
+
+int
+ifxmips_port_clear_puden(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_PUDEN + (port * 0xC)) & ~(1 << pin),
+               IFXMIPS_GPIO_P0_PUDEN + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_clear_puden);
+
+int
+ifxmips_port_set_stoff(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_STOFF + (port * 0xC)) | (1 << pin),
+               IFXMIPS_GPIO_P0_STOFF + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_set_stoff);
+
+int
+ifxmips_port_clear_stoff(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_STOFF + (port * 0xC)) & ~(1 << pin),
+               IFXMIPS_GPIO_P0_STOFF + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_clear_stoff);
+
+int
+ifxmips_port_set_dir_out(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_DIR + (port * 0xC)) | (1 << pin),
+               IFXMIPS_GPIO_P0_DIR + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_set_dir_out);
+
+int
+ifxmips_port_set_dir_in(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_DIR + (port * 0xC)) & ~(1 << pin),
+               IFXMIPS_GPIO_P0_DIR + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_set_dir_in);
+
+int
+ifxmips_port_set_output(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_OUT + (port * 0xC)) | (1 << pin),
+               IFXMIPS_GPIO_P0_OUT + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_set_output);
+
+int
+ifxmips_port_clear_output(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_OUT + (port * 0xC)) & ~(1 << pin),
+               IFXMIPS_GPIO_P0_OUT + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_clear_output);
+
+int
+ifxmips_port_get_input(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       if (ifxmips_r32(IFXMIPS_GPIO_P0_IN + (port * 0xC)) & (1 << pin))
+               return 0;
+       else
+               return 1;
+}
+EXPORT_SYMBOL(ifxmips_port_get_input);
+
+int
+ifxmips_port_set_altsel0(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0xC)) | (1 << pin),
+               IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_set_altsel0);
+
+int
+ifxmips_port_clear_altsel0(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0xC)) & ~(1 << pin),
+               IFXMIPS_GPIO_P0_ALTSEL0 + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_clear_altsel0);
+
+int
+ifxmips_port_set_altsel1(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0xC)) | (1 << pin),
+               IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_set_altsel1);
+
+int
+ifxmips_port_clear_altsel1(unsigned int port, unsigned int pin)
+{
+    IFXMIPS_GPIO_SANITY;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0xC)) & ~(1 << pin),
+               IFXMIPS_GPIO_P0_ALTSEL1 + (port * 0xC));
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_port_clear_altsel1);
+
+#ifdef CONFIG_IFXMIPS_GPIO_RST_BTN
+static inline void
+add_msg(struct sk_buff *skb, char *msg)
+{
+       char *scratch;
+       scratch = skb_put(skb, strlen(msg) + 1);
+       sprintf(scratch, msg);
+}
+
+static void
+hotplug_button(struct work_struct *wq)
+{
+       struct sk_buff *skb;
+       struct event_t *event;
+       size_t len;
+       char *scratch, *s;
+       char buf[128];
+
+       event = container_of(wq, struct event_t, wq);
+       if(!uevent_sock)
+               goto done;
+
+       s = event->set ? "pressed" : "released";
+       len = strlen(s) + 2;
+       skb = alloc_skb(len + 2048, GFP_KERNEL);
+       if(!skb)
+               goto done;
+
+       scratch = skb_put(skb, len);
+       sprintf(scratch, "%s@",s);
+       add_msg(skb, "HOME=/");
+       add_msg(skb, "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
+       add_msg(skb, "SUBSYSTEM=button");
+       add_msg(skb, "BUTTON=reset");
+       add_msg(skb, (event->set ? "ACTION=pressed" : "ACTION=released"));
+       sprintf(buf, "SEEN=%ld", (event->jiffies - seen)/HZ);
+       add_msg(skb, buf);
+       snprintf(buf, 128, "SEQNUM=%llu", uevent_next_seqnum());
+       add_msg(skb, buf);
+
+       NETLINK_CB(skb).dst_group = 1;
+       netlink_broadcast(uevent_sock, skb, 0, 1, GFP_KERNEL);
+done:
+       kfree(event);
+}
+
+static void
+reset_button_poll(unsigned long unused)
+{
+       struct event_t *event;
+
+       rst_button_timer.expires = jiffies + (HZ / 4);
+       add_timer(&rst_button_timer);
+
+       if (pressed != ifxmips_port_get_input(rst_port, rst_pin))
+       {
+               if(pressed)
+                       pressed = 0;
+               else
+                       pressed = 1;
+               event = (struct event_t *) kzalloc(sizeof(struct event_t), GFP_ATOMIC);
+               if (!event)
+               {
+                       printk("Could not alloc hotplug event\n");
+                       return;
+               }
+               event->set = pressed;
+               event->jiffies = jiffies;
+               INIT_WORK(&event->wq, (void *)(void *)hotplug_button);
+               schedule_work(&event->wq);
+               seen = jiffies;
+       }
+}
+#endif
+
+static int
+ifxmips_gpio_probe(struct platform_device *dev)
+{
+       int retval = 0;
+
+#ifdef CONFIG_IFXMIPS_GPIO_RST_BTN
+       rst_port = dev->resource[0].start;
+       rst_pin = dev->resource[0].end;
+       ifxmips_port_set_open_drain(rst_port, rst_pin);
+       ifxmips_port_clear_altsel0(rst_port, rst_pin);
+       ifxmips_port_clear_altsel1(rst_port, rst_pin);
+       ifxmips_port_set_dir_in(rst_port, rst_pin);
+       seen = jiffies;
+       init_timer(&rst_button_timer);
+       rst_button_timer.function = reset_button_poll;
+       rst_button_timer.expires = jiffies + HZ;
+       add_timer(&rst_button_timer);
+#endif
+       return retval;
+}
+
+static int
+ifxmips_gpio_remove(struct platform_device *pdev)
+{
+#ifdef CONFIG_IFXMIPS_GPIO_RST_BTN
+       del_timer_sync(&rst_button_timer);
+#endif
+       return 0;
+}
+
+static struct
+platform_driver ifxmips_gpio_driver = {
+       .probe = ifxmips_gpio_probe,
+       .remove = ifxmips_gpio_remove,
+       .driver = {
+               .name = "ifxmips_gpio",
+               .owner = THIS_MODULE,
+       },
+};
+
+int __init
+ifxmips_gpio_init(void)
+{
+       int ret = platform_driver_register(&ifxmips_gpio_driver);
+       if (ret)
+               printk(KERN_INFO "ifxmips_gpio : Error registering platfom driver!");
+       return ret;
+}
+
+void __exit
+ifxmips_gpio_exit(void)
+{
+       platform_driver_unregister(&ifxmips_gpio_driver);
+}
+
+module_init(ifxmips_gpio_init);
+module_exit(ifxmips_gpio_exit);
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/interrupt.c b/target/linux/ifxmips/files/arch/mips/ifxmips/interrupt.c
new file mode 100644 (file)
index 0000000..b47074d
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2005 Wu Qi Ming infineon
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+#include <asm/irq_cpu.h>
+
+void
+ifxmips_disable_irq(unsigned int irq_nr)
+{
+       int i;
+       u32 *ifxmips_ier = IFXMIPS_ICU_IM0_IER;
+
+       irq_nr -= INT_NUM_IRQ0;
+       for(i = 0; i <= 4; i++)
+       {
+               if(irq_nr < INT_NUM_IM_OFFSET){
+                       ifxmips_w32(ifxmips_r32(ifxmips_ier) & ~(1 << irq_nr ), ifxmips_ier);
+                       return;
+               }
+               ifxmips_ier += IFXMIPS_ICU_OFFSET;
+               irq_nr -= INT_NUM_IM_OFFSET;
+       }
+}
+EXPORT_SYMBOL(ifxmips_disable_irq);
+
+void
+ifxmips_mask_and_ack_irq(unsigned int irq_nr)
+{
+       int i;
+       u32 *ifxmips_ier = IFXMIPS_ICU_IM0_IER;
+       u32 *ifxmips_isr = IFXMIPS_ICU_IM0_ISR;
+
+       irq_nr -= INT_NUM_IRQ0;
+       for(i = 0; i <= 4; i++)
+       {
+               if(irq_nr < INT_NUM_IM_OFFSET)
+               {
+                       ifxmips_w32(ifxmips_r32(ifxmips_ier) & ~(1 << irq_nr ), ifxmips_ier);
+                       ifxmips_w32((1 << irq_nr ), ifxmips_isr);
+                       return;
+               }
+               ifxmips_ier += IFXMIPS_ICU_OFFSET;
+               ifxmips_isr += IFXMIPS_ICU_OFFSET;
+               irq_nr -= INT_NUM_IM_OFFSET;
+       }
+}
+EXPORT_SYMBOL(ifxmips_mask_and_ack_irq);
+
+void
+ifxmips_enable_irq(unsigned int irq_nr)
+{
+       int i;
+       u32 *ifxmips_ier = IFXMIPS_ICU_IM0_IER;
+
+       irq_nr -= INT_NUM_IRQ0;
+       for(i = 0; i <= 4; i++)
+       {
+               if(irq_nr < INT_NUM_IM_OFFSET)
+               {
+                       ifxmips_w32(ifxmips_r32(ifxmips_ier) | (1 << irq_nr ), ifxmips_ier);
+                       return;
+               }
+               ifxmips_ier += IFXMIPS_ICU_OFFSET;
+               irq_nr -= INT_NUM_IM_OFFSET;
+       }
+}
+EXPORT_SYMBOL(ifxmips_enable_irq);
+
+static unsigned int
+ifxmips_startup_irq(unsigned int irq)
+{
+       ifxmips_enable_irq(irq);
+       return 0;
+}
+
+static void
+ifxmips_end_irq(unsigned int irq)
+{
+       if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+               ifxmips_enable_irq (irq);
+}
+
+static struct hw_interrupt_type
+ifxmips_irq_type = {
+       "IFXMIPS",
+       .startup = ifxmips_startup_irq,
+       .enable = ifxmips_enable_irq,
+       .disable = ifxmips_disable_irq,
+       .unmask = ifxmips_enable_irq,
+       .ack = ifxmips_end_irq,
+       .mask = ifxmips_disable_irq,
+       .mask_ack = ifxmips_mask_and_ack_irq,
+       .end = ifxmips_end_irq,
+};
+
+static inline int
+ls1bit32(unsigned long x)
+{
+       __asm__ (
+               ".set push \n"
+               ".set mips32 \n"
+               "clz %0, %1 \n"
+               ".set pop \n"
+               : "=r" (x)
+               : "r" (x));
+       return 31 - x;
+}
+
+void
+ifxmips_hw_irqdispatch(int module)
+{
+       u32 irq;
+
+       irq = ifxmips_r32(IFXMIPS_ICU_IM0_IOSR + (module * IFXMIPS_ICU_OFFSET));
+       if(irq == 0)
+               return;
+
+       /* we need to do this due to a silicon bug */
+       irq = ls1bit32(irq);
+       do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
+
+       if((irq == 22) && (module == 0)){
+               ifxmips_w32(ifxmips_r32(IFXMIPS_EBU_PCC_ISTAT) | 0x10, IFXMIPS_EBU_PCC_ISTAT);
+       }
+}
+
+asmlinkage void
+plat_irq_dispatch(void)
+{
+       unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+       unsigned int i;
+
+       if(pending & CAUSEF_IP7)
+       {
+               do_IRQ(MIPS_CPU_TIMER_IRQ);
+               goto out;
+       } else {
+               for(i = 0; i < 5; i++)
+               {
+                       if(pending & (CAUSEF_IP2 << i))
+                       {
+                               ifxmips_hw_irqdispatch(i);
+                               goto out;
+                       }
+               }
+       }
+       printk("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
+
+out:
+       return;
+}
+
+static struct irqaction
+cascade = {
+       .handler = no_action,
+       .flags = IRQF_DISABLED,
+       .name = "cascade",
+};
+
+void __init
+arch_init_irq(void)
+{
+       int i;
+
+       for(i = 0; i < 5; i++)
+               ifxmips_w32(0, IFXMIPS_ICU_IM0_IER + (i * IFXMIPS_ICU_OFFSET));
+
+       mips_cpu_irq_init();
+
+       for(i = 2; i <= 6; i++)
+               setup_irq(i, &cascade);
+
+       for(i = INT_NUM_IRQ0; i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
+               set_irq_chip_and_handler(i, &ifxmips_irq_type, handle_level_irq);
+
+       set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+}
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/pmu.c b/target/linux/ifxmips/files/arch/mips/ifxmips/pmu.c
new file mode 100644 (file)
index 0000000..2831182
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <asm/ifxmips/ifxmips.h>
+
+void
+ifxmips_pmu_enable(unsigned int module)
+{
+       int err = 1000000;
+
+       ifxmips_w32(ifxmips_r32(IFXMIPS_PMU_PWDCR) & ~module, IFXMIPS_PMU_PWDCR);
+       while (--err && (ifxmips_r32(IFXMIPS_PMU_PWDSR) & module)) {}
+
+       if (!err)
+               panic("activating PMU module failed!");
+}
+EXPORT_SYMBOL(ifxmips_pmu_enable);
+
+void
+ifxmips_pmu_disable(unsigned int module)
+{
+       ifxmips_w32(ifxmips_r32(IFXMIPS_PMU_PWDCR) | module, IFXMIPS_PMU_PWDCR);
+}
+EXPORT_SYMBOL(ifxmips_pmu_disable);
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/prom.c b/target/linux/ifxmips/files/arch/mips/ifxmips/prom.c
new file mode 100644 (file)
index 0000000..880febc
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2005 Wu Qi Ming infineon
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/bootmem.h>
+#include <asm/bootinfo.h>
+#include <asm/ifxmips/ifxmips.h>
+
+static char buf[1024];
+unsigned int *prom_cp1_base = NULL;
+unsigned int prom_cp1_size = 0;
+
+#ifdef IFXMIPS_PROM_ASC0
+#define IFXMIPS_ASC_DIFF       0
+#else
+#define IFXMIPS_ASC_DIFF       IFXMIPS_ASC_BASE_DIFF
+#endif
+
+static inline u32
+asc_r32(unsigned long r)
+{
+       return ifxmips_r32((u32*)(IFXMIPS_ASC_BASE_ADDR + IFXMIPS_ASC_DIFF + r));
+}
+
+static inline void
+asc_w32(u32 v, unsigned long r)
+{
+       ifxmips_w32(v, (u32*)(IFXMIPS_ASC_BASE_ADDR + IFXMIPS_ASC_DIFF + r));
+}
+
+void
+prom_free_prom_memory(void)
+{
+}
+
+void
+prom_putchar(char c)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       while((asc_r32(IFXMIPS_ASC_FSTAT) & ASCFSTAT_TXFFLMASK) >> ASCFSTAT_TXFFLOFF);
+
+       if(c == '\n')
+               asc_w32('\r', IFXMIPS_ASC_TBUF);
+       asc_w32(c, IFXMIPS_ASC_TBUF);
+       local_irq_restore(flags);
+}
+
+void
+prom_printf(const char * fmt, ...)
+{
+       va_list args;
+       int l;
+       char *p, *buf_end;
+
+       va_start(args, fmt);
+       l = vsprintf(buf, fmt, args);
+       va_end(args);
+       buf_end = buf + l;
+
+       for(p = buf; p < buf_end; p++)
+               prom_putchar(*p);
+}
+
+unsigned int *prom_get_cp1_base(void)
+{
+       return prom_cp1_base;
+}
+EXPORT_SYMBOL(prom_get_cp1_base);
+
+unsigned int prom_get_cp1_size(void)
+{
+       return prom_cp1_size;
+}
+EXPORT_SYMBOL(prom_get_cp1_size);
+
+void __init
+prom_init(void)
+{
+       int argc = fw_arg0;
+       char **argv = (char **) fw_arg1;
+       char **envp = (char **) fw_arg2;
+
+       int memsize = 16;
+       int i;
+
+       mips_machtype = MACH_INFINEON_IFXMIPS;
+
+       argv = (char**)KSEG1ADDR((unsigned long)argv);
+       arcs_cmdline[0] = '\0';
+       for(i = 1; i < argc; i++)
+       {
+               char *a = (char*)KSEG1ADDR(argv[i]);
+               if(!a)
+                       continue;
+               if(strlen(arcs_cmdline) + strlen(a + 1) >= sizeof(arcs_cmdline))
+                       break;
+               strcat(arcs_cmdline, a);
+               strcat(arcs_cmdline, " ");
+       }
+
+       envp = (char**)KSEG1ADDR((unsigned long)envp);
+       while(*envp)
+       {
+               char *e = (char*)KSEG1ADDR(*envp);
+
+               if(!strncmp(e, "memsize=", 8))
+               {
+                       e += 8;
+                       memsize = simple_strtoul(e, NULL, 10);
+               }
+               envp++;
+       }
+
+       prom_cp1_size = 2;
+       memsize -= prom_cp1_size;
+       prom_cp1_base = (unsigned int*)(0xA0000000 + (memsize * 1024 * 1024));
+
+       prom_printf("Using %dMB Ram and reserving %dMB for cp1\n", memsize, prom_cp1_size);
+       memsize *= 1024 * 1024;
+
+       if(!*arcs_cmdline)
+               strcpy(&(arcs_cmdline[0]),
+                       "console=ttyS0,115200 rootfstype=squashfs,jffs2 init=/etc/preinit");
+
+       add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
+}
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/reset.c b/target/linux/ifxmips/files/arch/mips/ifxmips/reset.c
new file mode 100644 (file)
index 0000000..d94d8ac
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/ifxmips/ifxmips.h>
+
+static void
+ifxmips_machine_restart(char *command)
+{
+       printk(KERN_NOTICE "System restart\n");
+       local_irq_disable();
+
+       ifxmips_w32(ifxmips_r32(IFXMIPS_RCU_RST) | IFXMIPS_RCU_RST_ALL, IFXMIPS_RCU_RST);
+       for(;;);
+}
+
+static void
+ifxmips_machine_halt(void)
+{
+       printk(KERN_NOTICE "System halted.\n");
+       local_irq_disable();
+       for(;;);
+}
+
+static void
+ifxmips_machine_power_off(void)
+{
+       printk (KERN_NOTICE "Please turn off the power now.\n");
+       local_irq_disable();
+       for(;;);
+}
+
+void
+ifxmips_reboot_setup(void)
+{
+       _machine_restart = ifxmips_machine_restart;
+       _machine_halt = ifxmips_machine_halt;
+       pm_power_off = ifxmips_machine_power_off;
+}
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/setup.c b/target/linux/ifxmips/files/arch/mips/ifxmips/setup.c
new file mode 100644 (file)
index 0000000..a29a54d
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2004 peng.liu@infineon.com 
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+
+#include <linux/init.h>
+
+#include <asm/time.h>
+#include <asm/traps.h>
+#include <asm/cpu.h>
+#include <asm/irq.h>
+#include <asm/bootinfo.h>
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+#include <asm/ifxmips/ifxmips_pmu.h>
+#include <asm/ifxmips/ifxmips_cgu.h>
+#include <asm/ifxmips/ifxmips_prom.h>
+
+static unsigned int r4k_offset;
+static unsigned int r4k_cur;
+
+extern void ifxmips_reboot_setup(void);
+
+unsigned int
+ifxmips_get_cpu_ver(void)
+{
+       return (ifxmips_r32(IFXMIPS_MPS_CHIPID) & 0xF0000000) >> 28;
+}
+EXPORT_SYMBOL(ifxmips_get_cpu_ver);
+
+static __inline__ u32
+ifxmips_get_counter_resolution(void)
+{
+       u32 res;
+       __asm__ __volatile__(
+               ".set   push\n"
+               ".set   mips32r2\n"
+               ".set   noreorder\n"
+               "rdhwr  %0, $3\n"
+               "ehb\n"
+               ".set pop\n"
+               : "=&r" (res)
+               : /* no input */
+               : "memory");
+               instruction_hazard();
+               return res;
+}
+
+void __init
+plat_time_init(void)
+{
+       mips_hpt_frequency = ifxmips_get_cpu_hz() / ifxmips_get_counter_resolution();
+       r4k_cur = (read_c0_count() + r4k_offset);
+       write_c0_compare(r4k_cur);
+
+       ifxmips_pmu_enable(IFXMIPS_PMU_PWDCR_GPT | IFXMIPS_PMU_PWDCR_FPI);
+       ifxmips_w32(0x100, IFXMIPS_GPTU_GPT_CLC); // set clock divider to 1
+}
+
+void __init
+plat_mem_setup(void)
+{
+       u32 status;
+       prom_printf("This %s has a cpu rev of 0x%X\n", get_system_type(), ifxmips_get_cpu_ver());
+
+       status = read_c0_status();
+       status &= (~(1<<25));
+       write_c0_status(status);
+
+       ifxmips_reboot_setup();
+
+       ioport_resource.start = IOPORT_RESOURCE_START;
+       ioport_resource.end = IOPORT_RESOURCE_END;
+       iomem_resource.start = IOMEM_RESOURCE_START;
+       iomem_resource.end = IOMEM_RESOURCE_END;
+}
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/timer.c b/target/linux/ifxmips/files/arch/mips/ifxmips/timer.c
new file mode 100644 (file)
index 0000000..738f420
--- /dev/null
@@ -0,0 +1,844 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+#include <asm/ifxmips/ifxmips_cgu.h>
+#include <asm/ifxmips/ifxmips_gptu.h>
+#include <asm/ifxmips/ifxmips_pmu.h>
+
+#define MAX_NUM_OF_32BIT_TIMER_BLOCKS   6
+
+#ifdef TIMER1A
+#define FIRST_TIMER                   TIMER1A
+#else
+#define FIRST_TIMER                   2
+#endif
+
+/*
+ *  GPTC divider is set or not.
+ */
+#define GPTU_CLC_RMC_IS_SET             0
+
+/*
+ *  Timer Interrupt (IRQ)
+ */
+#define TIMER_INTERRUPT                 INT_NUM_IM3_IRL0 + 22  //  Must be adjusted when ICU driver is available
+
+/*
+ *  Bits Operation
+ */
+#define GET_BITS(x, msb, lsb)           (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
+#define SET_BITS(x, msb, lsb, value)    (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
+
+/*
+ *  GPTU Register Mapping
+ */
+#define IFXMIPS_GPTU                     (KSEG1 + 0x1E100A00)
+#define IFXMIPS_GPTU_CLC                 ((volatile u32*)(IFXMIPS_GPTU + 0x0000))
+#define IFXMIPS_GPTU_ID                  ((volatile u32*)(IFXMIPS_GPTU + 0x0008))
+#define IFXMIPS_GPTU_CON(n, X)           ((volatile u32*)(IFXMIPS_GPTU + 0x0010 + ((X) * 4) + ((n) - 1) * 0x0020))     //  X must be either A or B
+#define IFXMIPS_GPTU_RUN(n, X)           ((volatile u32*)(IFXMIPS_GPTU + 0x0018 + ((X) * 4) + ((n) - 1) * 0x0020))     //  X must be either A or B
+#define IFXMIPS_GPTU_RELOAD(n, X)        ((volatile u32*)(IFXMIPS_GPTU + 0x0020 + ((X) * 4) + ((n) - 1) * 0x0020))     //  X must be either A or B
+#define IFXMIPS_GPTU_COUNT(n, X)         ((volatile u32*)(IFXMIPS_GPTU + 0x0028 + ((X) * 4) + ((n) - 1) * 0x0020))     //  X must be either A or B
+#define IFXMIPS_GPTU_IRNEN               ((volatile u32*)(IFXMIPS_GPTU + 0x00F4))
+#define IFXMIPS_GPTU_IRNICR              ((volatile u32*)(IFXMIPS_GPTU + 0x00F8))
+#define IFXMIPS_GPTU_IRNCR               ((volatile u32*)(IFXMIPS_GPTU + 0x00FC))
+
+/*
+ *  Clock Control Register
+ */
+#define GPTU_CLC_SMC                    GET_BITS(*IFXMIPS_GPTU_CLC, 23, 16)
+#define GPTU_CLC_RMC                    GET_BITS(*IFXMIPS_GPTU_CLC, 15, 8)
+#define GPTU_CLC_FSOE                   (*IFXMIPS_GPTU_CLC & (1 << 5))
+#define GPTU_CLC_EDIS                   (*IFXMIPS_GPTU_CLC & (1 << 3))
+#define GPTU_CLC_SPEN                   (*IFXMIPS_GPTU_CLC & (1 << 2))
+#define GPTU_CLC_DISS                   (*IFXMIPS_GPTU_CLC & (1 << 1))
+#define GPTU_CLC_DISR                   (*IFXMIPS_GPTU_CLC & (1 << 0))
+
+#define GPTU_CLC_SMC_SET(value)         SET_BITS(0, 23, 16, (value))
+#define GPTU_CLC_RMC_SET(value)         SET_BITS(0, 15, 8, (value))
+#define GPTU_CLC_FSOE_SET(value)        ((value) ? (1 << 5) : 0)
+#define GPTU_CLC_SBWE_SET(value)        ((value) ? (1 << 4) : 0)
+#define GPTU_CLC_EDIS_SET(value)        ((value) ? (1 << 3) : 0)
+#define GPTU_CLC_SPEN_SET(value)        ((value) ? (1 << 2) : 0)
+#define GPTU_CLC_DISR_SET(value)        ((value) ? (1 << 0) : 0)
+
+/*
+ *  ID Register
+ */
+#define GPTU_ID_ID                      GET_BITS(*IFXMIPS_GPTU_ID, 15, 8)
+#define GPTU_ID_CFG                     GET_BITS(*IFXMIPS_GPTU_ID, 7, 5)
+#define GPTU_ID_REV                     GET_BITS(*IFXMIPS_GPTU_ID, 4, 0)
+
+/*
+ *  Control Register of Timer/Counter nX
+ *    n is the index of block (1 based index)
+ *    X is either A or B
+ */
+#define GPTU_CON_SRC_EG(n, X)           (*IFXMIPS_GPTU_CON(n, X) & (1 << 10))
+#define GPTU_CON_SRC_EXT(n, X)          (*IFXMIPS_GPTU_CON(n, X) & (1 << 9))
+#define GPTU_CON_SYNC(n, X)             (*IFXMIPS_GPTU_CON(n, X) & (1 << 8))
+#define GPTU_CON_EDGE(n, X)             GET_BITS(*IFXMIPS_GPTU_CON(n, X), 7, 6)
+#define GPTU_CON_INV(n, X)              (*IFXMIPS_GPTU_CON(n, X) & (1 << 5))
+#define GPTU_CON_EXT(n, X)              (*IFXMIPS_GPTU_CON(n, A) & (1 << 4))   //  Timer/Counter B does not have this bit
+#define GPTU_CON_STP(n, X)              (*IFXMIPS_GPTU_CON(n, X) & (1 << 3))
+#define GPTU_CON_CNT(n, X)              (*IFXMIPS_GPTU_CON(n, X) & (1 << 2))
+#define GPTU_CON_DIR(n, X)              (*IFXMIPS_GPTU_CON(n, X) & (1 << 1))
+#define GPTU_CON_EN(n, X)               (*IFXMIPS_GPTU_CON(n, X) & (1 << 0))
+
+#define GPTU_CON_SRC_EG_SET(value)      ((value) ? 0 : (1 << 10))
+#define GPTU_CON_SRC_EXT_SET(value)     ((value) ? (1 << 9) : 0)
+#define GPTU_CON_SYNC_SET(value)        ((value) ? (1 << 8) : 0)
+#define GPTU_CON_EDGE_SET(value)        SET_BITS(0, 7, 6, (value))
+#define GPTU_CON_INV_SET(value)         ((value) ? (1 << 5) : 0)
+#define GPTU_CON_EXT_SET(value)         ((value) ? (1 << 4) : 0)
+#define GPTU_CON_STP_SET(value)         ((value) ? (1 << 3) : 0)
+#define GPTU_CON_CNT_SET(value)         ((value) ? (1 << 2) : 0)
+#define GPTU_CON_DIR_SET(value)         ((value) ? (1 << 1) : 0)
+
+#define GPTU_RUN_RL_SET(value)          ((value) ? (1 << 2) : 0)
+#define GPTU_RUN_CEN_SET(value)         ((value) ? (1 << 1) : 0)
+#define GPTU_RUN_SEN_SET(value)         ((value) ? (1 << 0) : 0)
+
+#define GPTU_IRNEN_TC_SET(n, X, value)  ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
+#define GPTU_IRNCR_TC_SET(n, X, value)  ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
+
+#define TIMER_FLAG_MASK_SIZE(x)         (x & 0x0001)
+#define TIMER_FLAG_MASK_TYPE(x)         (x & 0x0002)
+#define TIMER_FLAG_MASK_STOP(x)         (x & 0x0004)
+#define TIMER_FLAG_MASK_DIR(x)          (x & 0x0008)
+#define TIMER_FLAG_NONE_EDGE            0x0000
+#define TIMER_FLAG_MASK_EDGE(x)         (x & 0x0030)
+#define TIMER_FLAG_REAL                 0x0000
+#define TIMER_FLAG_INVERT               0x0040
+#define TIMER_FLAG_MASK_INVERT(x)       (x & 0x0040)
+#define TIMER_FLAG_MASK_TRIGGER(x)      (x & 0x0070)
+#define TIMER_FLAG_MASK_SYNC(x)         (x & 0x0080)
+#define TIMER_FLAG_CALLBACK_IN_HB       0x0200
+#define TIMER_FLAG_MASK_HANDLE(x)       (x & 0x0300)
+#define TIMER_FLAG_MASK_SRC(x)          (x & 0x1000)
+
+struct timer_dev_timer {
+       unsigned int f_irq_on;
+       unsigned int irq;
+       unsigned int flag;
+       unsigned long arg1;
+       unsigned long arg2;
+};
+
+struct timer_dev {
+       struct mutex gptu_mutex;
+       unsigned int number_of_timers;
+       unsigned int occupation;
+       unsigned int f_gptu_on;
+       struct timer_dev_timer timer[MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2];
+};
+
+static int gptu_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+static int gptu_open(struct inode *, struct file *);
+static int gptu_release(struct inode *, struct file *);
+
+static struct file_operations gptu_fops = {
+       .owner = THIS_MODULE,
+       .ioctl = gptu_ioctl,
+       .open = gptu_open,
+       .release = gptu_release
+};
+
+static struct miscdevice gptu_miscdev = {
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "gptu",
+       .fops = &gptu_fops,
+};
+
+static struct timer_dev timer_dev;
+
+
+static irqreturn_t
+timer_irq_handler(int irq, void *p)
+{
+       unsigned int timer;
+       unsigned int flag;
+       struct timer_dev_timer *dev_timer = (struct timer_dev_timer*) p;
+
+       timer = irq - TIMER_INTERRUPT;
+       if(timer < timer_dev.number_of_timers && dev_timer == &timer_dev.timer[timer])
+       {
+               /*  Clear interrupt.    */
+               ifxmips_w32(1 << timer, IFXMIPS_GPTU_IRNCR);
+
+               /*  Call user hanler or signal. */
+               flag = dev_timer->flag;
+               if (!(timer & 0x01) || TIMER_FLAG_MASK_SIZE (flag) == TIMER_FLAG_16BIT)
+               {       /* 16-bit timer or timer A of 32-bit timer  */
+                       switch(TIMER_FLAG_MASK_HANDLE (flag))
+                       {
+                       case TIMER_FLAG_CALLBACK_IN_IRQ:
+                       case TIMER_FLAG_CALLBACK_IN_HB:
+                               if (dev_timer->arg1)
+                                       (*(timer_callback) dev_timer->arg1) (dev_timer->arg2);
+                               break;
+                       case TIMER_FLAG_SIGNAL:
+                               send_sig ((int) dev_timer->arg2, (struct task_struct *) dev_timer->arg1, 0);
+                               break;
+                       }
+               }
+       }
+       return IRQ_HANDLED;
+}
+
+static inline void
+ifxmips_enable_gptu(void)
+{
+       ifxmips_pmu_enable(IFXMIPS_PMU_PWDCR_GPT);
+
+       /*  Set divider as 1, disable write protection for SPEN, enable module. */
+       *IFXMIPS_GPTU_CLC =
+               GPTU_CLC_SMC_SET(0x00) | GPTU_CLC_RMC_SET(0x01) | GPTU_CLC_FSOE_SET(0) |
+               GPTU_CLC_SBWE_SET(1) | GPTU_CLC_EDIS_SET(0) | GPTU_CLC_SPEN_SET(0) | GPTU_CLC_DISR_SET(0);
+}
+
+static inline void
+ifxmips_disable_gptu(void)
+{
+       ifxmips_w32(0x00, IFXMIPS_GPTU_IRNEN);
+       ifxmips_w32(0xfff, IFXMIPS_GPTU_IRNCR);
+
+       /*  Set divider as 0, enable write protection for SPEN, disable module. */
+       *IFXMIPS_GPTU_CLC =
+               GPTU_CLC_SMC_SET (0x00) | GPTU_CLC_RMC_SET (0x00) | GPTU_CLC_FSOE_SET (0) |
+               GPTU_CLC_SBWE_SET (0) | GPTU_CLC_EDIS_SET (0) | GPTU_CLC_SPEN_SET (0) | GPTU_CLC_DISR_SET (1);
+
+       ifxmips_pmu_disable(IFXMIPS_PMU_PWDCR_GPT);
+}
+
+int
+ifxmips_request_timer(unsigned int timer, unsigned int flag, unsigned long value,
+                                       unsigned long arg1, unsigned long arg2)
+{
+       int ret = 0;
+       unsigned int con_reg, irnen_reg;
+       int n, X;
+
+       if(timer >= FIRST_TIMER + timer_dev.number_of_timers)
+               return -EINVAL;
+
+       printk(KERN_INFO "request_timer(%d, 0x%08X, %lu)...", (u32)timer, (u32)flag, value);
+
+       if(TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT)
+               value &= 0xFFFF;
+       else
+               timer &= ~0x01;
+
+       mutex_lock(&timer_dev.gptu_mutex);
+
+       /*
+        *  Allocate timer.
+        */
+       if (timer < FIRST_TIMER) {
+               unsigned int mask;
+               unsigned int shift;
+               unsigned int offset = TIMER2A;/* This takes care of TIMER1B which is the only choice for Voice TAPI system */
+
+               /*
+                *  Pick up a free timer.
+                */
+               if (TIMER_FLAG_MASK_SIZE (flag) == TIMER_FLAG_16BIT) {
+                       mask = 1 << offset;
+                       shift = 1;
+               }
+               else {
+                       mask = 3 << offset;
+                       shift = 2;
+               }
+               for (timer = offset;
+                    timer < offset + timer_dev.number_of_timers;
+                    timer += shift, mask <<= shift)
+                       if (!(timer_dev.occupation & mask)) {
+                               timer_dev.occupation |= mask;
+                               break;
+                       }
+               if (timer >= offset + timer_dev.number_of_timers) {
+                       printk("failed![%d]\n", __LINE__);
+                       mutex_unlock(&timer_dev.gptu_mutex);
+                       return -EINVAL;
+               }
+               else
+                       ret = timer;
+       }
+       else {
+               register unsigned int mask;
+
+               /*
+                *  Check if the requested timer is free.
+                */
+               mask = (TIMER_FLAG_MASK_SIZE (flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
+               if ((timer_dev.occupation & mask)) {
+                       printk("failed![%d] mask %#x, timer_dev.occupation %#x\n", __LINE__, mask, timer_dev.occupation);
+                       mutex_unlock(&timer_dev.gptu_mutex);
+                       return -EBUSY;
+               }
+               else {
+                       timer_dev.occupation |= mask;
+                       ret = 0;
+               }
+       }
+
+       /*
+        *  Prepare control register value.
+        */
+       switch (TIMER_FLAG_MASK_EDGE (flag)) {
+       default:
+       case TIMER_FLAG_NONE_EDGE:
+               con_reg = GPTU_CON_EDGE_SET (0x00);
+               break;
+       case TIMER_FLAG_RISE_EDGE:
+               con_reg = GPTU_CON_EDGE_SET (0x01);
+               break;
+       case TIMER_FLAG_FALL_EDGE:
+               con_reg = GPTU_CON_EDGE_SET (0x02);
+               break;
+       case TIMER_FLAG_ANY_EDGE:
+               con_reg = GPTU_CON_EDGE_SET (0x03);
+               break;
+       }
+       if (TIMER_FLAG_MASK_TYPE (flag) == TIMER_FLAG_TIMER)
+               con_reg |=
+                       TIMER_FLAG_MASK_SRC (flag) ==
+                       TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET (1) :
+                       GPTU_CON_SRC_EXT_SET (0);
+       else
+               con_reg |=
+                       TIMER_FLAG_MASK_SRC (flag) ==
+                       TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET (1) :
+                       GPTU_CON_SRC_EG_SET (0);
+       con_reg |=
+               TIMER_FLAG_MASK_SYNC (flag) ==
+               TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET (0) :
+               GPTU_CON_SYNC_SET (1);
+       con_reg |=
+               TIMER_FLAG_MASK_INVERT (flag) ==
+               TIMER_FLAG_REAL ? GPTU_CON_INV_SET (0) : GPTU_CON_INV_SET (1);
+       con_reg |=
+               TIMER_FLAG_MASK_SIZE (flag) ==
+               TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET (0) :
+               GPTU_CON_EXT_SET (1);
+       con_reg |=
+               TIMER_FLAG_MASK_STOP (flag) ==
+               TIMER_FLAG_ONCE ? GPTU_CON_STP_SET (1) : GPTU_CON_STP_SET (0);
+       con_reg |=
+               TIMER_FLAG_MASK_TYPE (flag) ==
+               TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET (0) :
+               GPTU_CON_CNT_SET (1);
+       con_reg |=
+               TIMER_FLAG_MASK_DIR (flag) ==
+               TIMER_FLAG_UP ? GPTU_CON_DIR_SET (1) : GPTU_CON_DIR_SET (0);
+
+       /*
+        *  Fill up running data.
+        */
+       timer_dev.timer[timer - FIRST_TIMER].flag = flag;
+       timer_dev.timer[timer - FIRST_TIMER].arg1 = arg1;
+       timer_dev.timer[timer - FIRST_TIMER].arg2 = arg2;
+       if (TIMER_FLAG_MASK_SIZE (flag) != TIMER_FLAG_16BIT)
+               timer_dev.timer[timer - FIRST_TIMER + 1].flag = flag;
+
+       /*
+        *  Enable GPTU module.
+        */
+       if (!timer_dev.f_gptu_on) {
+               ifxmips_enable_gptu ();
+               timer_dev.f_gptu_on = 1;
+       }
+
+       /*
+        *  Enable IRQ.
+        */
+       if (TIMER_FLAG_MASK_HANDLE (flag) != TIMER_FLAG_NO_HANDLE) {
+               if (TIMER_FLAG_MASK_HANDLE (flag) == TIMER_FLAG_SIGNAL)
+                       timer_dev.timer[timer - FIRST_TIMER].arg1 =
+                               (unsigned long) find_task_by_pid ((int) arg1);
+
+               irnen_reg = 1 << (timer - FIRST_TIMER);
+
+               if (TIMER_FLAG_MASK_HANDLE (flag) == TIMER_FLAG_SIGNAL
+                   || (TIMER_FLAG_MASK_HANDLE (flag) ==
+                       TIMER_FLAG_CALLBACK_IN_IRQ
+                       && timer_dev.timer[timer - FIRST_TIMER].arg1)) {
+                       enable_irq (timer_dev.timer[timer - FIRST_TIMER].irq);
+                       timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 1;
+               }
+       }
+       else
+               irnen_reg = 0;
+
+       /*
+        *  Write config register, reload value and enable interrupt.
+        */
+       n = timer >> 1;
+       X = timer & 0x01;
+       *IFXMIPS_GPTU_CON (n, X) = con_reg;
+       *IFXMIPS_GPTU_RELOAD (n, X) = value;
+//    printk("reload value = %d\n", (u32)value);
+       *IFXMIPS_GPTU_IRNEN |= irnen_reg;
+
+       mutex_unlock(&timer_dev.gptu_mutex);
+       printk("successful!\n");
+       return ret;
+}
+
+int
+ifxmips_free_timer(unsigned int timer)
+{
+       unsigned int flag;
+       unsigned int mask;
+       int n, X;
+
+       if(!timer_dev.f_gptu_on)
+               return -EINVAL;
+
+       if(timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
+               return -EINVAL;
+
+       mutex_lock(&timer_dev.gptu_mutex);
+
+       flag = timer_dev.timer[timer - FIRST_TIMER].flag;
+       if(TIMER_FLAG_MASK_SIZE (flag) != TIMER_FLAG_16BIT)
+               timer &= ~0x01;
+
+       mask = (TIMER_FLAG_MASK_SIZE (flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
+       if(((timer_dev.occupation & mask) ^ mask))
+       {
+               mutex_unlock(&timer_dev.gptu_mutex);
+               return -EINVAL;
+       }
+
+       n = timer >> 1;
+       X = timer & 0x01;
+
+       if(GPTU_CON_EN (n, X))
+               *IFXMIPS_GPTU_RUN (n, X) = GPTU_RUN_CEN_SET (1);
+
+       *IFXMIPS_GPTU_IRNEN &= ~GPTU_IRNEN_TC_SET (n, X, 1);
+       *IFXMIPS_GPTU_IRNCR |= GPTU_IRNCR_TC_SET (n, X, 1);
+
+       if(timer_dev.timer[timer - FIRST_TIMER].f_irq_on) {
+               disable_irq (timer_dev.timer[timer - FIRST_TIMER].irq);
+               timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 0;
+       }
+
+       timer_dev.occupation &= ~mask;
+       if(!timer_dev.occupation && timer_dev.f_gptu_on)
+       {
+               ifxmips_disable_gptu();
+               timer_dev.f_gptu_on = 0;
+       }
+
+       mutex_unlock(&timer_dev.gptu_mutex);
+
+       return 0;
+}
+
+int
+ifxmips_start_timer(unsigned int timer, int is_resume)
+{
+       unsigned int flag;
+       unsigned int mask;
+       int n, X;
+
+       if(!timer_dev.f_gptu_on)
+               return -EINVAL;
+
+       if(timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
+               return -EINVAL;
+
+       mutex_lock(&timer_dev.gptu_mutex);
+
+       flag = timer_dev.timer[timer - FIRST_TIMER].flag;
+       if(TIMER_FLAG_MASK_SIZE (flag) != TIMER_FLAG_16BIT)
+               timer &= ~0x01;
+
+       mask = (TIMER_FLAG_MASK_SIZE (flag) ==
+       TIMER_FLAG_16BIT ? 1 : 3) << timer;
+       if(((timer_dev.occupation & mask) ^ mask))
+       {
+               mutex_unlock(&timer_dev.gptu_mutex);
+               return -EINVAL;
+       }
+
+       n = timer >> 1;
+       X = timer & 0x01;
+
+       *IFXMIPS_GPTU_RUN (n, X) = GPTU_RUN_RL_SET (!is_resume) | GPTU_RUN_SEN_SET (1);
+
+       mutex_unlock(&timer_dev.gptu_mutex);
+
+       return 0;
+}
+
+int
+ifxmips_stop_timer(unsigned int timer)
+{
+       unsigned int flag;
+       unsigned int mask;
+       int n, X;
+
+       if (!timer_dev.f_gptu_on)
+               return -EINVAL;
+
+       if (timer < FIRST_TIMER
+           || timer >= FIRST_TIMER + timer_dev.number_of_timers)
+               return -EINVAL;
+
+       mutex_lock(&timer_dev.gptu_mutex);
+
+       flag = timer_dev.timer[timer - FIRST_TIMER].flag;
+       if(TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
+               timer &= ~0x01;
+
+       mask = (TIMER_FLAG_MASK_SIZE (flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
+       if(((timer_dev.occupation & mask) ^ mask))
+       {
+               mutex_unlock(&timer_dev.gptu_mutex);
+               return -EINVAL;
+       }
+
+       n = timer >> 1;
+       X = timer & 0x01;
+
+       *IFXMIPS_GPTU_RUN (n, X) = GPTU_RUN_CEN_SET (1);
+
+       mutex_unlock(&timer_dev.gptu_mutex);
+
+       return 0;
+}
+
+int
+ifxmips_reset_counter_flags(u32 timer, u32 flags)
+{
+       unsigned int oflag;
+       unsigned int mask, con_reg;
+       int n, X;
+
+       if(!timer_dev.f_gptu_on)
+               return -EINVAL;
+
+       if(timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
+               return -EINVAL;
+
+       mutex_lock(&timer_dev.gptu_mutex);
+
+       oflag = timer_dev.timer[timer - FIRST_TIMER].flag;
+       if(TIMER_FLAG_MASK_SIZE (oflag) != TIMER_FLAG_16BIT)
+               timer &= ~0x01;
+
+       mask = (TIMER_FLAG_MASK_SIZE (oflag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
+       if(((timer_dev.occupation & mask) ^ mask))
+       {
+               mutex_unlock(&timer_dev.gptu_mutex);
+               return -EINVAL;
+       }
+
+       switch(TIMER_FLAG_MASK_EDGE (flags))
+       {
+       default:
+       case TIMER_FLAG_NONE_EDGE:
+               con_reg = GPTU_CON_EDGE_SET(0x00);
+               break;
+       case TIMER_FLAG_RISE_EDGE:
+               con_reg = GPTU_CON_EDGE_SET(0x01);
+               break;
+       case TIMER_FLAG_FALL_EDGE:
+               con_reg = GPTU_CON_EDGE_SET(0x02);
+               break;
+       case TIMER_FLAG_ANY_EDGE:
+               con_reg = GPTU_CON_EDGE_SET(0x03);
+               break;
+       }
+       if(TIMER_FLAG_MASK_TYPE (flags) == TIMER_FLAG_TIMER)
+               con_reg |= TIMER_FLAG_MASK_SRC (flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET (1) : GPTU_CON_SRC_EXT_SET (0);
+       else
+               con_reg |= TIMER_FLAG_MASK_SRC (flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET (1) : GPTU_CON_SRC_EG_SET (0);
+       con_reg |= TIMER_FLAG_MASK_SYNC (flags) == TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET (0) : GPTU_CON_SYNC_SET (1);
+       con_reg |= TIMER_FLAG_MASK_INVERT (flags) == TIMER_FLAG_REAL ? GPTU_CON_INV_SET (0) : GPTU_CON_INV_SET (1);
+       con_reg |= TIMER_FLAG_MASK_SIZE (flags) == TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET (0) : GPTU_CON_EXT_SET (1);
+       con_reg |= TIMER_FLAG_MASK_STOP (flags) == TIMER_FLAG_ONCE ? GPTU_CON_STP_SET (1) : GPTU_CON_STP_SET (0);
+       con_reg |= TIMER_FLAG_MASK_TYPE (flags) == TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET (0) : GPTU_CON_CNT_SET (1);
+       con_reg |= TIMER_FLAG_MASK_DIR (flags) == TIMER_FLAG_UP ? GPTU_CON_DIR_SET (1) : GPTU_CON_DIR_SET (0);
+
+       timer_dev.timer[timer - FIRST_TIMER].flag = flags;
+       if(TIMER_FLAG_MASK_SIZE(flags) != TIMER_FLAG_16BIT)
+               timer_dev.timer[timer - FIRST_TIMER + 1].flag = flags;
+
+       n = timer >> 1;
+       X = timer & 0x01;
+
+       *IFXMIPS_GPTU_CON(n, X) = con_reg;
+       smp_wmb();
+       printk(KERN_INFO "[%s]: counter%d oflags %#x, nflags %#x, GPTU_CON %#x\n", __func__, timer, oflag, flags, *IFXMIPS_GPTU_CON (n, X));
+       mutex_unlock(&timer_dev.gptu_mutex);
+       return 0;
+}
+EXPORT_SYMBOL(ifxmips_reset_counter_flags);
+
+inline int
+ifxmips_get_count_value(unsigned int timer, unsigned long *value)
+{
+
+       unsigned int flag;
+       unsigned int mask;
+       int n, X;
+
+       if(!timer_dev.f_gptu_on)
+               return -EINVAL;
+
+       if(timer < FIRST_TIMER
+           || timer >= FIRST_TIMER + timer_dev.number_of_timers)
+               return -EINVAL;
+
+       mutex_lock(&timer_dev.gptu_mutex);
+
+       flag = timer_dev.timer[timer - FIRST_TIMER].flag;
+       if(TIMER_FLAG_MASK_SIZE (flag) != TIMER_FLAG_16BIT)
+               timer &= ~0x01;
+
+       mask = (TIMER_FLAG_MASK_SIZE (flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
+       if (((timer_dev.occupation & mask) ^ mask))
+       {
+               mutex_unlock(&timer_dev.gptu_mutex);
+               return -EINVAL;
+       }
+
+       n = timer >> 1;
+       X = timer & 0x01;
+
+       *value = *IFXMIPS_GPTU_COUNT (n, X);
+
+       mutex_unlock(&timer_dev.gptu_mutex);
+
+       return 0;
+}
+
+u32
+ifxmips_cal_divider(unsigned long freq)
+{
+       u64 module_freq, fpi = cgu_get_fpi_bus_clock(2);
+       u32 clock_divider = 1;
+       module_freq = fpi * 1000;
+       do_div(module_freq, clock_divider * freq);
+       return module_freq;
+}
+
+int
+ifxmips_set_timer (unsigned int timer, unsigned int freq, int is_cyclic,
+          int is_ext_src, unsigned int handle_flag, unsigned long arg1,
+          unsigned long arg2)
+{
+       unsigned long divider;
+       unsigned int flag;
+
+       divider = ifxmips_cal_divider(freq);
+       if (divider == 0)
+               return -EINVAL;
+       flag = ((divider & ~0xFFFF) ? TIMER_FLAG_32BIT : TIMER_FLAG_16BIT)
+               | (is_cyclic ? TIMER_FLAG_CYCLIC : TIMER_FLAG_ONCE)
+               | (is_ext_src ? TIMER_FLAG_EXT_SRC : TIMER_FLAG_INT_SRC)
+               | TIMER_FLAG_TIMER | TIMER_FLAG_DOWN
+               | TIMER_FLAG_MASK_HANDLE (handle_flag);
+
+       printk(KERN_INFO "set_timer(%d, %d), divider = %lu\n", timer, freq, divider);
+       return ifxmips_request_timer (timer, flag, divider, arg1, arg2);
+}
+
+int
+ifxmips_set_counter(unsigned int timer, unsigned int flag, u32 reload, unsigned long arg1, unsigned long arg2)
+{
+       printk(KERN_INFO "set_counter(%d, %#x, %d)\n", timer, flag, reload);
+       return ifxmips_request_timer(timer, flag, reload, arg1, arg2);
+}
+
+static int
+gptu_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+           unsigned long arg)
+{
+       int ret;
+       struct gptu_ioctl_param param;
+
+       if (!access_ok (VERIFY_READ, arg, sizeof (struct gptu_ioctl_param)))
+               return -EFAULT;
+       copy_from_user (&param, (void *) arg, sizeof (param));
+
+       if ((((cmd == GPTU_REQUEST_TIMER || cmd == GPTU_SET_TIMER
+              || GPTU_SET_COUNTER) && param.timer < 2)
+            || cmd == GPTU_GET_COUNT_VALUE || cmd == GPTU_CALCULATE_DIVIDER)
+           && !access_ok (VERIFY_WRITE, arg,
+                          sizeof (struct gptu_ioctl_param)))
+               return -EFAULT;
+
+       switch (cmd) {
+       case GPTU_REQUEST_TIMER:
+               ret = ifxmips_request_timer (param.timer, param.flag, param.value,
+                                    (unsigned long) param.pid,
+                                    (unsigned long) param.sig);
+               if (ret > 0) {
+                       copy_to_user (&((struct gptu_ioctl_param *) arg)->
+                                     timer, &ret, sizeof (&ret));
+                       ret = 0;
+               }
+               break;
+       case GPTU_FREE_TIMER:
+               ret = ifxmips_free_timer (param.timer);
+               break;
+       case GPTU_START_TIMER:
+               ret = ifxmips_start_timer (param.timer, param.flag);
+               break;
+       case GPTU_STOP_TIMER:
+               ret = ifxmips_stop_timer (param.timer);
+               break;
+       case GPTU_GET_COUNT_VALUE:
+               ret = ifxmips_get_count_value (param.timer, &param.value);
+               if (!ret)
+                       copy_to_user (&((struct gptu_ioctl_param *) arg)->
+                                     value, &param.value,
+                                     sizeof (param.value));
+               break;
+       case GPTU_CALCULATE_DIVIDER:
+               param.value = ifxmips_cal_divider (param.value);
+               if (param.value == 0)
+                       ret = -EINVAL;
+               else {
+                       copy_to_user (&((struct gptu_ioctl_param *) arg)->
+                                     value, &param.value,
+                                     sizeof (param.value));
+                       ret = 0;
+               }
+               break;
+       case GPTU_SET_TIMER:
+               ret = ifxmips_set_timer (param.timer, param.value,
+                                TIMER_FLAG_MASK_STOP (param.flag) !=
+                                TIMER_FLAG_ONCE ? 1 : 0,
+                                TIMER_FLAG_MASK_SRC (param.flag) ==
+                                TIMER_FLAG_EXT_SRC ? 1 : 0,
+                                TIMER_FLAG_MASK_HANDLE (param.flag) ==
+                                TIMER_FLAG_SIGNAL ? TIMER_FLAG_SIGNAL :
+                                TIMER_FLAG_NO_HANDLE,
+                                (unsigned long) param.pid,
+                                (unsigned long) param.sig);
+               if (ret > 0) {
+                       copy_to_user (&((struct gptu_ioctl_param *) arg)->
+                                     timer, &ret, sizeof (&ret));
+                       ret = 0;
+               }
+               break;
+       case GPTU_SET_COUNTER:
+               ifxmips_set_counter (param.timer, param.flag, param.value, 0, 0);
+               if (ret > 0) {
+                       copy_to_user (&((struct gptu_ioctl_param *) arg)->
+                                     timer, &ret, sizeof (&ret));
+                       ret = 0;
+               }
+               break;
+       default:
+               ret = -ENOTTY;
+       }
+
+       return ret;
+}
+
+static int
+gptu_open(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static int
+gptu_release(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+int __init
+ifxmips_gptu_init(void)
+{
+       int ret;
+       unsigned int i;
+
+       ifxmips_w32(0, IFXMIPS_GPTU_IRNEN);
+       ifxmips_w32(0xfff, IFXMIPS_GPTU_IRNCR);
+
+       memset(&timer_dev, 0, sizeof (timer_dev));
+       mutex_init(&timer_dev.gptu_mutex);
+
+       ifxmips_enable_gptu();
+       timer_dev.number_of_timers = GPTU_ID_CFG * 2;
+       ifxmips_disable_gptu ();
+       if(timer_dev.number_of_timers > MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2)
+               timer_dev.number_of_timers = MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2;
+       printk (KERN_INFO "gptu: totally %d 16-bit timers/counters\n", timer_dev.number_of_timers);
+
+       ret = misc_register(&gptu_miscdev);
+       if(ret)
+       {
+               printk(KERN_ERR "gptu: can't misc_register, get error %d\n", -ret);
+               return ret;
+       } else {
+               printk(KERN_INFO "gptu: misc_register on minor %d\n", gptu_miscdev.minor);
+       }
+
+       for(i = 0; i < timer_dev.number_of_timers; i++)
+       {
+               ret = request_irq (TIMER_INTERRUPT + i, timer_irq_handler, IRQF_TIMER, gptu_miscdev.name, &timer_dev.timer[i]);
+               if(ret)
+               {
+                       for (; i >= 0; i--)
+                               free_irq (TIMER_INTERRUPT + i, &timer_dev.timer[i]);
+                       misc_deregister(&gptu_miscdev);
+                       printk(KERN_ERR "gptu: failed in requesting irq (%d), get error %d\n", i, -ret);
+                       return ret;
+               } else {
+                       timer_dev.timer[i].irq = TIMER_INTERRUPT + i;
+                       disable_irq(timer_dev.timer[i].irq);
+                       printk(KERN_INFO "gptu: succeeded to request irq %d\n", timer_dev.timer[i].irq);
+               }
+       }
+
+       return 0;
+}
+
+void __exit
+ifxmips_gptu_exit(void)
+{
+       unsigned int i;
+
+       for(i = 0; i < timer_dev.number_of_timers; i++)
+       {
+               if(timer_dev.timer[i].f_irq_on)
+                       disable_irq (timer_dev.timer[i].irq);
+               free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
+       }
+       ifxmips_disable_gptu();
+       misc_deregister(&gptu_miscdev);
+}
+
+EXPORT_SYMBOL(ifxmips_request_timer);
+EXPORT_SYMBOL(ifxmips_free_timer);
+EXPORT_SYMBOL(ifxmips_start_timer);
+EXPORT_SYMBOL(ifxmips_stop_timer);
+EXPORT_SYMBOL(ifxmips_get_count_value);
+EXPORT_SYMBOL(ifxmips_cal_divider);
+EXPORT_SYMBOL(ifxmips_set_timer);
+EXPORT_SYMBOL(ifxmips_set_counter);
+
+module_init(ifxmips_gptu_init);
+module_exit(ifxmips_gptu_exit);
diff --git a/target/linux/ifxmips/files/arch/mips/pci/ops-ifxmips.c b/target/linux/ifxmips/files/arch/mips/pci/ops-ifxmips.c
new file mode 100644 (file)
index 0000000..e04c246
--- /dev/null
@@ -0,0 +1,120 @@
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+#include <asm/addrspace.h>
+#include <linux/vmalloc.h>
+#include <asm/ifxmips/ifxmips_ebu.h>
+
+#define IFXMIPS_PCI_CFG_BUSNUM_SHF 16
+#define IFXMIPS_PCI_CFG_DEVNUM_SHF 11
+#define IFXMIPS_PCI_CFG_FUNNUM_SHF 8
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+extern u32 ifxmips_pci_mapped_cfg;
+
+static int
+ifxmips_pci_config_access(unsigned char access_type,
+               struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data)
+{
+       unsigned long cfg_base;
+       unsigned long flags;
+
+       u32 temp;
+
+       /* IFXMips support slot from 0 to 15 */
+       /* dev_fn 0&0x68 (AD29) is ifxmips itself */
+       if ((bus->number != 0) || ((devfn & 0xf8) > 0x78)
+                       || ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68))
+               return 1;
+
+       spin_lock_irqsave(&ebu_lock, flags);
+
+       cfg_base = ifxmips_pci_mapped_cfg;
+       cfg_base |= (bus->number << IFXMIPS_PCI_CFG_BUSNUM_SHF) | (devfn <<
+                       IFXMIPS_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
+
+       /* Perform access */
+       if (access_type == PCI_ACCESS_WRITE)
+       {
+#ifdef CONFIG_SWAP_IO_SPACE
+               ifxmips_w32(swab32(*data), ((u32*)cfg_base));
+#else
+               ifxmips_w32(*data, ((u32*)cfg_base));
+#endif
+       } else {
+               *data = ifxmips_r32(((u32*)(cfg_base)));
+#ifdef CONFIG_SWAP_IO_SPACE
+               *data = swab32(*data);
+#endif
+       }
+       wmb();
+
+       /* clean possible Master abort */
+       cfg_base = (ifxmips_pci_mapped_cfg | (0x0 << IFXMIPS_PCI_CFG_FUNNUM_SHF)) + 4;
+       temp = ifxmips_r32(((u32*)(cfg_base)));
+#ifdef CONFIG_SWAP_IO_SPACE
+       temp = swab32 (temp);
+#endif
+       cfg_base = (ifxmips_pci_mapped_cfg | (0x68 << IFXMIPS_PCI_CFG_FUNNUM_SHF)) + 4;
+       ifxmips_w32(temp, ((u32*)cfg_base));
+
+       spin_unlock_irqrestore(&ebu_lock, flags);
+
+       if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
+               return 1;
+
+       return 0;
+}
+
+int
+ifxmips_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
+               int where, int size, u32 * val)
+{
+       u32 data = 0;
+
+       if (ifxmips_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       if (size == 1)
+               *val = (data >> ((where & 3) << 3)) & 0xff;
+       else if (size == 2)
+               *val = (data >> ((where & 3) << 3)) & 0xffff;
+       else
+               *val = data;
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+ifxmips_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
+               int where, int size, u32 val)
+{
+       u32 data = 0;
+
+       if (size == 4)
+       {
+               data = val;
+       } else {
+               if (ifxmips_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+
+               if (size == 1)
+                       data = (data & ~(0xff << ((where & 3) << 3))) |
+                               (val << ((where & 3) << 3));
+               else if (size == 2)
+                       data = (data & ~(0xffff << ((where & 3) << 3))) |
+                               (val << ((where & 3) << 3));
+       }
+
+       if (ifxmips_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       return PCIBIOS_SUCCESSFUL;
+}
diff --git a/target/linux/ifxmips/files/arch/mips/pci/pci-ifxmips.c b/target/linux/ifxmips/files/arch/mips/pci/pci-ifxmips.c
new file mode 100644 (file)
index 0000000..97efa37
--- /dev/null
@@ -0,0 +1,193 @@
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+#include <asm/ifxmips/ifxmips_cgu.h>
+#include <asm/addrspace.h>
+#include <linux/vmalloc.h>
+
+#define IFXMIPS_PCI_MEM_BASE    0x18000000
+#define IFXMIPS_PCI_MEM_SIZE    0x02000000
+#define IFXMIPS_PCI_IO_BASE     0x1AE00000
+#define IFXMIPS_PCI_IO_SIZE     0x00200000
+
+extern int ifxmips_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
+extern int ifxmips_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
+
+struct pci_ops ifxmips_pci_ops =
+{
+       .read = ifxmips_pci_read_config_dword,
+       .write = ifxmips_pci_write_config_dword
+};
+
+static struct resource pci_io_resource =
+{
+       .name = "io pci IO space",
+       .start = IFXMIPS_PCI_IO_BASE,
+       .end = IFXMIPS_PCI_IO_BASE + IFXMIPS_PCI_IO_SIZE - 1,
+       .flags = IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource =
+{
+       .name = "ext pci memory space",
+       .start = IFXMIPS_PCI_MEM_BASE,
+       .end = IFXMIPS_PCI_MEM_BASE + IFXMIPS_PCI_MEM_SIZE - 1,
+       .flags = IORESOURCE_MEM
+};
+
+static struct pci_controller ifxmips_pci_controller =
+{
+       .pci_ops = &ifxmips_pci_ops,
+       .mem_resource = &pci_mem_resource,
+       .mem_offset     = 0x00000000UL,
+       .io_resource = &pci_io_resource,
+       .io_offset      = 0x00000000UL,
+};
+
+u32 ifxmips_pci_mapped_cfg;
+int ifxmips_pci_external_clock = 0;
+
+static int __init
+ifxmips_pci_set_external_clk(char *str)
+{
+       printk("cgu: setting up external pci clock\n");
+       ifxmips_pci_external_clock = 1;
+       return 1;
+}
+__setup("pci_external_clk", ifxmips_pci_set_external_clk);
+
+int
+pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       u8 pin;
+
+       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+       switch(pin)
+       {
+               case 0:
+                       break;
+               case 1:
+                       //falling edge level triggered:0x4, low level:0xc, rising edge:0x2
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_EBU_PCC_CON) | 0xc, IFXMIPS_EBU_PCC_CON);
+                       ifxmips_w32(ifxmips_r32(IFXMIPS_EBU_PCC_IEN) | 0x10, IFXMIPS_EBU_PCC_IEN);
+                       break;
+               case 2:
+               case 3:
+               case 4:
+                       printk ("WARNING: interrupt pin %d not supported yet!\n", pin);
+               default:
+                       printk ("WARNING: invalid interrupt pin %d\n", pin);
+                       return 1;
+       }
+       return 0;
+}
+
+static void __init
+ifxmips_pci_startup(void)
+{
+       u32 temp_buffer;
+
+       cgu_setup_pci_clk(ifxmips_pci_external_clock);
+
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_OUT) | (1 << 5), IFXMIPS_GPIO_P1_OUT);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_OD) | (1 << 5), IFXMIPS_GPIO_P1_OD);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_DIR) | (1 << 5), IFXMIPS_GPIO_P1_DIR);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_ALTSEL1) & ~(1 << 5), IFXMIPS_GPIO_P1_ALTSEL1);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_ALTSEL0) & ~(1 << 5), IFXMIPS_GPIO_P1_ALTSEL0);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_DIR) & ~0x2000, IFXMIPS_GPIO_P1_DIR);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_DIR) | 0x4000, IFXMIPS_GPIO_P1_DIR);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_ALTSEL1) & ~0x6000, IFXMIPS_GPIO_P1_ALTSEL1);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_ALTSEL0) | 0x6000, IFXMIPS_GPIO_P1_ALTSEL0);
+       /* enable auto-switching between PCI and EBU */
+       ifxmips_w32(0xa, PCI_CR_CLK_CTRL);
+       /* busy, i.e. configuration is not done, PCI access has to be retried */
+       ifxmips_w32(ifxmips_r32(PCI_CR_PCI_MOD) & ~(1 << 24), PCI_CR_PCI_MOD);
+       wmb ();
+       /* BUS Master/IO/MEM access */
+       ifxmips_w32(ifxmips_r32(PCI_CS_STS_CMD) | 7, PCI_CS_STS_CMD);
+
+       /* enable external 2 PCI masters */
+       temp_buffer = ifxmips_r32(PCI_CR_PC_ARB);
+       temp_buffer &= (~(0xf << 16));
+       /* enable internal arbiter */
+       temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT);
+       /* enable internal PCI master reqest */
+       temp_buffer &= (~(3 << PCI_MASTER0_REQ_MASK_2BITS));
+
+       /* enable EBU reqest */
+       temp_buffer &= (~(3 << PCI_MASTER1_REQ_MASK_2BITS));
+
+       /* enable all external masters request */
+       temp_buffer &= (~(3 << PCI_MASTER2_REQ_MASK_2BITS));
+       ifxmips_w32(temp_buffer, PCI_CR_PC_ARB);
+       wmb ();
+
+       ifxmips_w32(0x18000000, PCI_CR_FCI_ADDR_MAP0);
+       ifxmips_w32(0x18400000, PCI_CR_FCI_ADDR_MAP1);
+       ifxmips_w32(0x18800000, PCI_CR_FCI_ADDR_MAP2);
+       ifxmips_w32(0x18c00000, PCI_CR_FCI_ADDR_MAP3);
+       ifxmips_w32(0x19000000, PCI_CR_FCI_ADDR_MAP4);
+       ifxmips_w32(0x19400000, PCI_CR_FCI_ADDR_MAP5);
+       ifxmips_w32(0x19800000, PCI_CR_FCI_ADDR_MAP6);
+       ifxmips_w32(0x19c00000, PCI_CR_FCI_ADDR_MAP7);
+       ifxmips_w32(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg);
+       ifxmips_w32(0x0e000008, PCI_CR_BAR11MASK);
+       ifxmips_w32(0, PCI_CR_PCI_ADDR_MAP11);
+       ifxmips_w32(0, PCI_CS_BASE_ADDR1);
+#ifdef CONFIG_SWAP_IO_SPACE
+       /* both TX and RX endian swap are enabled */
+       ifxmips_w32(ifxmips_r32(PCI_CR_PCI_EOI) | 3, PCI_CR_PCI_EOI);
+       wmb ();
+#endif
+       /*TODO: disable BAR2 & BAR3 - why was this in the origianl infineon code */
+       ifxmips_w32(ifxmips_r32(PCI_CR_BAR12MASK) | 0x80000000, PCI_CR_BAR12MASK);
+       ifxmips_w32(ifxmips_r32(PCI_CR_BAR13MASK) | 0x80000000, PCI_CR_BAR13MASK);
+       /*use 8 dw burst length */
+       ifxmips_w32(0x303, PCI_CR_FCI_BURST_LENGTH);
+       ifxmips_w32(ifxmips_r32(PCI_CR_PCI_MOD) | (1 << 24), PCI_CR_PCI_MOD);
+       wmb();
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_OUT) & ~(1 << 5), IFXMIPS_GPIO_P1_OUT);
+       wmb();
+       mdelay(1);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_GPIO_P1_OUT) | (1 << 5), IFXMIPS_GPIO_P1_OUT);
+}
+
+int __init
+pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin){
+       switch(slot)
+       {
+               case 13:
+                       /* IDSEL = AD29 --> USB Host Controller */
+                       return (INT_NUM_IM1_IRL0 + 17);
+               case 14:
+                       /* IDSEL = AD30 --> mini PCI connector */
+                       return (INT_NUM_IM0_IRL0 + 22);
+               default:
+                       printk("Warning: no IRQ found for PCI device in slot %d, pin %d\n", slot, pin);
+                       return 0;
+       }
+}
+
+int
+pcibios_init(void)
+{
+       extern int pci_probe_only;
+
+       pci_probe_only = 0;
+       printk("PCI: Probing PCI hardware on host bus 0.\n");
+       ifxmips_pci_startup ();
+       //      IFXMIPS_PCI_REG32(PCI_CR_CLK_CTRL_REG) &= (~8);
+       ifxmips_pci_mapped_cfg = (u32)ioremap_nocache(0x17000000, 0x800 * 16);
+       printk("IFXMips PCI mapped to 0x%08lX\n", (unsigned long)ifxmips_pci_mapped_cfg);
+       ifxmips_pci_controller.io_map_base = (unsigned long)ioremap(IFXMIPS_PCI_IO_BASE, IFXMIPS_PCI_IO_SIZE - 1);
+       printk("IFXMips PCI I/O mapped to 0x%08lX\n", (unsigned long)ifxmips_pci_controller.io_map_base);
+       register_pci_controller(&ifxmips_pci_controller);
+       return 0;
+}
+
+arch_initcall(pcibios_init);
diff --git a/target/linux/ifxmips/files/drivers/char/ifxmips_eeprom.c b/target/linux/ifxmips/files/drivers/char/ifxmips_eeprom.c
new file mode 100644 (file)
index 0000000..ea1303c
--- /dev/null
@@ -0,0 +1,541 @@
+/*
+ *   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 driver was originally based on the INCA-IP driver, but due to
+ *   fundamental conceptual drawbacks there has been changed a lot.
+ *
+ *   Based on INCA-IP driver Copyright (c) 2003 Gary Jennejohn <gj@denx.de>
+ *   Based on the VxWorks drivers Copyright (c) 2002, Infineon Technologies.
+ *
+ *   Copyright (C) 2006 infineon
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ *
+ */
+
+#define IFAP_EEPROM_DRV_VERSION "0.0.1"
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+#include <asm/ifxmips/ifx_ssc_defines.h>
+#include <asm/ifxmips/ifx_ssc.h>
+
+/* allow the user to set the major device number */
+static int ifxmips_eeprom_maj = 0;
+
+extern int ifx_ssc_init (void);
+extern int ifx_ssc_open (struct inode *inode, struct file *filp);
+extern int ifx_ssc_close (struct inode *inode, struct file *filp);
+extern void ifx_ssc_cleanup_module (void);
+extern int ifx_ssc_ioctl (struct inode *inode, struct file *filp,
+                         unsigned int cmd, unsigned long data);
+extern ssize_t ifx_ssc_kwrite (int port, const char *kbuf, size_t len);
+extern ssize_t ifx_ssc_kread (int port, char *kbuf, size_t len);
+
+extern int ifx_ssc_cs_low (unsigned int pin);
+extern int ifx_ssc_cs_high (unsigned int pin);
+extern int ifx_ssc_txrx (char *tx_buf, unsigned int tx_len, char *rx_buf, unsigned int rx_len);
+extern int ifx_ssc_tx (char *tx_buf, unsigned int tx_len);
+extern int ifx_ssc_rx (char *rx_buf, unsigned int rx_len);
+
+#define EEPROM_CS IFX_SSC_WHBGPOSTAT_OUT0_POS
+
+/* commands for EEPROM, x25160, x25140 */
+#define EEPROM_WREN                    ((unsigned char)0x06)
+#define EEPROM_WRDI                    ((unsigned char)0x04)
+#define EEPROM_RDSR                    ((unsigned char)0x05)
+#define EEPROM_WRSR                    ((unsigned char)0x01)
+#define EEPROM_READ                    ((unsigned char)0x03)
+#define EEPROM_WRITE                   ((unsigned char)0x02)
+#define EEPROM_PAGE_SIZE               4
+#define EEPROM_SIZE                    512
+
+static int
+eeprom_rdsr (void)
+{
+       int ret = 0;
+       unsigned char cmd = EEPROM_RDSR;
+       unsigned long flag;
+       char status;
+
+       local_irq_save(flag);
+
+       if ((ret = ifx_ssc_cs_low(EEPROM_CS)) == 0)
+               if ((ret = ifx_ssc_txrx(&cmd, 1, &status, 1)) >= 0)
+                       ret = status & 1;
+
+       ifx_ssc_cs_high(EEPROM_CS);
+       local_irq_restore(flag);
+
+       return ret;
+}
+
+void
+eeprom_wip_over (void)
+{
+       while (eeprom_rdsr())
+               printk("waiting for eeprom\n");
+}
+
+static int
+eeprom_wren (void)
+{
+       unsigned char cmd = EEPROM_WREN;
+       int ret = 0;
+       unsigned long flag;
+
+       local_irq_save(flag);
+       if ((ret = ifx_ssc_cs_low(EEPROM_CS)) == 0)
+               if ((ret = ifx_ssc_tx(&cmd, 1)) >= 0)
+                       ret = 0;
+
+       ifx_ssc_cs_high(EEPROM_CS);
+       local_irq_restore(flag);
+
+       if (!ret)
+               eeprom_wip_over();
+
+       return ret;
+}
+
+static int
+eeprom_wrsr (void)
+{
+       int ret = 0;
+       unsigned char cmd[2];
+       unsigned long flag;
+
+       cmd[0] = EEPROM_WRSR;
+       cmd[1] = 0;
+
+       if ((ret = eeprom_wren()))
+       {
+               printk ("eeprom_wren fails\n");
+               goto out1;
+       }
+
+       local_irq_save(flag);
+
+       if ((ret = ifx_ssc_cs_low(EEPROM_CS)))
+               goto out;
+
+       if ((ret = ifx_ssc_tx(cmd, 2)) < 0) {
+               ifx_ssc_cs_high(EEPROM_CS);
+               goto out;
+       }
+
+       if ((ret = ifx_ssc_cs_low(EEPROM_CS)))
+               goto out;
+
+       local_irq_restore(flag);
+       eeprom_wip_over();
+
+       return ret;
+
+out:
+       local_irq_restore (flag);
+       eeprom_wip_over ();
+
+out1:
+       return ret;
+}
+
+static int
+eeprom_read (unsigned int addr, unsigned char *buf, unsigned int len)
+{
+       int ret = 0;
+       unsigned char write_buf[2];
+       unsigned int eff = 0;
+       unsigned long flag;
+
+       while (1)
+       {
+               eeprom_wip_over();
+               eff = EEPROM_PAGE_SIZE - (addr % EEPROM_PAGE_SIZE);
+               eff = (eff < len) ? eff : len;
+               local_irq_save(flag);
+
+               if ((ret = ifx_ssc_cs_low(EEPROM_CS)) < 0)
+                       goto out;
+
+               write_buf[0] = EEPROM_READ | ((unsigned char) ((addr & 0x100) >> 5));
+               write_buf[1] = (addr & 0xff);
+
+               if ((ret = ifx_ssc_txrx (write_buf, 2, buf, eff)) != eff)
+               {
+                       printk("ssc_txrx fails %d\n", ret);
+                       ifx_ssc_cs_high (EEPROM_CS);
+                       goto out;
+               }
+
+               buf += ret;
+               len -= ret;
+               addr += ret;
+
+               if ((ret = ifx_ssc_cs_high(EEPROM_CS)))
+                       goto out;
+
+               local_irq_restore(flag);
+
+               if (len <= 0)
+                       goto out2;
+       }
+
+out:
+       local_irq_restore (flag);
+out2:
+       return ret;
+}
+
+static int
+eeprom_write (unsigned int addr, unsigned char *buf, unsigned int len)
+{
+       int ret = 0;
+       unsigned int eff = 0;
+       unsigned char write_buf[2];
+       int i;
+       unsigned char rx_buf[EEPROM_PAGE_SIZE];
+
+       while (1)
+       {
+               eeprom_wip_over();
+
+               if ((ret = eeprom_wren()))
+               {
+                       printk("eeprom_wren fails\n");
+                       goto out;
+               }
+
+               write_buf[0] = EEPROM_WRITE | ((unsigned char) ((addr & 0x100) >> 5));
+               write_buf[1] = (addr & 0xff);
+
+               eff = EEPROM_PAGE_SIZE - (addr % EEPROM_PAGE_SIZE);
+               eff = (eff < len) ? eff : len;
+
+               printk("EEPROM Write:\n");
+               for (i = 0; i < eff; i++) {
+                       printk("%2x ", buf[i]);
+                       if ((i % 16) == 15)
+                               printk("\n");
+               }
+               printk("\n");
+
+               if ((ret = ifx_ssc_cs_low(EEPROM_CS)))
+                       goto out;
+
+               if ((ret = ifx_ssc_tx (write_buf, 2)) < 0)
+               {
+                       printk("ssc_tx fails %d\n", ret);
+                       ifx_ssc_cs_high(EEPROM_CS);
+                       goto out;
+               }
+
+               if ((ret = ifx_ssc_tx (buf, eff)) != eff)
+               {
+                       printk("ssc_tx fails %d\n", ret);
+                       ifx_ssc_cs_high(EEPROM_CS);
+                       goto out;
+               }
+
+               buf += ret;
+               len -= ret;
+               addr += ret;
+
+               if ((ret = ifx_ssc_cs_high (EEPROM_CS)))
+                       goto out;
+
+               printk ("<==");
+               eeprom_read((addr - eff), rx_buf, eff);
+               for (i = 0; i < eff; i++)
+               {
+                       printk ("[%x]", rx_buf[i]);
+               }
+               printk ("\n");
+
+               if (len <= 0)
+                       break;
+       }
+
+out:
+       return ret;
+}
+
+int
+ifxmips_eeprom_open (struct inode *inode, struct file *filp)
+{
+       filp->f_pos = 0;
+       return 0;
+}
+
+int
+ifxmips_eeprom_close (struct inode *inode, struct file *filp)
+{
+       return 0;
+}
+
+int
+ifxmips_eeprom_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data)
+{
+       return 0;
+}
+
+ssize_t
+ifxmips_eeprom_read (char *buf, size_t len, unsigned int addr)
+{
+       int ret = 0;
+       unsigned int data;
+
+       printk("addr:=%d\n", addr);
+       printk("len:=%d\n", len);
+
+       if ((addr + len) > EEPROM_SIZE)
+       {
+               printk("invalid len\n");
+               addr = 0;
+               len = EEPROM_SIZE / 2;
+       }
+
+       if ((ret = ifx_ssc_open((struct inode *) 0, NULL)))
+       {
+               printk("ifxmips_eeprom_open fails\n");
+               goto out;
+       }
+
+       data = (unsigned int)IFX_SSC_MODE_RXTX;
+
+       if ((ret = ifx_ssc_ioctl((struct inode *) 0, NULL, IFX_SSC_RXTX_MODE_SET, (unsigned long) &data)))
+       {
+               printk("set RXTX mode fails\n");
+               goto out;
+       }
+
+       if ((ret = eeprom_wrsr()))
+       {
+               printk("EEPROM reset fails\n");
+               goto out;
+       }
+
+       if ((ret = eeprom_read(addr, buf, len)))
+       {
+               printk("eeprom read fails\n");
+               goto out;
+       }
+
+out:
+       if (ifx_ssc_close((struct inode *) 0, NULL))
+               printk("ifxmips_eeprom_close fails\n");
+
+       return len;
+}
+EXPORT_SYMBOL(ifxmips_eeprom_read);
+
+static ssize_t
+ifxmips_eeprom_fops_read (struct file *filp, char *ubuf, size_t len, loff_t * off)
+{
+       int ret = 0;
+       unsigned char ssc_rx_buf[EEPROM_SIZE];
+       long flag;
+
+       if (*off >= EEPROM_SIZE)
+               return 0;
+
+       if (*off + len > EEPROM_SIZE)
+               len = EEPROM_SIZE - *off;
+
+       if (len == 0)
+               return 0;
+
+       local_irq_save(flag);
+
+       if ((ret = ifxmips_eeprom_read(ssc_rx_buf, len, *off)) < 0)
+       {
+               printk("read fails, err=%x\n", ret);
+               local_irq_restore(flag);
+               return ret;
+       }
+
+       if (copy_to_user((void*)ubuf, ssc_rx_buf, ret) != 0)
+       {
+               local_irq_restore(flag);
+               ret = -EFAULT;
+       }
+
+       local_irq_restore(flag);
+       *off += len;
+
+       return len;
+}
+
+ssize_t
+ifxmips_eeprom_write (char *buf, size_t len, unsigned int addr)
+{
+       int ret = 0;
+       unsigned int data;
+
+       if ((ret = ifx_ssc_open ((struct inode *) 0, NULL)))
+       {
+               printk ("ifxmips_eeprom_open fails\n");
+               goto out;
+       }
+
+       data = (unsigned int) IFX_SSC_MODE_RXTX;
+
+       if ((ret = ifx_ssc_ioctl ((struct inode *) 0, NULL, IFX_SSC_RXTX_MODE_SET, (unsigned long) &data)))
+       {
+               printk ("set RXTX mode fails\n");
+               goto out;
+       }
+
+       if ((ret = eeprom_wrsr ())) {
+               printk ("EEPROM reset fails\n");
+               goto out;
+       }
+
+       if ((ret = eeprom_write (addr, buf, len))) {
+               printk ("eeprom write fails\n");
+               goto out;
+       }
+
+out:
+       if (ifx_ssc_close ((struct inode *) 0, NULL))
+               printk ("ifxmips_eeprom_close fails\n");
+
+       return ret;
+}
+EXPORT_SYMBOL(ifxmips_eeprom_write);
+
+static ssize_t
+ifxmips_eeprom_fops_write (struct file *filp, const char *ubuf, size_t len, loff_t * off)
+{
+       int ret = 0;
+       unsigned char ssc_tx_buf[EEPROM_SIZE];
+
+       if (*off >= EEPROM_SIZE)
+               return 0;
+
+       if (len + *off > EEPROM_SIZE)
+               len = EEPROM_SIZE - *off;
+
+       if ((ret = copy_from_user (ssc_tx_buf, ubuf, len)))
+               return EFAULT;
+
+       ret = ifxmips_eeprom_write (ssc_tx_buf, len, *off);
+
+       if (ret > 0)
+               *off = ret;
+
+       return ret;
+}
+
+loff_t
+ifxmips_eeprom_llseek (struct file * filp, loff_t off, int whence)
+{
+       loff_t newpos;
+       switch (whence) {
+       case SEEK_SET:
+               newpos = off;
+               break;
+
+       case SEEK_CUR:
+               newpos = filp->f_pos + off;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       if (newpos < 0)
+               return -EINVAL;
+
+       filp->f_pos = newpos;
+
+       return newpos;
+}
+
+static struct file_operations ifxmips_eeprom_fops = {
+      owner:THIS_MODULE,
+      llseek:ifxmips_eeprom_llseek,
+      read:ifxmips_eeprom_fops_read,
+      write:ifxmips_eeprom_fops_write,
+      ioctl:ifxmips_eeprom_ioctl,
+      open:ifxmips_eeprom_open,
+      release:ifxmips_eeprom_close,
+};
+
+int __init
+ifxmips_eeprom_init (void)
+{
+       int ret = 0;
+
+       ifxmips_eeprom_maj = register_chrdev(0, "eeprom", &ifxmips_eeprom_fops);
+
+       if (ifxmips_eeprom_maj < 0)
+       {
+               printk("failed to register eeprom device\n");
+               ret = -EINVAL;
+               
+               goto out;
+       }
+
+       printk("ifxmips_eeprom : /dev/eeprom mayor %d\n", ifxmips_eeprom_maj);
+
+out:
+       return ret;
+}
+
+void __exit
+ifxmips_eeprom_cleanup_module (void)
+{
+       /*if (unregister_chrdev (ifxmips_eeprom_maj, "eeprom")) {
+               printk ("Unable to unregister major %d for the EEPROM\n",
+                       maj);
+       }*/
+}
+
+module_exit (ifxmips_eeprom_cleanup_module);
+module_init (ifxmips_eeprom_init);
+
+MODULE_LICENSE ("GPL");
+MODULE_AUTHOR ("Peng Liu");
+MODULE_DESCRIPTION ("IFAP EEPROM driver");
+MODULE_SUPPORTED_DEVICE ("ifxmips_eeprom");
+
+
diff --git a/target/linux/ifxmips/files/drivers/char/ifxmips_mei_core.c b/target/linux/ifxmips/files/drivers/char/ifxmips_mei_core.c
new file mode 100644 (file)
index 0000000..e8787c5
--- /dev/null
@@ -0,0 +1,3658 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_mei_core.c
+** PROJECT      : Danube
+** MODULES      : MEI
+**
+** DATE         : 1 Jan 2006
+** AUTHOR       : TC Chen
+** DESCRIPTION  : MEI Driver
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Version $Date      $Author     $Comment
+   1.00.01             TC Chen     Fixed cell rate calculation issue
+                                  Fixed pvovider_id of adsl mib swapping issue
+   1.00.02             TC Chen     Added L3 Low Poewr Mode support.   
+   1.00.03             TC Chen     Fixed Clear Eoc transmit issue.
+   1.00.04  31/08/2006 TC Chen     Add ADSL Link/Data Led 
+                                  Add Dual Latency Path
+                                   Add AUTOBOOT_ENABLE_SET ioctl for autoboot 
+                                       mode enable/disable  
+                                   Fix fast path cell rate calculation
+   1.00.05  25/09/2006 TC Chen     Fix ATM QoS fail on interface 0(fast path).
+   1.00.06  02/10/2006 TC Chen     Change ifxmips_ppe_set_cell_rate to 
+                                       ifx_atm_set_cell_rate
+                                  Add ATM Led callback function
+   1.00.07  13/11/2006 TC Chen    Invert ADSL Link LED Signal
+   1.00.08  08/12/2006 TC Chen    Fix loop diagnostic warning message issue
+   1.00.09  20/12/2006 TC Chen    Workaround for USB OC interrupt which is trigegred once DSL reset
+******************************************************************************/
+
+/*
+ * ===========================================================================
+ *                           INCLUDE FILES
+ * ===========================================================================
+ */
+
+#include <asm/ifxmips/ifxmips_mei_linux.h>
+
+char IFXMIPS_MEI_VERSION[] = "1.00.09";
+
+#define IFXMIPS_MEI_CMV_EXTRA  //WINHOST debug
+#define IFX_ADSL_L3_MODE_SUPPORT       //L3 Low Power Mode Support
+#define IFX_ADSL_DUAL_LATENCY_SUPPORT
+#undef IFXMIPS_CLEAR_EOC               //clear eoc support
+
+// for ARC memory access
+#define WHILE_DELAY 20000
+#if defined(IFXMIPS_PORT_RTEMS)
+#undef IFXMIPS_DMA_DEBUG_MUTEX
+#else
+#define IFXMIPS_DMA_DEBUG_MUTEX
+#endif
+
+#define IMAGE_SWAP
+#define BOOT_SWAP
+#define HEADER_SWAP
+
+//TODO
+#undef DFE_LOOPBACK            // testing code //undefined by Henry , start to real link test.
+                   //165203:henryhsu 
+
+#ifdef DFE_LOOPBACK
+//#define DFE_MEM_TEST
+//#define DFE_PING_TEST
+#define DFE_ATM_LOOPBACK
+#endif
+
+#undef DATA_LED_ON_MODE
+#define DATA_LED_SUPPORT       // support adsl data led
+//#define DATA_LED_ADSL_FW_HANDLE // adsl data led handle by firmware
+#define CONFIG_IFXMIPS_MEI_LED // adsl led support
+
+//  Block size per BAR
+#define SDRAM_SEGMENT_SIZE     (64*1024)
+// Number of Bar registers
+#define MAX_BAR_REGISTERS      (17)
+
+#define XDATA_REGISTER         (15)
+
+#define IFXMIPS_MEI_DEVNAME "mei"
+
+#ifdef DFE_LOOPBACK
+#ifndef UINT32
+#define UINT32 unsigned long
+#endif
+#ifdef DFE_PING_TEST
+#include "dsp_xmem_arb_rand_em.h"
+#endif
+#ifdef DFE_MEM_TEST
+#include "aai_mem_test.h"
+#endif
+#ifdef DFE_ATM_LOOPBACK
+#include "aai_lpbk_dyn_rate.h"
+#endif
+#endif
+
+/************************************************************************
+ *  Function declaration
+ ************************************************************************/
+static MEI_ERROR meiDMAWrite (u32 destaddr, u32 * databuff, u32 databuffsize);
+static MEI_ERROR meiDMARead (u32 srcaddr, u32 * databuff, u32 databuffsize);
+static void meiControlModeSwitch (int mode);
+static void meiPollForDbgDone (void);
+static MEI_ERROR _meiDebugLongWordRead (u32 DEC_mode, u32 address,
+                                       u32 * data);
+static MEI_ERROR _meiDebugLongWordWrite (u32 DEC_mode, u32 address, u32 data);
+MEI_ERROR meiDebugWrite (u32 destaddr, u32 * databuff, u32 databuffsize);
+static MEI_ERROR meiDebugRead (u32 srcaddr, u32 * databuff, u32 databuffsize);
+static MEI_ERROR meiMailboxWrite (u16 * msgsrcbuffer, u16 msgsize);
+static MEI_ERROR meiDownloadBootCode (void);
+static MEI_ERROR meiHaltArc (void);
+static MEI_ERROR meiRunArc (void);
+static MEI_ERROR meiRunAdslModem (void);
+static int meiGetPage (u32 Page, u32 data, u32 MaxSize, u32 * Buffer,
+                      u32 * Dest);
+void makeCMV (u8 opcode, u8 group, u16 address, u16 index, int size,
+             u16 * data, u16 * CMVMSG);
+MEI_ERROR meiCMV (u16 * request, int reply, u16 * response);
+static void meiMailboxInterruptsDisable (void);
+static void meiMailboxInterruptsEnable (void);
+static int update_bar_register (int nTotalBar);
+static int free_image_buffer (int type);
+static int alloc_processor_memory (unsigned long size,
+                                  smmu_mem_info_t * adsl_mem_info);
+ssize_t mei_write (MEI_file_t * filp, char *buf, size_t size, loff_t * loff);
+int mei_ioctl (MEI_inode_t * ino, MEI_file_t * fil, unsigned int command,
+              unsigned long lon);
+
+#ifdef CONFIG_PROC_FS
+static int proc_read (struct file *file, char *buf, size_t nbytes,
+                     loff_t * ppos);
+static ssize_t proc_write (struct file *file, const char *buffer,
+                          size_t count, loff_t * ppos);
+#endif
+
+#ifdef CONFIG_IFXMIPS_MEI_MIB
+int mei_mib_ioctl (MEI_inode_t * ino, MEI_file_t * fil, unsigned int command,
+                  unsigned long lon);
+int mei_mib_adsl_link_up (void);
+int mei_mib_adsl_link_down (void);
+int ifxmips_mei_mib_init (void);
+int ifxmips_mei_mib_cleanup (void);
+#endif
+#if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
+static int ifxmips_mei_led_init (void);
+static int ifxmips_mei_led_cleanup (void);
+static int adsl_led_flash_task (void);
+#endif
+// for clearEoC 
+#ifdef IFXMIPS_CLEAR_EOC
+extern void ifx_push_eoc (struct sk_buff *pkt);
+#endif
+
+/************************************************************************
+ *  variable declaration
+ ************************************************************************/
+static smmu_mem_info_t adsl_mem_info[MAX_BAR_REGISTERS];
+static unsigned long image_size = 0;
+static struct timeval time_disconnect, time_showtime;
+static u16 unavailable_seconds = 0;
+#ifdef IFXMIPS_CLEAR_EOC
+static wait_queue_head_t wait_queue_hdlc_poll; ///clear eoc
+#endif
+
+static int showtime_lock_flag = 0;
+static int quiet_mode_flag = 0;
+
+int showtime = 0;
+static int major = IFXMIPS_MEI_MAJOR;
+MEI_mutex_t mei_sema;
+
+// Mei to ARC CMV count, reply count, ARC Indicator count
+static int indicator_count = 0;
+static int cmv_count = 0;
+static int reply_count = 0;
+static u16 Recent_indicator[MSG_LENGTH];
+static int reset_arc_flag = 0;
+
+// Used in interrupt handler as flags
+static int arcmsgav = 0;
+static int cmv_reply = 0;
+static int cmv_waiting = 0;
+static int modem_ready = 0;
+//  to wait for arc cmv reply, sleep on wait_queue_arcmsgav;
+static wait_queue_head_t wait_queue_arcmsgav;
+
+// CMV mailbox messages
+// ARC to MEI message
+static u16 CMV_RxMsg[MSG_LENGTH] __attribute__ ((aligned (4)));
+// MEI to ARC message
+static u16 CMV_TxMsg[MSG_LENGTH] __attribute__ ((aligned (4)));
+
+static u32 *mei_arc_swap_buff = NULL;  //  holding swap pages
+static ARC_IMG_HDR *img_hdr;
+static int arc_halt_flag = 0;
+static int nBar = 0;           // total bars to be used.
+
+static u32 loop_diagnostics_mode = 0;
+wait_queue_head_t wait_queue_loop_diagnostic;
+int loop_diagnostics_completed = 0;
+u32 adsl_mode, adsl_mode_extend;       // adsl mode : adsl/ 2/ 2+
+static int autoboot_enable_flag = 0;
+
+#ifdef IFX_ADSL_DUAL_LATENCY_SUPPORT
+static u8 bDualLatency = 0;
+#endif
+
+#ifdef IFXMIPS_CLEAR_EOC
+static u16 ceoc_read_idx = 0;
+#endif
+
+#ifdef IFX_ADSL_L3_MODE_SUPPORT
+static wait_queue_head_t wait_queue_l3;        // l3 power mode 
+static int l3_shutdown = 0;
+int get_l3_power_status (void);
+#endif
+
+#if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
+int led_status_on = 0, led_need_to_flash = 0;
+static int stop_led_module = 0;        //wakeup and clean led module
+static wait_queue_head_t wait_queue_led_polling;       // adsl led
+#endif
+
+static struct file_operations mei_operations = {
+      write : mei_write,
+      ioctl : mei_ioctl,
+};
+
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *meidir;
+static struct file_operations proc_operations = {
+      read:proc_read,
+      write:proc_write,
+};
+static reg_entry_t regs[PROC_ITEMS];   //total items to be monitored by /proc/mei
+#define NUM_OF_REG_ENTRY       (sizeof(regs)/sizeof(reg_entry_t))
+#endif //#ifdef CONFIG_PROC_FS
+
+#ifdef DFE_LOOPBACK
+unsigned char got_int = 0;
+#endif
+
+/////////////////               mei access Rd/Wr methods       ///////////////
+/**
+ * Write a value to register 
+ * This function writes a value to ifxmips register
+ * 
+ * \param      ul_address      The address to write
+ * \param      ul_data         The value to write
+ * \ingroup    Internal
+ */
+static void
+meiLongwordWrite (u32* ul_address, u32 ul_data)
+{
+       ifxmips_w32(ul_data, ul_address);
+       wmb();
+       return;
+}                              //    end of "meiLongwordWrite(..."
+
+/**
+ * Read the ifxmips register 
+ * This function read the value from ifxmips register
+ * 
+ * \param      ul_address      The address to write
+ * \param      pul_data        Pointer to the data
+ * \ingroup    Internal
+ */
+static void
+meiLongwordRead (u32* ul_address, u32 * pul_data)
+{
+       //*pul_data = *((volatile u32 *)ul_address);
+       *pul_data = ifxmips_r32(ul_address);
+       wmb();
+       return;
+}                              //    end of "meiLongwordRead(..."
+
+/**
+ * Write several DWORD datas to ARC memory via ARC DMA interface
+ * This function writes several DWORD datas to ARC memory via DMA interface.
+ * 
+ * \param      destaddr        The address to write
+ * \param      databuff        Pointer to the data buffer
+ * \param      databuffsize    Number of DWORDs to write
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiDMAWrite (u32 destaddr, u32 * databuff, u32 databuffsize)
+{
+       u32 *p = databuff;
+       u32 temp;
+       MEI_intstat_t flags;
+
+       if (destaddr & 3)
+               return MEI_FAILURE;
+
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_LOCKINT (flags);
+#endif
+
+       //printk("destaddr=%X,size=%d\n",destaddr,databuffsize);
+       //      Set the write transfer address
+       meiLongwordWrite (MEI_XFR_ADDR, destaddr);
+
+       //      Write the data pushed across DMA
+       while (databuffsize--) {
+               temp = *p;
+               if (databuff == (u32 *) CMV_TxMsg)
+                       MEI_HALF_WORD_SWAP (temp);
+               meiLongwordWrite (MEI_DATA_XFR, temp);
+               p++;
+       }                       //    end of "while(..."
+
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_UNLOCKINT (flags);
+#endif
+
+       return MEI_SUCCESS;
+
+}                              //    end of "meiDMAWrite(..."
+
+/**
+ * Read several DWORD datas from ARC memory via ARC DMA interface
+ * This function reads several DWORD datas from ARC memory via DMA interface.
+ * 
+ * \param      srcaddr         The address to read
+ * \param      databuff        Pointer to the data buffer
+ * \param      databuffsize    Number of DWORDs to read
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiDMARead (u32 srcaddr, u32 * databuff, u32 databuffsize)
+{
+       u32 *p = databuff;
+       u32 temp;
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_intstat_t flags;
+#endif
+       //printk("destaddr=%X,size=%X\n",srcaddr,databuffsize);
+       if (srcaddr & 3)
+               return MEI_FAILURE;
+
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_LOCKINT (flags);
+#endif
+
+       //      Set the read transfer address
+       meiLongwordWrite (MEI_XFR_ADDR, srcaddr);
+
+       //      Read the data popped across DMA
+       while (databuffsize--) {
+               meiLongwordRead (MEI_DATA_XFR, &temp);
+               if (databuff == (u32 *) CMV_RxMsg)      // swap half word
+                       MEI_HALF_WORD_SWAP (temp);
+               *p = temp;
+               p++;
+       }                       //    end of "while(..."
+
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_UNLOCKINT (flags);
+#endif
+
+       return MEI_SUCCESS;
+
+}                              //    end of "meiDMARead(..."
+
+/**
+ * Switch the ARC control mode
+ * This function switchs the ARC control mode to JTAG mode or MEI mode
+ * 
+ * \param      mode            The mode want to switch: JTAG_MASTER_MODE or MEI_MASTER_MODE.
+ * \ingroup    Internal
+ */
+static void
+meiControlModeSwitch (int mode)
+{
+       u32 temp = 0x0;
+       meiLongwordRead ( MEI_DBG_MASTER, &temp);
+       switch (mode) {
+       case JTAG_MASTER_MODE:
+               temp &= ~(HOST_MSTR);
+               break;
+       case MEI_MASTER_MODE:
+               temp |= (HOST_MSTR);
+               break;
+       default:
+               printk ("meiControlModeSwitch: unkonwn mode [%d]\n",
+                                mode);
+               return;
+       }
+       meiLongwordWrite (MEI_DBG_MASTER, temp);
+}
+
+/**
+ * Poll for transaction complete signal
+ * This function polls and waits for transaction complete signal.
+ * 
+ * \ingroup    Internal
+ */
+static void
+meiPollForDbgDone (void)
+{
+       u32 query = 0;
+       int i = 0;
+       while (i < WHILE_DELAY) {
+               meiLongwordRead (ARC_TO_MEI_INT, &query);
+               query &= (ARC_TO_MEI_DBG_DONE);
+               if (query)
+                       break;
+               i++;
+               if (i == WHILE_DELAY) {
+                       printk ("\n\n PollforDbg fail");
+               }
+       }
+       meiLongwordWrite ( ARC_TO_MEI_INT, ARC_TO_MEI_DBG_DONE);        // to clear this interrupt
+}                              //    end of "meiPollForDbgDone(..."
+
+/**
+ * ARC Debug Memory Access for a single DWORD reading.
+ * This function used for direct, address-based access to ARC memory.
+ * 
+ * \param      DEC_mode        ARC memory space to used
+ * \param      address         Address to read
+ * \param      data            Pointer to data
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+_meiDebugLongWordRead (u32 DEC_mode, u32 address, u32 * data)
+{
+       meiLongwordWrite ( MEI_DEBUG_DEC, DEC_mode);
+       meiLongwordWrite ( MEI_DEBUG_RAD, address);
+       meiPollForDbgDone ();
+       meiLongwordRead (MEI_DEBUG_DATA, data);
+       return MEI_SUCCESS;
+}
+
+/**
+ * ARC Debug Memory Access for a single DWORD writing.
+ * This function used for direct, address-based access to ARC memory.
+ * 
+ * \param      DEC_mode        ARC memory space to used
+ * \param      address         The address to write
+ * \param      data            The data to write
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+_meiDebugLongWordWrite (u32 DEC_mode, u32 address, u32 data)
+{
+       meiLongwordWrite (MEI_DEBUG_DEC, DEC_mode);
+       meiLongwordWrite (MEI_DEBUG_WAD, address);
+       meiLongwordWrite (MEI_DEBUG_DATA, data);
+       meiPollForDbgDone ();
+       return MEI_SUCCESS;
+}
+
+/**
+ * ARC Debug Memory Access for writing.
+ * This function used for direct, address-based access to ARC memory.
+ * 
+ * \param      destaddr        The address to ead
+ * \param      databuffer      Pointer to data
+ * \param      databuffsize    The number of DWORDs to read
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+
+MEI_ERROR
+meiDebugWrite (u32 destaddr, u32 * databuff, u32 databuffsize)
+{
+       u32 i;
+       u32 temp = 0x0;
+       u32 address = 0x0;
+       u32 *buffer = 0x0;
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_intstat_t flags;
+#endif
+
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_LOCKINT (flags);
+#endif
+
+       //      Open the debug port before DMP memory write
+       meiControlModeSwitch (MEI_MASTER_MODE);
+
+       meiLongwordWrite (MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
+
+       //      For the requested length, write the address and write the data
+       address = destaddr;
+       buffer = databuff;
+       for (i = 0; i < databuffsize; i++) {
+               temp = *buffer;
+               _meiDebugLongWordWrite (MEI_DEBUG_DEC_DMP1_MASK, address,
+                                       temp);
+               address += 4;
+               buffer++;
+       }                       //    end of "for(..."
+
+       //      Close the debug port after DMP memory write
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_UNLOCKINT (flags);
+#endif
+
+       //      Return
+       return MEI_SUCCESS;
+
+}                              //    end of "meiDebugWrite(..."
+
+/**
+ * ARC Debug Memory Access for reading.
+ * This function used for direct, address-based access to ARC memory.
+ * 
+ * \param      srcaddr         The address to read
+ * \param      databuffer      Pointer to data
+ * \param      databuffsize    The number of DWORDs to read
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiDebugRead (u32 srcaddr, u32 * databuff, u32 databuffsize)
+{
+       u32 i;
+       u32 temp = 0x0;
+       u32 address = 0x0;
+       u32 *buffer = 0x0;
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_intstat_t flags;
+#endif
+
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_LOCKINT (flags);
+#endif
+
+       //      Open the debug port before DMP memory read
+       meiControlModeSwitch (MEI_MASTER_MODE);
+
+       meiLongwordWrite (MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK);
+
+       //      For the requested length, write the address and read the data
+       address = srcaddr;
+       buffer = databuff;
+       for (i = 0; i < databuffsize; i++) {
+               _meiDebugLongWordRead (MEI_DEBUG_DEC_DMP1_MASK, address,
+                                      &temp);
+               *buffer = temp;
+               address += 4;
+               buffer++;
+       }                       //    end of "for(..."
+
+       //      Close the debug port after DMP memory read
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+
+#ifdef IFXMIPS_DMA_DEBUG_MUTEX
+       MEI_UNLOCKINT (flags);
+#endif
+
+       //      Return
+       return MEI_SUCCESS;
+
+}                              //    end of "meiDebugRead(..."
+
+/**
+ * Send a message to ARC MailBox.
+ * This function sends a message to ARC Mailbox via ARC DMA interface.
+ * 
+ * \param      msgsrcbuffer    Pointer to message.
+ * \param      msgsize         The number of words to write.
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiMailboxWrite (u16 * msgsrcbuffer, u16 msgsize)
+{
+       int i;
+       u32 arc_mailbox_status = 0x0;
+       u32 temp = 0;
+       MEI_ERROR meiMailboxError = MEI_SUCCESS;
+
+       //      Write to mailbox
+       meiMailboxError =
+               meiDMAWrite (MEI_TO_ARC_MAILBOX, (u32 *) msgsrcbuffer,
+                            msgsize / 2);
+       meiMailboxError =
+               meiDMAWrite (MEI_TO_ARC_MAILBOXR, (u32 *) (&temp), 1);
+
+       //      Notify arc that mailbox write completed
+       cmv_waiting = 1;
+       meiLongwordWrite (MEI_TO_ARC_INT, MEI_TO_ARC_MSGAV);
+
+       i = 0;
+       while (i < WHILE_DELAY) {       // wait for ARC to clear the bit
+               meiLongwordRead ( MEI_TO_ARC_INT, &arc_mailbox_status);
+               if ((arc_mailbox_status & MEI_TO_ARC_MSGAV) !=
+                   MEI_TO_ARC_MSGAV)
+                       break;
+               i++;
+               if (i == WHILE_DELAY) {
+                       printk
+                               ("\n\n MEI_TO_ARC_MSGAV not cleared by ARC");
+                       meiMailboxError = MEI_FAILURE;
+               }
+       }
+
+       //      Return
+       return meiMailboxError;
+
+}                              //    end of "meiMailboxWrite(..."
+
+/**
+ * Read a message from ARC MailBox.
+ * This function reads a message from ARC Mailbox via ARC DMA interface.
+ * 
+ * \param      msgsrcbuffer    Pointer to message.
+ * \param      msgsize         The number of words to read
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiMailboxRead (u16 * msgdestbuffer, u16 msgsize)
+{
+       MEI_ERROR meiMailboxError = MEI_SUCCESS;
+       //      Read from mailbox
+       meiMailboxError =
+               meiDMARead (ARC_TO_MEI_MAILBOX, (u32 *) msgdestbuffer,
+                           msgsize / 2);
+
+       //      Notify arc that mailbox read completed
+       meiLongwordWrite (ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV);
+
+       //      Return
+       return meiMailboxError;
+
+}                              //    end of "meiMailboxRead(..."
+
+/**
+ * Download boot pages to ARC.
+ * This function downloads boot pages to ARC.
+ * 
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiDownloadBootPages (void)
+{
+       int boot_loop;
+       int page_size;
+       u32 dest_addr;
+
+       /*
+        **     DMA the boot code page(s)
+        */
+#ifndef HEADER_SWAP
+       for (boot_loop = 1; boot_loop < le32_to_cpu (img_hdr->count);
+            boot_loop++)
+#else
+       for (boot_loop = 1; boot_loop < (img_hdr->count); boot_loop++)
+#endif
+       {
+#ifndef HEADER_SWAP
+               if (le32_to_cpu (img_hdr->page[boot_loop].p_size) & BOOT_FLAG)
+#else
+               if ((img_hdr->page[boot_loop].p_size) & BOOT_FLAG)
+#endif
+               {
+                       page_size =
+                               meiGetPage (boot_loop, GET_PROG, MAXSWAPSIZE,
+                                           mei_arc_swap_buff, &dest_addr);
+                       if (page_size > 0) {
+                               meiDMAWrite (dest_addr, mei_arc_swap_buff,
+                                            page_size);
+                       }
+               }
+#ifndef HEADER_SWAP
+               if (le32_to_cpu (img_hdr->page[boot_loop].d_size) & BOOT_FLAG)
+#else
+               if ((img_hdr->page[boot_loop].d_size) & BOOT_FLAG)
+#endif
+               {
+                       page_size =
+                               meiGetPage (boot_loop, GET_DATA, MAXSWAPSIZE,
+                                           mei_arc_swap_buff, &dest_addr);
+                       if (page_size > 0) {
+                               meiDMAWrite (dest_addr, mei_arc_swap_buff,
+                                            page_size);
+                       }
+               }
+       }
+       return MEI_SUCCESS;
+}
+
+/**
+ * Initial efuse rar.
+ **/
+static void
+mei_fuse_rar_init (void)
+{
+       u32 data = 0;
+       meiDMAWrite (IRAM0_BASE, &data, 1);
+       meiDMAWrite (IRAM0_BASE + 4, &data, 1);
+       meiDMAWrite (IRAM1_BASE, &data, 1);
+       meiDMAWrite (IRAM1_BASE + 4, &data, 1);
+       meiDMAWrite (BRAM_BASE, &data, 1);
+       meiDMAWrite (BRAM_BASE + 4, &data, 1);
+       meiDMAWrite (ADSL_DILV_BASE, &data, 1);
+       meiDMAWrite (ADSL_DILV_BASE + 4, &data, 1);
+}
+
+/**
+ * efuse rar program
+ **/
+static void
+mei_fuse_prg (void)
+{
+       u32 reg_data, fuse_value;
+       int i = 0;
+       meiLongwordRead ( IFXMIPS_RCU_RST, &reg_data);
+       while ((reg_data & 0x10000000) == 0) {
+               meiLongwordRead ( IFXMIPS_RCU_RST, &reg_data);
+               //add a watchdog
+               i++;
+               /* 0x4000 translate to  about 16 ms@111M, so should be enough */
+               if (i == 0x4000)
+                       return;
+       }
+       // STEP a: Prepare memory for external accesses
+       // Write fuse_en bit24
+       meiLongwordRead (IFXMIPS_RCU_RST, &reg_data);
+       meiLongwordWrite (IFXMIPS_RCU_RST, reg_data | (1 << 24));
+
+       mei_fuse_rar_init ();
+       for (i = 0; i < 4; i++) {
+               meiLongwordRead((u32*)(IFXMIPS_FUSE_BASE_ADDR + (i * 4)), &fuse_value);
+               switch (fuse_value & 0xF0000) {
+               case 0x80000:
+                       reg_data =
+                               ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
+                                (RX_DILV_ADDR_BIT_MASK + 0x1));
+                       meiDMAWrite (ADSL_DILV_BASE, &reg_data, 1);
+                       break;
+               case 0x90000:
+                       reg_data =
+                               ((fuse_value & RX_DILV_ADDR_BIT_MASK) |
+                                (RX_DILV_ADDR_BIT_MASK + 0x1));
+                       meiDMAWrite (ADSL_DILV_BASE + 4, &reg_data, 1);
+                       break;
+               case 0xA0000:
+                       reg_data =
+                               ((fuse_value & IRAM0_ADDR_BIT_MASK) |
+                                (IRAM0_ADDR_BIT_MASK + 0x1));
+                       meiDMAWrite (IRAM0_BASE, &reg_data, 1);
+                       break;
+               case 0xB0000:
+                       reg_data =
+                               ((fuse_value & IRAM0_ADDR_BIT_MASK) |
+                                (IRAM0_ADDR_BIT_MASK + 0x1));
+                       meiDMAWrite (IRAM0_BASE + 4, &reg_data, 1);
+                       break;
+               case 0xC0000:
+                       reg_data =
+                               ((fuse_value & IRAM1_ADDR_BIT_MASK) |
+                                (IRAM1_ADDR_BIT_MASK + 0x1));
+                       meiDMAWrite (IRAM1_BASE, &reg_data, 1);
+                       break;
+               case 0xD0000:
+                       reg_data =
+                               ((fuse_value & IRAM1_ADDR_BIT_MASK) |
+                                (IRAM1_ADDR_BIT_MASK + 0x1));
+                       meiDMAWrite (IRAM1_BASE + 4, &reg_data, 1);
+                       break;
+               case 0xE0000:
+                       reg_data =
+                               ((fuse_value & BRAM_ADDR_BIT_MASK) |
+                                (BRAM_ADDR_BIT_MASK + 0x1));
+                       meiDMAWrite (BRAM_BASE, &reg_data, 1);
+                       break;
+               case 0xF0000:
+                       reg_data =
+                               ((fuse_value & BRAM_ADDR_BIT_MASK) |
+                                (BRAM_ADDR_BIT_MASK + 0x1));
+                       meiDMAWrite (BRAM_BASE + 4, &reg_data, 1);
+                       break;
+               default:        // PPE efuse
+                       break;
+               }
+       }
+       meiLongwordRead (IFXMIPS_RCU_RST, &reg_data);
+       meiLongwordWrite (IFXMIPS_RCU_RST, reg_data & 0xF7FFFFFF);
+}
+
+/**
+ * Download boot code to ARC.
+ * This function downloads boot code to ARC.
+ * 
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiDownloadBootCode (void)
+{
+       u32 arc_debug_data = ACL_CLK_MODE_ENABLE;       //0x10
+
+       meiMailboxInterruptsDisable ();
+
+       //      Switch arc control from JTAG mode to MEI mode
+       meiControlModeSwitch (MEI_MASTER_MODE);
+       //enable ac_clk signal  
+       _meiDebugLongWordRead (MEI_DEBUG_DEC_DMP1_MASK, CRI_CCR0,
+                              &arc_debug_data);
+       arc_debug_data |= ACL_CLK_MODE_ENABLE;
+       _meiDebugLongWordWrite (MEI_DEBUG_DEC_DMP1_MASK, CRI_CCR0,
+                               arc_debug_data);
+       //Switch arc control from MEI mode to JTAG mode
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+
+       mei_fuse_prg ();        //program fuse rar
+
+       meiDownloadBootPages ();
+
+       return MEI_SUCCESS;
+
+}                              //    end of "meiDownloadBootCode(..."
+
+//#endif
+
+/**
+ * Halt the ARC.
+ * This function halts the ARC.
+ * 
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiHaltArc (void)
+{
+       u32 arc_debug_data = 0x0;
+
+       //      Switch arc control from JTAG mode to MEI mode
+       meiControlModeSwitch (MEI_MASTER_MODE);
+       _meiDebugLongWordRead (MEI_DEBUG_DEC_AUX_MASK, ARC_DEBUG,
+                              &arc_debug_data);
+       arc_debug_data |= (BIT1);
+       _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, ARC_DEBUG,
+                               arc_debug_data);
+       //      Switch arc control from MEI mode to JTAG mode
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+       arc_halt_flag = 1;
+
+       MEI_WAIT (10);
+       //      Return
+       return MEI_SUCCESS;
+
+}                              //    end of "meiHalt(..."
+
+/**
+ * Run the ARC.
+ * This function runs the ARC.
+ * 
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiRunArc (void)
+{
+       u32 arc_debug_data = 0x0;
+
+       //      Switch arc control from JTAG mode to MEI mode- write '1' to bit0
+       meiControlModeSwitch (MEI_MASTER_MODE);
+       _meiDebugLongWordRead (MEI_DEBUG_DEC_AUX_MASK, AUX_STATUS,
+                              &arc_debug_data);
+
+       //      Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared)
+       arc_debug_data &= ~(BIT25);
+       _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, AUX_STATUS,
+                               arc_debug_data);
+
+       //      Switch arc control from MEI mode to JTAG mode- write '0' to bit0
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+       //      Enable mask for arc codeswap interrupts
+       meiMailboxInterruptsEnable ();
+       arc_halt_flag = 0;
+
+       //      Return
+       return MEI_SUCCESS;
+
+}                              //    end of "meiActivate(..."
+
+/**
+ * Reset the ARC.
+ * This function resets the ARC.
+ * 
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiResetARC (void)
+{
+
+       u32 arc_debug_data = 0;
+       showtime = 0;
+
+       meiHaltArc ();
+
+       meiLongwordRead (IFXMIPS_RCU_RST, &arc_debug_data);
+       meiLongwordWrite (IFXMIPS_RCU_RST,
+                         arc_debug_data | IFXMIPS_RCU_RST_REQ_DFE |
+                         IFXMIPS_RCU_RST_REQ_AFE);
+       meiLongwordWrite (IFXMIPS_RCU_RST, arc_debug_data);
+       // reset ARC
+       meiLongwordWrite(MEI_RST_CONTROL, MEI_SOFT_RESET);
+       meiLongwordWrite(MEI_RST_CONTROL, 0);
+
+       meiMailboxInterruptsDisable ();
+       MEI_MUTEX_INIT (mei_sema, 1);
+       reset_arc_flag = 1;
+       modem_ready = 0;
+       return MEI_SUCCESS;
+}
+
+/**
+ * Reset the ARC, download boot codes, and run the ARC.
+ * This function resets the ARC, downloads boot codes to ARC, and runs the ARC.
+ * 
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+static MEI_ERROR
+meiRunAdslModem (void)
+{
+       int nSize = 0, idx = 0;
+
+       img_hdr = (ARC_IMG_HDR *) adsl_mem_info[0].address;
+#if    defined(HEADER_SWAP)
+       if ((img_hdr->count) * sizeof (ARC_SWP_PAGE_HDR) > SDRAM_SEGMENT_SIZE)
+#else //define(HEADER_SWAP)
+       if (le32_to_cpu (img_hdr->count) * sizeof (ARC_SWP_PAGE_HDR) >
+           SDRAM_SEGMENT_SIZE)
+#endif //define(HEADER_SWAP)
+       {
+               printk
+                       ("segment_size is smaller than firmware header size\n");
+               return -1;
+       }
+       // check image size 
+       for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
+               nSize += adsl_mem_info[idx].nCopy;
+       }
+       if (nSize != image_size) {
+               printk
+                       ("Firmware download is not completed. \nPlease download firmware again!\n");
+               return -1;
+       }
+       // TODO: check crc
+       ///
+       if (reset_arc_flag == 0) {
+               u32 arc_debug_data;
+
+               meiResetARC ();
+               meiControlModeSwitch (MEI_MASTER_MODE);
+               //enable ac_clk signal  
+               _meiDebugLongWordRead (MEI_DEBUG_DEC_DMP1_MASK, CRI_CCR0,
+                                      &arc_debug_data);
+               arc_debug_data |= ACL_CLK_MODE_ENABLE;
+               _meiDebugLongWordWrite (MEI_DEBUG_DEC_DMP1_MASK, CRI_CCR0,
+                                       arc_debug_data);
+               meiControlModeSwitch (JTAG_MASTER_MODE);
+               meiHaltArc ();
+               update_bar_register (nBar);
+       }
+       reset_arc_flag = 0;
+       if (arc_halt_flag == 0) {
+               meiHaltArc ();
+       }
+       printk ("Starting to meiDownloadBootCode\n");
+
+       meiDownloadBootCode();
+       // 1.00.09  20/12/2006 TC Chen
+       // disable USB OC interrupt, reset DSL chip will triger OC interrupt
+       disable_irq(IFXMIPS_USB_OC_INT);
+
+       meiRunArc ();
+
+       MEI_WAIT (100);         //wait 100ms 
+
+       //1.00.09  20/12/2006 TC Chen
+       // restore USB OC interrupt
+       MEI_MASK_AND_ACK_IRQ(IFXMIPS_USB_OC_INT);
+       enable_irq(IFXMIPS_USB_OC_INT);
+
+       if (modem_ready != 1) {
+               printk ("Running ADSL modem firmware fail!\n");
+               return MEI_FAILURE;
+       }
+
+
+       return MEI_SUCCESS;
+}
+
+/**
+ * Get the page's data pointer
+ * This function caculats the data address from the firmware header.
+ * 
+ * \param      Page            The page number.
+ * \param      data            Data page or program page.
+ * \param      MaxSize         The maximum size to read.
+ * \param      Buffer          Pointer to data.
+ * \param      Dest            Pointer to the destination address.
+ * \return     The number of bytes to read.
+ * \ingroup    Internal
+ */
+static int
+meiGetPage (u32 Page, u32 data, u32 MaxSize, u32 * Buffer, u32 * Dest)
+{
+       u32 size;
+       u32 i;
+       u32 *p;
+       u32 idx, offset, nBar = 0;
+
+       if (Page > img_hdr->count)
+               return -2;
+       /*
+        **     Get program or data size, depending on "data" flag
+        */
+#ifndef HEADER_SWAP
+       size = (data ==
+               GET_DATA) ? le32_to_cpu (img_hdr->page[Page].
+                                        d_size) : le32_to_cpu (img_hdr->
+                                                               page[Page].
+                                                               p_size);
+#else
+       size = (data ==
+               GET_DATA) ? (img_hdr->page[Page].d_size) : (img_hdr->
+                                                           page[Page].
+                                                           p_size);
+#endif
+       size &= BOOT_FLAG_MASK; //      Clear boot bit!
+       if (size > MaxSize)
+               return -1;
+
+       if (size == 0)
+               return 0;
+       /*
+        **     Get program or data offset, depending on "data" flag
+        */
+#ifndef HEADER_SWAP
+       i = data ? le32_to_cpu (img_hdr->page[Page].
+                               d_offset) : le32_to_cpu (img_hdr->page[Page].
+                                                        p_offset);
+#else
+       i = data ? (img_hdr->page[Page].d_offset) : (img_hdr->page[Page].
+                                                    p_offset);
+#endif
+
+       /*
+        **     Copy data/program to buffer
+        */
+
+       idx = i / SDRAM_SEGMENT_SIZE;
+       offset = i % SDRAM_SEGMENT_SIZE;
+       p = (u32 *) ((u8 *) adsl_mem_info[idx].address + offset);
+
+       for (i = 0; i < size; i++) {
+               if (offset + i * 4 - (nBar * SDRAM_SEGMENT_SIZE) >=
+                   SDRAM_SEGMENT_SIZE) {
+                       idx++;
+                       nBar++;
+                       p = (u32 *) ((u8 *)
+                                    KSEG1ADDR ((u32) adsl_mem_info[idx].
+                                               address));
+               }
+               Buffer[i] = *p++;
+#ifdef BOOT_SWAP
+#ifndef IMAGE_SWAP
+               Buffer[i] = le32_to_cpu (Buffer[i]);
+#endif
+#endif
+       }
+
+       /*
+        **     Pass back data/program destination address
+        */
+#ifndef HEADER_SWAP
+       *Dest = data ? le32_to_cpu (img_hdr->page[Page].
+                                   d_dest) : le32_to_cpu (img_hdr->
+                                                          page[Page].p_dest);
+#else
+       *Dest = data ? (img_hdr->page[Page].d_dest) : (img_hdr->page[Page].
+                                                      p_dest);
+#endif
+
+       return size;
+}
+
+////////////////makeCMV(Opcode, Group, Address, Index, Size, Data), CMV in u16 TxMessage[MSG_LENGTH]///////////////////////////
+
+/**
+ * Compose a message.
+ * This function compose a message from opcode, group, address, index, size, and data
+ * 
+ * \param      opcode          The message opcode
+ * \param      group           The message group number
+ * \param      address         The message address.
+ * \param      index           The message index.
+ * \param      size            The number of words to read/write.
+ * \param      data            The pointer to data.
+ * \param      CMVMSG          The pointer to message buffer.
+ * \ingroup    Internal
+ */
+void
+makeCMV (u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data,
+        u16 * CMVMSG)
+{
+       memset (CMVMSG, 0, MSG_LENGTH * 2);
+       CMVMSG[0] = (opcode << 4) + (size & 0xf);
+       CMVMSG[1] = (((index == 0) ? 0 : 1) << 7) + (group & 0x7f);
+       CMVMSG[2] = address;
+       CMVMSG[3] = index;
+       if (opcode == H2D_CMV_WRITE)
+               memcpy (CMVMSG + 4, data, size * 2);
+       return;
+}
+
+/**
+ * Send a message to ARC and read the response
+ * This function sends a message to arc, waits the response, and reads the responses.
+ * 
+ * \param      request         Pointer to the request
+ * \param      reply           Wait reply or not.
+ * \param      response        Pointer to the response
+ * \return     MEI_SUCCESS or MEI_FAILURE
+ * \ingroup    Internal
+ */
+MEI_ERROR
+meiCMV (u16 * request, int reply, u16 * response)      // write cmv to arc, if reply needed, wait for reply
+{
+       MEI_ERROR meierror;
+#if defined(IFXMIPS_PORT_RTEMS)
+       int delay_counter = 0;
+#endif
+
+       cmv_reply = reply;
+       memcpy (CMV_TxMsg, request, MSG_LENGTH * 2);
+       arcmsgav = 0;
+
+       meierror = meiMailboxWrite (CMV_TxMsg, MSG_LENGTH);
+
+       if (meierror != MEI_SUCCESS) {
+               cmv_waiting = 0;
+               arcmsgav = 0;
+               printk ("\n\n MailboxWrite Fail.");
+               return meierror;
+       }
+       else {
+               cmv_count++;
+       }
+
+       if (cmv_reply == NO_REPLY)
+               return MEI_SUCCESS;
+
+#if !defined(IFXMIPS_PORT_RTEMS)
+       if (arcmsgav == 0)
+               MEI_WAIT_EVENT_TIMEOUT (wait_queue_arcmsgav, CMV_TIMEOUT);
+#else
+       while (arcmsgav == 0 && delay_counter < CMV_TIMEOUT / 5) {
+               MEI_WAIT (5);
+               delay_counter++;
+       }
+#endif
+
+       cmv_waiting = 0;
+       if (arcmsgav == 0) {    //CMV_timeout
+               arcmsgav = 0;
+               printk ("\nmeiCMV: MEI_MAILBOX_TIMEOUT\n");
+               return MEI_MAILBOX_TIMEOUT;
+       }
+       else {
+               arcmsgav = 0;
+               reply_count++;
+               memcpy (response, CMV_RxMsg, MSG_LENGTH * 2);
+               return MEI_SUCCESS;
+       }
+       return MEI_SUCCESS;
+}
+
+/////////////////////          Interrupt handler     /////////////////////////
+/**
+ * Disable ARC to MEI interrupt
+ * 
+ * \ingroup    Internal
+ */
+static void
+meiMailboxInterruptsDisable (void)
+{
+       meiLongwordWrite (ARC_TO_MEI_INT_MASK, 0x0);
+}                              //    end of "meiMailboxInterruptsDisable(..."
+
+/**
+ * Eable ARC to MEI interrupt
+ * 
+ * \ingroup    Internal
+ */
+static void
+meiMailboxInterruptsEnable (void)
+{
+       meiLongwordWrite (ARC_TO_MEI_INT_MASK, MSGAV_EN);
+}                              //    end of "meiMailboxInterruptsEnable(..."
+
+/**
+ * MEI interrupt handler
+ * 
+ * \param int1 
+ * \param void0
+ * \param regs Pointer to the structure of ifxmips mips registers
+ * \ingroup    Internal
+ */
+irqreturn_t
+mei_interrupt_arcmsgav (int int1, void *void0)
+{
+       u32 scratch;
+
+#if defined(DFE_LOOPBACK) && defined(DFE_PING_TEST)
+       dfe_loopback_irq_handler ();
+       goto out;
+#endif //DFE_LOOPBACK
+
+       meiDebugRead (ARC_MEI_MAILBOXR, &scratch, 1);
+       if (scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK) {
+               printk("\n\n Receive Code Swap Request interrupt!!!");
+               goto out;
+       }
+       else if (scratch & OMB_CLEAREOC_INTERRUPT_CODE) // clear eoc message interrupt
+       {
+               meiLongwordWrite (ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV);
+#if defined (IFXMIPS_CLEAR_EOC)
+               MEI_WAKEUP_EVENT (wait_queue_hdlc_poll);
+#endif
+               MEI_MASK_AND_ACK_IRQ (IFXMIPS_MEI_INT);
+               goto out;
+       }
+       else {                  // normal message
+               meiMailboxRead (CMV_RxMsg, MSG_LENGTH);
+#if 0
+               {
+                       int msg_idx = 0;
+                       printk ("got interrupt\n");
+                       for (msg_idx = 0; msg_idx < MSG_LENGTH; msg_idx++) {
+                               printk ("%04X ", CMV_RxMsg[msg_idx]);
+                               if (msg_idx % 8 == 7)
+                                       printk ("\n");
+                       }
+                       printk ("\n");
+               }
+#endif
+               if (cmv_waiting == 1) {
+                       arcmsgav = 1;
+                       cmv_waiting = 0;
+#if !defined(IFXMIPS_PORT_RTEMS)
+                       MEI_WAKEUP_EVENT (wait_queue_arcmsgav);
+#endif
+               }
+               else {
+                       indicator_count++;
+                       memcpy ((char *) Recent_indicator, (char *) CMV_RxMsg,
+                               MSG_LENGTH * 2);
+                       if (((CMV_RxMsg[0] & 0xff0) >> 4) == D2H_AUTONOMOUS_MODEM_READY_MSG)    // arc ready
+                       {       //check ARC ready message
+                               printk ("Got MODEM_READY_MSG\n");
+                               modem_ready = 1;
+                               MEI_MUTEX_UNLOCK (mei_sema);    // allow cmv access
+                       }
+               }
+       }
+
+       MEI_MASK_AND_ACK_IRQ (IFXMIPS_MEI_INT);
+out:
+       return IRQ_HANDLED;;
+}
+
+////////////////////////hdlc ////////////////
+
+/**
+ * Get the hdlc status
+ * 
+ * \return     HDLC status
+ * \ingroup    Internal
+ */
+static unsigned int
+ifx_me_hdlc_status (void)
+{
+       u16 CMVMSG[MSG_LENGTH];
+       int ret;
+
+       if (showtime != 1)
+               return -ENETRESET;
+
+       makeCMV (H2D_CMV_READ, STAT, 14, 0, 1, NULL, CMVMSG);   //Get HDLC status 
+       ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
+                        (unsigned long) CMVMSG);
+       if (ret != 0) {
+               return -EIO;
+       }
+       return CMVMSG[4] & 0x0F;
+}
+
+/**
+ * Check if the me is reslved.
+ * 
+ * \param      status          the me status
+ * \return     ME_HDLC_UNRESOLVED or ME_HDLC_RESOLVED
+ * \ingroup    Internal
+ */
+int
+ifx_me_is_resloved (int status)
+{
+       u16 CMVMSG[MSG_LENGTH];
+       int ret;
+       if (adsl_mode <= 8 && adsl_mode_extend == 0)    // adsl mode
+       {
+               makeCMV (H2D_CMV_READ, CNTL, 2, 0, 1, NULL, CMVMSG);    //Get ME-HDLC Control
+               ret = mei_ioctl ((struct inode *) 0, NULL,
+                                IFXMIPS_MEI_CMV_WINHOST,
+                                (unsigned long) CMVMSG);
+               if (ret != 0) {
+                       return ME_HDLC_UNRESOLVED;
+               }
+               if (CMVMSG[4] & (1 << 0)) {
+                       return ME_HDLC_UNRESOLVED;
+               }
+       }
+       else {
+               if (status == ME_HDLC_MSG_QUEUED
+                   || status == ME_HDLC_MSG_SENT)
+                       return ME_HDLC_UNRESOLVED;
+               if (status == ME_HDLC_IDLE) {
+                       makeCMV (H2D_CMV_READ, CNTL, 2, 0, 1, NULL, CMVMSG);    //Get ME-HDLC Control
+                       ret = mei_ioctl ((struct inode *) 0, NULL,
+                                        IFXMIPS_MEI_CMV_WINHOST,
+                                        (unsigned long) CMVMSG);
+                       if (ret != 0) {
+                               return IFX_POP_EOC_FAIL;
+                       }
+                       if (CMVMSG[4] & (1 << 0)) {
+                               return ME_HDLC_UNRESOLVED;
+                       }
+               }
+       }
+       return ME_HDLC_RESOLVED;
+}
+
+int
+_ifx_me_hdlc_send (unsigned char *hdlc_pkt, int pkt_len, int max_length)
+{
+       int ret;
+       u16 CMVMSG[MSG_LENGTH];
+       u16 data = 0;
+       u16 len = 0;
+       int rx_length = 0;
+       int write_size = 0;
+
+       if (pkt_len > max_length) {
+               makeCMV (H2D_CMV_READ, INFO, 85, 2, 1, NULL, CMVMSG);   //Get ME-HDLC Control
+               ret = mei_ioctl ((struct inode *) 0, NULL,
+                                IFXMIPS_MEI_CMV_WINHOST,
+                                (unsigned long) CMVMSG);
+               if (ret != 0) {
+                       return -EIO;
+               }
+               rx_length = CMVMSG[4];
+               if (rx_length + max_length < pkt_len) {
+                       printk ("Exceed maximum eoc rx(%d)+tx(%d) message length\n", rx_length, max_length);
+                       return -EMSGSIZE;
+               }
+               data = 1;
+               makeCMV (H2D_CMV_WRITE, INFO, 85, 6, 1, &data, CMVMSG); //disable RX Eoc
+               ret = mei_ioctl ((struct inode *) 0, NULL,
+                                IFXMIPS_MEI_CMV_WINHOST,
+                                (unsigned long) CMVMSG);
+               if (ret != 0) {
+                       return -EIO;
+               }
+       }
+       while (len < pkt_len) {
+               write_size = pkt_len - len;
+               if (write_size > 24)
+                       write_size = 24;
+               //printk("len=%d,write_size=%d,pkt_len=%d\n",len,write_size,pkt_len);
+               memset (CMVMSG, 0, sizeof (CMVMSG));
+               makeCMV (H2D_CMV_WRITE, INFO, 81, len / 2, (write_size + 1) / 2, (u16 *) (hdlc_pkt + len), CMVMSG);     //Write clear eoc message to ARC
+               ret = mei_ioctl ((struct inode *) 0, NULL,
+                                IFXMIPS_MEI_CMV_WINHOST,
+                                (unsigned long) CMVMSG);
+               if (ret != 0) {
+                       return -EIO;
+               }
+               len += write_size;
+       }
+       makeCMV (H2D_CMV_WRITE, INFO, 83, 2, 1, &len, CMVMSG);  //Update tx message length
+       ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
+                        (unsigned long) CMVMSG);
+       if (ret != 0) {
+               return -EIO;
+       }
+
+       data = (1 << 0);
+       makeCMV (H2D_CMV_WRITE, CNTL, 2, 0, 1, &data, CMVMSG);  //Start to send
+       ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
+                        (unsigned long) CMVMSG);
+       if (ret != 0) {
+               return -EIO;
+       }
+       return 0;
+}
+
+/**
+ * Send hdlc packets
+ * 
+ * \param      hdlc_pkt        Pointer to hdlc packet
+ * \param      hdlc_pkt_len    The number of bytes to send
+ * \return     success or failure.
+ * \ingroup    Internal
+ */
+int
+ifx_me_hdlc_send (unsigned char *hdlc_pkt, int hdlc_pkt_len)
+{
+       int hdlc_status = 0;
+       u16 CMVMSG[MSG_LENGTH];
+       int max_hdlc_tx_length = 0, ret = 0, retry = 0;
+       int power_mode = 0;
+       int send_busy_counter = 0;
+       int send_retry = 0;
+
+      HDLC_SEND:
+       // retry 1000 times (10 seconds)
+       while (retry < 1000) {
+               /* In L2 power mode, do not read the OHC related parameters, 
+                  instead give the indication to the calling IOCTL, 
+                  that the readout fails (just return -EBUSY).  */
+               power_mode = get_l3_power_status();
+               if (power_mode == L2_POWER_MODE) {
+                       return -EBUSY;
+               }
+
+               hdlc_status = ifx_me_hdlc_status ();
+               if (ifx_me_is_resloved (hdlc_status) == ME_HDLC_RESOLVED)       // arc ready to send HDLC message
+               {
+                       makeCMV (H2D_CMV_READ, INFO, 83, 0, 1, NULL, CMVMSG);   //Get Maximum Allowed HDLC Tx Message Length
+                       ret = mei_ioctl ((struct inode *) 0, NULL,
+                                        IFXMIPS_MEI_CMV_WINHOST,
+                                        (unsigned long) CMVMSG);
+                       if (ret != 0) {
+                               printk
+                                       ("ifx_me_hdlc_send failed. Return -EIO");
+                               return -EIO;
+                       }
+                       max_hdlc_tx_length = CMVMSG[4];
+                       ret = _ifx_me_hdlc_send (hdlc_pkt, hdlc_pkt_len,
+                                                max_hdlc_tx_length);
+                       return ret;
+               }
+               else {
+                       if (hdlc_status == ME_HDLC_MSG_SENT)
+                               send_busy_counter++;
+               }
+               retry++;
+               MEI_WAIT (1);
+       }
+       // wait 10 seconds and FW still report busy -> reset FW HDLC status
+       if (send_busy_counter > 950 && send_retry == 0) {
+               u16 data = 0;
+               send_retry = 1;
+               retry = 0;
+               printk ("Reset FW HDLC status!!\n");
+               send_busy_counter = 0;
+               data = (1 << 1);
+               makeCMV (H2D_CMV_WRITE, CNTL, 2, 0, 1, NULL, CMVMSG);   //Force reset to idle
+               ret = mei_ioctl ((struct inode *) 0, NULL,
+                                IFXMIPS_MEI_CMV_WINHOST,
+                                (unsigned long) CMVMSG);
+               if (ret != 0) {
+                       return -EIO;
+               }
+               goto HDLC_SEND;
+       }
+       printk ("ifx_me_hdlc_send failed. Return -EBUSY");
+       return -EBUSY;
+}
+
+/**
+ * Read the hdlc packets
+ * 
+ * \param      hdlc_pkt        Pointer to hdlc packet
+ * \param      hdlc_pkt_len    The maximum number of bytes to read
+ * \return     The number of bytes which reads.
+ * \ingroup    Internal
+ */
+int
+ifx_mei_hdlc_read (char *hdlc_pkt, int max_hdlc_pkt_len)
+{
+       u16 CMVMSG[MSG_LENGTH];
+       int msg_read_len, ret = 0, pkt_len = 0, retry = 0;
+
+       while (retry < 10) {
+               ret = ifx_me_hdlc_status ();
+               if (ret == ME_HDLC_RESP_RCVD) {
+                       int current_size = 0;
+                       makeCMV (H2D_CMV_READ, INFO, 83, 3, 1, NULL, CMVMSG);   //Get EoC packet length
+                       ret = mei_ioctl ((MEI_inode_t *) 0, NULL,
+                                        IFXMIPS_MEI_CMV_WINHOST,
+                                        (unsigned long) CMVMSG);
+                       if (ret != 0) {
+                               return -EIO;
+                       }
+
+                       pkt_len = CMVMSG[4];
+                       if (pkt_len > max_hdlc_pkt_len) {
+                               ret = -ENOMEM;
+                               goto error;
+                       }
+                       while (current_size < pkt_len) {
+                               if (pkt_len - current_size >
+                                   (MSG_LENGTH * 2 - 8))
+                                       msg_read_len = (MSG_LENGTH * 2 - 8);
+                               else
+                                       msg_read_len =
+                                               pkt_len - (current_size);
+                               makeCMV (H2D_CMV_READ, INFO, 82, 0 + (current_size / 2), (msg_read_len + 1) / 2, NULL, CMVMSG); //Get hdlc packet
+                               ret = mei_ioctl ((MEI_inode_t *) 0, NULL,
+                                                IFXMIPS_MEI_CMV_WINHOST,
+                                                (unsigned long) CMVMSG);
+                               if (ret != 0) {
+                                       goto error;
+                               }
+                               memcpy (hdlc_pkt + current_size, &CMVMSG[4],
+                                       msg_read_len);
+                               current_size += msg_read_len;
+                       }
+                       ret = current_size;
+                       break;
+               }
+               else {
+                       ret = -ENODATA;
+               }
+
+               retry++;
+
+               MEI_WAIT (10);
+       }
+      error:
+       return ret;
+}
+
+#if defined(IFXMIPS_CLEAR_EOC)
+int
+ifx_me_ceoc_send (struct sk_buff *eoc_pkt)
+{
+       int ret, pkt_len = 0;
+       unsigned char *pkt_data_ptr;
+       int offset = 0;
+       int swap_idx = 0;
+
+       if (adsl_mode <= 8 && adsl_mode_extend == 0)    // adsl mode
+       {
+               pkt_len = eoc_pkt->len;
+
+               pkt_data_ptr = kmalloc (pkt_len + 3, GFP_KERNEL);
+
+               offset = 2;
+               pkt_data_ptr[0] = 0x4c;
+               pkt_data_ptr[1] = 0x81;
+               pkt_len += 2;
+       } else {
+               pkt_len = eoc_pkt->len + 4;
+               pkt_data_ptr = kmalloc (pkt_len + 1 + 2, GFP_KERNEL);
+               memset (pkt_data_ptr, 0, pkt_len + 1 + 2);
+               //fill clear eoc header
+               pkt_data_ptr[0] = 0x1;
+               pkt_data_ptr[1] = 0x8;
+               pkt_data_ptr[2] = 0x4c;
+               pkt_data_ptr[3] = 0x81;
+               offset = 4;
+       }
+       for (swap_idx = 0; swap_idx < (eoc_pkt->len / 2) * 2; swap_idx += 2)
+       {
+               //printk("%02X %02X ",eoc_pkt->data[swap_idx],eoc_pkt->data[swap_idx+1]);
+               pkt_data_ptr[swap_idx + offset] = eoc_pkt->data[swap_idx + 1];
+               pkt_data_ptr[swap_idx + 1 + offset] = eoc_pkt->data[swap_idx];
+       }
+       if (eoc_pkt->len % 2)
+       {
+               //printk("%02X ",eoc_pkt->data[eoc_pkt->len-1]);
+               pkt_data_ptr[eoc_pkt->len - 1 + offset] =
+                       eoc_pkt->data[eoc_pkt->len - 1];
+               pkt_data_ptr[eoc_pkt->len + offset] =
+                       eoc_pkt->data[eoc_pkt->len - 1];
+       }
+       ret = ifx_me_hdlc_send (pkt_data_ptr, pkt_len);
+
+       if (pkt_data_ptr != eoc_pkt->data)
+       {
+               kfree (pkt_data_ptr);
+       }
+       dev_kfree_skb (eoc_pkt);
+       return ret;
+}
+
+int
+get_me_ceoc_data (int pkt_len, int rx_buffer_addr, int rx_buffer_len,
+                 u8 * data_ptr1)
+{
+       int ret;
+       MEI_ERROR dma_ret;
+       u16 CMVMSG[MSG_LENGTH];
+       int read_size, aread_size;
+       int offset = 0;
+       u8 *data = NULL, *data_ptr = NULL;
+       int i, j;
+       int over_read = 0;
+
+       i = j = 0;
+
+       read_size = (pkt_len / 4) + 4;
+       offset = ceoc_read_idx % 4;
+       over_read = read_size * 4 - pkt_len - offset;
+
+       ceoc_read_idx = (ceoc_read_idx & 0xFFFFFFFC);
+
+       data = kmalloc (read_size * 4, GFP_KERNEL);
+       if (data == NULL)
+               goto error;
+       data_ptr = kmalloc (read_size * 4, GFP_KERNEL);
+       if (data_ptr == NULL)
+               goto error;
+       if (ceoc_read_idx + read_size * 4 >= rx_buffer_len) {
+               aread_size = (rx_buffer_len - ceoc_read_idx) / 4;
+       }
+       else {
+               aread_size = read_size;
+       }
+
+       //printk("aread_size = %d,ceoc_read_idx=%d,read_size=%d,offset=%d\n",aread_size,ceoc_read_idx,read_size,offset);
+       dma_ret =
+               meiDebugRead (rx_buffer_addr + ceoc_read_idx, (u32 *) (data),
+                             aread_size);
+       ceoc_read_idx += aread_size * 4;
+       if (aread_size != read_size) {
+               dma_ret =
+                       meiDebugRead (rx_buffer_addr,
+                                     (u32 *) (data) + aread_size,
+                                     read_size - aread_size);
+               ceoc_read_idx = (read_size - aread_size) * 4;
+       }
+       if (ceoc_read_idx < over_read)
+               ceoc_read_idx = rx_buffer_len + ceoc_read_idx - over_read;
+       else
+               ceoc_read_idx -= over_read;
+
+       if (offset == 0 || offset == 2) {
+               for (i = 0; i < read_size; i++) {
+                       // 3412 --> 1234
+
+                       for (j = 0; j < 4; j++) {
+                               if (i * 4 + j - offset >= 0)
+                                       data_ptr[i * 4 + j - offset] =
+                                               data[i * 4 + (3 - j)];
+                       }
+               }
+
+       }
+       else if (offset == 1) {
+               for (i = 0; i < pkt_len; i = i + 4) {
+
+                       data_ptr[i + 1] = data[i + 1];
+                       data_ptr[i] = data[i + 2];
+                       data_ptr[i + 3] = data[i + 7];
+                       data_ptr[i + 2] = data[i];
+               }
+       }
+       else if (offset == 3) {
+               for (i = 0; i < pkt_len; i = i + 4) {
+                       data_ptr[i + 1] = data[i + 7];
+                       data_ptr[i + 0] = data[i];
+                       data_ptr[i + 3] = data[i + 5];
+                       data_ptr[i + 2] = data[i + 6];
+               }
+       }
+       if (pkt_len % 2 == 1)
+               data_ptr[pkt_len - 1] = data_ptr[pkt_len];
+
+       kfree (data);
+       memcpy (data_ptr1, data_ptr, pkt_len);
+       kfree (data_ptr);
+
+       makeCMV (H2D_CMV_WRITE, INFO, 85, 3, 1, &ceoc_read_idx, CMVMSG);
+       ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
+                        (unsigned long) CMVMSG);
+       if (ret != 0) {
+               goto error;
+       }
+
+       return dma_ret;
+      error:
+       kfree (data);
+       kfree (data_ptr);
+       return -1;
+}
+
+int
+ifx_me_ceoc_receive (int ceoc_write_idx, int rx_buffer_len,
+                    struct sk_buff **eoc_pkt)
+{
+       u16 CMVMSG[MSG_LENGTH];
+       int pkt_len, ret;
+       u16 lsw_addr, msw_addr;
+       u32 rx_buffer_addr = 0;
+       MEI_ERROR dma_ret;
+
+       //printk("rx_buffer_len=%d,ceoc_read_idx=%d,ceoc_write_idx=%d\n",rx_buffer_len,ceoc_read_idx,ceoc_write_idx);
+       if (ceoc_write_idx > ceoc_read_idx) {
+               pkt_len = ceoc_write_idx - ceoc_read_idx;
+       }
+       else {
+               pkt_len = rx_buffer_len - ceoc_read_idx + ceoc_write_idx;
+       }
+       *eoc_pkt = dev_alloc_skb (pkt_len);
+       if (*eoc_pkt == NULL) {
+               printk ("Out of memory!\n");
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       makeCMV (H2D_CMV_READ, INFO, 85, 0, 1, NULL, CMVMSG);   //Get HDLC packet 
+       ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
+                        (unsigned long) CMVMSG);
+       if (ret != 0) {
+               goto error;
+       }
+       lsw_addr = CMVMSG[4];
+
+       makeCMV (H2D_CMV_READ, INFO, 85, 1, 1, NULL, CMVMSG);   //Get HDLC packet 
+       ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
+                        (unsigned long) CMVMSG);
+       if (ret != 0) {
+               goto error;
+       }
+       msw_addr = CMVMSG[4];
+       rx_buffer_addr = msw_addr << 16 | lsw_addr;
+       dma_ret =
+               get_me_ceoc_data (pkt_len, rx_buffer_addr, rx_buffer_len,
+                                 (u16 *) skb_put (*eoc_pkt, pkt_len));
+       if (dma_ret != MEI_SUCCESS) {
+               ret = -EIO;
+               goto error;
+       }
+
+       return 0;
+      error:
+       if (*eoc_pkt != NULL)
+               dev_kfree_skb (*eoc_pkt);
+       return ret;
+}
+
+int
+ifx_mei_ceoc_rx (void)
+{
+       u16 CMVMSG[MSG_LENGTH];
+       int rx_buffer_len, ret, pkt_len = 0;
+       struct sk_buff *eoc_pkt;
+       u16 ceoc_write_idx = 0;
+
+       makeCMV (H2D_CMV_READ, INFO, 85, 2, 1, NULL, CMVMSG);   //Get EoC packet length
+       ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
+                        (unsigned long) CMVMSG);
+       if (ret != 0) {
+               printk ("ioctl fail!!\n");
+       }
+       rx_buffer_len = CMVMSG[4];
+
+       makeCMV (H2D_CMV_READ, INFO, 85, 4, 1, NULL, CMVMSG);   //Get write index
+       ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST,
+                        (unsigned long) CMVMSG);
+       if (ret != 0) {
+               return -EIO;
+       }
+
+       ceoc_write_idx = CMVMSG[4];
+       ret = ifx_me_ceoc_receive (ceoc_write_idx, rx_buffer_len, &eoc_pkt);
+#if defined (CONFIG_ATM_IFXMIPS)
+       if (ret == 0) {
+               skb_pull (eoc_pkt, 2);  // skip 4c 81 header
+               ifx_push_ceoc (eoc_pkt);        //pass data to higher layer
+       }
+
+       return ret;
+#endif
+}
+
+static int
+adsl_clear_eoc_poll (void *unused)
+{
+       struct task_struct *tsk = current;
+
+       daemonize("mei_eoc_poll");
+       strcpy(tsk->comm, "mei_ceoc_poll");
+       sigfillset(&tsk->blocked);
+
+       while (1)
+       {
+               MEI_WAIT_EVENT (wait_queue_hdlc_poll);
+               if (showtime)
+                       ifx_mei_ceoc_rx();
+               }
+       return 0;
+}
+#endif //#if defined(IFXMIPS_CLEAR_EOC)
+
+#ifdef IFXMIPS_CLEAR_EOC
+static int
+ifxmips_mei_ceoc_init (void)
+{
+       kernel_thread (adsl_clear_eoc_poll, NULL,
+                      CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+       return 0;
+}
+#endif
+
+//////////////////////  Driver Structure        ///////////////////////
+
+/**
+ * Free the memory for ARC firmware
+ * 
+ * \param      type    Free all memory or free the unused memory after showtime
+ * \ingroup    Internal
+ */
+static int
+free_image_buffer (int type)
+{
+       int idx = 0;
+       for (idx = 0; idx < MAX_BAR_REGISTERS; idx++) {
+               printk ("meminfo[%d].type=%d,size=%ld,addr=%X\n", idx,
+                                adsl_mem_info[idx].type, adsl_mem_info[idx].size,
+                                (unsigned int)adsl_mem_info[idx].address);
+               if (type == FREE_ALL || adsl_mem_info[idx].type == type) {
+                       if (adsl_mem_info[idx].size > 0) {
+                               kfree (adsl_mem_info[idx].org_address);
+                               adsl_mem_info[idx].address = 0;
+                               adsl_mem_info[idx].size = 0;
+                               adsl_mem_info[idx].type = 0;
+                               adsl_mem_info[idx].nCopy = 0;
+                       }
+               }
+       }
+       return 0;
+}
+
+/**
+ * Allocate memory for ARC firmware
+ * 
+ * \param      size            The number of bytes to allocate.
+ * \param      adsl_mem_info   Pointer to firmware information.
+ * \ingroup    Internal
+ */
+static int
+alloc_processor_memory (unsigned long size, smmu_mem_info_t * adsl_mem_info)
+{
+       char *mem_ptr = NULL;
+       char *org_mem_ptr = NULL;
+       int idx = 0;
+       long total_size = 0;
+       long img_size = size;
+       int err = 0;
+
+       // Alloc Swap Pages
+       while (img_size > 0 && idx < MAX_BAR_REGISTERS) {
+               // skip bar15 for XDATA usage.
+#ifndef DFE_LOOPBACK
+               if (idx == XDATA_REGISTER)
+                       idx++;
+#endif
+               if (idx == MAX_BAR_REGISTERS - 1)
+               {
+                       //allocate 1MB memory for bar16
+                       org_mem_ptr = kmalloc (1024 * 1024, GFP_ATOMIC);
+                       mem_ptr = (char*)((unsigned long) (org_mem_ptr +  1023) & 0xFFFFFC00);
+                       adsl_mem_info[idx].size = 1024 * 1024;
+               } else {
+                       org_mem_ptr = kmalloc (SDRAM_SEGMENT_SIZE, GFP_ATOMIC);
+                       mem_ptr = (char*)((unsigned long) (org_mem_ptr + 1023) & 0xFFFFFC00);
+                       adsl_mem_info[idx].size = SDRAM_SEGMENT_SIZE;
+               }
+               if (org_mem_ptr == NULL)
+               {
+                       printk ("kmalloc memory fail!\n");
+                       err = -ENOMEM;
+                       goto allocate_error;
+               }
+               adsl_mem_info[idx].address = mem_ptr;
+               adsl_mem_info[idx].org_address = org_mem_ptr;
+
+               img_size -= SDRAM_SEGMENT_SIZE;
+               total_size += SDRAM_SEGMENT_SIZE;
+               printk("alloc memory idx=%d,img_size=%ld,addr=%X\n",
+                               idx, img_size, (unsigned int)adsl_mem_info[idx].address);
+               idx++;
+       }
+       if (img_size > 0)
+       {
+               printk ("Image size is too large!\n");
+               err = -EFBIG;
+               goto allocate_error;
+       }
+       err = idx;
+       return err;
+
+      allocate_error:
+       free_image_buffer (FREE_ALL);
+       return err;
+}
+
+/**
+ * Program the BAR registers
+ * 
+ * \param      nTotalBar       The number of bar to program.
+ * \ingroup    Internal
+ */
+static int
+update_bar_register (int nTotalBar)
+{
+       int idx = 0;
+
+       for (idx = 0; idx < nTotalBar; idx++) {
+               //skip XDATA register
+               if (idx == XDATA_REGISTER)
+                       idx++;
+               meiLongwordWrite ( MEI_XMEM_BAR_BASE + idx * 4,
+                                 (((uint32_t) adsl_mem_info[idx].
+                                   address) & 0x0FFFFFFF));
+               printk ("BAR%d=%08X, addr=%08X\n", idx,
+                                (((uint32_t) adsl_mem_info[idx].
+                                  address) & 0x0FFFFFFF),
+                                (((uint32_t) adsl_mem_info[idx].address)));
+       }
+       for (idx = nTotalBar; idx < MAX_BAR_REGISTERS; idx++) {
+               if (idx == XDATA_REGISTER)
+                       idx++;
+               meiLongwordWrite ( MEI_XMEM_BAR_BASE + idx * 4,
+                                 (((uint32_t) adsl_mem_info[nTotalBar - 1].
+                                   address) & 0x0FFFFFFF));
+       }
+
+       meiLongwordWrite (MEI_XMEM_BAR_BASE + XDATA_REGISTER * 4,
+                         (((uint32_t) adsl_mem_info[XDATA_REGISTER].
+                           address) & 0x0FFFFFFF));
+       // update MEI_XDATA_BASE_SH
+       printk ("update bar15 register with %08lX\n",
+                        ((unsigned long) adsl_mem_info[XDATA_REGISTER].
+                         address) & 0x0FFFFFFF);
+       meiLongwordWrite (MEI_XDATA_BASE_SH,
+                         ((unsigned long) adsl_mem_info[XDATA_REGISTER].
+                          address) & 0x0FFFFFFF);
+       return MEI_SUCCESS;
+}
+
+/**
+ * Copy the firmware to BARs memory.
+ * 
+ * \param      filp            Pointer to the file structure.
+ * \param      buf             Pointer to the data.
+ * \param      size            The number of bytes to copy.
+ * \param      loff            The file offset.
+ * \return     The current file position.
+ * \ingroup    Internal
+ */
+ssize_t
+mei_write (MEI_file_t * filp, char *buf, size_t size, loff_t * loff)
+{
+       ARC_IMG_HDR img_hdr_tmp, *img_hdr;
+
+       size_t nRead = 0, nCopy = 0;
+       char *mem_ptr;
+       ssize_t retval = -ENOMEM;
+       int idx = 0;
+
+       if (*loff == 0) {
+               if (size < sizeof (img_hdr)) {
+                       printk ("Firmware size is too small!\n");
+                       return retval;
+               }
+               copy_from_user ((char *) &img_hdr_tmp, buf,
+                               sizeof (img_hdr_tmp));
+               image_size = le32_to_cpu (img_hdr_tmp.size) + 8;        // header of image_size and crc are not included.
+               if (image_size > 1024 * 1024) {
+                       printk ("Firmware size is too large!\n");
+                       return retval;
+               }
+               // check if arc is halt
+               if (arc_halt_flag != 1) {
+                       meiResetARC ();
+                       meiHaltArc ();
+               }
+
+               // reset part of PPE 
+               *(unsigned long *) (IFXMIPS_PPE32_SRST) = 0xC30;
+               *(unsigned long *) (IFXMIPS_PPE32_SRST) = 0xFFF;
+
+               free_image_buffer (FREE_ALL);   //free all
+
+               retval = alloc_processor_memory (image_size, adsl_mem_info);
+               if (retval < 0) {
+                       printk ("Error: No memory space left.\n");
+                       goto error;
+               }
+
+               for (idx = 0; idx < retval; idx++) {
+                       //skip XDATA register
+                       if (idx == XDATA_REGISTER)
+                               idx++;
+                       if (idx * SDRAM_SEGMENT_SIZE <
+                           le32_to_cpu (img_hdr_tmp.page[0].p_offset)) {
+                               adsl_mem_info[idx].type = FREE_RELOAD;
+                       }
+                       else {
+                               adsl_mem_info[idx].type = FREE_SHOWTIME;
+                       }
+
+               }
+               nBar = retval;
+
+               img_hdr = (ARC_IMG_HDR *) adsl_mem_info[0].address;
+
+#if !defined(__LINUX__)
+               adsl_mem_info[XDATA_REGISTER].org_address =
+                       kmalloc (SDRAM_SEGMENT_SIZE + 1023, GFP_ATOMIC);
+#else
+               adsl_mem_info[XDATA_REGISTER].org_address =
+                       kmalloc (SDRAM_SEGMENT_SIZE, GFP_ATOMIC);
+#endif
+               adsl_mem_info[XDATA_REGISTER].address =
+                       (char
+                        *) ((unsigned long) (adsl_mem_info[XDATA_REGISTER].
+                                             org_address +
+                                             1023) & 0xFFFFFC00);
+               adsl_mem_info[XDATA_REGISTER].size = SDRAM_SEGMENT_SIZE;
+               if (adsl_mem_info[XDATA_REGISTER].address == NULL) {
+                       printk ("kmalloc memory fail!\n");
+                       retval = -ENOMEM;
+                       goto error;
+               }
+               adsl_mem_info[XDATA_REGISTER].type = FREE_RELOAD;
+               update_bar_register (nBar);
+
+       }
+       else if (image_size == 0) {
+               printk ("Error: Firmware size=0! \n");
+               goto error;
+       }
+       else {
+               if (arc_halt_flag == 0) {
+                       printk
+                               ("Please download the firmware from the beginning of the firmware!\n");
+                       goto error;
+               }
+       }
+
+       nRead = 0;
+       while (nRead < size) {
+               long offset = ((long) (*loff) + nRead) % SDRAM_SEGMENT_SIZE;
+               idx = (((long) (*loff)) + nRead) / SDRAM_SEGMENT_SIZE;
+               mem_ptr = (char *)
+                       KSEG1ADDR ((unsigned long) (adsl_mem_info[idx].
+                                                   address) + offset);
+               if ((size - nRead + offset) > SDRAM_SEGMENT_SIZE)
+                       nCopy = SDRAM_SEGMENT_SIZE - offset;
+               else
+                       nCopy = size - nRead;
+               copy_from_user (mem_ptr, buf + nRead, nCopy);
+#ifdef IMAGE_SWAP
+               for (offset = 0; offset < (nCopy / 4); offset++) {
+                       ((unsigned long *) mem_ptr)[offset] =
+                               le32_to_cpu (((unsigned long *)
+                                             mem_ptr)[offset]);
+               }
+#endif //IMAGE_SWAP
+               nRead += nCopy;
+               adsl_mem_info[idx].nCopy += nCopy;
+       }
+
+#if    ( defined(HEADER_SWAP) && !defined(IMAGE_SWAP)) || (defined(IMAGE_SWAP) && !defined(HEADER_SWAP))
+       if (*loff == 0) {
+
+               for (idx = 0;
+                    idx <
+                    (sizeof (ARC_IMG_HDR) +
+                     (le32_to_cpu (img_hdr_tmp.count) -
+                      1) * sizeof (ARC_SWP_PAGE_HDR)) / 4; idx++) {
+                       ((unsigned long *) img_hdr)[idx] =
+                               le32_to_cpu (((unsigned long *)
+                                             img_hdr)[idx]);
+               }
+       }
+#endif //( defined(HEADER_SWAP) && !defined(IMAGE_SWAP)) || (defined(IMAGE_SWAP) && !defined(HEADER_SWAP))
+       printk ("size=%X,loff=%08X\n", size, (unsigned int) *loff);
+
+       *loff += size;
+       return size;
+      error:
+       free_image_buffer (FREE_ALL);
+
+       return retval;
+}
+
+/********************************************************
+ * L3 Power Mode                                        *
+ ********************************************************/
+/**
+ * Send a CMV message.
+ * This function sends a CMV message to ARC
+ * 
+ * \param      opcode          The message opcode
+ * \param      group           The message group number
+ * \param      address         The message address.
+ * \param      index           The message index.
+ * \param      size            The number of words to read/write.
+ * \param      data            The pointer to data.
+ * \param      CMVMSG          The pointer to message buffer.
+ * \return     0: success 
+ * \ingroup    Internal
+ */
+int
+send_cmv (u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data, u16 * CMVMSG)
+{
+       int ret;
+
+       makeCMV(opcode, group, address, index, size, data, CMVMSG);
+       ret = mei_ioctl((struct inode *) 0, NULL, IFXMIPS_MEI_CMV_WINHOST, (unsigned long)CMVMSG);
+       return ret;
+}
+
+#ifdef IFX_ADSL_L3_MODE_SUPPORT
+
+/**
+ * Check the L3 request from CO
+ * This function Check if CPE received the L3 request from CO
+ * \return     1: got L3 request.  
+ * \ingroup    Internal
+ */
+int
+check_co_l3_shutdown_request (void)
+{
+       u16 CMVMSG[MSG_LENGTH];
+       if (modem_ready == 1) {
+               if (send_cmv (H2D_CMV_READ, STAT, 4, 0, 1, NULL, CMVMSG) != 0) {
+                       return -EBUSY;
+               }
+               if (CMVMSG[4] & BIT14) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/**
+ * Check the L3 status
+ * This function get the CPE Power Management Mode status
+ * \return     0: L0 Mode
+ *             2: L2 Mode
+ *             3: L3 Mode
+ * \ingroup    Internal
+ */
+int
+get_l3_power_status (void)
+{
+       u16 CMVMSG[MSG_LENGTH];
+       if (modem_ready == 0) {
+               return L3_POWER_MODE;
+       }
+       else {
+               if (send_cmv (H2D_CMV_READ, STAT, 18, 0, 1, NULL, CMVMSG) !=
+                   0) {
+                       return -EBUSY;
+               }
+               return ((int) CMVMSG[4]);
+
+       }
+       return 0;
+}
+
+/**
+ * Send a L3 request to CO
+ * This function send a L3 request to CO and check the CO response.
+ * \return     0: Success. Others: Fail.
+ * \ingroup    Internal
+ */
+int
+send_l3_shutdown_cmd (void)
+{
+       u16 cmd = 0x1;
+       int nRetry = 0;
+       u16 CMVMSG[MSG_LENGTH];
+
+       if (modem_ready == 0) {
+               return -EBUSY;
+       }
+       // send l3 request to CO
+       if (send_cmv (H2D_CMV_WRITE, CNTL, 3, 0, 1, &cmd, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+      retry:
+       MEI_WAIT (10);
+
+       // check CO response
+       if (send_cmv (H2D_CMV_READ, STAT, 20, 0, 1, NULL, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+       if (CMVMSG[4] == 0) {
+               nRetry++;
+               if (nRetry < 10) {
+                       goto retry;
+               }
+               else {
+                       return -EBUSY;
+               }
+
+       }
+       else if (CMVMSG[4] == 1)        // reject
+       {
+               return -EPERM;
+       }
+       else if (CMVMSG[4] == 2)        // ok
+       {
+               return 0;
+       }
+       else if (CMVMSG[4] == 3)        // failure
+       {
+               return -EAGAIN;
+       }
+       return 0;
+}
+
+/**
+ * Enable L3 Power Mode
+ * This function send a L3 request to CO and check the CO response. Then reboot the CPE to enter L3 Mode.
+ * \return     0: Success. Others: Fail.
+ * \ingroup    Internal
+ */
+int
+set_l3_shutdown (void)
+{
+       int ret = 0;
+       if (l3_shutdown == 0) {
+               // send l3 request to CO
+               ret = send_l3_shutdown_cmd ();
+               if (ret == 0)   //got CO ACK
+               {
+                       //reboot adsl and block autoboot daemon
+                       ret = mei_ioctl ((struct inode *) 0, NULL, IFXMIPS_MEI_REBOOT, (unsigned long)NULL);
+                       l3_shutdown = 1;
+               }
+       }
+       return ret;
+}
+
+/**
+ * Disable L3 Power Mode
+ * This function disable L3 Mode and wake up the autoboot daemon.
+ * \return     0: Success.
+ * \ingroup    Internal
+ */
+//l3 power mode disable
+int
+set_l3_power_on (void)
+{
+       if (l3_shutdown == 1) {
+               l3_shutdown = 0;
+               // wakeup autoboot daemon
+               MEI_WAKEUP_EVENT (wait_queue_l3);
+
+       }
+       return 0;
+}
+
+/********************************************************
+ * End of L3 Power Mode                                 *
+ ********************************************************/
+#endif //IFX_ADSL_L3_MODE_SUPPORT
+
+#ifdef CONFIG_IFXMIPS_MEI_LED
+/*
+ *  LED Initialization function
+ */
+int
+meiADSLLedInit (void)
+{
+       u16 data = 0x0600;
+       u16 CMVMSG[MSG_LENGTH];
+
+       data = 0x0400;
+#if defined(DATA_LED_SUPPORT) && defined (DATA_LED_ADSL_FW_HANDLE)
+       data |= 0x200;
+#endif
+       // Setup ADSL Link/Data LED
+       if (send_cmv (H2D_CMV_WRITE, INFO, 91, 0, 1, &data, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+
+       if (send_cmv (H2D_CMV_WRITE, INFO, 91, 2, 1, &data, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+
+       // Let FW to handle ADSL Link LED
+       data = 0x0a03;          //invert the LED signal as per input from Stefan on 13/11/2006
+       if (send_cmv (H2D_CMV_WRITE, INFO, 91, 4, 1, &data, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+
+#ifdef DATA_LED_SUPPORT
+#ifdef DATA_LED_ADSL_FW_HANDLE
+
+       // Turn ADSL Data LED on
+       data = 0x0900;
+       if (send_cmv (H2D_CMV_WRITE, INFO, 91, 5, 1, &data, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+#else
+       ifxmips_led_set(0x1);
+#endif
+#endif
+       return 0;
+}
+#endif
+
+#ifdef IFX_ADSL_DUAL_LATENCY_SUPPORT
+/* 
+ * Dual Latency Path Initialization function
+ */
+int
+meiDualLatencyInit (void)
+{
+       u16 nDual = 0;
+       u16 CMVMSG[MSG_LENGTH];
+
+       // setup up stream path 
+       if (bDualLatency & DUAL_LATENCY_US_ENABLE) {
+               nDual = 2;
+       }
+       else {
+               nDual = 1;
+       }
+
+       if (send_cmv (H2D_CMV_WRITE, CNFG, 10, 0, 1, &nDual, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+
+       if (send_cmv (H2D_CMV_WRITE, CNFG, 11, 0, 1, &nDual, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+
+       // setup down stream path       
+       if (bDualLatency & DUAL_LATENCY_DS_ENABLE) {
+               nDual = 2;
+       }
+       else {
+               nDual = 1;
+       }
+
+       if (send_cmv (H2D_CMV_WRITE, CNFG, 21, 0, 1, &nDual, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+       if (send_cmv (H2D_CMV_WRITE, CNFG, 22, 0, 1, &nDual, CMVMSG) != 0) {
+               return -EBUSY;
+       }
+       return 0;
+}
+
+int
+mei_is_dual_latency_enabled (void)
+{
+       return bDualLatency;
+}
+#endif
+
+int
+meiAdslStartupInit (void)
+{
+#ifdef CONFIG_IFXMIPS_MEI_LED
+       meiADSLLedInit ();
+#endif
+#ifdef IFX_ADSL_DUAL_LATENCY_SUPPORT
+       meiDualLatencyInit ();
+#endif
+       return 0;
+}
+
+/**
+ * MEI IO controls for user space accessing
+ * 
+ * \param      ino             Pointer to the stucture of inode.
+ * \param      fil             Pointer to the stucture of file.
+ * \param      command         The ioctl command.
+ * \param      lon             The address of data.
+ * \return     Success or failure.
+ * \ingroup    Internal
+ */
+int
+mei_ioctl (MEI_inode_t * ino, MEI_file_t * fil, unsigned int command,
+          unsigned long lon)
+{
+       int i;
+
+       int meierr = MEI_SUCCESS;
+       meireg regrdwr;
+       meidebug debugrdwr;
+       u32 arc_debug_data, reg_data;
+#ifdef IFXMIPS_CLEAR_EOC
+       u16 data;
+       struct sk_buff *eoc_skb;
+#endif //IFXMIPS_CLEAR_EOC
+       u16 RxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
+       u16 TxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
+
+       int from_kernel = 0;    //joelin
+       if (ino == (MEI_inode_t *) 0)
+               from_kernel = 1;        //joelin
+       if (command < IFXMIPS_MEI_START) {
+#ifdef CONFIG_IFXMIPS_MEI_MIB
+               return mei_mib_ioctl (ino, fil, command, lon);
+#endif //CONFIG_IFXMIPS_MEI_MIB
+
+               if (command == IFXMIPS_MIB_LO_ATUR
+                   || command == IFXMIPS_MIB_LO_ATUC)
+                       return MEI_SUCCESS;
+               printk
+                       ("No such ioctl command (0x%X)! MEI ADSL MIB is not supported!\n",
+                        command);
+               return -ENOIOCTLCMD;
+       }
+       else {
+               switch (command) {
+               case IFXMIPS_MEI_START:
+
+                       showtime = 0;
+                       loop_diagnostics_completed = 0;
+                       if (time_disconnect.tv_sec == 0)
+                               do_gettimeofday (&time_disconnect);
+
+                       if (MEI_MUTEX_LOCK (mei_sema))  //disable CMV access until ARC ready
+                       {
+                               printk ("-ERESTARTSYS\n");
+                               return -ERESTARTSYS;
+                       }
+
+                       meiMailboxInterruptsDisable (); //disable all MEI interrupts
+                       if (mei_arc_swap_buff == NULL) {
+                               mei_arc_swap_buff =
+                                       (u32 *) kmalloc (MAXSWAPSIZE * 4,
+                                                        GFP_KERNEL);
+                               if (mei_arc_swap_buff == NULL) {
+                                       printk
+                                               ("\n\n malloc fail for codeswap buff");
+                                       meierr = MEI_FAILURE;
+                               }
+                       }
+                       if (meiRunAdslModem () != MEI_SUCCESS) {
+                               printk
+                                       ("meiRunAdslModem()  error...");
+                               meierr = MEI_FAILURE;
+                       }
+#ifdef IFX_ADSL_L3_MODE_SUPPORT
+                       /* L3 Power Mode Start */
+                       if (l3_shutdown == 1) {
+                               // block autoboot daemon until l3 power mode disable
+                               MEI_WAIT_EVENT (wait_queue_l3);
+                       }
+                       /* L3 Power Mode End */
+#endif //IFX_ADSL_L3_MODE_SUPPORT
+                       if (autoboot_enable_flag)
+                               meiAdslStartupInit ();
+                       break;
+
+               case IFXMIPS_MEI_SHOWTIME:
+                       if (MEI_MUTEX_LOCK (mei_sema))
+                               return -ERESTARTSYS;
+
+                       do_gettimeofday (&time_showtime);
+                       unavailable_seconds +=
+                               time_showtime.tv_sec - time_disconnect.tv_sec;
+                       time_disconnect.tv_sec = 0;
+                       makeCMV (H2D_CMV_READ, RATE, 0, 0, 4, NULL, TxMessage); //maximum allowed tx message length, in bytes
+                       if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
+                           MEI_SUCCESS) {
+                               printk
+                                       ("\n\nCMV fail, Group RAGE Address 0 Index 0");
+                       }
+                       else {
+                               u32 rate_fast;
+                               u32 rate_intl;
+                               rate_intl = RxMessage[4] | RxMessage[5] << 16;
+                               rate_fast = RxMessage[6] | RxMessage[7] << 16;
+                               // 609251:tc.chen Fix ATM QoS issue start
+                               if (rate_intl && rate_fast)     // apply cell rate to each path
+                               {
+#ifdef CONFIG_ATM_IFXMIPS
+                                       ifx_atm_set_cell_rate (1,
+                                                              rate_intl /
+                                                              (53 * 8));
+                                       ifx_atm_set_cell_rate (0,
+                                                              rate_fast /
+                                                              (53 * 8));
+#endif
+                               }
+                               else if (rate_fast)     // apply fast path cell rate to atm interface 0
+                               {
+#ifdef CONFIG_ATM_IFXMIPS
+                                       ifx_atm_set_cell_rate (0,
+                                                              rate_fast /
+                                                              (53 * 8));
+#endif
+                               }
+                               else if (rate_intl)     // apply interleave path cell rate to atm interface 0
+                               {
+#ifdef CONFIG_ATM_IFXMIPS
+                                       ifx_atm_set_cell_rate (0,
+                                                              rate_intl /
+                                                              (53 * 8));
+#endif
+                               }
+                               else {
+                                       printk ("Got rate fail.\n");
+                               }
+                               // 609251:tc.chen end 
+                       }
+
+#ifdef IFXMIPS_CLEAR_EOC
+                       data = 1;
+                       makeCMV (H2D_CMV_WRITE, OPTN, 24, 0, 1, &data,
+                                TxMessage);
+                       if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
+                           MEI_SUCCESS) {
+                               printk ("Enable clear eoc fail!\n");
+                       }
+#endif
+                       // read adsl mode
+                       makeCMV (H2D_CMV_READ, STAT, 1, 0, 1, NULL,
+                                TxMessage);
+                       if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
+                           MEI_SUCCESS) {
+#ifdef IFXMIPS_MEI_DEBUG_ON
+                               printk ("\n\nCMV fail, Group STAT Address 1 Index 0");
+#endif
+                       }
+                       adsl_mode = RxMessage[4];
+                       makeCMV (H2D_CMV_READ, STAT, 17, 0, 1, NULL,
+                                TxMessage);
+                       if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
+                           MEI_SUCCESS) {
+#ifdef IFXMIPS_MEI_DEBUG_ON
+                               printk ("\n\nCMV fail, Group STAT Address 1 Index 0");
+#endif
+                       }
+                       adsl_mode_extend = RxMessage[4];
+#ifdef CONFIG_IFXMIPS_MEI_MIB
+                       mei_mib_adsl_link_up ();
+#endif
+
+//joelin 04/16/2005-start
+                       makeCMV (H2D_CMV_WRITE, PLAM, 10, 0, 1,
+                                &unavailable_seconds, TxMessage);
+                       if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
+                           MEI_SUCCESS) {
+                               printk
+                                       ("\n\nCMV fail, Group 7 Address 10 Index 0");
+                       }
+
+//joelin 04/16/2005-end         
+                       showtime = 1;
+                       free_image_buffer (FREE_SHOWTIME);
+                       MEI_MUTEX_UNLOCK (mei_sema);
+                       break;
+
+               case IFXMIPS_MEI_HALT:
+                       if (arc_halt_flag == 0) {
+                               meiResetARC ();
+                               meiHaltArc ();
+                       }
+                       break;
+               case IFXMIPS_MEI_RUN:
+                       if (arc_halt_flag == 1) {
+                               meiRunArc ();
+                       }
+                       break;
+               case IFXMIPS_MEI_CMV_WINHOST:
+                       if (MEI_MUTEX_LOCK (mei_sema))
+                               return -ERESTARTSYS;
+
+                       if (!from_kernel)
+                               copy_from_user ((char *) TxMessage, (char *) lon, MSG_LENGTH * 2);      //joelin
+                       else
+                               memcpy (TxMessage, (char *) lon,
+                                       MSG_LENGTH * 2);
+
+                       if (meiCMV (TxMessage, YES_REPLY, RxMessage) !=
+                           MEI_SUCCESS) {
+                               printk
+                                       ("\n\nWINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",
+                                        TxMessage[0], TxMessage[1],
+                                        TxMessage[2], TxMessage[3],
+                                        RxMessage[0], RxMessage[1],
+                                        RxMessage[2], RxMessage[3],
+                                        RxMessage[4]);
+                               meierr = MEI_FAILURE;
+                       }
+                       else {
+                               if (!from_kernel)       //joelin
+                                       copy_to_user ((char *) lon,
+                                                     (char *) RxMessage,
+                                                     MSG_LENGTH * 2);
+                               else
+                                       memcpy ((char *) lon,
+                                               (char *) RxMessage,
+                                               MSG_LENGTH * 2);
+                       }
+
+                       MEI_MUTEX_UNLOCK (mei_sema);
+                       break;
+#ifdef IFXMIPS_MEI_CMV_EXTRA
+               case IFXMIPS_MEI_CMV_READ:
+                       copy_from_user ((char *) (&regrdwr), (char *) lon,
+                                       sizeof (meireg));
+                       meiLongwordRead ((u32*)regrdwr.iAddress, &(regrdwr.iData));
+
+                       copy_to_user((char *) lon, (char *) (&regrdwr), sizeof (meireg));
+                       break;
+
+               case IFXMIPS_MEI_CMV_WRITE:
+                       copy_from_user ((char *) (&regrdwr), (char *) lon, sizeof (meireg));
+                       meiLongwordWrite ((u32*)regrdwr.iAddress, regrdwr.iData);
+                       break;
+
+               case IFXMIPS_MEI_REMOTE:
+                       copy_from_user ((char *) (&i), (char *) lon,
+                                       sizeof (int));
+                       if (i == 0) {
+                               meiMailboxInterruptsEnable ();
+
+                               MEI_MUTEX_UNLOCK (mei_sema);
+                       }
+                       else if (i == 1) {
+                               meiMailboxInterruptsDisable ();
+                               if (MEI_MUTEX_LOCK (mei_sema))
+                                       return -ERESTARTSYS;
+                       }
+                       else {
+                               printk
+                                       ("\n\n IFXMIPS_MEI_REMOTE argument error");
+                               meierr = MEI_FAILURE;
+                       }
+                       break;
+
+               case IFXMIPS_MEI_READDEBUG:
+               case IFXMIPS_MEI_WRITEDEBUG:
+#if 0                          //tc.chen:It is no necessary to acquire lock to read debug memory!!
+                       if (MEI_MUTEX_LOCK (mei_sema))
+                               return -ERESTARTSYS;
+#endif
+                       if (!from_kernel)
+                               copy_from_user ((char *) (&debugrdwr),
+                                               (char *) lon,
+                                               sizeof (debugrdwr));
+                       else
+                               memcpy ((char *) (&debugrdwr), (char *) lon,
+                                       sizeof (debugrdwr));
+
+                       if (command == IFXMIPS_MEI_READDEBUG)
+                               meiDebugRead (debugrdwr.iAddress,
+                                             debugrdwr.buffer,
+                                             debugrdwr.iCount);
+                       else
+                               meiDebugWrite (debugrdwr.iAddress,
+                                              debugrdwr.buffer,
+                                              debugrdwr.iCount);
+
+                       if (!from_kernel)
+                               copy_to_user ((char *) lon, (char *) (&debugrdwr), sizeof (debugrdwr)); //dying gasp
+#if 0                          //tc.chen:It is no necessary to acquire lock to read debug memory!!
+                       MEI_MUTEX_UNLOCK (mei_sema);
+#endif
+                       break;
+               case IFXMIPS_MEI_RESET:
+               case IFXMIPS_MEI_REBOOT:
+
+#ifdef CONFIG_IFXMIPS_MEI_MIB
+                       mei_mib_adsl_link_down ();
+#endif
+
+#ifdef IFX_ADSL_L3_MODE_SUPPORT
+                       /* L3 Power Mode start */
+                       if (check_co_l3_shutdown_request () == 1)       //co request
+                       {
+                               // cpe received co L3 request
+                               l3_shutdown = 1;
+                       }
+                       /* L3 Power Mode end */
+#endif //IFX_ADSL_L3_MODE_SUPPORT
+
+                       meiResetARC ();
+                       meiControlModeSwitch (MEI_MASTER_MODE);
+                       //enable ac_clk signal  
+                       _meiDebugLongWordRead (MEI_DEBUG_DEC_DMP1_MASK,
+                                              CRI_CCR0, &arc_debug_data);
+                       arc_debug_data |= ACL_CLK_MODE_ENABLE;
+                       _meiDebugLongWordWrite (MEI_DEBUG_DEC_DMP1_MASK,
+                                               CRI_CCR0, arc_debug_data);
+                       meiControlModeSwitch (JTAG_MASTER_MODE);
+                       meiHaltArc ();
+                       update_bar_register (nBar);
+                       break;
+               case IFXMIPS_MEI_DOWNLOAD:
+                       // DMA the boot code page(s)
+                       printk ("Start download pages");
+                       meiDownloadBootPages ();
+                       break;
+#endif //IFXMIPS_MEI_CMV_EXTRA
+                       //for clearEoC
+#ifdef IFXMIPS_CLEAR_EOC
+               case IFXMIPS_MEI_EOC_SEND:
+                       if (!showtime) {
+                               return -EIO;
+                       }
+                       if (!from_kernel) {
+                               copy_from_user ((char *) (&debugrdwr),
+                                               (char *) lon,
+                                               sizeof (debugrdwr));
+                               eoc_skb =
+                                       dev_alloc_skb (debugrdwr.iCount * 4);
+                               if (eoc_skb == NULL) {
+                                       printk
+                                               ("\n\nskb alloc fail");
+                                       break;
+                               }
+
+                               eoc_skb->len = debugrdwr.iCount * 4;
+                               memcpy (skb_put
+                                       (eoc_skb, debugrdwr.iCount * 4),
+                                       (char *) debugrdwr.buffer,
+                                       debugrdwr.iCount * 4);
+                       }
+                       else {
+                               eoc_skb = (struct sk_buff *) lon;
+                       }
+                       ifx_me_ceoc_send (eoc_skb);     //pass data to higher layer
+                       break;
+#endif // IFXMIPS_CLEAR_EOC
+               case IFXMIPS_MEI_JTAG_ENABLE:
+                       printk ("ARC JTAG Enable.\n");
+                       *(IFXMIPS_GPIO_P0_DIR) = (*IFXMIPS_GPIO_P0_DIR) & (~0x800);     // set gpio11 to input
+                       *(IFXMIPS_GPIO_P0_ALTSEL0) = ((*IFXMIPS_GPIO_P0_ALTSEL0) & (~0x800));
+                       *(IFXMIPS_GPIO_P0_ALTSEL1) = ((*IFXMIPS_GPIO_P0_ALTSEL1) & (~0x800));
+                       *IFXMIPS_GPIO_P0_OD = (*IFXMIPS_GPIO_P0_OD) | 0x800;
+
+                       //enable ARC JTAG
+                       meiLongwordRead(IFXMIPS_RCU_RST, &reg_data);
+                       meiLongwordWrite(IFXMIPS_RCU_RST, reg_data | IFXMIPS_RCU_RST_REQ_ARC_JTAG);
+                       break;
+
+               case GET_ADSL_LOOP_DIAGNOSTICS_MODE:
+                       copy_to_user ((char *) lon, (char *) &loop_diagnostics_mode, sizeof(int));
+                       break;
+               case LOOP_DIAGNOSTIC_MODE_COMPLETE:
+                       loop_diagnostics_completed = 1;
+#ifdef CONFIG_IFXMIPS_MEI_MIB
+                       // read adsl mode
+                       makeCMV (H2D_CMV_READ, STAT, 1, 0, 1, NULL, TxMessage);
+                       if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
+#ifdef IFXMIPS_MEI_DEBUG_ON
+                               printk ("\n\nCMV fail, Group STAT Address 1 Index 0");
+#endif
+                       }
+                       adsl_mode = RxMessage[4];
+
+                       makeCMV (H2D_CMV_READ, STAT, 17, 0, 1, NULL, TxMessage);
+                       if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
+#ifdef IFXMIPS_MEI_DEBUG_ON
+                               printk ("\n\nCMV fail, Group STAT Address 1 Index 0");
+#endif
+                       }
+                       adsl_mode_extend = RxMessage[4];
+#endif
+                       MEI_WAKEUP_EVENT (wait_queue_loop_diagnostic);
+                       break;
+               case SET_ADSL_LOOP_DIAGNOSTICS_MODE:
+                       if (lon != loop_diagnostics_mode) {
+                               loop_diagnostics_completed = 0;
+                               loop_diagnostics_mode = lon;
+#if 0 //08/12/2006 tc.chen : autoboot daemon should reset dsl
+                               mei_ioctl ((MEI_inode_t *) 0, NULL,
+                                          IFXMIPS_MEI_REBOOT,
+                                          (unsigned long) NULL);
+#endif
+                       }
+                       break;
+               case IS_ADSL_LOOP_DIAGNOSTICS_MODE_COMPLETE:
+                       copy_to_user ((char *) lon,
+                                     (char *) &loop_diagnostics_completed,
+                                     sizeof (int));
+                       break;
+#ifdef IFX_ADSL_L3_MODE_SUPPORT
+                       /* L3 Power Mode Start */
+               case GET_POWER_MANAGEMENT_MODE:
+                       i = get_l3_power_status ();
+                       copy_to_user ((char *) lon, (char *) &i,
+                                     sizeof (int));
+                       break;
+               case SET_L3_POWER_MODE:
+                       i = 1;
+                       copy_from_user ((char *) &i, (char *) lon,
+                                       sizeof (int));
+                       if (i == 0) {
+                               return set_l3_shutdown ();
+                       }
+                       else {
+                               return set_l3_power_on ();
+                       }
+                       break;
+                       /* L3 Power Mode End */
+#endif //IFX_ADSL_L3_MODE_SUPPORT
+#ifdef IFX_ADSL_DUAL_LATENCY_SUPPORT
+               case GET_ADSL_DUAL_LATENCY:
+                       i = mei_is_dual_latency_enabled ();
+                       if (i < 0)
+                               return i;
+                       copy_to_user ((char *) lon, (char *) &i,
+                                     sizeof (int));
+                       break;
+               case SET_ADSL_DUAL_LATENCY:
+                       i = 0;
+                       copy_from_user ((char *) &i, (char *) lon,
+                                       sizeof (int));
+                       if (i > DUAL_LATENCY_US_DS_ENABLE) {
+                               return -EINVAL;
+                       }
+                       if (i != bDualLatency) {
+                               bDualLatency = i;
+                               i = 1;  // DualLatency update,need to reboot arc
+                       }
+                       else {
+                               i = 0;  // DualLatency is the same
+                       }
+                       if (modem_ready && i)   // modem is already start, reboot arc to apply Dual Latency changed
+                       {
+                               mei_ioctl ((MEI_inode_t *) 0, NULL,
+                                          IFXMIPS_MEI_REBOOT,
+                                          (unsigned long) NULL);
+                       }
+                       break;
+
+#endif
+               case QUIET_MODE_GET:
+                       copy_to_user ((char *) lon, (char *) &quiet_mode_flag,
+                                     sizeof (int));
+                       break;
+               case QUIET_MODE_SET:
+                       copy_from_user ((char *) &i, (char *) lon,
+                                       sizeof (int));
+                       if (i > 1 || i < 0)
+                               return -EINVAL;
+                       if (i == 1) {
+                               u16 CMVMSG[MSG_LENGTH];
+                               u16 data = 0;
+                               makeCMV (H2D_CMV_WRITE, INFO, 94, 0, 1, &data, CMVMSG); // set tx power to 0
+                               meierr = mei_ioctl ((struct inode *) 0, NULL,
+                                                   IFXMIPS_MEI_CMV_WINHOST,
+                                                   (unsigned long) CMVMSG);
+                       }
+                       quiet_mode_flag = i;
+                       break;
+               case SHOWTIME_LOCK_GET:
+                       copy_to_user ((char *) lon,
+                                     (char *) &showtime_lock_flag,
+                                     sizeof (int));
+                       break;
+               case SHOWTIME_LOCK_SET:
+                       copy_from_user ((char *) &i, (char *) lon,
+                                       sizeof (int));
+                       if (i > 1 || i < 0)
+                               return -EINVAL;
+                       showtime_lock_flag = i;
+                       break;
+               case AUTOBOOT_ENABLE_SET:
+                       copy_from_user ((char *) &i, (char *) lon,
+                                       sizeof (int));
+                       if (i > 1 || i < 0)
+                               return -EINVAL;
+                       autoboot_enable_flag = i;
+                       break;
+               default:
+                       printk
+                               ("The ioctl command(0x%X is not supported!\n",
+                                command);
+                       meierr = -ENOIOCTLCMD;
+               }
+       }
+       return meierr;
+}                              //mei_ioctl
+
+////////////////////     procfs debug    ///////////////////////////
+
+#ifdef CONFIG_PROC_FS
+static int
+proc_read (struct file *file, char *buf, size_t nbytes, loff_t * ppos)
+{
+       int i_ino = (file->f_dentry->d_inode)->i_ino;
+       char outputbuf[64];
+       int count = 0;
+       int i;
+       u32 version = 0;
+       reg_entry_t *current_reg = NULL;
+       u16 RxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
+       u16 TxMessage[MSG_LENGTH] __attribute__ ((aligned (4)));
+
+       for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
+               if (regs[i].low_ino == i_ino) {
+                       current_reg = &regs[i];
+                       break;
+               }
+       }
+       if (current_reg == NULL)
+               return -EINVAL;
+
+       if (current_reg->flag == (int *) 8) {
+               ///proc/mei/version
+               //format:
+               //Firmware version: major.minor.sub_version.int_version.rel_state.spl_appl
+               ///Firmware Date Time Code: date/month min:hour
+               if (*ppos > 0)  /* Assume reading completed in previous read */
+                       return 0;       // indicates end of file
+               if (MEI_MUTEX_LOCK (mei_sema))
+                       return -ERESTARTSYS;
+
+               if (indicator_count < 1) {
+                       MEI_MUTEX_UNLOCK (mei_sema);
+                       return -EAGAIN;
+               }
+               //major:bits 0-7 
+               //minor:bits 8-15
+               makeCMV (H2D_CMV_READ, INFO, 54, 0, 1, NULL, TxMessage);
+               if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
+                       MEI_MUTEX_UNLOCK (mei_sema);
+                       return -EIO;
+               }
+               version = RxMessage[4];
+               count = sprintf (outputbuf, "%d.%d.", (version) & 0xff,
+                                (version >> 8) & 0xff);
+
+               //sub_version:bits 4-7
+               //int_version:bits 0-3
+               //spl_appl:bits 8-13
+               //rel_state:bits 14-15
+               makeCMV (H2D_CMV_READ, INFO, 54, 1, 1, NULL, TxMessage);
+               if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
+                       MEI_MUTEX_UNLOCK (mei_sema);
+                       return -EFAULT;
+               }
+               version = RxMessage[4];
+               count += sprintf (outputbuf + count, "%d.%d.%d.%d",
+                                 (version >> 4) & 0xf,
+                                 version & 0xf,
+                                 (version >> 14) & 0x3,
+                                 (version >> 8) & 0x3f);
+               //Date:bits 0-7
+               //Month:bits 8-15
+               makeCMV (H2D_CMV_READ, INFO, 55, 0, 1, NULL, TxMessage);
+               if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
+                       MEI_MUTEX_UNLOCK (mei_sema);
+                       return -EIO;
+               }
+               version = RxMessage[4];
+
+               //Hour:bits 0-7
+               //Minute:bits 8-15
+               makeCMV (H2D_CMV_READ, INFO, 55, 1, 1, NULL, TxMessage);
+               if (meiCMV (TxMessage, YES_REPLY, RxMessage) != MEI_SUCCESS) {
+                       MEI_MUTEX_UNLOCK (mei_sema);
+                       return -EFAULT;
+               }
+               version += (RxMessage[4] << 16);
+               count += sprintf (outputbuf + count, " %d/%d %d:%d\n",
+                                 version & 0xff, (version >> 8) & 0xff,
+                                 (version >> 25) & 0xff,
+                                 (version >> 16) & 0xff);
+               MEI_MUTEX_UNLOCK (mei_sema);
+
+               *ppos += count;
+       }
+       else if (current_reg->flag != (int *) Recent_indicator) {
+               if (*ppos > 0)  /* Assume reading completed in previous read */
+                       return 0;       // indicates end of file
+               count = sprintf (outputbuf, "0x%08X\n\n",
+                                *(current_reg->flag));
+               *ppos += count;
+               if (count > nbytes)     /* Assume output can be read at one time */
+                       return -EINVAL;
+       }
+       else {
+               if ((int) (*ppos) / ((int) 7) == 16)
+                       return 0;       // indicate end of the message
+               count = sprintf (outputbuf, "0x%04X\n\n",
+                                *(((u16 *) (current_reg->flag)) +
+                                  (int) (*ppos) / ((int) 7)));
+               *ppos += count;
+       }
+       if (copy_to_user (buf, outputbuf, count))
+               return -EFAULT;
+       return count;
+}
+
+static ssize_t
+proc_write (struct file *file, const char *buffer, size_t count,
+           loff_t * ppos)
+{
+       int i_ino = (file->f_dentry->d_inode)->i_ino;
+       reg_entry_t *current_reg = NULL;
+       int i;
+       unsigned long newRegValue;
+       char *endp;
+
+       for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
+               if (regs[i].low_ino == i_ino) {
+                       current_reg = &regs[i];
+                       break;
+               }
+       }
+       if ((current_reg == NULL)
+           || (current_reg->flag == (int *) Recent_indicator))
+               return -EINVAL;
+
+       newRegValue = simple_strtoul (buffer, &endp, 0);
+       *(current_reg->flag) = (int) newRegValue;
+       return (count + endp - buffer);
+}
+#endif //CONFIG_PROC_FS
+
+//TODO, for loopback test
+#ifdef DFE_LOOPBACK
+#define mte_reg_base   (0x4800*4+0x20000)
+
+/* Iridia Registers Address Constants */
+#define MTE_Reg(r)     (int)(mte_reg_base + (r*4))
+
+#define IT_AMODE               MTE_Reg(0x0004)
+
+#define OMBOX_BASE     0xDF80
+#define OMBOX1         (OMBOX_BASE+0x4)
+#define IMBOX_BASE     0xDFC0
+
+#define TIMER_DELAY    (1024)
+#define BC0_BYTES      (32)
+#define BC1_BYTES      (30)
+#define NUM_MB         (12)
+#define TIMEOUT_VALUE  2000
+
+static void
+BFMWait (u32 cycle)
+{
+       u32 i;
+       for (i = 0; i < cycle; i++);
+}
+
+static void
+WriteRegLong (u32 addr, u32 data)
+{
+       //*((volatile u32 *)(addr)) =  data; 
+       IFXMIPS_WRITE_REGISTER_L (data, addr);
+}
+
+static u32
+ReadRegLong (u32 addr)
+{
+       // u32  rd_val;
+       //rd_val = *((volatile u32 *)(addr));
+       // return rd_val;
+       return IFXMIPS_READ_REGISTER_L (addr);
+}
+
+/* This routine writes the mailbox with the data in an input array */
+static void
+WriteMbox (u32 * mboxarray, u32 size)
+{
+       meiDebugWrite (IMBOX_BASE, mboxarray, size);
+       printk ("write to %X\n", IMBOX_BASE);
+       meiLongwordWrite ( MEI_TO_ARC_INT, MEI_TO_ARC_MSGAV);
+}
+
+/* This routine reads the output mailbox and places the results into an array */
+static void
+ReadMbox (u32 * mboxarray, u32 size)
+{
+       meiDebugRead (OMBOX_BASE, mboxarray, size);
+       printk ("read from %X\n", OMBOX_BASE);
+}
+
+static void
+MEIWriteARCValue (u32 address, u32 value)
+{
+       u32 i, check = 0;
+
+       /* Write address register */
+       IFXMIPS_WRITE_REGISTER_L (address, MEI_DEBUG_WAD);
+
+       /* Write data register */
+       IFXMIPS_WRITE_REGISTER_L (value, MEI_DEBUG_DATA);
+
+       /* wait until complete - timeout at 40 */
+       for (i = 0; i < 40; i++) {
+               check = IFXMIPS_READ_REGISTER_L (ARC_TO_MEI_INT);
+
+               if ((check & ARC_TO_MEI_DBG_DONE))
+                       break;
+       }
+       /* clear the flag */
+       IFXMIPS_WRITE_REGISTER_L (ARC_TO_MEI_DBG_DONE, ARC_TO_MEI_INT);
+}
+
+void
+arc_code_page_download (uint32_t arc_code_length, uint32_t * start_address)
+{
+       int count;
+       printk ("try to download pages,size=%d\n", arc_code_length);
+       meiControlModeSwitch (MEI_MASTER_MODE);
+       if (arc_halt_flag == 0) {
+               meiHaltArc ();
+       }
+       meiLongwordWrite ( MEI_XFR_ADDR, 0);
+       for (count = 0; count < arc_code_length; count++) {
+               meiLongwordWrite ( MEI_DATA_XFR,
+                                 *(start_address + count));
+       }
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+}
+static int
+load_jump_table (unsigned long addr)
+{
+       int i;
+       uint32_t addr_le, addr_be;
+       uint32_t jump_table[32];
+       for (i = 0; i < 16; i++) {
+               addr_le = i * 8 + addr;
+               addr_be = ((addr_le >> 16) & 0xffff);
+               addr_be |= ((addr_le & 0xffff) << 16);
+               jump_table[i * 2 + 0] = 0x0f802020;
+               jump_table[i * 2 + 1] = addr_be;
+               //printk("jt %X %08X %08X\n",i,jump_table[i*2+0],jump_table[i*2+1]);
+       }
+       arc_code_page_download (32, &jump_table[0]);
+       return 0;
+}
+
+void
+dfe_loopback_irq_handler (void)
+{
+       uint32_t rd_mbox[10];
+
+       memset (&rd_mbox[0], 0, 10 * 4);
+       ReadMbox (&rd_mbox[0], 6);
+       if (rd_mbox[0] == 0x0) {
+               printk ("Get ARC_ACK\n");
+               got_int = 1;
+       }
+       else if (rd_mbox[0] == 0x5) {
+               printk ("Get ARC_BUSY\n");
+               got_int = 2;
+       }
+       else if (rd_mbox[0] == 0x3) {
+               printk ("Get ARC_EDONE\n");
+               if (rd_mbox[1] == 0x0) {
+                       got_int = 3;
+                       printk ("Get E_MEMTEST\n");
+                       if (rd_mbox[2] != 0x1) {
+                               got_int = 4;
+                               printk ("Get Result %X\n",
+                                                rd_mbox[2]);
+                       }
+               }
+       }
+       meiLongwordWrite ( ARC_TO_MEI_INT, ARC_TO_MEI_DBG_DONE);
+       MEI_MASK_AND_ACK_IRQ (IFXMIPS_MEI_INT);
+       disable_irq (IFXMIPS_MEI_INT);
+       //got_int = 1;
+       return;
+}
+
+static void
+wait_mem_test_result (void)
+{
+       uint32_t mbox[5];
+       mbox[0] = 0;
+       printk ("Waiting Starting\n");
+       while (mbox[0] == 0) {
+               ReadMbox (&mbox[0], 5);
+       }
+       printk ("Try to get mem test result.\n");
+       ReadMbox (&mbox[0], 5);
+       if (mbox[0] == 0xA) {
+               printk ("Success.\n");
+       }
+       else if (mbox[0] == 0xA) {
+               printk
+                       ("Fail,address %X,except data %X,receive data %X\n",
+                        mbox[1], mbox[2], mbox[3]);
+       }
+       else {
+               printk ("Fail\n");
+       }
+}
+
+static int
+arc_ping_testing (void)
+{
+#define MEI_PING 0x00000001
+       uint32_t wr_mbox[10], rd_mbox[10];
+       int i;
+       for (i = 0; i < 10; i++) {
+               wr_mbox[i] = 0;
+               rd_mbox[i] = 0;
+       }
+
+       printk ("send ping msg\n");
+       wr_mbox[0] = MEI_PING;
+       WriteMbox (&wr_mbox[0], 10);
+
+       while (got_int == 0) {
+               MEI_WAIT (100);
+       }
+
+       printk ("send start event\n");
+       got_int = 0;
+
+       wr_mbox[0] = 0x4;
+       wr_mbox[1] = 0;
+       wr_mbox[2] = 0;
+       wr_mbox[3] = (uint32_t) 0xf5acc307e;
+       wr_mbox[4] = 5;
+       wr_mbox[5] = 2;
+       wr_mbox[6] = 0x1c000;
+       wr_mbox[7] = 64;
+       wr_mbox[8] = 0;
+       wr_mbox[9] = 0;
+       WriteMbox (&wr_mbox[0], 10);
+       enable_irq (IFXMIPS_MEI_INT);
+       //printk("meiMailboxWrite ret=%d\n",i);
+       meiLongwordWrite ( MEI_TO_ARC_INT, MEI_TO_ARC_MSGAV);
+       printk ("sleeping\n");
+       while (1) {
+               if (got_int > 0) {
+
+                       if (got_int > 3)
+                               printk ("got_int >>>> 3\n");
+                       else
+                               printk ("got int = %d\n", got_int);
+                       got_int = 0;
+                       //schedule();
+                       enable_irq (IFXMIPS_MEI_INT);
+               }
+               //mbox_read(&rd_mbox[0],6);
+               MEI_WAIT (100);
+       }
+}
+
+static MEI_ERROR
+DFE_Loopback_Test (void)
+{
+       int i = 0;
+       u32 arc_debug_data = 0, temp;
+
+       meiResetARC ();
+       // start the clock
+       arc_debug_data = ACL_CLK_MODE_ENABLE;
+       meiDebugWrite (CRI_CCR0, &arc_debug_data, 1);
+
+#if defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
+       // WriteARCreg(AUX_XMEM_LTEST,0);
+       meiControlModeSwitch (MEI_MASTER_MODE);
+#define AUX_XMEM_LTEST 0x128
+       _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, AUX_XMEM_LTEST, 0);
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+
+       // WriteARCreg(AUX_XDMA_GAP,0); 
+       meiControlModeSwitch (MEI_MASTER_MODE);
+#define AUX_XDMA_GAP 0x114
+       _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, AUX_XDMA_GAP, 0);
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+
+       meiControlModeSwitch (MEI_MASTER_MODE);
+       temp = 0;
+       _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK,
+                               (u32) MEI_XDATA_BASE_SH, temp);
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+
+       i = alloc_processor_memory (SDRAM_SEGMENT_SIZE * 16, adsl_mem_info);
+       if (i >= 0) {
+               int idx;
+
+               for (idx = 0; idx < i; idx++) {
+                       adsl_mem_info[idx].type = FREE_RELOAD;
+                       IFXMIPS_WRITE_REGISTER_L ((((uint32_t)
+                                                  adsl_mem_info[idx].
+                                                  address) & 0x0fffffff),
+                                                MEI_XMEM_BAR_BASE + idx * 4);
+                       printk ("bar%d(%X)=%X\n", idx,
+                                        MEI_XMEM_BAR_BASE + idx * 4,
+                                        (((uint32_t) adsl_mem_info[idx].
+                                          address) & 0x0fffffff));
+                       memset ((u8 *) adsl_mem_info[idx].address, 0,
+                               SDRAM_SEGMENT_SIZE);
+               }
+
+               meiLongwordWrite ( MEI_XDATA_BASE_SH, ((unsigned long)
+                                                           adsl_mem_info
+                                                           [XDATA_REGISTER].
+                                                           address) &
+                                 0x0FFFFFFF);
+
+       }
+       else {
+               printk ("cannot load image: no memory\n\n");
+               return MEI_FAILURE;
+       }
+       //WriteARCreg(AUX_IC_CTRL,2);
+       meiControlModeSwitch (MEI_MASTER_MODE);
+#define AUX_IC_CTRL 0x11
+       _meiDebugLongWordWrite (MEI_DEBUG_DEC_AUX_MASK, AUX_IC_CTRL, 2);
+       meiControlModeSwitch (JTAG_MASTER_MODE);
+
+       meiHaltArc ();
+
+#ifdef DFE_PING_TEST
+
+       printk ("ping test image size=%d\n", sizeof (code_array));
+       memcpy ((u8 *) (adsl_mem_info[0].address + 0x1004), &code_array[0],
+               sizeof (code_array));
+       load_jump_table (0x80000 + 0x1004);
+
+#endif //DFE_PING_TEST
+
+       printk ("ARC ping test code download complete\n");
+#endif //defined( DFE_PING_TEST )|| defined( DFE_ATM_LOOPBACK)
+#ifdef DFE_MEM_TEST
+       meiLongwordWrite (ARC_TO_MEI_INT_MASK, MSGAV_EN);
+
+       arc_code_page_download (1537, &mem_test_code_array[0]);
+       printk ("ARC mem test code download complete\n");
+#endif //DFE_MEM_TEST
+#ifdef DFE_ATM_LOOPBACK
+       arc_debug_data = 0xf;
+       arc_code_page_download (1077, &code_array[0]);
+       // Start Iridia IT_AMODE (in dmp access) why is it required?
+       meiDebugWrite (0x32010, &arc_debug_data, 1);
+#endif //DFE_ATM_LOOPBACK
+       meiMailboxInterruptsEnable ();
+       meiRunArc ();
+
+#ifdef DFE_PING_TEST
+       arc_ping_testing ();
+#endif //DFE_PING_TEST
+#ifdef DFE_MEM_TEST
+       wait_mem_test_result ();
+#endif //DFE_MEM_TEST
+
+       free_image_buffer (FREE_ALL);
+       return MEI_SUCCESS;
+}
+
+#endif //DFE_LOOPBACK
+//end of TODO, for loopback test
+
+#if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
+
+/* 
+ *  Led Thread Main function
+ */
+static int
+led_poll (void *unused)
+{
+       struct task_struct *tsk = current;
+
+       daemonize("mei_led_poll");
+       strcpy (tsk->comm, "atm_led");
+       sigfillset (&tsk->blocked);
+
+       stop_led_module = 0;    //begin polling ...
+
+       while (!stop_led_module) {
+               if (led_status_on || led_need_to_flash) {
+                       adsl_led_flash_task ();
+               }
+               if (led_status_on)      //sleep 200 ms to check if need to turn led off
+               {
+                       interruptible_sleep_on_timeout
+                               (&wait_queue_led_polling, 25);
+               }
+               else {
+                       interruptible_sleep_on (&wait_queue_led_polling);
+               }
+       }
+       return 0;
+}
+
+/* 
+ * API for atm driver to notify led thread a data coming/sending 
+ */
+#if defined (CONFIG_ATM_IFXMIPS)
+static int
+adsl_led_flash (void)
+{
+       if (!modem_ready)
+               return 0;
+
+       if (led_status_on == 0 && led_need_to_flash == 0)
+       {
+               wake_up_interruptible (&wait_queue_led_polling);        //wake up and clean led module 
+       }
+       led_need_to_flash = 1;  //asking to flash led
+
+       return 0;
+}
+#endif
+/*
+ * Main task for led controlling.
+ */
+static int
+adsl_led_flash_task (void)
+{
+#ifdef DATA_LED_ADSL_FW_HANDLE
+       u16 one = 1;
+       u16 zero = 0;
+       u16 data = 0x0600;
+       u16 CMVMSG[MSG_LENGTH];
+#endif
+
+//      printk("Task Running...\n");    //joelin  test
+
+       if (!showtime) {
+               led_need_to_flash = 0;
+               led_status_on = 0;
+               return 0;
+       }
+
+       if (led_status_on == 0 && led_need_to_flash == 1) {
+
+#ifdef DATA_LED_ADSL_FW_HANDLE
+               data = 0x0901;  //flash
+               send_cmv (H2D_CMV_WRITE, INFO, 91, 5, 1, &data, CMVMSG);        //use GPIO9 for TR68 data led .flash.
+#else
+               ifxmips_led_blink_set(0x0); // data
+               ifxmips_led_blink_set(0x1); // link
+#endif
+               led_status_on = 1;
+
+       }
+       else if (led_status_on == 1 && led_need_to_flash == 0) {
+#ifdef DATA_LED_ADSL_FW_HANDLE
+#ifdef DATA_LED_ON_MODE
+               data = 0x0903;  //use GPIO9 for TR68 data led .turn on.
+#else
+               data = 0x0900;  //off
+#endif
+               printk ("off %04X\n", data);
+               send_cmv (H2D_CMV_WRITE, INFO, 91, 5, 1, &data, CMVMSG);        //use GPIO9 for TR68 data led .off.
+#else
+#endif
+               led_status_on = 0;
+       }
+       led_need_to_flash = 0;
+       return 0;
+}
+
+/* 
+ * Led initialization function
+ * This function create a thread to polling atm traffic and do led blanking
+ */
+static int
+ifxmips_mei_led_init (void)
+{
+       init_waitqueue_head (&wait_queue_led_polling);  // adsl led for led function
+       kernel_thread (led_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD);
+       return 0;
+}
+
+/* 
+ * Led destory function
+ */
+static int
+ifxmips_mei_led_cleanup (void)
+{
+       stop_led_module = 1;    //wake up and clean led module 
+       wake_up_interruptible (&wait_queue_led_polling);        //wake up and clean led module   
+       return 0;
+}
+#endif //#ifdef CONFIG_IFXMIPS_MEI_LED
+
+////////////////////////////////////////////////////////////////////////////
+int __init
+ifxmips_mei_init_module (void)
+{
+       struct proc_dir_entry *entry;
+       int i;
+       u32 temp;
+#ifdef CONFIG_DEVFS_FS
+       char buf[10];
+#endif
+       reg_entry_t regs_temp[PROC_ITEMS] =     // Items being debugged
+       {
+               /*  {   flag,                   name,              description } */
+               {&arcmsgav, "arcmsgav", "arc to mei message ", 0},
+               {&cmv_reply, "cmv_reply", "cmv needs reply", 0},
+               {&cmv_waiting, "cmv_waiting",
+                "waiting for cmv reply from arc", 0},
+               {&indicator_count, "indicator_count",
+                "ARC to MEI indicator count", 0},
+               {&cmv_count, "cmv_count", "MEI to ARC CMVs", 0},
+               {&reply_count, "reply_count", "ARC to MEI Reply", 0},
+               {(int *) Recent_indicator, "Recent_indicator",
+                "most recent indicator", 0},
+               {(int *) 8, "version", "version of firmware", 0},
+       };
+       do_gettimeofday (&time_disconnect);
+
+       printk ("Danube MEI version:%s\n", IFXMIPS_MEI_VERSION);
+
+       memcpy ((char *) regs, (char *) regs_temp, sizeof (regs_temp));
+       MEI_MUTEX_INIT (mei_sema, 1);   // semaphore initialization, mutex
+       MEI_INIT_WAKELIST ("arcq", wait_queue_arcmsgav);        // for ARCMSGAV
+       MEI_INIT_WAKELIST ("arcldq", wait_queue_loop_diagnostic);       // for loop diagnostic function
+#ifdef IFX_ADSL_L3_MODE_SUPPORT
+       MEI_INIT_WAKELIST ("arcl3q", wait_queue_l3);    // for l3 power mode
+#endif //IFX_ADSL_L3_MODE_SUPPORT
+
+
+       memset (&adsl_mem_info[0], 0, sizeof (smmu_mem_info_t) * MAX_BAR_REGISTERS);
+#if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
+       printk("not enabling mei leds due to bug that makes the board hang\n");
+//     ifxmips_mei_led_init ();
+#endif
+
+#ifdef CONFIG_IFXMIPS_MEI_MIB
+       ifxmips_mei_mib_init ();
+#endif
+
+#ifdef IFXMIPS_CLEAR_EOC
+       MEI_INIT_WAKELIST ("arceoc", wait_queue_hdlc_poll);
+       ifxmips_mei_ceoc_init ();
+#endif
+       // power up mei 
+       temp = ifxmips_r32(IFXMIPS_PMU_PWDCR);
+       temp &= 0xffff7dbe;
+       ifxmips_w32(temp, IFXMIPS_PMU_PWDCR);
+
+#if defined (CONFIG_ATM_IFXMIPS)
+       IFX_ATM_LED_Callback_Register (adsl_led_flash);
+#endif
+       if (register_chrdev (major, IFXMIPS_MEI_DEVNAME, &mei_operations) != 0) {
+               printk("\n\n unable to register major for ifxmips_mei!!!");
+               return -ENODEV;
+       } else {
+               printk("registered ifxmips_mei on #%d\n", major);
+       }
+
+       disable_irq(IFXMIPS_MEI_INT);
+
+       if (request_irq(IFXMIPS_MEI_INT, mei_interrupt_arcmsgav, 0, "ifxmips_mei_arcmsgav", NULL) != 0) {
+               printk("\n\n unable to register irq(%d) for ifxmips_mei!!!",
+                       IFXMIPS_MEI_INT);
+               return -1;
+       }
+
+//     enable_irq(IFXMIPS_MEI_INT);
+       // procfs
+       meidir = proc_mkdir(MEI_DIRNAME, &proc_root);
+       if (meidir == NULL)
+       {
+               printk(": can't create /proc/" MEI_DIRNAME "\n\n");
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < NUM_OF_REG_ENTRY; i++) {
+               entry = create_proc_entry (regs[i].name,
+                                          S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, meidir);
+               if (entry)
+               {
+                       regs[i].low_ino = entry->low_ino;
+                       entry->proc_fops = &proc_operations;
+               } else {
+                       printk (": can't create /proc/" MEI_DIRNAME "/%s\n\n", regs[i].name);
+                       return -ENOMEM;
+               }
+       }
+
+       ///////////////////////////////// register net device ////////////////////////////
+#ifdef DFE_LOOPBACK
+       DFE_Loopback_Test ();
+#endif //DFE_LOOPBACK
+       return 0;
+}
+
+void __exit
+ifxmips_mei_cleanup_module (void)
+{
+       int i;
+
+#if defined(CONFIG_IFXMIPS_MEI_LED) && defined(DATA_LED_SUPPORT)
+       ifxmips_mei_led_cleanup ();
+#endif
+       showtime = 0;           //joelin,clear task
+
+#ifdef CONFIG_PROC_FS
+       for (i = 0; i < NUM_OF_REG_ENTRY; i++)
+               remove_proc_entry (regs[i].name, meidir);
+
+       remove_proc_entry (MEI_DIRNAME, &proc_root);
+#endif //CONFIG_PROC_FS
+
+#if defined (CONFIG_ATM_IFXMIPS)
+       IFX_ATM_LED_Callback_Unregister (adsl_led_flash);
+#endif
+       disable_irq (IFXMIPS_MEI_INT);
+       free_irq(IFXMIPS_MEI_INT, NULL);
+
+#ifdef CONFIG_DEVFS_FS
+       devfs_unregister (mei_devfs_handle);
+#else
+       unregister_chrdev (major, "ifxmips_mei");
+#endif
+#ifdef CONFIG_IFXMIPS_MEI_MIB
+       ifxmips_mei_mib_cleanup ();
+#endif
+
+       free_image_buffer (FREE_ALL);
+       return;
+}
+
+EXPORT_SYMBOL (meiDebugRead);
+EXPORT_SYMBOL (meiDebugWrite);
+EXPORT_SYMBOL (ifx_me_hdlc_send);
+EXPORT_SYMBOL (ifx_mei_hdlc_read);
+MODULE_LICENSE ("GPL");
+
+module_init (ifxmips_mei_init_module);
+module_exit (ifxmips_mei_cleanup_module);
diff --git a/target/linux/ifxmips/files/drivers/char/ifxmips_ssc.c b/target/linux/ifxmips/files/drivers/char/ifxmips_ssc.c
new file mode 100644 (file)
index 0000000..35b32e8
--- /dev/null
@@ -0,0 +1,1417 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2006 infineon
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ *
+ */
+
+// ### TO DO: general issues:
+//            - power management
+//            - interrupt handling (direct/indirect)
+//            - pin/mux-handling (just overall concept due to project dependency)
+//            - multiple instances capability
+//            - slave functionality
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+#include <asm/ifxmips/ifx_ssc_defines.h>
+#include <asm/ifxmips/ifx_ssc.h>
+
+/* allow the user to set the major device number */
+static int maj = 0;
+
+/*
+ * This is the per-channel data structure containing pointers, flags
+ * and variables for the port. This driver supports a maximum of PORT_CNT.
+ * isp is allocated in ifx_ssc_init() based on the chip version.
+ */
+static struct ifx_ssc_port *isp;
+
+/* other forward declarations */
+static unsigned int ifx_ssc_get_kernel_clk (struct ifx_ssc_port *info);
+static void tx_int (struct ifx_ssc_port *);
+
+extern unsigned int ifxmips_get_fpi_hz (void);
+extern void ifxmips_mask_and_ack_irq (unsigned int irq_nr);
+
+static inline unsigned int
+ifx_ssc_get_kernel_clk (struct ifx_ssc_port *info)
+{
+       unsigned int rmc;
+
+       rmc = (ifxmips_r32(IFXMIPS_SSC_CLC) & IFX_CLC_RUN_DIVIDER_MASK) >> IFX_CLC_RUN_DIVIDER_OFFSET;
+       if (rmc == 0)
+       {
+               printk ("ifx_ssc_get_kernel_clk rmc==0 \n");
+               return 0;
+       }
+       return ifxmips_get_fpi_hz () / rmc;
+}
+
+inline static void
+rx_int (struct ifx_ssc_port *info)
+{
+       int fifo_fill_lev, bytes_in_buf, i;
+       unsigned long tmp_val;
+       unsigned long *tmp_ptr;
+       unsigned int rx_valid_cnt;
+       /* number of words waiting in the RX FIFO */
+       fifo_fill_lev = (ifxmips_r32(IFXMIPS_SSC_FSTAT) & IFX_SSC_FSTAT_RECEIVED_WORDS_MASK) >> IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET;
+       bytes_in_buf = info->rxbuf_end - info->rxbuf_ptr;
+       // transfer with 32 bits per entry
+       while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) {
+               tmp_ptr = (unsigned long *) info->rxbuf_ptr;
+               *tmp_ptr = ifxmips_r32(IFXMIPS_SSC_RB);
+               info->rxbuf_ptr += 4;
+               info->stats.rxBytes += 4;
+               fifo_fill_lev--;
+               bytes_in_buf -= 4;
+       }
+
+       // now do the rest as mentioned in STATE.RXBV
+       while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) {
+               rx_valid_cnt = (ifxmips_r32(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET;
+               if (rx_valid_cnt == 0)
+                       break;
+
+               if (rx_valid_cnt > bytes_in_buf)
+                       rx_valid_cnt = bytes_in_buf;
+
+               tmp_val = ifxmips_r32(IFXMIPS_SSC_RB);
+
+               for (i = 0; i < rx_valid_cnt; i++)
+               {
+                       *info->rxbuf_ptr = (tmp_val >> (8 * (rx_valid_cnt - i - 1))) & 0xff;
+                       bytes_in_buf--;
+                       info->rxbuf_ptr++;
+               }
+               info->stats.rxBytes += rx_valid_cnt;
+       }
+
+       // check if transfer is complete
+       if (info->rxbuf_ptr >= info->rxbuf_end)
+       {
+               disable_irq(IFXMIPS_SSC_RIR);
+               wake_up_interruptible (&info->rwait);
+       } else if ((info->opts.modeRxTx == IFX_SSC_MODE_RX) && (ifxmips_r32(IFXMIPS_SSC_RXCNT) == 0))
+       {
+               if (info->rxbuf_end - info->rxbuf_ptr < IFX_SSC_RXREQ_BLOCK_SIZE)
+                       ifxmips_w32((info->rxbuf_end - info->rxbuf_ptr) << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
+               else
+                       ifxmips_w32(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET,  IFXMIPS_SSC_RXREQ);
+       }
+}
+
+inline static void
+tx_int (struct ifx_ssc_port *info)
+{
+
+       int fifo_space, fill, i;
+       fifo_space = ((ifxmips_r32(IFXMIPS_SSC_ID) & IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET)
+               - ((ifxmips_r32(IFXMIPS_SSC_FSTAT) & IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK) >> IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET);
+
+       if (fifo_space == 0)
+               return;
+
+       fill = info->txbuf_end - info->txbuf_ptr;
+
+       if (fill > fifo_space * 4)
+               fill = fifo_space * 4;
+
+       for (i = 0; i < fill / 4; i++)
+       {
+               // at first 32 bit access
+               ifxmips_w32(*(UINT32 *) info->txbuf_ptr, IFXMIPS_SSC_TB);
+               info->txbuf_ptr += 4;
+       }
+
+       fifo_space -= fill / 4;
+       info->stats.txBytes += fill & ~0x3;
+       fill &= 0x3;
+       if ((fifo_space > 0) & (fill > 1))
+       {
+               // trailing 16 bit access
+               WRITE_PERIPHERAL_REGISTER_16 (*(UINT16 *) info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
+               info->txbuf_ptr += 2;
+               info->stats.txBytes += 2;
+               fifo_space--;
+               fill -= 2;
+       }
+
+       if ((fifo_space > 0) & (fill > 0))
+       {
+               // trailing 8 bit access
+               WRITE_PERIPHERAL_REGISTER_8 (*(UINT8 *) info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
+               info->txbuf_ptr++;
+               info->stats.txBytes++;
+       }
+
+       // check if transmission complete
+       if (info->txbuf_ptr >= info->txbuf_end)
+       {
+               disable_irq(IFXMIPS_SSC_TIR);
+               kfree (info->txbuf);
+               info->txbuf = NULL;
+       }
+
+}
+
+irqreturn_t
+ifx_ssc_rx_int (int irq, void *dev_id)
+{
+       struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id;
+       rx_int (info);
+
+       return IRQ_HANDLED;
+}
+
+irqreturn_t
+ifx_ssc_tx_int (int irq, void *dev_id)
+{
+       struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id;
+       tx_int (info);
+
+       return IRQ_HANDLED;
+}
+
+irqreturn_t
+ifx_ssc_err_int (int irq, void *dev_id)
+{
+       struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id;
+       unsigned int state;
+       unsigned int write_back = 0;
+       unsigned long flags;
+
+       local_irq_save (flags);
+       state = ifxmips_r32(IFXMIPS_SSC_STATE);
+
+       if ((state & IFX_SSC_STATE_RX_UFL) != 0) {
+               info->stats.rxUnErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR;
+       }
+
+       if ((state & IFX_SSC_STATE_RX_OFL) != 0) {
+               info->stats.rxOvErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR;
+       }
+
+       if ((state & IFX_SSC_STATE_TX_OFL) != 0) {
+               info->stats.txOvErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR;
+       }
+
+       if ((state & IFX_SSC_STATE_TX_UFL) != 0) {
+               info->stats.txUnErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR;
+       }
+
+       if ((state & IFX_SSC_STATE_MODE_ERR) != 0) {
+               info->stats.modeErr++;
+               write_back |= IFX_SSC_WHBSTATE_CLR_MODE_ERROR;
+       }
+
+       if (write_back)
+               ifxmips_w32(write_back, IFXMIPS_SSC_WHBSTATE);
+
+       local_irq_restore (flags);
+
+       return IRQ_HANDLED;
+}
+
+static void
+ifx_ssc_abort (struct ifx_ssc_port *info)
+{
+       unsigned long flags;
+       bool enabled;
+
+       local_irq_save (flags);
+
+       disable_irq(IFXMIPS_SSC_RIR);
+       disable_irq(IFXMIPS_SSC_TIR);
+       disable_irq(IFXMIPS_SSC_EIR);
+
+       local_irq_restore (flags);
+
+       // disable SSC (also aborts a receive request!)
+       // ### TO DO: Perhaps it's better to abort after the receiption of a 
+       // complete word. The disable cuts the transmission immediatly and 
+       // releases the chip selects. This could result in unpredictable 
+       // behavior of connected external devices!
+       enabled = (ifxmips_r32(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_ENABLED) != 0;
+       ifxmips_w32(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
+
+       // flush fifos
+       ifxmips_w32(IFX_SSC_XFCON_FIFO_FLUSH, IFXMIPS_SSC_TXFCON);
+       ifxmips_w32(IFX_SSC_XFCON_FIFO_FLUSH, IFXMIPS_SSC_RXFCON);
+
+       // free txbuf
+       if (info->txbuf != NULL)
+       {
+               kfree (info->txbuf);
+               info->txbuf = NULL;
+       }
+
+       // wakeup read process
+       if (info->rxbuf != NULL)
+               wake_up_interruptible (&info->rwait);
+
+       // clear pending int's 
+       ifxmips_mask_and_ack_irq(IFXMIPS_SSC_RIR);
+       ifxmips_mask_and_ack_irq(IFXMIPS_SSC_TIR);
+       ifxmips_mask_and_ack_irq(IFXMIPS_SSC_EIR);
+
+       // clear error flags
+       ifxmips_w32(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, IFXMIPS_SSC_WHBSTATE);
+
+       if (enabled)
+               ifxmips_w32(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
+
+}
+
+/*
+ * This routine is called whenever a port is opened.  It enforces
+ * exclusive opening of a port and enables interrupts, etc.
+ */
+int
+ifx_ssc_open (struct inode *inode, struct file *filp)
+{
+       struct ifx_ssc_port *info;
+       int line;
+       int from_kernel = 0;
+
+       if ((inode == (struct inode *) 0) || (inode == (struct inode *) 1)) {
+               from_kernel = 1;
+               line = (int) inode;
+       } else {
+               line = MINOR (filp->f_dentry->d_inode->i_rdev);
+       }
+
+       /* don't open more minor devices than we can support */
+       if (line < 0 || line >= PORT_CNT)
+               return -ENXIO;
+
+       info = &isp[line];
+
+       /* exclusive open */
+       if (info->port_is_open != 0)
+               return -EBUSY;
+       info->port_is_open++;
+
+       disable_irq(IFXMIPS_SSC_RIR);
+       disable_irq(IFXMIPS_SSC_TIR);
+       disable_irq(IFXMIPS_SSC_EIR);
+
+       /* Flush and enable TX/RX FIFO */
+       ifxmips_w32((IFX_SSC_DEF_TXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_FLUSH | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_TXFCON);
+       ifxmips_w32((IFX_SSC_DEF_RXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_FLUSH | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_RXFCON);
+
+       /* logically flush the software FIFOs */
+       info->rxbuf_ptr = 0;
+       info->txbuf_ptr = 0;
+
+       /* clear all error bits */
+       ifxmips_w32(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, IFXMIPS_SSC_WHBSTATE);
+
+       // clear pending interrupts
+       ifxmips_mask_and_ack_irq(IFXMIPS_SSC_RIR);
+       ifxmips_mask_and_ack_irq(IFXMIPS_SSC_TIR);
+       ifxmips_mask_and_ack_irq(IFXMIPS_SSC_EIR);
+
+       ifxmips_w32(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
+
+       return 0;
+}
+EXPORT_SYMBOL(ifx_ssc_open);
+
+int
+ifx_ssc_close (struct inode *inode, struct file *filp)
+{
+       struct ifx_ssc_port *info;
+       int idx;
+
+       if ((inode == (struct inode *) 0) || (inode == (struct inode *) 1))
+               idx = (int) inode;
+       else
+               idx = MINOR (filp->f_dentry->d_inode->i_rdev);
+
+       if (idx < 0 || idx >= PORT_CNT)
+               return -ENXIO;
+
+       info = &isp[idx];
+       if (!info)
+               return -ENXIO;
+
+       ifxmips_w32(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
+
+       ifx_ssc_abort(info);
+
+       info->port_is_open--;
+
+       return 0;
+}
+EXPORT_SYMBOL(ifx_ssc_close);
+
+static ssize_t
+ifx_ssc_read_helper_poll (struct ifx_ssc_port *info, char *buf, size_t len, int from_kernel)
+{
+       ssize_t ret_val;
+       unsigned long flags;
+
+       if (info->opts.modeRxTx == IFX_SSC_MODE_TX)
+               return -EFAULT;
+       local_irq_save (flags);
+       info->rxbuf_ptr = info->rxbuf;
+       info->rxbuf_end = info->rxbuf + len;
+       local_irq_restore (flags);
+       /* Vinetic driver always works in IFX_SSC_MODE_RXTX */
+       /* TXRX in poll mode */
+       while (info->rxbuf_ptr < info->rxbuf_end)
+       {
+               if (info->txbuf_ptr < info->txbuf_end)
+                       tx_int (info);
+
+               rx_int (info);
+       };
+
+       ret_val = info->rxbuf_ptr - info->rxbuf;
+
+       return ret_val;
+}
+
+static ssize_t
+ifx_ssc_read_helper (struct ifx_ssc_port *info, char *buf, size_t len, int from_kernel)
+{
+       ssize_t ret_val;
+       unsigned long flags;
+       DECLARE_WAITQUEUE (wait, current);
+
+       if (info->opts.modeRxTx == IFX_SSC_MODE_TX)
+               return -EFAULT;
+
+       local_irq_save (flags);
+       info->rxbuf_ptr = info->rxbuf;
+       info->rxbuf_end = info->rxbuf + len;
+
+       if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX)
+       {
+               if ((info->txbuf == NULL) || (info->txbuf != info->txbuf_ptr) || (info->txbuf_end != len + info->txbuf))
+               {
+                       local_irq_restore (flags);
+                       printk ("IFX SSC - %s: write must be called before calling " "read in combined RX/TX!\n", __func__);
+                       return -EFAULT;
+               }
+
+               local_irq_restore(flags);
+               tx_int (info);
+
+               if (info->txbuf_ptr < info->txbuf_end)
+                       enable_irq(IFXMIPS_SSC_TIR);
+
+               enable_irq(IFXMIPS_SSC_RIR);
+       } else {
+               local_irq_restore(flags);
+               if (ifxmips_r32(IFXMIPS_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK)
+                       return -EBUSY;
+               enable_irq(IFXMIPS_SSC_RIR);
+               if (len < IFX_SSC_RXREQ_BLOCK_SIZE)
+                       ifxmips_w32(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
+               else
+                       ifxmips_w32(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
+       }
+
+       __add_wait_queue (&info->rwait, &wait);
+       set_current_state (TASK_INTERRUPTIBLE);
+
+       do {
+               local_irq_save (flags);
+               if (info->rxbuf_ptr >= info->rxbuf_end)
+                       break;
+
+               local_irq_restore (flags);
+
+               if (signal_pending (current))
+               {
+                       ret_val = -ERESTARTSYS;
+                       goto out;
+               }
+               schedule();
+       } while (1);
+
+       ret_val = info->rxbuf_ptr - info->rxbuf;
+       local_irq_restore (flags);
+
+out:
+       current->state = TASK_RUNNING;
+       __remove_wait_queue (&info->rwait, &wait);
+
+       return (ret_val);
+}
+
+static ssize_t
+ifx_ssc_write_helper (struct ifx_ssc_port *info, const char *buf,
+                     size_t len, int from_kernel)
+{
+       if (info->opts.modeRxTx == IFX_SSC_MODE_RX)
+               return -EFAULT;
+
+       info->txbuf_ptr = info->txbuf;
+       info->txbuf_end = len + info->txbuf;
+       if (info->opts.modeRxTx == IFX_SSC_MODE_TX)
+       {
+               tx_int (info);
+               if (info->txbuf_ptr < info->txbuf_end)
+               {
+                       enable_irq(IFXMIPS_SSC_TIR);
+               }
+       }
+
+       return len;
+}
+
+ssize_t
+ifx_ssc_kread (int port, char *kbuf, size_t len)
+{
+       struct ifx_ssc_port *info;
+       ssize_t ret_val;
+
+       if (port < 0 || port >= PORT_CNT)
+               return -ENXIO;
+
+       if (len == 0)
+               return 0;
+
+       info = &isp[port];
+
+       if (info->rxbuf != NULL)
+       {
+               printk ("SSC device busy\n");
+               return -EBUSY;
+       }
+
+       info->rxbuf = kbuf;
+       if (info->rxbuf == NULL)
+       {
+               printk ("SSC device error\n");
+               return -EINVAL;
+       }
+
+       ret_val = ifx_ssc_read_helper_poll (info, kbuf, len, 1);
+       info->rxbuf = NULL;
+
+       disable_irq(IFXMIPS_SSC_RIR);
+
+       return ret_val;
+}
+EXPORT_SYMBOL(ifx_ssc_kread);
+
+ssize_t
+ifx_ssc_kwrite (int port, const char *kbuf, size_t len)
+{
+       struct ifx_ssc_port *info;
+       ssize_t ret_val;
+
+       if (port < 0 || port >= PORT_CNT)
+               return -ENXIO;
+
+       if (len == 0)
+               return 0;
+
+       info = &isp[port];
+
+       // check if transmission in progress
+       if (info->txbuf != NULL)
+               return -EBUSY;
+
+       info->txbuf = (char *) kbuf;
+
+       ret_val = ifx_ssc_write_helper (info, info->txbuf, len, 1);
+
+       if (ret_val < 0)
+               info->txbuf = NULL;
+
+       return ret_val;
+}
+EXPORT_SYMBOL(ifx_ssc_kwrite);
+
+static ssize_t
+ifx_ssc_read (struct file *filp, char *ubuf, size_t len, loff_t * off)
+{
+       ssize_t ret_val;
+       int idx;
+       struct ifx_ssc_port *info;
+
+       idx = MINOR (filp->f_dentry->d_inode->i_rdev);
+       info = &isp[idx];
+
+       if (info->rxbuf != NULL)
+               return -EBUSY;
+
+       info->rxbuf = kmalloc (len + 3, GFP_KERNEL);
+       if (info->rxbuf == NULL)
+               return -ENOMEM;
+
+       ret_val = ifx_ssc_read_helper (info, info->rxbuf, len, 0);
+       if (copy_to_user ((void *) ubuf, info->rxbuf, ret_val) != 0)
+               ret_val = -EFAULT;
+
+       disable_irq(IFXMIPS_SSC_RIR);
+
+       kfree (info->rxbuf);
+       info->rxbuf = NULL;
+
+       return (ret_val);
+}
+
+static ssize_t
+ifx_ssc_write (struct file *filp, const char *ubuf, size_t len, loff_t * off)
+{
+       int idx;
+       struct ifx_ssc_port *info;
+       int ret_val;
+
+       if (len == 0)
+               return (0);
+
+       idx = MINOR (filp->f_dentry->d_inode->i_rdev);
+       info = &isp[idx];
+
+       if (info->txbuf != NULL)
+               return -EBUSY;
+
+       info->txbuf = kmalloc (len + 3, GFP_KERNEL);
+       if (info->txbuf == NULL)
+               return -ENOMEM;
+
+       ret_val = copy_from_user (info->txbuf, ubuf, len);
+       if (ret_val == 0)
+               ret_val = ifx_ssc_write_helper (info, info->txbuf, len, 0);
+       else
+               ret_val = -EFAULT;
+
+       if (ret_val < 0)
+       {
+               kfree (info->txbuf);
+               info->txbuf = NULL;
+       }
+
+       return (ret_val);
+}
+
+static struct ifx_ssc_frm_status *
+ifx_ssc_frm_status_get (struct ifx_ssc_port *info)
+{
+       unsigned long tmp;
+
+       tmp = ifxmips_r32(IFXMIPS_SSC_SFSTAT);
+       info->frm_status.DataBusy = (tmp & IFX_SSC_SFSTAT_IN_DATA) > 0;
+       info->frm_status.PauseBusy = (tmp & IFX_SSC_SFSTAT_IN_PAUSE) > 0;
+       info->frm_status.DataCount = (tmp & IFX_SSC_SFSTAT_DATA_COUNT_MASK) >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET;
+       info->frm_status.PauseCount = (tmp & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET;
+       tmp = ifxmips_r32(IFXMIPS_SSC_SFCON);
+       info->frm_status.EnIntAfterData = (tmp & IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE) > 0;
+       info->frm_status.EnIntAfterPause = (tmp & IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE) > 0;
+
+       return &info->frm_status;
+}
+
+
+static struct ifx_ssc_frm_opts *
+ifx_ssc_frm_control_get (struct ifx_ssc_port *info)
+{
+       unsigned long tmp;
+
+       tmp = ifxmips_r32(IFXMIPS_SSC_SFCON);
+       info->frm_opts.FrameEnable = (tmp & IFX_SSC_SFCON_SF_ENABLE) > 0;
+       info->frm_opts.DataLength = (tmp & IFX_SSC_SFCON_DATA_LENGTH_MASK) >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
+       info->frm_opts.PauseLength = (tmp & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
+       info->frm_opts.IdleData = (tmp & IFX_SSC_SFCON_PAUSE_DATA_MASK) >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
+       info->frm_opts.IdleClock = (tmp & IFX_SSC_SFCON_PAUSE_CLOCK_MASK) >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
+       info->frm_opts.StopAfterPause = (tmp & IFX_SSC_SFCON_STOP_AFTER_PAUSE) > 0;
+
+       return &info->frm_opts;
+}
+
+static int
+ifx_ssc_frm_control_set (struct ifx_ssc_port *info)
+{
+       unsigned long tmp;
+
+       if ((info->frm_opts.DataLength > IFX_SSC_SFCON_DATA_LENGTH_MAX)
+           || (info->frm_opts.DataLength < 1)
+           || (info->frm_opts.PauseLength > IFX_SSC_SFCON_PAUSE_LENGTH_MAX)
+           || (info->frm_opts.PauseLength < 1)
+           || (info->frm_opts.IdleData & ~(IFX_SSC_SFCON_PAUSE_DATA_MASK >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET))
+           || (info->frm_opts.IdleClock & ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET)))
+               return -EINVAL;
+
+       // read interrupt bits (they're not changed here)
+       tmp = ifxmips_r32(IFXMIPS_SSC_SFCON) &
+               (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE | IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE);
+
+       // set all values with respect to it's bit position (for data and pause 
+       // length set N-1)
+       tmp = (info->frm_opts.DataLength - 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
+       tmp |= (info->frm_opts.PauseLength - 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
+       tmp |= info->frm_opts.IdleData << IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
+       tmp |= info->frm_opts.IdleClock << IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
+       tmp |= info->frm_opts.FrameEnable * IFX_SSC_SFCON_SF_ENABLE;
+       tmp |= info->frm_opts.StopAfterPause * IFX_SSC_SFCON_STOP_AFTER_PAUSE;
+
+       ifxmips_w32(tmp, IFXMIPS_SSC_SFCON);
+
+       return 0;
+}
+
+static int
+ifx_ssc_rxtx_mode_set (struct ifx_ssc_port *info, unsigned int val)
+{
+       unsigned long tmp;
+
+       if (!(info) || (val & ~(IFX_SSC_MODE_MASK)))
+               return -EINVAL;
+
+       if ((ifxmips_r32(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_BUSY)
+           || (ifxmips_r32(IFXMIPS_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK))
+               return -EBUSY;
+
+       tmp = (ifxmips_r32(IFXMIPS_SSC_CON) & ~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)) | (val);
+       ifxmips_w32(tmp, IFXMIPS_SSC_SFCON);
+       info->opts.modeRxTx = val;
+
+       return 0;
+}
+
+static int
+ifx_ssc_sethwopts (struct ifx_ssc_port *info)
+{
+       unsigned long flags, bits;
+       struct ifx_ssc_hwopts *opts = &info->opts;
+
+       if ((opts->dataWidth < IFX_SSC_MIN_DATA_WIDTH)
+           || (opts->dataWidth > IFX_SSC_MAX_DATA_WIDTH))
+               return -EINVAL;
+
+       bits = (opts->dataWidth - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET;
+       bits |= IFX_SSC_CON_ENABLE_BYTE_VALID;
+
+       if (opts->rxOvErrDetect)
+               bits |= IFX_SSC_CON_RX_OFL_CHECK;
+       if (opts->rxUndErrDetect)
+               bits |= IFX_SSC_CON_RX_UFL_CHECK;
+       if (opts->txOvErrDetect)
+               bits |= IFX_SSC_CON_TX_OFL_CHECK;
+       if (opts->txUndErrDetect)
+               bits |= IFX_SSC_CON_TX_UFL_CHECK;
+       if (opts->loopBack)
+               bits |= IFX_SSC_CON_LOOPBACK_MODE;
+       if (opts->echoMode)
+               bits |= IFX_SSC_CON_ECHO_MODE_ON;
+       if (opts->headingControl)
+               bits |= IFX_SSC_CON_MSB_FIRST;
+       if (opts->clockPhase)
+               bits |= IFX_SSC_CON_LATCH_THEN_SHIFT;
+       if (opts->clockPolarity)
+               bits |= IFX_SSC_CON_CLOCK_FALL;
+
+       switch (opts->modeRxTx)
+       {
+       case IFX_SSC_MODE_TX:
+               bits |= IFX_SSC_CON_RX_OFF;
+               break;
+       case IFX_SSC_MODE_RX:
+               bits |= IFX_SSC_CON_TX_OFF;
+               break;
+       }
+
+       local_irq_save (flags);
+
+       ifxmips_w32(bits, IFXMIPS_SSC_CON);
+       ifxmips_w32((info->opts.gpoCs << IFX_SSC_GPOCON_ISCSB0_POS) |
+                                  (info->opts.gpoInv << IFX_SSC_GPOCON_INVOUT0_POS), IFXMIPS_SSC_GPOCON);
+
+       ifxmips_w32(info->opts.gpoCs << IFX_SSC_WHBGPOSTAT_SETOUT0_POS, IFXMIPS_SSC_WHBGPOSTAT);
+
+       //master mode
+       if (opts->masterSelect)
+               ifxmips_w32(IFX_SSC_WHBSTATE_SET_MASTER_SELECT, IFXMIPS_SSC_WHBSTATE);
+       else
+               ifxmips_w32(IFX_SSC_WHBSTATE_CLR_MASTER_SELECT, IFXMIPS_SSC_WHBSTATE);
+
+       // init serial framing
+       ifxmips_w32(0, IFXMIPS_SSC_SFCON);
+       /* set up the port pins */
+       //check for general requirements to switch (external) pad/pin characteristics
+       /* TODO: P0.9 SPI_CS4, P0.10 SPI_CS5, P 0.11 SPI_CS6, because of ASC0 */
+       /* p0.15 SPI_CS1(EEPROM), P0.13 SPI_CS3, */
+       /* Set p0.15 to alternative 01, others to 00 (In/OUT) */
+       *(IFXMIPS_GPIO_P0_DIR) = (*IFXMIPS_GPIO_P0_DIR) | (0xA000);
+       *(IFXMIPS_GPIO_P0_ALTSEL0) = (((*IFXMIPS_GPIO_P0_ALTSEL0) | (0x8000)) & (~(0x2000)));
+       *(IFXMIPS_GPIO_P0_ALTSEL1) = (((*IFXMIPS_GPIO_P0_ALTSEL1) & (~0x8000)) & (~(0x2000)));
+       *(IFXMIPS_GPIO_P0_OD) = (*IFXMIPS_GPIO_P0_OD) | 0xA000;
+
+       /* p1.6 SPI_CS2(SFLASH), p1.0 SPI_DIN, p1.1 SPI_DOUT, p1.2 SPI_CLK */
+       *(IFXMIPS_GPIO_P1_DIR) = ((*IFXMIPS_GPIO_P1_DIR) | (0x46)) & (~1);
+       *(IFXMIPS_GPIO_P1_ALTSEL0) = ((*IFXMIPS_GPIO_P1_ALTSEL0) | (0x47));
+       *(IFXMIPS_GPIO_P1_ALTSEL1) = (*IFXMIPS_GPIO_P1_ALTSEL1) & (~0x47);
+       *(IFXMIPS_GPIO_P1_OD) = (*IFXMIPS_GPIO_P1_OD) | 0x0046;
+
+       /*CS3 */
+       /*TODO: CS4 CS5 CS6 */
+       *IFXMIPS_GPIO_P0_OUT = ((*IFXMIPS_GPIO_P0_OUT) | 0x2000);
+
+       local_irq_restore (flags);
+
+       return 0;
+}
+
+static int
+ifx_ssc_set_baud (struct ifx_ssc_port *info, unsigned int baud)
+{
+       unsigned int ifx_ssc_clock;
+       unsigned int br;
+       unsigned long flags;
+       bool enabled;
+       int retval = 0;
+
+       ifx_ssc_clock = ifx_ssc_get_kernel_clk(info);
+       if (ifx_ssc_clock == 0)
+       {
+               retval = -EINVAL;
+               goto out;
+       }
+
+       local_irq_save (flags);
+
+       enabled = (ifxmips_r32(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_ENABLED);
+       ifxmips_w32(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
+
+       br = (((ifx_ssc_clock >> 1) + baud / 2) / baud) - 1;
+       wmb();
+
+       if (br > 0xffff || ((br == 0) &&
+                       ((ifxmips_r32(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_MASTER) == 0))) {
+               local_irq_restore (flags);
+               printk ("%s: invalid baudrate %u\n", __func__, baud);
+               return -EINVAL;
+       }
+
+       ifxmips_w32(br, IFXMIPS_SSC_BR);
+
+       if (enabled)
+               ifxmips_w32(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
+
+       local_irq_restore(flags);
+
+out:
+       return retval;
+}
+
+static int
+ifx_ssc_hwinit (struct ifx_ssc_port *info)
+{
+       unsigned long flags;
+       bool enabled;
+
+       enabled = (ifxmips_r32(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_ENABLED);
+       ifxmips_w32(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
+
+       if (ifx_ssc_sethwopts (info) < 0)
+       {
+               printk ("%s: setting the hardware options failed\n", __func__);
+               return -EINVAL;
+       }
+
+       if (ifx_ssc_set_baud (info, info->baud) < 0)
+       {
+               printk ("%s: setting the baud rate failed\n", __func__);
+               return -EINVAL;
+       }
+
+       local_irq_save (flags);
+
+       /* TX FIFO */
+       ifxmips_w32((IFX_SSC_DEF_TXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_TXFCON);
+       /* RX FIFO */
+       ifxmips_w32((IFX_SSC_DEF_RXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_RXFCON);
+
+       local_irq_restore (flags);
+
+       if (enabled)
+               ifxmips_w32(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
+
+       return 0;
+}
+
+int
+ifx_ssc_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data)
+{
+       struct ifx_ssc_port *info;
+       int line, ret_val = 0;
+       unsigned long flags;
+       unsigned long tmp;
+       int from_kernel = 0;
+
+       if ((inode == (struct inode *) 0) || (inode == (struct inode *) 1))
+       {
+               from_kernel = 1;
+               line = (int) inode;
+       } else {
+               line = MINOR (filp->f_dentry->d_inode->i_rdev);
+       }
+
+       if (line < 0 || line >= PORT_CNT)
+               return -ENXIO;
+
+       info = &isp[line];
+
+       switch (cmd)
+       {
+       case IFX_SSC_STATS_READ:
+               /* data must be a pointer to a struct ifx_ssc_statistics */
+               if (from_kernel)
+                       memcpy ((void *) data, (void *) &info->stats,
+                               sizeof (struct ifx_ssc_statistics));
+               else if (copy_to_user ((void *) data,
+                                      (void *) &info->stats,
+                                      sizeof (struct ifx_ssc_statistics)))
+                       ret_val = -EFAULT;
+               break;
+       case IFX_SSC_STATS_RESET:
+               /* just resets the statistics counters */
+               memset ((void *) &info->stats, 0,
+                       sizeof (struct ifx_ssc_statistics));
+               break;
+       case IFX_SSC_BAUD_SET:
+               /* if the buffers are not empty then the port is */
+               /* busy and we shouldn't change things on-the-fly! */
+               if (!info->txbuf || !info->rxbuf ||
+                   (ifxmips_r32(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_BUSY)) {
+                       ret_val = -EBUSY;
+                       break;
+               }
+               /* misuse flags */
+               if (from_kernel)
+                       flags = *((unsigned long *) data);
+               else if (copy_from_user ((void *) &flags,
+                                        (void *) data, sizeof (flags))) {
+                       ret_val = -EFAULT;
+                       break;
+               }
+               if (flags == 0) {
+                       ret_val = -EINVAL;
+                       break;
+               }
+               if (ifx_ssc_set_baud (info, flags) < 0) {
+                       ret_val = -EINVAL;
+                       break;
+               }
+               info->baud = flags;
+               break;
+       case IFX_SSC_BAUD_GET:
+               if (from_kernel)
+                       *((unsigned int *) data) = info->baud;
+               else if (copy_to_user ((void *) data,
+                                      (void *) &info->baud,
+                                      sizeof (unsigned long)))
+                       ret_val = -EFAULT;
+               break;
+       case IFX_SSC_RXTX_MODE_SET:
+               if (from_kernel)
+                       tmp = *((unsigned long *) data);
+               else if (copy_from_user ((void *) &tmp,
+                                        (void *) data, sizeof (tmp))) {
+                       ret_val = -EFAULT;
+                       break;
+               }
+               ret_val = ifx_ssc_rxtx_mode_set (info, tmp);
+               break;
+       case IFX_SSC_RXTX_MODE_GET:
+               tmp = ifxmips_r32(IFXMIPS_SSC_CON) &
+                       (~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF));
+               if (from_kernel)
+                       *((unsigned int *) data) = tmp;
+               else if (copy_to_user ((void *) data,
+                                      (void *) &tmp, sizeof (tmp)))
+                       ret_val = -EFAULT;
+               break;
+
+       case IFX_SSC_ABORT:
+               ifx_ssc_abort (info);
+               break;
+
+       case IFX_SSC_GPO_OUT_SET:
+               if (from_kernel)
+                       tmp = *((unsigned long *) data);
+               else if (copy_from_user ((void *) &tmp,
+                                        (void *) data, sizeof (tmp))) {
+                       ret_val = -EFAULT;
+                       break;
+               }
+               if (tmp > IFX_SSC_MAX_GPO_OUT)
+                       ret_val = -EINVAL;
+               else
+                       ifxmips_w32(1 << (tmp + IFX_SSC_WHBGPOSTAT_SETOUT0_POS),
+                                IFXMIPS_SSC_WHBGPOSTAT);
+               break;
+       case IFX_SSC_GPO_OUT_CLR:
+               if (from_kernel)
+                       tmp = *((unsigned long *) data);
+               else if (copy_from_user ((void *) &tmp, (void *) data, sizeof (tmp))) {
+                       ret_val = -EFAULT;
+                       break;
+               }
+               if (tmp > IFX_SSC_MAX_GPO_OUT)
+                       ret_val = -EINVAL;
+               else {
+                       ifxmips_w32(1 << (tmp + IFX_SSC_WHBGPOSTAT_CLROUT0_POS),
+                                IFXMIPS_SSC_WHBGPOSTAT);
+               }
+               break;
+       case IFX_SSC_GPO_OUT_GET:
+               tmp = ifxmips_r32(IFXMIPS_SSC_GPOSTAT);
+               if (from_kernel)
+                       *((unsigned int *) data) = tmp;
+               else if (copy_to_user ((void *) data,
+                                      (void *) &tmp, sizeof (tmp)))
+                       ret_val = -EFAULT;
+               break;
+       case IFX_SSC_FRM_STATUS_GET:
+               ifx_ssc_frm_status_get (info);
+               if (from_kernel)
+                       memcpy ((void *) data, (void *) &info->frm_status,
+                               sizeof (struct ifx_ssc_frm_status));
+               else if (copy_to_user ((void *) data,
+                                      (void *) &info->frm_status,
+                                      sizeof (struct ifx_ssc_frm_status)))
+                       ret_val = -EFAULT;
+               break;
+       case IFX_SSC_FRM_CONTROL_GET:
+               ifx_ssc_frm_control_get (info);
+               if (from_kernel)
+                       memcpy ((void *) data, (void *) &info->frm_opts,
+                               sizeof (struct ifx_ssc_frm_opts));
+               else if (copy_to_user ((void *) data,
+                                      (void *) &info->frm_opts,
+                                      sizeof (struct ifx_ssc_frm_opts)))
+                       ret_val = -EFAULT;
+               break;
+       case IFX_SSC_FRM_CONTROL_SET:
+               if (from_kernel)
+                       memcpy ((void *) &info->frm_opts, (void *) data,
+                               sizeof (struct ifx_ssc_frm_opts));
+               else if (copy_to_user ((void *) &info->frm_opts,
+                                      (void *) data,
+                                      sizeof (struct ifx_ssc_frm_opts))) {
+                       ret_val = -EFAULT;
+                       break;
+               }
+               ret_val = ifx_ssc_frm_control_set (info);
+               break;
+       case IFX_SSC_HWOPTS_SET:
+               /* data must be a pointer to a struct ifx_ssc_hwopts */
+               /* if the buffers are not empty then the port is */
+               /* busy and we shouldn't change things on-the-fly! */
+               if (!info->txbuf || !info->rxbuf ||
+                   (ifxmips_r32(IFXMIPS_SSC_STATE)
+                    & IFX_SSC_STATE_BUSY)) {
+                       ret_val = -EBUSY;
+                       break;
+               }
+               if (from_kernel)
+                       memcpy ((void *) &info->opts, (void *) data,
+                               sizeof (struct ifx_ssc_hwopts));
+               else if (copy_from_user ((void *) &info->opts,
+                                        (void *) data, sizeof(struct ifx_ssc_hwopts))) {
+                       ret_val = -EFAULT;
+                       break;
+               }
+               if (ifx_ssc_hwinit (info) < 0) {
+                       ret_val = -EIO;
+               }
+               break;
+       case IFX_SSC_HWOPTS_GET:
+               /* data must be a pointer to a struct ifx_ssc_hwopts */
+               if (from_kernel)
+                       memcpy ((void *) data, (void *) &info->opts,
+                               sizeof (struct ifx_ssc_hwopts));
+               else if (copy_to_user ((void *) data,
+                                      (void *) &info->opts,
+                                      sizeof (struct ifx_ssc_hwopts)))
+                       ret_val = -EFAULT;
+               break;
+       default:
+               ret_val = -ENOIOCTLCMD;
+       }
+
+       return ret_val;
+}
+EXPORT_SYMBOL(ifx_ssc_ioctl);
+
+static struct file_operations ifx_ssc_fops = {
+      .owner = THIS_MODULE,
+      .read = ifx_ssc_read,
+      .write = ifx_ssc_write,
+      .ioctl = ifx_ssc_ioctl,
+      .open = ifx_ssc_open,
+      .release = ifx_ssc_close,
+};
+
+int __init
+ifx_ssc_init (void)
+{
+       struct ifx_ssc_port *info;
+       int i, nbytes;
+       unsigned long flags;
+       int ret_val;
+
+       ret_val = -ENOMEM;
+       nbytes = PORT_CNT * sizeof(struct ifx_ssc_port);
+       isp = (struct ifx_ssc_port*)kmalloc(nbytes, GFP_KERNEL);
+
+       if (isp == NULL)
+       {
+               printk("%s: no memory for isp\n", __func__);
+               return (ret_val);
+       }
+       memset(isp, 0, nbytes);
+
+       ret_val = -ENXIO;
+       if ((i = register_chrdev (maj, "ssc", &ifx_ssc_fops)) < 0)
+       {
+               printk ("Unable to register major %d for the Infineon SSC\n", maj);
+               if (maj == 0)
+               {
+                       goto errout;
+               } else {
+                       maj = 0;
+                       if ((i = register_chrdev (maj, "ssc", &ifx_ssc_fops)) < 0)
+                       {
+                               printk ("Unable to register major %d for the Infineon SSC\n", maj);
+                               goto errout;
+                       }
+               }
+       }
+
+       if (maj == 0)
+               maj = i;
+
+       /* set default values in ifx_ssc_port */
+       for (i = 0; i < PORT_CNT; i++) {
+               info = &isp[i];
+               info->port_nr = i;
+               /* default values for the HwOpts */
+               info->opts.AbortErrDetect = IFX_SSC_DEF_ABRT_ERR_DETECT;
+               info->opts.rxOvErrDetect = IFX_SSC_DEF_RO_ERR_DETECT;
+               info->opts.rxUndErrDetect = IFX_SSC_DEF_RU_ERR_DETECT;
+               info->opts.txOvErrDetect = IFX_SSC_DEF_TO_ERR_DETECT;
+               info->opts.txUndErrDetect = IFX_SSC_DEF_TU_ERR_DETECT;
+               info->opts.loopBack = IFX_SSC_DEF_LOOP_BACK;
+               info->opts.echoMode = IFX_SSC_DEF_ECHO_MODE;
+               info->opts.idleValue = IFX_SSC_DEF_IDLE_DATA;
+               info->opts.clockPolarity = IFX_SSC_DEF_CLOCK_POLARITY;
+               info->opts.clockPhase = IFX_SSC_DEF_CLOCK_PHASE;
+               info->opts.headingControl = IFX_SSC_DEF_HEADING_CONTROL;
+               info->opts.dataWidth = IFX_SSC_DEF_DATA_WIDTH;
+               info->opts.modeRxTx = IFX_SSC_DEF_MODE_RXTX;
+               info->opts.gpoCs = IFX_SSC_DEF_GPO_CS;
+               info->opts.gpoInv = IFX_SSC_DEF_GPO_INV;
+               info->opts.masterSelect = IFX_SSC_DEF_MASTERSLAVE;
+               info->baud = IFX_SSC_DEF_BAUDRATE;
+               info->rxbuf = NULL;
+               info->txbuf = NULL;
+               /* values specific to SSC1 */
+               if (i == 0) {
+                       info->mapbase = IFXMIPS_SSC_BASE_ADDR;
+               }
+
+               ifxmips_w32(IFX_SSC_DEF_RMC << IFX_CLC_RUN_DIVIDER_OFFSET, IFXMIPS_SSC_CLC);
+
+               init_waitqueue_head (&info->rwait);
+
+               local_irq_save (flags);
+
+               // init serial framing register
+               ifxmips_w32(IFX_SSC_DEF_SFCON, IFXMIPS_SSC_SFCON);
+
+               ret_val = request_irq(IFXMIPS_SSC_TIR, ifx_ssc_tx_int, IRQF_DISABLED, "ifx_ssc_tx", info);
+               if (ret_val)
+               {
+                       printk("%s: unable to get irq %d\n", __func__, IFXMIPS_SSC_TIR);
+                       local_irq_restore(flags);
+                       goto errout;
+               }
+
+               ret_val = request_irq(IFXMIPS_SSC_RIR, ifx_ssc_rx_int, IRQF_DISABLED, "ifx_ssc_rx", info);
+               if (ret_val)
+               {
+                       printk ("%s: unable to get irq %d\n", __func__, IFXMIPS_SSC_RIR);
+                       local_irq_restore (flags);
+                       goto irqerr;
+               }
+
+               ret_val = request_irq(IFXMIPS_SSC_EIR, ifx_ssc_err_int, IRQF_DISABLED, "ifx_ssc_err", info);
+               if (ret_val)
+               {
+                       printk ("%s: unable to get irq %d\n", __func__, IFXMIPS_SSC_EIR);
+                       local_irq_restore (flags);
+                       goto irqerr;
+               }
+               ifxmips_w32(IFX_SSC_DEF_IRNEN, IFXMIPS_SSC_IRN);
+
+               //enable_irq(IFXMIPS_SSC_TIR);
+               //enable_irq(IFXMIPS_SSC_RIR);
+               //enable_irq(IFXMIPS_SSC_EIR);
+
+               local_irq_restore (flags);
+       }
+
+       for (i = 0; i < PORT_CNT; i++) {
+               info = &isp[i];
+               if (ifx_ssc_hwinit (info) < 0)
+               {
+                       printk ("%s: hardware init failed for port %d\n", __func__, i);
+                       goto irqerr;
+               }
+       }
+
+
+       return 0;
+
+irqerr:
+       free_irq(IFXMIPS_SSC_TIR, &isp[0]);
+       free_irq(IFXMIPS_SSC_RIR, &isp[0]);
+       free_irq(IFXMIPS_SSC_EIR, &isp[0]);
+errout:
+       kfree (isp);
+       return (ret_val);
+}
+
+void
+ifx_ssc_cleanup_module (void)
+{
+       int i;
+
+       for (i = 0; i < PORT_CNT; i++) {
+               ifxmips_w32(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
+               free_irq(IFXMIPS_SSC_TIR, &isp[i]);
+               free_irq(IFXMIPS_SSC_RIR, &isp[i]);
+               free_irq(IFXMIPS_SSC_EIR, &isp[i]);
+       }
+       kfree (isp);
+}
+
+module_init(ifx_ssc_init);
+module_exit(ifx_ssc_cleanup_module);
+
+
+inline int
+ifx_ssc_cs_low (u32 pin)
+{
+       int ret = 0;
+       if ((ret = ifx_ssc_ioctl ((struct inode *) 0, NULL, IFX_SSC_GPO_OUT_CLR, (unsigned long) &pin)))
+               printk ("clear CS %d fails\n", pin);
+       wmb ();
+
+       return ret;
+}
+EXPORT_SYMBOL(ifx_ssc_cs_low);
+
+inline int
+ifx_ssc_cs_high (u32 pin)
+{
+       int ret = 0;
+       if ((ret = ifx_ssc_ioctl((struct inode *) 0, NULL, IFX_SSC_GPO_OUT_SET, (unsigned long) &pin)))
+               printk ("set CS %d fails\n", pin);
+       wmb ();
+
+       return ret;
+}
+EXPORT_SYMBOL(ifx_ssc_cs_high);
+
+static int
+ssc_session (char *tx_buf, u32 tx_len, char *rx_buf, u32 rx_len)
+{
+       int ret = 0;
+
+       char *ssc_tx_buf = NULL;
+       char *ssc_rx_buf = NULL;
+       int eff_size = 0;
+       u8 mode = 0;
+
+       if (tx_buf == NULL && tx_len == 0 && rx_buf == NULL && rx_len == 0) {
+               printk ("invalid parameters\n");
+               ret = -EINVAL;
+               goto ssc_session_exit;
+       }
+       else if (tx_buf == NULL || tx_len == 0) {
+               if (rx_buf != NULL && rx_len != 0) {
+                       mode = IFX_SSC_MODE_RX;
+               }
+               else {
+                       printk ("invalid parameters\n");
+                       ret = -EINVAL;
+                       goto ssc_session_exit;
+               }
+       }
+       else if (rx_buf == NULL || rx_len == 0) {
+               if (tx_buf != NULL && tx_len != 0) {
+                       mode = IFX_SSC_MODE_TX;
+               }
+               else {
+                       printk ("invalid parameters\n");
+                       ret = -EINVAL;
+                       goto ssc_session_exit;
+               }
+       }
+       else {
+               mode = IFX_SSC_MODE_RXTX;
+       }
+
+       if (mode == IFX_SSC_MODE_RXTX) {
+               eff_size = tx_len + rx_len;
+       }
+       else if (mode == IFX_SSC_MODE_RX) {
+               eff_size = rx_len;
+       }
+       else {
+               eff_size = tx_len;
+       }
+
+       //4 bytes alignment,  required by driver
+       /* change by TaiCheng */
+       //if (in_irq()){
+       if (1) {
+               ssc_tx_buf =
+                       (char *) kmalloc (sizeof (char) *
+                                         ((eff_size + 3) & (~3)),
+                                         GFP_ATOMIC);
+               ssc_rx_buf =
+                       (char *) kmalloc (sizeof (char) *
+                                         ((eff_size + 3) & (~3)),
+                                         GFP_ATOMIC);
+       }
+       else {
+               ssc_tx_buf =
+                       (char *) kmalloc (sizeof (char) *
+                                         ((eff_size + 3) & (~3)),
+                                         GFP_KERNEL);
+               ssc_rx_buf =
+                       (char *) kmalloc (sizeof (char) *
+                                         ((eff_size + 3) & (~3)),
+                                         GFP_KERNEL);
+       }
+       if (ssc_tx_buf == NULL || ssc_rx_buf == NULL) {
+               printk ("no memory for size of %d\n", eff_size);
+               ret = -ENOMEM;
+               goto ssc_session_exit;
+       }
+       memset ((void *) ssc_tx_buf, 0, eff_size);
+       memset ((void *) ssc_rx_buf, 0, eff_size);
+
+       if (tx_len > 0) {
+               memcpy (ssc_tx_buf, tx_buf, tx_len);
+       }
+
+       ret = ifx_ssc_kwrite (0, ssc_tx_buf, eff_size);
+
+       if (ret > 0) {
+               ssc_tx_buf = NULL;      //should be freed by ifx_ssc_kwrite
+       }
+
+       if (ret != eff_size) {
+               printk ("ifx_ssc_write return %d\n", ret);
+               goto ssc_session_exit;
+       }
+       ret = ifx_ssc_kread (0, ssc_rx_buf, eff_size);
+       if (ret != eff_size) {
+               printk ("ifx_ssc_read return %d\n", ret);
+               goto ssc_session_exit;
+       }
+
+       memcpy (rx_buf, ssc_rx_buf + tx_len, rx_len);
+
+       if (mode == IFX_SSC_MODE_TX) {
+               ret = tx_len;
+       }
+       else {
+               ret = rx_len;
+       }
+      ssc_session_exit:
+
+       if (ssc_tx_buf != NULL)
+               kfree (ssc_tx_buf);
+       if (ssc_rx_buf != NULL)
+               kfree (ssc_rx_buf);
+
+       if (ret < 0) {
+               printk ("ssc session fails\n");
+       }
+       return ret;
+}
+
+int
+ifx_ssc_txrx (char *tx_buf, u32 tx_len, char *rx_buf, u32 rx_len)
+{
+       return ssc_session(tx_buf, tx_len, rx_buf, rx_len);
+}
+EXPORT_SYMBOL(ifx_ssc_txrx);
+
+int
+ifx_ssc_tx (char *tx_buf, u32 tx_len)
+{
+       return ssc_session(tx_buf, tx_len, NULL, 0);
+}
+EXPORT_SYMBOL(ifx_ssc_tx);
+
+int
+ifx_ssc_rx (char *rx_buf, u32 rx_len)
+{
+       return ssc_session(NULL, 0, rx_buf, rx_len);
+}
+EXPORT_SYMBOL(ifx_ssc_rx);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("ifxmips ssc driver");
+
diff --git a/target/linux/ifxmips/files/drivers/leds/leds-ifxmips.c b/target/linux/ifxmips/files/drivers/leds/leds-ifxmips.c
new file mode 100644 (file)
index 0000000..090516c
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2006 infineon
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+#include <linux/errno.h>
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_gpio.h>
+#include <asm/ifxmips/ifxmips_pmu.h>
+#include <linux/leds.h>
+#include <linux/delay.h>
+
+#define DRVNAME                                                        "ifxmips_led"
+
+#define IFXMIPS_LED_CLK_EDGE                   IFXMIPS_LED_FALLING
+//#define IFXMIPS_LED_CLK_EDGE                 IFXMIPS_LED_RISING
+
+#define IFXMIPS_LED_SPEED                              IFXMIPS_LED_8HZ
+
+#define IFXMIPS_LED_GPIO_PORT                  0
+
+#define IFXMIPS_MAX_LED                                        24
+
+struct ifxmips_led {
+       struct led_classdev cdev;
+       u8 bit;
+};
+
+void
+ifxmips_led_set (unsigned int led)
+{
+       led &= 0xffffff;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CPU0) | led, IFXMIPS_LED_CPU0);
+}
+EXPORT_SYMBOL(ifxmips_led_set);
+
+void
+ifxmips_led_clear (unsigned int led)
+{
+       led = ~(led & 0xffffff);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CPU0) & led, IFXMIPS_LED_CPU0);
+}
+EXPORT_SYMBOL(ifxmips_led_clear);
+
+void
+ifxmips_led_blink_set (unsigned int led)
+{
+       led &= 0xffffff;
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CON0) | led, IFXMIPS_LED_CON0);
+}
+EXPORT_SYMBOL(ifxmips_led_blink_set);
+
+void
+ifxmips_led_blink_clear (unsigned int led)
+{
+       led = ~(led & 0xffffff);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CON0) & led, IFXMIPS_LED_CON0);
+}
+EXPORT_SYMBOL(ifxmips_led_blink_clear);
+
+void
+ifxmips_ledapi_set(struct led_classdev *led_cdev, enum led_brightness value)
+{
+       struct ifxmips_led *led_dev = container_of(led_cdev, struct ifxmips_led, cdev);
+
+       if(value)
+               ifxmips_led_set(1 << led_dev->bit);
+       else
+               ifxmips_led_clear(1 << led_dev->bit);
+}
+
+void
+ifxmips_led_setup_gpio (void)
+{
+       int i = 0;
+
+       /* we need to setup pins SH,D,ST (4,5,6) */
+       for (i = 4; i < 7; i++)
+       {
+               ifxmips_port_set_altsel0(IFXMIPS_LED_GPIO_PORT, i);
+               ifxmips_port_clear_altsel1(IFXMIPS_LED_GPIO_PORT, i);
+               ifxmips_port_set_dir_out(IFXMIPS_LED_GPIO_PORT, i);
+               ifxmips_port_set_open_drain(IFXMIPS_LED_GPIO_PORT, i);
+       }
+}
+
+static int
+ifxmips_led_probe(struct platform_device *dev)
+{
+       int i = 0;
+
+       ifxmips_led_setup_gpio();
+
+       ifxmips_w32(0, IFXMIPS_LED_AR);
+       ifxmips_w32(0, IFXMIPS_LED_CPU0);
+       ifxmips_w32(0, IFXMIPS_LED_CPU1);
+       ifxmips_w32(LED_CON0_SWU, IFXMIPS_LED_CON0);
+       ifxmips_w32(0, IFXMIPS_LED_CON1);
+
+       /* setup the clock edge that the shift register is triggered on */
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CON0) & ~IFXMIPS_LED_EDGE_MASK, IFXMIPS_LED_CON0);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CON0) | IFXMIPS_LED_CLK_EDGE, IFXMIPS_LED_CON0);
+
+       /* per default leds 15-0 are set */
+       ifxmips_w32(IFXMIPS_LED_GROUP1 | IFXMIPS_LED_GROUP0, IFXMIPS_LED_CON1);
+
+       /* leds are update periodically by the FPID */
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CON1) & ~IFXMIPS_LED_UPD_MASK, IFXMIPS_LED_CON1);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CON1) | IFXMIPS_LED_UPD_SRC_FPI, IFXMIPS_LED_CON1);
+
+       /* set led update speed */
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CON1) & ~IFXMIPS_LED_MASK, IFXMIPS_LED_CON1);
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CON1) | IFXMIPS_LED_SPEED, IFXMIPS_LED_CON1);
+
+       /* adsl 0 and 1 leds are updated by the arc */
+       ifxmips_w32(ifxmips_r32(IFXMIPS_LED_CON0) | IFXMIPS_LED_ADSL_SRC, IFXMIPS_LED_CON0);
+
+       /* per default, the leds are turned on */
+       ifxmips_pmu_enable(IFXMIPS_PMU_PWDCR_LED);
+
+       for(i = 0; i < IFXMIPS_MAX_LED; i++)
+       {
+               struct ifxmips_led *tmp = kzalloc(sizeof(struct ifxmips_led), GFP_KERNEL);
+               tmp->cdev.brightness_set = ifxmips_ledapi_set;
+               tmp->cdev.name = kmalloc(sizeof("ifxmips:led:00"), GFP_KERNEL);
+               sprintf((char*)tmp->cdev.name, "ifxmips:led:%02d", i);
+               tmp->cdev.default_trigger = NULL;
+               tmp->bit = i;
+               led_classdev_register(&dev->dev, &tmp->cdev);
+       }
+
+       return 0;
+}
+
+static int
+ifxmips_led_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static struct
+platform_driver ifxmips_led_driver = {
+       .probe = ifxmips_led_probe,
+       .remove = ifxmips_led_remove,
+       .driver = {
+               .name = DRVNAME,
+               .owner = THIS_MODULE,
+       },
+};
+
+int __init
+ifxmips_led_init (void)
+{
+       int ret = platform_driver_register(&ifxmips_led_driver);
+       if (ret)
+               printk(KERN_INFO "ifxmips_led: Error registering platfom driver!");
+
+       return ret;
+}
+
+void __exit
+ifxmips_led_exit (void)
+{
+       platform_driver_unregister(&ifxmips_led_driver);
+}
+
+module_init(ifxmips_led_init);
+module_exit(ifxmips_led_exit);
diff --git a/target/linux/ifxmips/files/drivers/mtd/maps/ifxmips.c b/target/linux/ifxmips/files/drivers/mtd/maps/ifxmips.c
new file mode 100644 (file)
index 0000000..b3692e7
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * 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
+ *
+ * Copyright (C) 2004 Liu Peng Infineon IFAP DC COM CPE
+ * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_prom.h>
+#include <asm/ifxmips/ifxmips_ebu.h>
+#include <linux/magic.h>
+#include <linux/platform_device.h>
+
+static struct map_info
+ifxmips_map = {
+       .name = "ifxmips_mtd",
+       .bankwidth = 2,
+       .size = 0x400000,
+};
+
+static map_word
+ifxmips_read16(struct map_info * map, unsigned long adr)
+{
+       unsigned long flags;
+       map_word temp;
+       spin_lock_irqsave(&ebu_lock, flags);
+       adr ^= 2;
+       temp.x[0] = *((__u16*)(map->virt + adr));
+       spin_unlock_irqrestore(&ebu_lock, flags);
+       return temp;
+}
+
+static void
+ifxmips_write16(struct map_info *map, map_word d, unsigned long adr)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&ebu_lock, flags);
+       adr ^= 2;
+       *((__u16*)(map->virt + adr)) = d.x[0];
+       spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+void
+ifxmips_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+       unsigned char *p;
+       unsigned char *to_8;
+       unsigned long flags;
+       spin_lock_irqsave(&ebu_lock, flags);
+       from = (unsigned long)(from + map->virt);
+       p = (unsigned char*) from;
+       to_8 = (unsigned char*) to;
+       while(len--)
+               *to_8++ = *p++;
+       spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+void
+ifxmips_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+       unsigned char *p =  (unsigned char*)from;
+       unsigned char *to_8;
+       unsigned long flags;
+       spin_lock_irqsave(&ebu_lock, flags);
+       to += (unsigned long) map->virt;
+       to_8 = (unsigned char*)to;
+       while(len--)
+               *p++ = *to_8++;
+       spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+static struct mtd_partition
+ifxmips_partitions[] = {
+       {
+               name:"uboot",
+               offset:0x00000000,
+               size:0x00020000,
+       },
+       {
+               name:"uboot_env",
+               offset:0x00020000,
+               size:0x00010000,
+       },
+       {
+               name:"kernel",
+               offset:0x00030000,
+               size:0x0,
+       },
+       {
+               name:"rootfs",
+               offset:0x0,
+               size:0x0,
+       },
+       {
+               name:"board_config",
+               offset:0x0,
+               size:0x0,
+       },
+};
+
+int
+find_uImage_size(unsigned long start_offset){
+       unsigned long temp;
+       ifxmips_copy_from(&ifxmips_map, &temp, start_offset + 12, 4);
+       printk(KERN_INFO "ifxmips_mtd: kernel size is %ld \n", temp + 0x40);
+       return temp + 0x40;
+}
+
+int
+find_brn_block(unsigned long start_offset){
+       unsigned char temp[9];
+       ifxmips_copy_from(&ifxmips_map, &temp, start_offset, 8);
+       temp[8] = '\0';
+       printk(KERN_INFO "data in brn block %s\n", temp);
+       if(memcmp(temp, "BRN-BOOT", 8) == 0)
+               return 1;
+       else
+               return 0;
+}
+
+int
+detect_squashfs_partition(unsigned long start_offset){
+       unsigned long temp;
+       ifxmips_copy_from(&ifxmips_map, &temp, start_offset, 4);
+       return (temp == SQUASHFS_MAGIC);
+}
+
+static int
+ifxmips_mtd_probe(struct platform_device *dev)
+{
+       struct mtd_info *ifxmips_mtd = NULL;
+       struct mtd_partition *parts = NULL;
+       unsigned long uimage_size;
+
+       ifxmips_w32(0x1d7ff, IFXMIPS_EBU_BUSCON0);
+
+       ifxmips_map.read = ifxmips_read16;
+       ifxmips_map.write = ifxmips_write16;
+       ifxmips_map.copy_from = ifxmips_copy_from;
+       ifxmips_map.copy_to = ifxmips_copy_to;
+       ifxmips_map.phys = dev->resource->start;
+       ifxmips_map.size = dev->resource->end - ifxmips_map.phys + 1;
+       ifxmips_map.virt = ioremap_nocache(ifxmips_map.phys, ifxmips_map.size);
+
+       if(!ifxmips_map.virt)
+       {
+               printk(KERN_WARNING "ifxmips_mtd: failed to ioremap!\n");
+               return -EIO;
+       }
+
+       ifxmips_mtd = (struct mtd_info *) do_map_probe("cfi_probe", &ifxmips_map);
+       if(!ifxmips_mtd)
+       {
+               iounmap(ifxmips_map.virt);
+               printk(KERN_WARNING "ifxmips_mtd: probing failed\n");
+               return -ENXIO;
+       }
+
+       ifxmips_mtd->owner = THIS_MODULE;
+       uimage_size = find_uImage_size(ifxmips_partitions[2].offset);
+
+       if(detect_squashfs_partition(ifxmips_partitions[2].offset + uimage_size))
+       {
+               printk(KERN_INFO "ifxmips_mtd: found a squashfs following the uImage\n");
+       } else {
+               uimage_size &= ~0xffff;
+               uimage_size += 0x10000;
+       }
+
+       parts = &ifxmips_partitions[0];
+       ifxmips_partitions[2].size = uimage_size;
+       ifxmips_partitions[3].offset = ifxmips_partitions[2].offset + ifxmips_partitions[2].size;
+       ifxmips_partitions[3].size = ((ifxmips_mtd->size >> 20) * 1024 * 1024) - ifxmips_partitions[3].offset;
+       if(ifxmips_has_brn_block())
+       {
+               ifxmips_partitions[3].size -= ifxmips_mtd->erasesize;
+               ifxmips_partitions[4].offset = ifxmips_mtd->size - ifxmips_mtd->erasesize;
+               ifxmips_partitions[4].size = ifxmips_mtd->erasesize;
+               add_mtd_partitions(ifxmips_mtd, parts, 5);
+       } else {
+               add_mtd_partitions(ifxmips_mtd, parts, 4);
+       }
+
+       printk(KERN_INFO "ifxmips_mtd: added ifxmips flash with %dMB\n", ifxmips_mtd->size >> 20);
+       return 0;
+}
+
+static struct
+platform_driver ifxmips_mtd_driver = {
+       .probe = ifxmips_mtd_probe,
+       .driver = {
+               .name = "ifxmips_mtd",
+               .owner = THIS_MODULE,
+       },
+};
+
+int __init
+init_ifxmips_mtd(void)
+{
+       int ret = platform_driver_register(&ifxmips_mtd_driver);
+       if(ret)
+               printk(KERN_INFO "ifxmips_mtd: error registering platfom driver!");
+       return ret;
+}
+
+static void __exit
+cleanup_ifxmips_mtd(void)
+{
+       platform_driver_unregister(&ifxmips_mtd_driver);
+}
+
+module_init(init_ifxmips_mtd);
+module_exit(cleanup_ifxmips_mtd);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("MTD map driver for IFXMIPS boards");
diff --git a/target/linux/ifxmips/files/drivers/net/ifxmips_mii0.c b/target/linux/ifxmips/files/drivers/net/ifxmips_mii0.c
new file mode 100644 (file)
index 0000000..fe7f25e
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2005 Wu Qi Ming <Qi-Ming.Wu@infineon.com>
+ *   Copyright (C) 2008 John Crispin <blogic@openwrt.org> 
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <linux/in.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/ethtool.h>
+#include <asm/checksum.h>
+#include <linux/init.h>
+#include <asm/delay.h>
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_dma.h>
+#include <asm/ifxmips/ifxmips_pmu.h>
+
+struct ifxmips_mii_priv {
+       struct net_device_stats stats;
+       struct dma_device_info *dma_device;
+       struct sk_buff *skb;
+};
+
+static struct net_device *ifxmips_mii0_dev;
+static unsigned char mac_addr[MAX_ADDR_LEN];
+
+void
+ifxmips_write_mdio(u32 phy_addr, u32 phy_reg, u16 phy_data)
+{
+       u32 val = MDIO_ACC_REQUEST |
+               ((phy_addr & MDIO_ACC_ADDR_MASK) << MDIO_ACC_ADDR_OFFSET) |
+               ((phy_reg & MDIO_ACC_REG_MASK) << MDIO_ACC_REG_OFFSET) |
+               phy_data;
+
+       while(ifxmips_r32(IFXMIPS_PPE32_MDIO_ACC) & MDIO_ACC_REQUEST);
+       ifxmips_w32(val, IFXMIPS_PPE32_MDIO_ACC);
+}
+EXPORT_SYMBOL(ifxmips_write_mdio);
+
+unsigned short
+ifxmips_read_mdio(u32 phy_addr, u32 phy_reg)
+{
+       u32 val = MDIO_ACC_REQUEST | MDIO_ACC_READ |
+               ((phy_addr & MDIO_ACC_ADDR_MASK) << MDIO_ACC_ADDR_OFFSET) |
+               ((phy_reg & MDIO_ACC_REG_MASK) << MDIO_ACC_REG_OFFSET);
+
+       while(ifxmips_r32(IFXMIPS_PPE32_MDIO_ACC) & MDIO_ACC_REQUEST);
+       ifxmips_w32(val, IFXMIPS_PPE32_MDIO_ACC);
+       while(ifxmips_r32(IFXMIPS_PPE32_MDIO_ACC) & MDIO_ACC_REQUEST){};
+       val = ifxmips_r32(IFXMIPS_PPE32_MDIO_ACC) & MDIO_ACC_VAL_MASK;
+       return val;
+}
+EXPORT_SYMBOL(ifxmips_read_mdio);
+
+int
+ifxmips_ifxmips_mii_open(struct net_device *dev)
+{
+       struct ifxmips_mii_priv* priv = (struct ifxmips_mii_priv*)dev->priv;
+       struct dma_device_info* dma_dev = priv->dma_device;
+       int i;
+
+       for(i = 0; i < dma_dev->max_rx_chan_num; i++)
+       {
+               if((dma_dev->rx_chan[i])->control == IFXMIPS_DMA_CH_ON)
+                       (dma_dev->rx_chan[i])->open(dma_dev->rx_chan[i]);
+       }
+       netif_start_queue(dev);
+       return 0;
+}
+
+int
+ifxmips_mii_release(struct net_device *dev){
+       struct ifxmips_mii_priv* priv = (struct ifxmips_mii_priv*)dev->priv;
+       struct dma_device_info* dma_dev = priv->dma_device;
+       int i;
+
+       for(i = 0; i < dma_dev->max_rx_chan_num; i++)
+               dma_dev->rx_chan[i]->close(dma_dev->rx_chan[i]);
+       netif_stop_queue(dev);
+       return 0;
+}
+
+int
+ifxmips_mii_hw_receive(struct net_device* dev,struct dma_device_info* dma_dev)
+{
+       struct ifxmips_mii_priv *priv = (struct ifxmips_mii_priv*)dev->priv;
+       unsigned char* buf = NULL;
+       struct sk_buff *skb = NULL;
+       int len = 0;
+
+       len = dma_device_read(dma_dev, &buf, (void**)&skb);
+
+       if(len >= ETHERNET_PACKET_DMA_BUFFER_SIZE)
+       {
+               printk(KERN_INFO "ifxmips_mii0: packet too large %d\n",len);
+               goto ifxmips_mii_hw_receive_err_exit;
+       }
+
+       /* remove CRC */
+       len -= 4;
+       if(skb == NULL)
+       {
+               printk(KERN_INFO "ifxmips_mii0: cannot restore pointer\n");
+               goto ifxmips_mii_hw_receive_err_exit;
+       }
+
+       if(len > (skb->end - skb->tail))
+       {
+               printk(KERN_INFO "ifxmips_mii0: BUG, len:%d end:%p tail:%p\n",
+                       (len+4), skb->end, skb->tail);
+               goto ifxmips_mii_hw_receive_err_exit;
+       }
+
+       skb_put(skb, len);
+       skb->dev = dev;
+       skb->protocol = eth_type_trans(skb, dev);
+       netif_rx(skb);
+
+       priv->stats.rx_packets++;
+       priv->stats.rx_bytes += len;
+       return 0;
+
+ifxmips_mii_hw_receive_err_exit:
+       if(len == 0)
+       {
+               if(skb)
+                       dev_kfree_skb_any(skb);
+               priv->stats.rx_errors++;
+               priv->stats.rx_dropped++;
+               return -EIO;
+       } else {
+               return len;
+       }
+}
+
+int
+ifxmips_mii_hw_tx(char *buf, int len, struct net_device *dev)
+{
+       int ret = 0;
+       struct ifxmips_mii_priv *priv = dev->priv;
+       struct dma_device_info* dma_dev = priv->dma_device;
+       ret = dma_device_write(dma_dev, buf, len, priv->skb);
+       return ret;
+}
+
+int
+ifxmips_mii_tx(struct sk_buff *skb, struct net_device *dev)
+{
+       int len;
+       char *data;
+       struct ifxmips_mii_priv *priv = dev->priv;
+       struct dma_device_info* dma_dev = priv->dma_device;
+
+       len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+       data = skb->data;
+       priv->skb = skb;
+       dev->trans_start = jiffies;
+       // TODO we got more than 1 dma channel, so we should do something intelligent
+       // here to select one
+       dma_dev->current_tx_chan = 0;
+
+       wmb();
+
+       if(ifxmips_mii_hw_tx(data, len, dev) != len)
+       {
+               dev_kfree_skb_any(skb);
+               priv->stats.tx_errors++;
+               priv->stats.tx_dropped++;
+       } else {
+               priv->stats.tx_packets++;
+               priv->stats.tx_bytes+=len;
+       }
+
+       return 0;
+}
+
+void
+ifxmips_mii_tx_timeout(struct net_device *dev)
+{
+       int i;
+       struct ifxmips_mii_priv* priv = (struct ifxmips_mii_priv*)dev->priv;
+
+       priv->stats.tx_errors++;
+       for(i = 0; i < priv->dma_device->max_tx_chan_num; i++)
+               priv->dma_device->tx_chan[i]->disable_irq(priv->dma_device->tx_chan[i]);
+       netif_wake_queue(dev);
+       return;
+}
+
+int
+dma_intr_handler(struct dma_device_info* dma_dev, int status)
+{
+       int i;
+
+       switch(status)
+       {
+       case RCV_INT:
+               ifxmips_mii_hw_receive(ifxmips_mii0_dev, dma_dev);
+               break;
+
+       case TX_BUF_FULL_INT:
+               printk(KERN_INFO "ifxmips_mii0: tx buffer full\n");
+               netif_stop_queue(ifxmips_mii0_dev);
+               for (i = 0; i < dma_dev->max_tx_chan_num; i++)
+               {
+                       if ((dma_dev->tx_chan[i])->control==IFXMIPS_DMA_CH_ON)
+                               dma_dev->tx_chan[i]->enable_irq(dma_dev->tx_chan[i]);
+               }
+               break;
+
+       case TRANSMIT_CPT_INT:
+               for(i = 0; i < dma_dev->max_tx_chan_num; i++)
+                       dma_dev->tx_chan[i]->disable_irq(dma_dev->tx_chan[i]);
+
+               netif_wake_queue(ifxmips_mii0_dev);
+               break;
+       }
+
+       return 0;
+}
+
+unsigned char*
+ifxmips_etop_dma_buffer_alloc(int len, int *byte_offset, void **opt)
+{
+       unsigned char *buffer = NULL;
+       struct sk_buff *skb = NULL;
+
+       skb = dev_alloc_skb(ETHERNET_PACKET_DMA_BUFFER_SIZE);
+       if(skb == NULL)
+               return NULL;
+
+       buffer = (unsigned char*)(skb->data);
+       skb_reserve(skb, 2);
+       *(int*)opt = (int)skb;
+       *byte_offset = 2;
+
+       return buffer;
+}
+
+void
+ifxmips_etop_dma_buffer_free(unsigned char *dataptr, void *opt)
+{
+       struct sk_buff *skb = NULL;
+
+       if(opt == NULL)
+       {
+               kfree(dataptr);
+       } else {
+               skb = (struct sk_buff*)opt;
+               dev_kfree_skb_any(skb);
+       }
+}
+
+static struct net_device_stats*
+ifxmips_get_stats(struct net_device *dev)
+{
+       return (struct net_device_stats *)dev->priv;
+}
+
+static int
+ifxmips_mii_dev_init(struct net_device *dev)
+{
+       int i;
+       struct ifxmips_mii_priv *priv;
+
+       ether_setup(dev);
+       printk(KERN_INFO "ifxmips_mii0: %s is up\n", dev->name);
+       dev->open = ifxmips_ifxmips_mii_open;
+       dev->stop = ifxmips_mii_release;
+       dev->hard_start_xmit = ifxmips_mii_tx;
+       dev->get_stats = ifxmips_get_stats;
+       dev->tx_timeout = ifxmips_mii_tx_timeout;
+       dev->watchdog_timeo = 10 * HZ;
+       memset(dev->priv, 0, sizeof(struct ifxmips_mii_priv));
+       priv = dev->priv;
+       priv->dma_device = dma_device_reserve("PPE");
+       if(!priv->dma_device){
+               BUG();
+               return -ENODEV;
+       }
+       priv->dma_device->buffer_alloc = &ifxmips_etop_dma_buffer_alloc;
+       priv->dma_device->buffer_free = &ifxmips_etop_dma_buffer_free;
+       priv->dma_device->intr_handler = &dma_intr_handler;
+       priv->dma_device->max_rx_chan_num = 4;
+
+       for(i = 0; i < priv->dma_device->max_rx_chan_num; i++)
+       {
+               priv->dma_device->rx_chan[i]->packet_size = ETHERNET_PACKET_DMA_BUFFER_SIZE;
+               priv->dma_device->rx_chan[i]->control = IFXMIPS_DMA_CH_ON;
+       }
+
+       for(i = 0; i < priv->dma_device->max_tx_chan_num; i++)
+               if(i == 0)
+                       priv->dma_device->tx_chan[i]->control = IFXMIPS_DMA_CH_ON;
+               else
+                       priv->dma_device->tx_chan[i]->control = IFXMIPS_DMA_CH_OFF;
+
+       dma_device_register(priv->dma_device);
+
+       printk(KERN_INFO "ifxmips_mii0: using mac=");
+       for(i = 0; i < 6; i++)
+       {
+               dev->dev_addr[i] = mac_addr[i];
+               printk("%02X%c", dev->dev_addr[i], (i == 5)?('\n'):(':'));
+       }
+       return 0;
+}
+
+static void
+ifxmips_mii_chip_init(int mode)
+{
+       ifxmips_pmu_enable(IFXMIPS_PMU_PWDCR_DMA);
+       ifxmips_pmu_enable(IFXMIPS_PMU_PWDCR_PPE);
+
+       if(mode == REV_MII_MODE)
+               ifxmips_w32_mask(PPE32_MII_MASK, PPE32_MII_REVERSE, IFXMIPS_PPE32_CFG);
+       else if(mode == MII_MODE)
+               ifxmips_w32_mask(PPE32_MII_MASK, PPE32_MII_NORMAL, IFXMIPS_PPE32_CFG);
+       ifxmips_w32(PPE32_PLEN_UNDER | PPE32_PLEN_OVER, IFXMIPS_PPE32_IG_PLEN_CTRL);
+       ifxmips_w32(PPE32_CGEN, IFXMIPS_PPE32_ENET_MAC_CFG);
+       wmb();
+}
+
+static int
+ifxmips_mii_probe(struct platform_device *dev)
+{
+       int result = 0;
+       unsigned char *mac = (unsigned char*)dev->dev.platform_data;
+       ifxmips_mii0_dev = alloc_etherdev(sizeof(struct ifxmips_mii_priv));
+       ifxmips_mii0_dev->init = ifxmips_mii_dev_init;
+       memcpy(mac_addr, mac, 6);
+       strcpy(ifxmips_mii0_dev->name, "eth%d");
+       ifxmips_mii_chip_init(REV_MII_MODE);
+       result = register_netdev(ifxmips_mii0_dev);
+       if (result)
+       {
+               printk(KERN_INFO "ifxmips_mii0: error %i registering device \"%s\"\n", result, ifxmips_mii0_dev->name);
+               goto out;
+       }
+
+       printk(KERN_INFO "ifxmips_mii0: driver loaded!\n");
+
+out:
+       return result;
+}
+
+static int
+ifxmips_mii_remove(struct platform_device *dev)
+{
+       struct ifxmips_mii_priv *priv = (struct ifxmips_mii_priv*)ifxmips_mii0_dev->priv;
+
+       printk(KERN_INFO "ifxmips_mii0: ifxmips_mii0 cleanup\n");
+
+       dma_device_unregister(priv->dma_device);
+       dma_device_release(priv->dma_device);
+       kfree(priv->dma_device);
+       kfree(ifxmips_mii0_dev->priv);
+       unregister_netdev(ifxmips_mii0_dev);
+       return 0;
+}
+
+static struct
+platform_driver ifxmips_mii_driver = {
+       .probe = ifxmips_mii_probe,
+       .remove = ifxmips_mii_remove,
+       .driver = {
+               .name = "ifxmips_mii0",
+               .owner = THIS_MODULE,
+       },
+};
+
+int __init
+ifxmips_mii_init(void)
+{
+       int ret = platform_driver_register(&ifxmips_mii_driver);
+       if (ret)
+               printk(KERN_INFO "ifxmips_mii0: Error registering platfom driver!");
+       return ret;
+}
+
+static void __exit
+ifxmips_mii_cleanup(void)
+{
+       platform_driver_unregister(&ifxmips_mii_driver);
+}
+
+module_init(ifxmips_mii_init);
+module_exit(ifxmips_mii_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("ethernet map driver for IFXMIPS boards");
diff --git a/target/linux/ifxmips/files/drivers/serial/ifxmips_asc.c b/target/linux/ifxmips/files/drivers/serial/ifxmips_asc.c
new file mode 100644 (file)
index 0000000..2dc8917
--- /dev/null
@@ -0,0 +1,599 @@
+/*
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ * 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
+ *
+ * Copyright (C) 2004 Infineon IFAP DC COM CPE
+ * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+
+#define PORT_IFXMIPSASC  111
+
+#include <linux/serial_core.h>
+
+#define UART_DUMMY_UER_RX 1
+
+static void ifxmipsasc_tx_chars(struct uart_port *port);
+extern void prom_printf(const char * fmt, ...);
+static struct uart_port ifxmipsasc_port[2];
+static struct uart_driver ifxmipsasc_reg;
+extern unsigned int ifxmips_get_fpi_hz(void);
+
+static void
+ifxmipsasc_stop_tx(struct uart_port *port)
+{
+       return;
+}
+
+static void
+ifxmipsasc_start_tx(struct uart_port *port)
+{
+       unsigned long flags;
+       local_irq_save(flags);
+       ifxmipsasc_tx_chars(port);
+       local_irq_restore(flags);
+       return;
+}
+
+static void
+ifxmipsasc_stop_rx(struct uart_port *port)
+{
+       ifxmips_w32(ASCWHBSTATE_CLRREN, port->membase + IFXMIPS_ASC_WHBSTATE);
+}
+
+static void
+ifxmipsasc_enable_ms(struct uart_port *port)
+{
+}
+
+static void
+ifxmipsasc_rx_chars(struct uart_port *port)
+{
+       struct tty_struct *tty = port->info->tty;
+       unsigned int ch = 0, rsr = 0, fifocnt;
+
+       fifocnt = ifxmips_r32(port->membase + IFXMIPS_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
+       while(fifocnt--)
+       {
+               u8 flag = TTY_NORMAL;
+               ch = ifxmips_r32(port->membase + IFXMIPS_ASC_RBUF);
+               rsr = (ifxmips_r32(port->membase + IFXMIPS_ASC_STATE) & ASCSTATE_ANY) | UART_DUMMY_UER_RX;
+               tty_flip_buffer_push(tty);
+               port->icount.rx++;
+
+               /*
+                * Note that the error handling code is
+                * out of the main execution path
+                */
+               if(rsr & ASCSTATE_ANY)
+               {
+                       if(rsr & ASCSTATE_PE)
+                       {
+                               port->icount.parity++;
+                               ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_WHBSTATE) | ASCWHBSTATE_CLRPE, port->membase + IFXMIPS_ASC_WHBSTATE);
+                       } else if(rsr & ASCSTATE_FE)
+                       {
+                               port->icount.frame++;
+                               ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_WHBSTATE) | ASCWHBSTATE_CLRFE, port->membase + IFXMIPS_ASC_WHBSTATE);
+                       }
+                       if(rsr & ASCSTATE_ROE)
+                       {
+                               port->icount.overrun++;
+                               ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_WHBSTATE) | ASCWHBSTATE_CLRROE, port->membase + IFXMIPS_ASC_WHBSTATE);
+                       }
+
+                       rsr &= port->read_status_mask;
+
+                       if(rsr & ASCSTATE_PE)
+                               flag = TTY_PARITY;
+                       else if(rsr & ASCSTATE_FE)
+                               flag = TTY_FRAME;
+               }
+
+               if((rsr & port->ignore_status_mask) == 0)
+                       tty_insert_flip_char(tty, ch, flag);
+
+               if(rsr & ASCSTATE_ROE)
+                       /*
+                        * Overrun is special, since it's reported
+                        * immediately, and doesn't affect the current
+                        * character
+                        */
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+       }
+       if(ch != 0)
+               tty_flip_buffer_push(tty);
+       return;
+}
+
+
+static void
+ifxmipsasc_tx_chars(struct uart_port *port)
+{
+       struct circ_buf *xmit = &port->info->xmit;
+       if(uart_tx_stopped(port))
+       {
+               ifxmipsasc_stop_tx(port);
+               return;
+       }
+
+       while(((ifxmips_r32(port->membase + IFXMIPS_ASC_FSTAT) & ASCFSTAT_TXFFLMASK)
+                               >> ASCFSTAT_TXFFLOFF) != TXFIFO_FULL)
+       {
+               if(port->x_char)
+               {
+                       ifxmips_w32(port->x_char, port->membase + IFXMIPS_ASC_TBUF);
+                       port->icount.tx++;
+                       port->x_char = 0;
+                       continue;
+               }
+
+               if(uart_circ_empty(xmit))
+                       break;
+
+               ifxmips_w32(port->info->xmit.buf[port->info->xmit.tail], port->membase + IFXMIPS_ASC_TBUF);
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+               port->icount.tx++;
+       }
+
+       if(uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(port);
+}
+
+static irqreturn_t
+ifxmipsasc_tx_int(int irq, void *_port)
+{
+       struct uart_port *port = (struct uart_port*) _port;
+       ifxmips_w32(ASC_IRNCR_TIR, port->membase + IFXMIPS_ASC_IRNCR);
+       ifxmipsasc_start_tx(port);
+       ifxmips_mask_and_ack_irq(irq);
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t
+ifxmipsasc_er_int(int irq, void *_port)
+{
+       struct uart_port *port = (struct uart_port*) _port;
+       /* clear any pending interrupts */
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_WHBSTATE) | ASCWHBSTATE_CLRPE |
+                       ASCWHBSTATE_CLRFE | ASCWHBSTATE_CLRROE, port->membase + IFXMIPS_ASC_WHBSTATE);
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t
+ifxmipsasc_rx_int(int irq, void *_port)
+{
+       struct uart_port *port = (struct uart_port*)_port;
+       ifxmips_w32(ASC_IRNCR_RIR, port->membase + IFXMIPS_ASC_IRNCR);
+       ifxmipsasc_rx_chars((struct uart_port*)port);
+       ifxmips_mask_and_ack_irq(irq);
+       return IRQ_HANDLED;
+}
+
+static unsigned int
+ifxmipsasc_tx_empty(struct uart_port *port)
+{
+       int status;
+       status = ifxmips_r32(port->membase + IFXMIPS_ASC_FSTAT) & ASCFSTAT_TXFFLMASK;
+       return status ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int
+ifxmipsasc_get_mctrl(struct uart_port *port)
+{
+       return TIOCM_CTS | TIOCM_CAR | TIOCM_DSR;
+}
+
+static void
+ifxmipsasc_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+}
+
+static void
+ifxmipsasc_break_ctl(struct uart_port *port, int break_state)
+{
+}
+
+static int
+ifxmipsasc_startup(struct uart_port *port)
+{
+       unsigned long flags;
+       int retval;
+
+       port->uartclk = ifxmips_get_fpi_hz();
+
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_CLC) & ~IFXMIPS_ASC_CLC_DISS, port->membase + IFXMIPS_ASC_CLC);
+       ifxmips_w32(((ifxmips_r32(port->membase + IFXMIPS_ASC_CLC) & ~ASCCLC_RMCMASK)) | (1 << ASCCLC_RMCOFFSET), port->membase + IFXMIPS_ASC_CLC);
+       ifxmips_w32(0, port->membase + IFXMIPS_ASC_PISEL);
+       ifxmips_w32(((TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) | ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU, port->membase + IFXMIPS_ASC_TXFCON);
+       ifxmips_w32(((RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK) | ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU, port->membase + IFXMIPS_ASC_RXFCON);
+       wmb ();
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_CON) | ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN, port->membase + IFXMIPS_ASC_CON);
+
+       local_irq_save(flags);
+
+       retval = request_irq(port->irq, ifxmipsasc_tx_int, IRQF_DISABLED, "asc_tx", port);
+       if(retval)
+       {
+               printk("failed to request ifxmipsasc_tx_int\n");
+               return retval;
+       }
+
+       retval = request_irq(port->irq + 2, ifxmipsasc_rx_int, IRQF_DISABLED, "asc_rx", port);
+       if(retval)
+       {
+               printk("failed to request ifxmipsasc_rx_int\n");
+               goto err1;
+       }
+
+       retval = request_irq(port->irq + 3, ifxmipsasc_er_int, IRQF_DISABLED, "asc_er", port);
+       if(retval)
+       {
+               printk("failed to request ifxmipsasc_er_int\n");
+               goto err2;
+       }
+
+       ifxmips_w32(ASC_IRNREN_RX_BUF | ASC_IRNREN_TX_BUF | ASC_IRNREN_ERR | ASC_IRNREN_TX, port->membase + IFXMIPS_ASC_IRNREN);
+
+       local_irq_restore(flags);
+       return 0;
+
+err2:
+       free_irq(port->irq + 2, port);
+err1:
+       free_irq(port->irq, port);
+       local_irq_restore(flags);
+       return retval;
+}
+
+static void
+ifxmipsasc_shutdown(struct uart_port *port)
+{
+       free_irq(port->irq, port);
+       free_irq(port->irq + 2, port);
+       free_irq(port->irq + 3, port);
+
+       ifxmips_w32(0, port->membase + IFXMIPS_ASC_CON);
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_RXFCON) | ASCRXFCON_RXFFLU, port->membase + IFXMIPS_ASC_RXFCON);
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_RXFCON) & ~ASCRXFCON_RXFEN, port->membase + IFXMIPS_ASC_RXFCON);
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_TXFCON) | ASCTXFCON_TXFFLU, port->membase + IFXMIPS_ASC_TXFCON);
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_TXFCON) & ~ASCTXFCON_TXFEN, port->membase + IFXMIPS_ASC_TXFCON);
+}
+
+static void ifxmipsasc_set_termios(struct uart_port *port, struct ktermios *new, struct ktermios *old)
+{
+       unsigned int cflag;
+       unsigned int iflag;
+       unsigned int quot;
+       unsigned int baud;
+       unsigned int con = 0;
+       unsigned long flags;
+
+       cflag = new->c_cflag;
+       iflag = new->c_iflag;
+
+       switch(cflag & CSIZE)
+       {
+       case CS7:
+               con = ASCCON_M_7ASYNC;
+               break;
+
+       case CS5:
+       case CS6:
+       default:
+               con = ASCCON_M_8ASYNC;
+               break;
+       }
+
+       if(cflag & CSTOPB)
+               con |= ASCCON_STP;
+
+       if(cflag & PARENB)
+       {
+               if(!(cflag & PARODD))
+                       con &= ~ASCCON_ODD;
+               else
+                       con |= ASCCON_ODD;
+       }
+
+       port->read_status_mask = ASCSTATE_ROE;
+       if(iflag & INPCK)
+               port->read_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
+
+       port->ignore_status_mask = 0;
+       if(iflag & IGNPAR)
+               port->ignore_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
+
+       if(iflag & IGNBRK)
+       {
+               /*
+                * If we're ignoring parity and break indicators,
+                * ignore overruns too (for real raw support).
+                */
+               if(iflag & IGNPAR)
+                       port->ignore_status_mask |= ASCSTATE_ROE;
+       }
+
+       if((cflag & CREAD) == 0)
+               port->ignore_status_mask |= UART_DUMMY_UER_RX;
+
+       /* set error signals  - framing, parity  and overrun, enable receiver */
+       con |= ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN;
+
+       local_irq_save(flags);
+
+       /* set up CON */
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_CON) | con, port->membase + IFXMIPS_ASC_CON);
+
+       /* Set baud rate - take a divider of 2 into account */
+    baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
+       quot = uart_get_divisor(port, baud);
+       quot = quot / 2 - 1;
+
+       /* disable the baudrate generator */
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_CON) & ~ASCCON_R, port->membase + IFXMIPS_ASC_CON);
+
+       /* make sure the fractional divider is off */
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_CON) & ~ASCCON_FDE, port->membase + IFXMIPS_ASC_CON);
+
+       /* set up to use divisor of 2 */
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_CON) & ~ASCCON_BRS, port->membase + IFXMIPS_ASC_CON);
+
+       /* now we can write the new baudrate into the register */
+       ifxmips_w32(quot, port->membase + IFXMIPS_ASC_BG);
+
+       /* turn the baudrate generator back on */
+       ifxmips_w32(ifxmips_r32(port->membase + IFXMIPS_ASC_CON) | ASCCON_R, port->membase + IFXMIPS_ASC_CON);
+
+       /* enable rx */
+       ifxmips_w32(ASCWHBSTATE_SETREN, port->membase + IFXMIPS_ASC_WHBSTATE);
+
+       local_irq_restore(flags);
+}
+
+static const char*
+ifxmipsasc_type(struct uart_port *port)
+{
+       if(port->type == PORT_IFXMIPSASC)
+       {
+               if(port->membase == (void*)IFXMIPS_ASC_BASE_ADDR)
+                       return "asc0";
+               else
+                       return "asc1";
+       } else {
+               return NULL;
+       }
+}
+
+static void
+ifxmipsasc_release_port(struct uart_port *port)
+{
+}
+
+static int
+ifxmipsasc_request_port(struct uart_port *port)
+{
+       return 0;
+}
+
+static void
+ifxmipsasc_config_port(struct uart_port *port, int flags)
+{
+       if(flags & UART_CONFIG_TYPE)
+       {
+               port->type = PORT_IFXMIPSASC;
+               ifxmipsasc_request_port(port);
+       }
+}
+
+static int
+ifxmipsasc_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+       int ret = 0;
+       if(ser->type != PORT_UNKNOWN && ser->type != PORT_IFXMIPSASC)
+               ret = -EINVAL;
+       if(ser->irq < 0 || ser->irq >= NR_IRQS)
+               ret = -EINVAL;
+       if(ser->baud_base < 9600)
+               ret = -EINVAL;
+       return ret;
+}
+
+static struct uart_ops ifxmipsasc_pops =
+{
+       .tx_empty =             ifxmipsasc_tx_empty,
+       .set_mctrl =    ifxmipsasc_set_mctrl,
+       .get_mctrl =    ifxmipsasc_get_mctrl,
+       .stop_tx =              ifxmipsasc_stop_tx,
+       .start_tx =             ifxmipsasc_start_tx,
+       .stop_rx =              ifxmipsasc_stop_rx,
+       .enable_ms =    ifxmipsasc_enable_ms,
+       .break_ctl =    ifxmipsasc_break_ctl,
+       .startup =              ifxmipsasc_startup,
+       .shutdown =             ifxmipsasc_shutdown,
+       .set_termios =  ifxmipsasc_set_termios,
+       .type =                 ifxmipsasc_type,
+       .release_port = ifxmipsasc_release_port,
+       .request_port = ifxmipsasc_request_port,
+       .config_port =  ifxmipsasc_config_port,
+       .verify_port =  ifxmipsasc_verify_port,
+};
+
+static struct uart_port ifxmipsasc_port[2] =
+{
+       {
+               membase:                (void *)IFXMIPS_ASC_BASE_ADDR,
+               mapbase:                IFXMIPS_ASC_BASE_ADDR,
+               iotype:                 SERIAL_IO_MEM,
+               irq:                    IFXMIPSASC_TIR(0),
+               uartclk:                0,
+               fifosize:               16,
+               type:                   PORT_IFXMIPSASC,
+               ops:                    &ifxmipsasc_pops,
+               flags:                  ASYNC_BOOT_AUTOCONF,
+               line:                   0
+       }, {
+               membase:                (void *)(IFXMIPS_ASC_BASE_ADDR + IFXMIPS_ASC_BASE_DIFF),
+               mapbase:                IFXMIPS_ASC_BASE_ADDR + IFXMIPS_ASC_BASE_DIFF,
+               iotype:                 SERIAL_IO_MEM,
+               irq:                    IFXMIPSASC_TIR(1),
+               uartclk:                0,
+               fifosize:               16,
+               type:                   PORT_IFXMIPSASC,
+               ops:                    &ifxmipsasc_pops,
+               flags:                  ASYNC_BOOT_AUTOCONF,
+               line:                   1
+       }
+};
+
+static void
+ifxmipsasc_console_write(struct console *co, const char *s, u_int count)
+{
+       int port = co->index;
+       int i, fifocnt;
+       unsigned long flags;
+       local_irq_save(flags);
+       for(i = 0; i < count; i++)
+       {
+               do {
+                       fifocnt = (ifxmips_r32((u32*)(IFXMIPS_ASC_BASE_ADDR + (port * IFXMIPS_ASC_BASE_DIFF) + IFXMIPS_ASC_FSTAT)) & ASCFSTAT_TXFFLMASK)
+                                       >> ASCFSTAT_TXFFLOFF;
+               } while(fifocnt == TXFIFO_FULL);
+
+               if(s[i] == '\0')
+                       break;
+
+               if(s[i] == '\n')
+               {
+                       ifxmips_w32('\r', (u32*)(IFXMIPS_ASC_BASE_ADDR + (port * IFXMIPS_ASC_BASE_DIFF) + IFXMIPS_ASC_TBUF));
+                       do {
+                               fifocnt = (ifxmips_r32((u32*)(IFXMIPS_ASC_BASE_ADDR + (port * IFXMIPS_ASC_BASE_DIFF) + IFXMIPS_ASC_FSTAT)) & ASCFSTAT_TXFFLMASK)
+                                       >> ASCFSTAT_TXFFLOFF;
+                       } while(fifocnt == TXFIFO_FULL);
+               }
+               ifxmips_w32(s[i], (u32*)(IFXMIPS_ASC_BASE_ADDR + (port * IFXMIPS_ASC_BASE_DIFF) + IFXMIPS_ASC_TBUF));
+       }
+
+       local_irq_restore(flags);
+}
+
+static int __init
+ifxmipsasc_console_setup(struct console *co, char *options)
+{
+       int port = co->index;
+       int baud = 115200;
+       int bits = 8;
+       int parity = 'n';
+       int flow = 'n';
+       ifxmipsasc_port[port].uartclk = ifxmips_get_fpi_hz();
+       ifxmipsasc_port[port].type = PORT_IFXMIPSASC;
+       if(options)
+               uart_parse_options(options, &baud, &parity, &bits, &flow);
+       return uart_set_options(&ifxmipsasc_port[port], co, baud, parity, bits, flow);
+}
+
+static struct console ifxmipsasc_console[2] =
+{
+       {
+               name:           "ttyS",
+               write:          ifxmipsasc_console_write,
+               device:         uart_console_device,
+               setup:          ifxmipsasc_console_setup,
+               flags:          CON_PRINTBUFFER,
+               index:          0,
+               data:           &ifxmipsasc_reg,
+       }, {
+               name:           "ttyS",
+               write:          ifxmipsasc_console_write,
+               device:         uart_console_device,
+               setup:          ifxmipsasc_console_setup,
+               flags:          CON_PRINTBUFFER,
+               index:          1,
+               data:           &ifxmipsasc_reg,
+       }
+};
+
+static int __init
+ifxmipsasc_console_init(void)
+{
+       register_console(&ifxmipsasc_console[0]);
+       register_console(&ifxmipsasc_console[1]);
+       return 0;
+}
+console_initcall(ifxmipsasc_console_init);
+
+static struct uart_driver ifxmipsasc_reg =
+{
+       .owner =                        THIS_MODULE,
+       .driver_name =          "serial",
+       .dev_name =                     "ttyS",
+       .major =                        TTY_MAJOR,
+       .minor =                        64,
+       .nr =                           2,
+       .cons =                         &ifxmipsasc_console[1],
+};
+
+int __init
+ifxmipsasc_init(void)
+{
+       int ret;
+       uart_register_driver(&ifxmipsasc_reg);
+       ret = uart_add_one_port(&ifxmipsasc_reg, &ifxmipsasc_port[0]);
+       ret = uart_add_one_port(&ifxmipsasc_reg, &ifxmipsasc_port[1]);
+       return 0;
+}
+
+void __exit
+ifxmipsasc_exit(void)
+{
+       uart_unregister_driver(&ifxmipsasc_reg);
+}
+
+module_init(ifxmipsasc_init);
+module_exit(ifxmipsasc_exit);
+
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("MIPS IFXMips serial port driver");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/ifxmips/files/drivers/watchdog/ifxmips_wdt.c b/target/linux/ifxmips/files/drivers/watchdog/ifxmips_wdt.c
new file mode 100644 (file)
index 0000000..58e2161
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * 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
+ *
+ * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
+ * Based on EP93xx wdt driver
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/platform_device.h>
+#include <asm/uaccess.h>
+#include <asm-mips/ifxmips/ifxmips_cgu.h>
+#include <asm-mips/ifxmips/ifxmips.h>
+
+#define IFXMIPS_WDT_PW1                  0x00BE0000
+#define IFXMIPS_WDT_PW2                  0x00DC0000
+
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+static int wdt_ok_to_close = 0;
+#endif
+
+int wdt_timeout = 30;
+
+int
+ifxmips_wdt_enable(unsigned int timeout)
+{
+       u32 fpi;
+       fpi = cgu_get_io_region_clock();
+       ifxmips_w32(IFXMIPS_WDT_PW1, IFXMIPS_BIU_WDT_CR);
+       ifxmips_w32(IFXMIPS_WDT_PW2 |
+               (0x3 << 26) | // PWL
+               (0x3 << 24) | // CLKDIV
+               (0x1 << 31) | // enable
+               ((timeout * (fpi / 0x40000)) + 0x1000), // reload 
+               IFXMIPS_BIU_WDT_CR);
+       return 0;
+}
+
+void
+ifxmips_wdt_disable(void)
+{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+       wdt_ok_to_close = 0;
+#endif
+       ifxmips_w32(IFXMIPS_WDT_PW1, IFXMIPS_BIU_WDT_CR);
+       ifxmips_w32(IFXMIPS_WDT_PW2, IFXMIPS_BIU_WDT_CR);
+}
+
+static ssize_t
+ifxmips_wdt_write(struct file *file, const char __user *data, size_t len,
+                loff_t *ppos)
+{
+       size_t i;
+
+       if(!len)
+               return 0;
+
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+       for(i = 0; i != len; i++)
+       {
+               char c;
+               if(get_user(c, data + i))
+                       return -EFAULT;
+               if(c == 'V')
+                       wdt_ok_to_close = 1;
+       }
+#endif
+       ifxmips_wdt_enable(wdt_timeout);
+       return len;
+}
+
+static struct watchdog_info ident = {
+       .options = WDIOF_MAGICCLOSE,
+       .identity = "ifxmips Watchdog",
+};
+
+static int
+ifxmips_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+                unsigned long arg)
+{
+       int ret = -ENOTTY;
+
+       switch(cmd)
+       {
+       case WDIOC_GETSUPPORT:
+               ret = copy_to_user((struct watchdog_info __user *)arg, &ident,
+                               sizeof(ident)) ? -EFAULT : 0;
+               break;
+
+       case WDIOC_GETTIMEOUT:
+               ret = put_user(wdt_timeout, (int __user *)arg);
+               break;
+
+       case WDIOC_SETTIMEOUT:
+               ret = get_user(wdt_timeout, (int __user*)arg);
+               break;
+
+       case WDIOC_KEEPALIVE:
+               ifxmips_wdt_enable(wdt_timeout);
+               ret = 0;
+               break;
+       }
+       return ret;
+}
+
+static int
+ifxmips_wdt_open(struct inode *inode, struct file *file)
+{
+       ifxmips_wdt_enable(wdt_timeout);
+       return nonseekable_open(inode, file);
+}
+
+static int ifxmips_wdt_release(struct inode *inode, struct file *file)
+{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+       if(wdt_ok_to_close)
+               ifxmips_wdt_disable();
+       else
+#endif
+               printk("ifxmips_wdt: watchdog closed without warning, rebooting system\n");
+       return 0;
+}
+
+static const struct file_operations ifxmips_wdt_fops = {
+       .owner          = THIS_MODULE,
+       .write          = ifxmips_wdt_write,
+       .ioctl          = ifxmips_wdt_ioctl,
+       .open           = ifxmips_wdt_open,
+       .release        = ifxmips_wdt_release,
+};
+
+static struct miscdevice ifxmips_wdt_miscdev = {
+       .minor          = WATCHDOG_MINOR,
+       .name           = "watchdog",
+       .fops           = &ifxmips_wdt_fops,
+};
+
+static int
+ifxmips_wdt_probe(struct platform_device *dev)
+{
+       int err;
+       err = misc_register(&ifxmips_wdt_miscdev);
+       if(err)
+               printk("ifxmips_wdt: error creating device\n");
+       else
+               printk("ifxmips_wdt: loaded\n");
+       return err;
+}
+
+static int
+ifxmips_wdt_remove(struct platform_device *dev)
+{
+       ifxmips_wdt_disable();
+       misc_deregister(&ifxmips_wdt_miscdev);
+       return 0;
+}
+
+
+static struct platform_driver ifxmips_wdt_driver = {
+       .probe = ifxmips_wdt_probe,
+       .remove = ifxmips_wdt_remove,
+       .driver = {
+               .name = "ifxmips_wdt",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init
+init_ifxmips_wdt(void)
+{
+       int ret = platform_driver_register(&ifxmips_wdt_driver);
+       if(ret)
+               printk(KERN_INFO "ifxmips_wdt: error registering platfom driver!");
+       return ret;
+}
+
+static void __exit
+exit_ifxmips_wdt(void)
+{
+       platform_driver_unregister(&ifxmips_wdt_driver);
+}
+
+module_init(init_ifxmips_wdt);
+module_exit(exit_ifxmips_wdt);
+
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("ifxmips Watchdog");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifx_peripheral_definitions.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifx_peripheral_definitions.h
new file mode 100644 (file)
index 0000000..5bd788f
--- /dev/null
@@ -0,0 +1,119 @@
+//*************************************************************************
+//* Summary of definitions which are used in each peripheral              *
+//*************************************************************************
+
+#ifndef peripheral_definitions_h
+#define peripheral_definitions_h
+
+////#include "cpu.h"
+//
+///* These files have to be included by each peripheral */
+//#include <sysdefs.h>
+//#include <excep.h>
+//#include <cpusubsys.h>
+//#include <sys_api.h>
+//#include <mips.h>
+//#include "SRAM_address_map.h"
+//
+///* common header files for all CPU's */
+//#include "iiu.h"
+//#include "bcu.h"
+//#include "FPI_address_map.h"
+//#include "direct_interrupts.h"
+
+/////////////////////////////////////////////////////////////////////////
+
+//extern  int _clz();
+//extern void _nop();
+//extern void _sleep();
+//extern void sys_enable_int();
+
+typedef unsigned char UINT8;
+typedef signed char INT8;
+typedef unsigned short UINT16;
+typedef signed short INT16;
+typedef unsigned int UINT32;
+typedef signed int INT32;
+typedef unsigned long long UINT64;
+typedef signed long long INT64;
+
+#define REG8( addr )             (*(volatile UINT8 *) (addr))
+#define REG16( addr )            (*(volatile UINT16 *)(addr))
+#define REG32( addr )            (*(volatile UINT32 *)(addr))
+#define REG64( addr )            (*(volatile UINT64 *)(addr))
+
+/* define routine to set FPI access in Supervisor Mode */
+#define IFX_SUPERVISOR_ON()                         REG32(FB0_CFG) = 0x01
+/* Supervisor mode ends, following functions will be done in User mode */
+#define IFX_SUPERVISOR_OFF()                        REG32(FB0_CFG) = 0x00
+/* Supervisor mode ends, following functions will be done in User mode */
+#define IFX_SUPERVISOR_MODE()                       REG32(FB0_CFG)
+/* Supervisor mode ends, following functions will be done in User mode */
+#define IFX_SUPERVISOR_SET(svm)                     REG32(FB0_CFG) = svm
+/* enable all Interrupts in IIU */
+//#define IFX_ENABLE_IRQ(irq_mask, im_base)           REG32(im_base | IIU_MASK) = irq_mask
+///* get all high priority interrupt bits in IIU */
+//#define IFX_GET_IRQ_MASKED(im_base)                 REG32(im_base | IIU_IRMASKED)
+///* signal ends of interrupt to IIU */
+//#define IFX_CLEAR_DIRECT_IRQ(irq_bit, im_base)      REG32(im_base | IIU_IR) = irq_bit
+///* force IIU interrupt register */
+//#define IFX_FORCE_IIU_REGISTER(data, im_base)       REG32(im_base | IIU_IRDEBUG) = data
+///* get all bits of interrupt register */
+//#define IFX_GET_IRQ_UNMASKED(im_base)               REG32(im_base | IIU_IR)
+/* insert a NOP instruction */
+#define NOP                                     _nop()
+/* CPU goes to power down mode until interrupt occurs */
+#define IFX_CPU_SLEEP                               _sleep()
+/* enable all interrupts to CPU */
+#define IFX_CPU_ENABLE_ALL_INTERRUPT                sys_enable_int()
+/* get all low priority interrupt bits in peripheral */
+#define IFX_GET_LOW_PRIO_IRQ(int_reg)               REG32(int_reg)
+/* clear low priority interrupt bit in peripheral */
+#define IFX_CLEAR_LOW_PRIO_IRQ(irq_bit, int_reg)    REG32(int_reg) = irq_bit
+/* write FPI bus */
+#define WRITE_FPI_BYTE(data, addr)              REG8(addr) = data
+#define WRITE_FPI_16BIT(data, addr)             REG16(addr) = data
+#define WRITE_FPI_32BIT(data, addr)             REG32(addr) = data
+/* read FPI bus */
+#define READ_FPI_BYTE(addr)                     REG8(addr)
+#define READ_FPI_16BIT(addr)                    REG16(addr)
+#define READ_FPI_32BIT(addr)                    REG32(addr)
+/* write peripheral register */
+#define WRITE_PERIPHERAL_REGISTER(data, addr)   REG32(addr) = data
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define WRITE_PERIPHERAL_REGISTER_16(data, addr) REG16(addr) = data
+#define WRITE_PERIPHERAL_REGISTER_8(data, addr) REG8(addr) = data
+#else //not CONFIG_CPU_LITTLE_ENDIAN
+#define WRITE_PERIPHERAL_REGISTER_16(data, addr) REG16(addr+2) = data
+#define WRITE_PERIPHERAL_REGISTER_8(data, addr) REG8(addr+3) = data
+#endif //CONFIG_CPU_LITTLE_ENDIAN
+
+/* read peripheral register */
+#define READ_PERIPHERAL_REGISTER(addr)          REG32(addr)
+
+/* read/modify(or)/write peripheral register */
+#define RMW_OR_PERIPHERAL_REGISTER(data, addr) REG32(addr) = REG32(addr) | data
+/* read/modify(and)/write peripheral register */
+#define RMW_AND_PERIPHERAL_REGISTER(data, addr)        REG32(addr) = REG32(addr) & (UINT32)data
+
+/* CPU-independent mnemonic constants */
+/* CLC register bits */
+#define IFX_CLC_ENABLE                0x00000000
+#define IFX_CLC_DISABLE               0x00000001
+#define IFX_CLC_DISABLE_STATUS        0x00000002
+#define IFX_CLC_SUSPEND_ENABLE        0x00000004
+#define IFX_CLC_CLOCK_OFF_DISABLE     0x00000008
+#define IFX_CLC_OVERWRITE_SPEN_FSOE   0x00000010
+#define IFX_CLC_FAST_CLOCK_SWITCH_OFF 0x00000020
+#define IFX_CLC_RUN_DIVIDER_MASK      0x0000FF00
+#define IFX_CLC_RUN_DIVIDER_OFFSET    8
+#define IFX_CLC_SLEEP_DIVIDER_MASK    0x00FF0000
+#define IFX_CLC_SLEEP_DIVIDER_OFFSET  16
+#define IFX_CLC_SPECIFIC_DIVIDER_MASK 0x00FF0000
+#define IFX_CLC_SPECIFIC_DIVIDER_OFFSET 24
+
+/* number of cycles to wait for interrupt service routine to be called */
+#define WAIT_CYCLES   50
+
+#endif /* PERIPHERAL_DEFINITIONS_H not yet defined */
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifx_ssc.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifx_ssc.h
new file mode 100644 (file)
index 0000000..c6dd5d4
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * ifx_ssc.h defines some data sructures used in ifx_ssc.c
+ *
+ * Copyright (C) 2004 Michael Schoenenborn (IFX COM TI BT)
+ *
+ *
+ */
+
+#ifndef __IFX_SSC_H
+#define __IFX_SSC_H
+#ifdef __KERNEL__
+#include <asm/ifxmips/ifx_ssc_defines.h>
+#endif //__KERNEL__
+
+#define PORT_CNT               1       // assume default value
+
+/* symbolic constants to be used in SSC routines */
+
+// ### TO DO: bad performance
+#define IFX_SSC_TXFIFO_ITL     1
+#define IFX_SSC_RXFIFO_ITL     1
+
+struct ifx_ssc_statistics {
+       unsigned int abortErr;  /* abort error */
+       unsigned int modeErr;   /* master/slave mode error */
+       unsigned int txOvErr;   /* TX Overflow error */
+       unsigned int txUnErr;   /* TX Underrun error */
+       unsigned int rxOvErr;   /* RX Overflow error */
+       unsigned int rxUnErr;   /* RX Underrun error */
+       unsigned int rxBytes;
+       unsigned int txBytes;
+};
+
+struct ifx_ssc_hwopts {
+       unsigned int AbortErrDetect:1;  /* Abort Error detection (in slave mode) */
+       unsigned int rxOvErrDetect:1;   /* Receive Overflow Error detection */
+       unsigned int rxUndErrDetect:1;  /* Receive Underflow Error detection */
+       unsigned int txOvErrDetect:1;   /* Transmit Overflow Error detection */
+       unsigned int txUndErrDetect:1;  /* Transmit Underflow Error detection */
+       unsigned int echoMode:1;        /* Echo mode */
+       unsigned int loopBack:1;        /* Loopback mode */
+       unsigned int idleValue:1;       /* Idle value */
+       unsigned int clockPolarity:1;   /* Idle clock is high or low */
+       unsigned int clockPhase:1;      /* Tx on trailing or leading edge */
+       unsigned int headingControl:1;  /* LSB first or MSB first */
+       unsigned int dataWidth:6;       /* from 2 up to 32 bits */
+       unsigned int masterSelect:1;    /* Master or Slave mode */
+       unsigned int modeRxTx:2;        /* rx/tx mode */
+       unsigned int gpoCs:8;   /* choose outputs to use for chip select */
+       unsigned int gpoInv:8;  /* invert GPO outputs */
+};
+
+struct ifx_ssc_frm_opts {
+       bool FrameEnable;       // SFCON.SFEN
+       unsigned int DataLength;        // SFCON.DLEN
+       unsigned int PauseLength;       // SFCON.PLEN
+       unsigned int IdleData;  // SFCON.IDAT
+       unsigned int IdleClock; // SFCON.ICLK
+       bool StopAfterPause;    // SFCON.STOP
+};
+
+struct ifx_ssc_frm_status {
+       bool DataBusy;          // SFSTAT.DBSY
+       bool PauseBusy;         // SFSTAT.PBSY
+       unsigned int DataCount; // SFSTAT.DCNT
+       unsigned int PauseCount;        // SFSTAT.PCNT
+       bool EnIntAfterData;    // SFCON.IBEN
+       bool EnIntAfterPause;   // SFCON.IAEN
+};
+
+typedef struct {
+       char *buf;
+       size_t len;
+} ifx_ssc_buf_item_t;
+
+// data structures for batch execution
+typedef union {
+       struct {
+               bool save_options;
+       } init;
+       ifx_ssc_buf_item_t read;
+       ifx_ssc_buf_item_t write;
+       ifx_ssc_buf_item_t rd_wr;
+       unsigned int set_baudrate;
+       struct ifx_ssc_frm_opts set_frm;
+       unsigned int set_gpo;
+       struct ifx_ssc_hwopts set_hwopts;
+} ifx_ssc_batch_cmd_param;
+
+struct ifx_ssc_batch_list {
+       unsigned int cmd;
+       ifx_ssc_batch_cmd_param cmd_param;
+       struct ifx_ssc_batch_list *next;
+};
+
+#ifdef __KERNEL__
+#define IFX_SSC_IS_MASTER(p) ((p)->opts.masterSelect == SSC_MASTER_MODE)
+
+struct ifx_ssc_port {
+       unsigned long mapbase;
+       struct ifx_ssc_hwopts opts;
+       struct ifx_ssc_statistics stats;
+       struct ifx_ssc_frm_status frm_status;
+       struct ifx_ssc_frm_opts frm_opts;
+       /* wait queue for ifx_ssc_read() */
+       wait_queue_head_t rwait, pwait;
+       int port_nr;
+       char port_is_open;      /* exclusive open  - boolean */
+//      int no_of_bits; /* number of _valid_ bits */
+//      int elem_size; /* shift for element (no of bytes)*/
+       /* buffer and pointers to the read/write position */
+       char *rxbuf;            /* buffer for RX */
+       char *rxbuf_end;        /* buffer end pointer for RX */
+       volatile char *rxbuf_ptr;       /* buffer write pointer for RX */
+       char *txbuf;            /* buffer for TX */
+       char *txbuf_end;        /* buffer end pointer for TX */
+       volatile char *txbuf_ptr;       /* buffer read pointer for TX */
+       unsigned int baud;
+       /* each channel has its own interrupts */
+       /* (transmit/receive/error/frame) */
+       unsigned int txirq, rxirq, errirq, frmirq;
+};
+/* default values for SSC configuration */
+// values of CON
+#define IFX_SSC_DEF_IDLE_DATA       1  /* enable */
+#define IFX_SSC_DEF_BYTE_VALID_CTL  1  /* enable */
+#define IFX_SSC_DEF_DATA_WIDTH      32 /* bits */
+#define IFX_SSC_DEF_ABRT_ERR_DETECT 0  /* disable */
+#define IFX_SSC_DEF_RO_ERR_DETECT   1  /* enable */
+#define IFX_SSC_DEF_RU_ERR_DETECT   0  /* disable */
+#define IFX_SSC_DEF_TO_ERR_DETECT   0  /* disable */
+#define IFX_SSC_DEF_TU_ERR_DETECT   0  /* disable */
+#define IFX_SSC_DEF_LOOP_BACK       0  /* disable */
+#define IFX_SSC_DEF_ECHO_MODE       0  /* disable */
+#define IFX_SSC_DEF_CLOCK_POLARITY  0  /* low */
+#define IFX_SSC_DEF_CLOCK_PHASE     1  /* 0: shift on leading edge, latch on trailling edge, 1, otherwise */
+#define IFX_SSC_DEF_HEADING_CONTROL IFX_SSC_MSB_FIRST
+#define IFX_SSC_DEF_MODE_RXTX      IFX_SSC_MODE_RXTX
+// other values
+#define IFX_SSC_DEF_MASTERSLAVE            IFX_SSC_MASTER_MODE /* master */
+#ifdef CONFIG_USE_EMULATOR
+#define IFX_SSC_DEF_BAUDRATE       10000
+#else
+#define IFX_SSC_DEF_BAUDRATE       2000000
+#endif
+#define IFX_SSC_DEF_RMC                    0x10
+
+#define IFX_SSC_DEF_TXFIFO_FL       8
+#define IFX_SSC_DEF_RXFIFO_FL       1
+
+#if 1                          //TODO
+#define IFX_SSC_DEF_GPO_CS         0x3 /* no chip select */
+#define IFX_SSC_DEF_GPO_INV        0   /* no chip select */
+#else
+#error "what is ur Chip Select???"
+#endif
+#define IFX_SSC_DEF_SFCON          0   /* no serial framing */
+#if 0
+#define IFX_SSC_DEF_IRNEN          IFX_SSC_T_BIT | /* enable all int's */\
+                                   IFX_SSC_R_BIT | IFX_SSC_E_BIT | IFX_SSC_F_BIT
+#endif
+#define IFX_SSC_DEF_IRNEN          IFX_SSC_T_BIT | /* enable all int's */\
+                                   IFX_SSC_R_BIT | IFX_SSC_E_BIT
+#endif /* __KERNEL__ */
+
+// batch execution commands
+#define IFX_SSC_BATCH_CMD_INIT         1
+#define IFX_SSC_BATCH_CMD_READ         2
+#define IFX_SSC_BATCH_CMD_WRITE                3
+#define IFX_SSC_BATCH_CMD_RD_WR                4
+#define IFX_SSC_BATCH_CMD_SET_BAUDRATE 5
+#define IFX_SSC_BATCH_CMD_SET_HWOPTS   6
+#define IFX_SSC_BATCH_CMD_SET_FRM      7
+#define IFX_SSC_BATCH_CMD_SET_GPO      8
+#define IFX_SSC_BATCH_CMD_FIFO_FLUSH   9
+//#define IFX_SSC_BATCH_CMD_    
+//#define IFX_SSC_BATCH_CMD_    
+#define IFX_SSC_BATCH_CMD_END_EXEC     0
+
+/* Macros to configure SSC hardware */
+/* headingControl: */
+#define IFX_SSC_LSB_FIRST            0
+#define IFX_SSC_MSB_FIRST            1
+/* dataWidth: */
+#define IFX_SSC_MIN_DATA_WIDTH       2
+#define IFX_SSC_MAX_DATA_WIDTH       32
+/* master/slave mode select */
+#define IFX_SSC_MASTER_MODE          1
+#define IFX_SSC_SLAVE_MODE           0
+/* rx/tx mode */
+// ### TO DO: !!! ATTENTION! Hardware dependency => move to ifx_ssc_defines.h
+#define IFX_SSC_MODE_RXTX           0
+#define IFX_SSC_MODE_RX                     1
+#define IFX_SSC_MODE_TX                     2
+#define IFX_SSC_MODE_OFF            3
+#define IFX_SSC_MODE_MASK           IFX_SSC_MODE_RX | IFX_SSC_MODE_TX
+
+/* GPO values */
+#define IFX_SSC_MAX_GPO_OUT         7
+
+#define IFX_SSC_RXREQ_BLOCK_SIZE     32768
+
+/***********************/
+/* defines for ioctl's */
+/***********************/
+#define IFX_SSC_IOCTL_MAGIC     'S'
+/* read out the statistics */
+#define IFX_SSC_STATS_READ _IOR(IFX_SSC_IOCTL_MAGIC, 1, struct ifx_ssc_statistics)
+/* clear the statistics */
+#define IFX_SSC_STATS_RESET _IO(IFX_SSC_IOCTL_MAGIC, 2)
+/* set the baudrate */
+#define IFX_SSC_BAUD_SET _IOW(IFX_SSC_IOCTL_MAGIC, 3, unsigned int)
+/* get the current baudrate */
+#define IFX_SSC_BAUD_GET _IOR(IFX_SSC_IOCTL_MAGIC, 4, unsigned int)
+/* set hardware options */
+#define IFX_SSC_HWOPTS_SET _IOW(IFX_SSC_IOCTL_MAGIC, 5, struct ifx_ssc_hwopts)
+/* get the current hardware options */
+#define IFX_SSC_HWOPTS_GET _IOR(IFX_SSC_IOCTL_MAGIC, 6, struct ifx_ssc_hwopts)
+/* set transmission mode */
+#define IFX_SSC_RXTX_MODE_SET _IOW(IFX_SSC_IOCTL_MAGIC, 7, unsigned int)
+/* get the current transmission mode */
+#define IFX_SSC_RXTX_MODE_GET _IOR(IFX_SSC_IOCTL_MAGIC, 8, unsigned int)
+/* abort transmission */
+#define IFX_SSC_ABORT _IO(IFX_SSC_IOCTL_MAGIC, 9)
+#define IFX_SSC_FIFO_FLUSH _IO(IFX_SSC_IOCTL_MAGIC, 9)
+
+/* set general purpose outputs */
+#define IFX_SSC_GPO_OUT_SET _IOW(IFX_SSC_IOCTL_MAGIC, 32, unsigned int)
+/* clear general purpose outputs */
+#define IFX_SSC_GPO_OUT_CLR _IOW(IFX_SSC_IOCTL_MAGIC, 33, unsigned int)
+/* get general purpose outputs */
+#define IFX_SSC_GPO_OUT_GET _IOR(IFX_SSC_IOCTL_MAGIC, 34, unsigned int)
+
+/*** serial framing ***/
+/* get status of serial framing */
+#define IFX_SSC_FRM_STATUS_GET _IOR(IFX_SSC_IOCTL_MAGIC, 48, struct ifx_ssc_frm_status)
+/* get counter reload values and control bits */
+#define IFX_SSC_FRM_CONTROL_GET _IOR(IFX_SSC_IOCTL_MAGIC, 49, struct ifx_ssc_frm_opts)
+/* set counter reload values and control bits */
+#define IFX_SSC_FRM_CONTROL_SET _IOW(IFX_SSC_IOCTL_MAGIC, 50, struct ifx_ssc_frm_opts)
+
+/*** batch execution ***/
+/* do batch execution */
+#define IFX_SSC_BATCH_EXEC _IOW(IFX_SSC_IOCTL_MAGIC, 64, struct ifx_ssc_batch_list)
+
+#ifdef __KERNEL__
+// routines from ifx_ssc.c
+// ### TO DO
+/* kernel interface for read and write */
+ssize_t ifx_ssc_kread (int, char *, size_t);
+ssize_t ifx_ssc_kwrite (int, const char *, size_t);
+
+#ifdef CONFIG_IFX_VP_KERNEL_TEST
+void ifx_ssc_tc (void);
+#endif // CONFIG_IFX_VP_KERNEL_TEST
+
+#endif //__KERNEL__
+#endif // __IFX_SSC_H
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifx_ssc_defines.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifx_ssc_defines.h
new file mode 100644 (file)
index 0000000..805d48a
--- /dev/null
@@ -0,0 +1,547 @@
+#ifndef IFX_SSC_DEFINES_H
+#define IFX_SSC_DEFINES_H
+
+#include "ifx_peripheral_definitions.h"
+
+/* maximum SSC FIFO size */
+#define IFX_SSC_MAX_FIFO_SIZE 32
+
+/* register map of SSC  */
+
+/* address of the Clock Control Register of the SSC */
+#define IFX_SSC_CLC                 0x00000000
+/* IFX_SSC_CLC register is significant in bits 23 downto 8 and in bits 5, 3, 2, 0  
+   bit 1 is hardware modified*/
+#define IFX_SSC_CLC_readmask  0x00FFFFEF
+#define IFX_SSC_CLC_writemask 0x00FFFF3D
+#define IFX_SSC_CLC_hwmask    0x00000002
+#define IFX_SSC_CLC_dontcare (IFX_SSC_CLC_readmask & IFX_SSC_CLC_writemask & ~IFX_SSC_CLC_hwmask)
+
+/* address of Port Input Select Register of the SSC */
+#define IFX_SSC_PISEL 0x00000004
+/* IFX_SSC_PISEL register is significant in lowest three bits only */
+#define IFX_SSC_PISEL_readmask  0x00000007
+#define IFX_SSC_PISEL_writemask 0x00000007
+#define IFX_SSC_PISEL_hwmask    0x00000000
+#define IFX_SSC_PISEL_dontcare (IFX_SSC_PISEL_readmask & IFX_SSC_PISEL_writemask & ~IFX_SSC_PISEL_hwmask)
+
+/* address of Identification Register of the SSC */
+#define IFX_SSC_ID 0x00000008
+/* IFX_SSC_ID register is significant in no bit */
+#define IFX_SSC_ID_readmask  0x0000FF3F
+#define IFX_SSC_ID_writemask 0x00000000
+#define IFX_SSC_ID_hwmask    0x00000000
+#define IFX_SSC_ID_dontcare (IFX_SSC_ID_readmask & IFX_SSC_ID_writemask & ~IFX_SSC_ID_hwmask)
+
+/* address of the Control Register of the SSC */
+#define IFX_SSC_CON            0x00000010
+/* IFX_SSC_CON register is significant in bits 23:22, 20:16 and 12:0 */
+#define IFX_SSC_CON_readmask  0x01DF1FFF
+#define IFX_SSC_CON_writemask 0x01DF1FFF
+#define IFX_SSC_CON_hwmask    0x00000000
+#define IFX_SSC_CON_dontcare (IFX_SSC_CON_readmask & IFX_SSC_CON_writemask & ~IFX_SSC_CON_hwmask)
+
+/* address of the Status Register of the SSC */
+#define IFX_SSC_STATE          0x00000014
+/* IFX_SSC_STATE register is readable in bits 30:28, 26:24, 20:16, 12:7 and 2:0
+   all bits except 1:0 are hardware modified */
+#define IFX_SSC_STATE_readmask  0x771F3F87
+#define IFX_SSC_STATE_writemask 0x00000000
+#define IFX_SSC_STATE_hwmask    0x771F3F84
+#define IFX_SSC_STATE_dontcare (IFX_SSC_STATE_readmask & IFX_SSC_STATE_writemask & ~IFX_SSC_STATE_hwmask)
+
+/* address of the Write Hardware Modified Control Register Bits of the SSC */
+#define IFX_SSC_WHBSTATE            0x00000018
+/* IFX_SSC_WHBSTATE register is write only */
+#define IFX_SSC_WHBSTATE_readmask  0x00000000
+#define IFX_SSC_WHBSTATE_writemask 0x0000FFFF
+#define IFX_SSC_WHBSTATE_hwmask    0x00000000
+#define IFX_SSC_WHBSTATE_dontcare (IFX_SSC_WHBSTATE_readmask & IFX_SSC_WHBSTATE_writemask & ~IFX_SSC_WHBSTATE_hwmask)
+
+/* address of the Baudrate Timer Reload Register of the SSC */
+#define IFX_SSC_BR              0x00000040
+/* IFX_SSC_BR register is significant in  bit 15 downto 0*/
+#define IFX_SSC_BR_readmask  0x0000FFFF
+#define IFX_SSC_BR_writemask 0x0000FFFF
+#define IFX_SSC_BR_hwmask    0x00000000
+#define IFX_SSC_BR_dontcare (IFX_SSC_BR_readmask & IFX_SSC_BR_writemask & ~IFX_SSC_BR_hwmask)
+
+/* address of the Baudrate Timer Status Register of the SSC */
+#define IFX_SSC_BRSTAT              0x00000044
+/* IFX_SSC_BRSTAT register is significant in  bit 15 downto 0*/
+#define IFX_SSC_BRSTAT_readmask  0x0000FFFF
+#define IFX_SSC_BRSTAT_writemask 0x00000000
+#define IFX_SSC_BRSTAT_hwmask    0x0000FFFF
+#define IFX_SSC_BRSTAT_dontcare (IFX_SSC_BRSTAT_readmask & IFX_SSC_BRSTAT_writemask & ~IFX_SSC_BRSTAT_hwmask)
+
+/* address of the Transmitter Buffer Register of the SSC */
+#define IFX_SSC_TB              0x00000020
+/* IFX_SSC_TB register is significant in  bit 31 downto 0*/
+#define IFX_SSC_TB_readmask  0xFFFFFFFF
+#define IFX_SSC_TB_writemask 0xFFFFFFFF
+#define IFX_SSC_TB_hwmask    0x00000000
+#define IFX_SSC_TB_dontcare (IFX_SSC_TB_readmask & IFX_SSC_TB_writemask & ~IFX_SSC_TB_hwmask)
+
+/* address of the Reciver Buffer Register of the SSC */
+#define IFX_SSC_RB              0x00000024
+/* IFX_SSC_RB register is significant in no bits*/
+#define IFX_SSC_RB_readmask  0xFFFFFFFF
+#define IFX_SSC_RB_writemask 0x00000000
+#define IFX_SSC_RB_hwmask    0xFFFFFFFF
+#define IFX_SSC_RB_dontcare (IFX_SSC_RB_readmask & IFX_SSC_RB_writemask & ~IFX_SSC_RB_hwmask)
+
+/* address of the Receive FIFO Control Register of the SSC */
+#define IFX_SSC_RXFCON              0x00000030
+/* IFX_SSC_RXFCON register is significant in bit 13 downto 8 and bit 1 downto 0 */
+#define IFX_SSC_RXFCON_readmask  0x00003F03
+#define IFX_SSC_RXFCON_writemask 0x00003F03
+#define IFX_SSC_RXFCON_hwmask    0x00000000
+#define IFX_SSC_RXFCON_dontcare (IFX_SSC_RXFCON_readmask & IFX_SSC_RXFCON_writemask & ~IFX_SSC_RXFCON_hwmask)
+
+/* address of the Transmit FIFO Control Register of the SSC */
+#define IFX_SSC_TXFCON              0x00000034
+/* IFX_SSC_TXFCON register is significant in bit 13 downto 8 and bit 1 downto 0 */
+#define IFX_SSC_TXFCON_readmask  0x00003F03
+#define IFX_SSC_TXFCON_writemask 0x00003F03
+#define IFX_SSC_TXFCON_hwmask    0x00000000
+#define IFX_SSC_TXFCON_dontcare (IFX_SSC_TXFCON_readmask & IFX_SSC_TXFCON_writemask & ~IFX_SSC_TXFCON_hwmask)
+
+/* address of the FIFO Status Register of the SSC */
+#define IFX_SSC_FSTAT               0x00000038
+/* IFX_SSC_FSTAT register is significant in no bit*/
+#define IFX_SSC_FSTAT_readmask  0x00003F3F
+#define IFX_SSC_FSTAT_writemask 0x00000000
+#define IFX_SSC_FSTAT_hwmask    0x00003F3F
+#define IFX_SSC_FSTAT_dontcare (IFX_SSC_FSTAT_readmask & IFX_SSC_FSTAT_writemask & ~IFX_SSC_FSTAT_hwmask)
+
+/* address of the Data Frame Control register of the SSC */
+#define IFX_SSC_SFCON               0x00000060
+#define IFX_SSC_SFCON_readmask  0xFFDFFFFD
+#define IFX_SSC_SFCON_writemask 0xFFDFFFFD
+#define IFX_SSC_SFCON_hwmask    0x00000000
+#define IFX_SSC_SFCON_dontcare (IFX_SSC_SFCON_readmask & IFX_SSC_SFCON_writemask & ~IFX_SSC_SFCON_hwmask)
+
+/* address of the Data Frame Status register of the SSC */
+#define IFX_SSC_SFSTAT               0x00000064
+#define IFX_SSC_SFSTAT_readmask  0xFFC0FFF3
+#define IFX_SSC_SFSTAT_writemask 0x00000000
+#define IFX_SSC_SFSTAT_hwmask    0xFFC0FFF3
+#define IFX_SSC_SFSTAT_dontcare (IFX_SSC_SFSTAT_readmask & IFX_SSC_SFSTAT_writemask & ~IFX_SSC_SFSTAT_hwmask)
+
+/* address of the General Purpose Output Control register of the SSC */
+#define IFX_SSC_GPOCON               0x00000070
+#define IFX_SSC_GPOCON_readmask  0x0000FFFF
+#define IFX_SSC_GPOCON_writemask 0x0000FFFF
+#define IFX_SSC_GPOCON_hwmask    0x00000000
+#define IFX_SSC_GPOCON_dontcare (IFX_SSC_GPOCON_readmask & IFX_SSC_GPOCON_writemask & ~IFX_SSC_GPOCON_hwmask)
+
+/* address of the General Purpose Output Status register of the SSC */
+#define IFX_SSC_GPOSTAT               0x00000074
+#define IFX_SSC_GPOSTAT_readmask  0x000000FF
+#define IFX_SSC_GPOSTAT_writemask 0x00000000
+#define IFX_SSC_GPOSTAT_hwmask    0x00000000
+#define IFX_SSC_GPOSTAT_dontcare (IFX_SSC_GPOSTAT_readmask & IFX_SSC_GPOSTAT_writemask & ~IFX_SSC_GPOSTAT_hwmask)
+
+/* address of the Force GPO Status register of the SSC */
+#define IFX_SSC_WHBGPOSTAT               0x00000078
+#define IFX_SSC_WHBGPOSTAT_readmask  0x00000000
+#define IFX_SSC_WHBGPOSTAT_writemask 0x0000FFFF
+#define IFX_SSC_WHBGPOSTAT_hwmask    0x00000000
+#define IFX_SSC_WHBGPOSTAT_dontcare (IFX_SSC_WHBGPOSTAT_readmask & IFX_SSC_WHBGPOSTAT_writemask & ~IFX_SSC_WHBGPOSTAT_hwmask)
+
+/* address of the Receive Request Register of the SSC */
+#define IFX_SSC_RXREQ               0x00000080
+#define IFX_SSC_RXREQ_readmask  0x0000FFFF
+#define IFX_SSC_RXREQ_writemask 0x0000FFFF
+#define IFX_SSC_RXREQ_hwmask    0x00000000
+#define IFX_SSC_RXREQ_dontcare (IFX_SSC_RXREQ_readmask & IFX_SSC_RXREQ_writemask & ~IFX_SSC_RXREQ_hwmask)
+
+/* address of the Receive Count Register of the SSC */
+#define IFX_SSC_RXCNT               0x00000084
+#define IFX_SSC_RXCNT_readmask  0x0000FFFF
+#define IFX_SSC_RXCNT_writemask 0x00000000
+#define IFX_SSC_RXCNT_hwmask    0x0000FFFF
+#define IFX_SSC_RXCNT_dontcare (IFX_SSC_RXCNT_readmask & IFX_SSC_RXCNT_writemask & ~IFX_SSC_RXCNT_hwmask)
+
+/* address of the DMA Configuration Register of the SSC */
+#define IFX_SSC_DMACON               0x000000EC
+#define IFX_SSC_DMACON_readmask  0x0000FFFF
+#define IFX_SSC_DMACON_writemask 0x00000000
+#define IFX_SSC_DMACON_hwmask    0x0000FFFF
+#define IFX_SSC_DMACON_dontcare (IFX_SSC_DMACON_readmask & IFX_SSC_DMACON_writemask & ~IFX_SSC_DMACON_hwmask)
+
+//------------------------------------------------------
+// interrupt register for enabling interrupts, mask register of irq_reg
+#define IFX_SSC_IRN_EN 0xF4
+// read/write
+#define IFX_SSC_IRN_EN_readmask  0x0000000F
+#define IFX_SSC_IRN_EN_writemask 0x0000000F
+#define IFX_SSC_IRN_EN_hwmask    0x00000000
+#define IFX_SSC_IRN_EN_dontcare  (IFX_SSC_IRN_EN_readmask & IFX_SSC_IRN_EN_writemask & ~IFX_SSC_IRN_EN_hwmask)
+
+// interrupt register for accessing interrupts
+#define IFX_SSC_IRN_CR                0xF8
+// read/write
+#define IFX_SSC_IRN_CR_readmask  0x0000000F
+#define IFX_SSC_IRN_CR_writemask 0x0000000F
+#define IFX_SSC_IRN_CR_hwmask    0x0000000F
+#define IFX_SSC_IRN_CR_dontcare  (IFX_SSC_IRN_CR_readmask & IFX_SSC_IRN_CR_writemask & ~IFX_SSC_IRN_CR_hwmask)
+
+// interrupt register for stimulating interrupts
+#define IFX_SSC_IRN_ICR                  0xFC
+// read/write
+#define IFX_SSC_IRN_ICR_readmask  0x0000000F
+#define IFX_SSC_IRN_ICR_writemask 0x0000000F
+#define IFX_SSC_IRN_ICR_hwmask    0x00000000
+#define IFX_SSC_IRN_ICR_dontcare  (IFX_SSC_IRN_ICR_readmask & IFX_SSC_IRN_ICR_writemask & ~IFX_SSC_IRN_ICR_hwmask)
+
+//---------------------------------------------------------------------
+// Number of IRQs and bitposition of IRQ
+#define IFX_SSC_NUM_IRQ           4
+#define IFX_SSC_T_BIT       0x00000001
+#define IFX_SSC_R_BIT       0x00000002
+#define IFX_SSC_E_BIT       0x00000004
+#define IFX_SSC_F_BIT       0x00000008
+
+/* bit masks for SSC registers */
+
+/* ID register */
+#define IFX_SSC_PERID_REV_MASK      0x0000001F
+#define IFX_SSC_PERID_CFG_MASK      0x00000020
+#define IFX_SSC_PERID_ID_MASK       0x0000FF00
+#define IFX_SSC_PERID_REV_OFFSET    0
+#define IFX_SSC_PERID_CFG_OFFSET    5
+#define IFX_SSC_PERID_ID_OFFSET     8
+#define IFX_SSC_PERID_ID            0x45
+#define IFX_SSC_PERID_DMA_ON        0x00000020
+#define IFX_SSC_PERID_RXFS_MASK     0x003F0000
+#define IFX_SSC_PERID_RXFS_OFFSET   16
+#define IFX_SSC_PERID_TXFS_MASK     0x3F000000
+#define IFX_SSC_PERID_TXFS_OFFSET   24
+
+/* PISEL register */
+#define IFX_SSC_PISEL_MASTER_IN_A       0x0000
+#define IFX_SSC_PISEL_MASTER_IN_B       0x0001
+#define IFX_SSC_PISEL_SLAVE_IN_A        0x0000
+#define IFX_SSC_PISEL_SLAVE_IN_B        0x0002
+#define IFX_SSC_PISEL_CLOCK_IN_A        0x0000
+#define IFX_SSC_PISEL_CLOCK_IN_B        0x0004
+
+/* IFX_SSC_CON register */
+#define IFX_SSC_CON_ECHO_MODE_ON       0x01000000
+#define IFX_SSC_CON_ECHO_MODE_OFF      0x00000000
+#define IFX_SSC_CON_IDLE_HIGH          0x00800000
+#define IFX_SSC_CON_IDLE_LOW           0x00000000
+#define IFX_SSC_CON_ENABLE_BYTE_VALID  0x00400000
+#define IFX_SSC_CON_DISABLE_BYTE_VALID 0x00000000
+#define IFX_SSC_CON_DATA_WIDTH_OFFSET  16
+#define IFX_SSC_CON_DATA_WIDTH_MASK    0x001F0000
+#define IFX_SSC_ENCODE_DATA_WIDTH(width) (((width - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET) & IFX_SSC_CON_DATA_WIDTH_MASK)
+
+#define IFX_SSC_CON_RESET_ON_BAUDERR   0x00002000
+#define IFX_SSC_CON_GO_ON_ON_BAUDERR   0x00000000
+
+#define IFX_SSC_CON_RX_UFL_CHECK       0x00001000
+#define IFX_SSC_CON_RX_UFL_IGNORE      0x00000000
+#define IFX_SSC_CON_TX_UFL_CHECK       0x00000800
+#define IFX_SSC_CON_TX_UFL_IGNORE      0x00000000
+#define IFX_SSC_CON_ABORT_ERR_CHECK    0x00000400
+#define IFX_SSC_CON_ABORT_ERR_IGNORE   0x00000000
+#define IFX_SSC_CON_RX_OFL_CHECK       0x00000200
+#define IFX_SSC_CON_RX_OFL_IGNORE      0x00000000
+#define IFX_SSC_CON_TX_OFL_CHECK       0x00000100
+#define IFX_SSC_CON_TX_OFL_IGNORE      0x00000000
+#define IFX_SSC_CON_ALL_ERR_CHECK      0x00001F00
+#define IFX_SSC_CON_ALL_ERR_IGNORE     0x00000000
+
+#define IFX_SSC_CON_LOOPBACK_MODE      0x00000080
+#define IFX_SSC_CON_NO_LOOPBACK        0x00000000
+#define IFX_SSC_CON_HALF_DUPLEX        0x00000080
+#define IFX_SSC_CON_FULL_DUPLEX        0x00000000
+#define IFX_SSC_CON_CLOCK_FALL         0x00000040
+#define IFX_SSC_CON_CLOCK_RISE         0x00000000
+#define IFX_SSC_CON_SHIFT_THEN_LATCH   0x00000000
+#define IFX_SSC_CON_LATCH_THEN_SHIFT   0x00000020
+#define IFX_SSC_CON_MSB_FIRST          0x00000010
+#define IFX_SSC_CON_LSB_FIRST          0x00000000
+#define IFX_SSC_CON_ENABLE_CSB         0x00000008
+#define IFX_SSC_CON_DISABLE_CSB        0x00000000
+#define IFX_SSC_CON_INVERT_CSB         0x00000004
+#define IFX_SSC_CON_TRUE_CSB           0x00000000
+#define IFX_SSC_CON_RX_OFF             0x00000002
+#define IFX_SSC_CON_RX_ON              0x00000000
+#define IFX_SSC_CON_TX_OFF             0x00000001
+#define IFX_SSC_CON_TX_ON              0x00000000
+
+/* IFX_SSC_STATE register */
+#define IFX_SSC_STATE_RX_BYTE_VALID_OFFSET 28
+#define IFX_SSC_STATE_RX_BYTE_VALID_MASK   0x70000000
+#define IFX_SSC_DECODE_RX_BYTE_VALID(con_state) ((con_state & IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET)
+#define IFX_SSC_STATE_TX_BYTE_VALID_OFFSET 24
+#define IFX_SSC_STATE_TX_BYTE_VALID_MASK   0x07000000
+#define IFX_SSC_DECODE_TX_BYTE_VALID(con_state) ((con_state & IFX_SSC_STATE_TX_BYTE_VALID_MASK) >> IFX_SSC_STATE_TX_BYTE_VALID_OFFSET)
+#define IFX_SSC_STATE_BIT_COUNT_OFFSET     16
+#define IFX_SSC_STATE_BIT_COUNT_MASK       0x001F0000
+#define IFX_SSC_DECODE_DATA_WIDTH(con_state) (((con_state & IFX_SSC_STATE_BIT_COUNT_MASK) >> IFX_SSC_STATE_BIT_COUNT_OFFSET) + 1)
+#define IFX_SSC_STATE_BUSY                 0x00002000
+#define IFX_SSC_STATE_RX_UFL               0x00001000
+#define IFX_SSC_STATE_TX_UFL               0x00000800
+#define IFX_SSC_STATE_ABORT_ERR            0x00000400
+#define IFX_SSC_STATE_RX_OFL               0x00000200
+#define IFX_SSC_STATE_TX_OFL               0x00000100
+#define IFX_SSC_STATE_MODE_ERR             0x00000080
+#define IFX_SSC_STATE_SLAVE_IS_SELECTED    0x00000004
+#define IFX_SSC_STATE_IS_MASTER            0x00000002
+#define IFX_SSC_STATE_IS_ENABLED           0x00000001
+
+/* WHBSTATE register */
+#define IFX_SSC_WHBSTATE_DISABLE_SSC        0x0001
+#define IFX_SSC_WHBSTATE_CONFIGURATION_MODE 0x0001
+#define IFX_SSC_WHBSTATE_CLR_ENABLE         0x0001
+
+#define IFX_SSC_WHBSTATE_ENABLE_SSC         0x0002
+#define IFX_SSC_WHBSTATE_RUN_MODE           0x0002
+#define IFX_SSC_WHBSTATE_SET_ENABLE         0x0002
+
+#define IFX_SSC_WHBSTATE_SLAVE_MODE         0x0004
+#define IFX_SSC_WHBSTATE_CLR_MASTER_SELECT  0x0004
+
+#define IFX_SSC_WHBSTATE_MASTER_MODE        0x0008
+#define IFX_SSC_WHBSTATE_SET_MASTER_SELECT  0x0008
+
+#define IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR   0x0010
+#define IFX_SSC_WHBSTATE_SET_RX_UFL_ERROR   0x0020
+
+#define IFX_SSC_WHBSTATE_CLR_MODE_ERROR     0x0040
+#define IFX_SSC_WHBSTATE_SET_MODE_ERROR     0x0080
+
+#define IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR   0x0100
+#define IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR   0x0200
+#define IFX_SSC_WHBSTATE_CLR_ABORT_ERROR    0x0400
+#define IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR   0x0800
+#define IFX_SSC_WHBSTATE_SET_TX_OFL_ERROR   0x1000
+#define IFX_SSC_WHBSTATE_SET_RX_OFL_ERROR   0x2000
+#define IFX_SSC_WHBSTATE_SET_ABORT_ERROR    0x4000
+#define IFX_SSC_WHBSTATE_SET_TX_UFL_ERROR   0x8000
+#define IFX_SSC_WHBSTATE_CLR_ALL_ERROR      0x0F50
+#define IFX_SSC_WHBSTATE_SET_ALL_ERROR      0xF0A0
+
+/* BR register */
+#define IFX_SSC_BR_BAUDRATE_OFFSET      0
+#define IFX_SSC_BR_BAUDRATE_MASK        0xFFFF
+
+/* BR_STAT register */
+#define IFX_SSC_BRSTAT_BAUDTIMER_OFFSET      0
+#define IFX_SSC_BRSTAT_BAUDTIMER_MASK        0xFFFF
+
+/* TB register */
+#define IFX_SSC_TB_DATA_OFFSET      0
+#define IFX_SSC_TB_DATA_MASK        0xFFFFFFFF
+
+/* RB register */
+#define IFX_SSC_RB_DATA_OFFSET      0
+#define IFX_SSC_RB_DATA_MASK        0xFFFFFFFF
+
+/* RXFCON and TXFCON registers */
+#define IFX_SSC_XFCON_FIFO_DISABLE      0x0000
+#define IFX_SSC_XFCON_FIFO_ENABLE       0x0001
+#define IFX_SSC_XFCON_FIFO_FLUSH        0x0002
+#define IFX_SSC_XFCON_ITL_MASK          0x00003F00
+#define IFX_SSC_XFCON_ITL_OFFSET        8
+
+/* FSTAT register */
+#define IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET  0
+#define IFX_SSC_FSTAT_RECEIVED_WORDS_MASK    0x003F
+#define IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET  8
+#define IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK    0x3F00
+
+/* GPOCON register */
+#define IFX_SSC_GPOCON_INVOUT0_POS      0
+#define IFX_SSC_GPOCON_INV_OUT0         0x00000001
+#define IFX_SSC_GPOCON_TRUE_OUT0        0x00000000
+#define IFX_SSC_GPOCON_INVOUT1_POS      1
+#define IFX_SSC_GPOCON_INV_OUT1         0x00000002
+#define IFX_SSC_GPOCON_TRUE_OUT1        0x00000000
+#define IFX_SSC_GPOCON_INVOUT2_POS      2
+#define IFX_SSC_GPOCON_INV_OUT2         0x00000003
+#define IFX_SSC_GPOCON_TRUE_OUT2        0x00000000
+#define IFX_SSC_GPOCON_INVOUT3_POS      3
+#define IFX_SSC_GPOCON_INV_OUT3         0x00000008
+#define IFX_SSC_GPOCON_TRUE_OUT3        0x00000000
+#define IFX_SSC_GPOCON_INVOUT4_POS      4
+#define IFX_SSC_GPOCON_INV_OUT4         0x00000010
+#define IFX_SSC_GPOCON_TRUE_OUT4        0x00000000
+#define IFX_SSC_GPOCON_INVOUT5_POS      5
+#define IFX_SSC_GPOCON_INV_OUT5         0x00000020
+#define IFX_SSC_GPOCON_TRUE_OUT5        0x00000000
+#define IFX_SSC_GPOCON_INVOUT6_POS      6
+#define IFX_SSC_GPOCON_INV_OUT6         0x00000040
+#define IFX_SSC_GPOCON_TRUE_OUT6        0x00000000
+#define IFX_SSC_GPOCON_INVOUT7_POS      7
+#define IFX_SSC_GPOCON_INV_OUT7         0x00000080
+#define IFX_SSC_GPOCON_TRUE_OUT7        0x00000000
+#define IFX_SSC_GPOCON_INV_OUT_ALL      0x000000FF
+#define IFX_SSC_GPOCON_TRUE_OUT_ALL     0x00000000
+
+#define IFX_SSC_GPOCON_ISCSB0_POS       8
+#define IFX_SSC_GPOCON_IS_CSB0          0x00000100
+#define IFX_SSC_GPOCON_IS_GPO0          0x00000000
+#define IFX_SSC_GPOCON_ISCSB1_POS       9
+#define IFX_SSC_GPOCON_IS_CSB1          0x00000200
+#define IFX_SSC_GPOCON_IS_GPO1          0x00000000
+#define IFX_SSC_GPOCON_ISCSB2_POS       10
+#define IFX_SSC_GPOCON_IS_CSB2          0x00000400
+#define IFX_SSC_GPOCON_IS_GPO2          0x00000000
+#define IFX_SSC_GPOCON_ISCSB3_POS       11
+#define IFX_SSC_GPOCON_IS_CSB3          0x00000800
+#define IFX_SSC_GPOCON_IS_GPO3          0x00000000
+#define IFX_SSC_GPOCON_ISCSB4_POS       12
+#define IFX_SSC_GPOCON_IS_CSB4          0x00001000
+#define IFX_SSC_GPOCON_IS_GPO4          0x00000000
+#define IFX_SSC_GPOCON_ISCSB5_POS       13
+#define IFX_SSC_GPOCON_IS_CSB5          0x00002000
+#define IFX_SSC_GPOCON_IS_GPO5          0x00000000
+#define IFX_SSC_GPOCON_ISCSB6_POS       14
+#define IFX_SSC_GPOCON_IS_CSB6          0x00004000
+#define IFX_SSC_GPOCON_IS_GPO6          0x00000000
+#define IFX_SSC_GPOCON_ISCSB7_POS       15
+#define IFX_SSC_GPOCON_IS_CSB7          0x00008000
+#define IFX_SSC_GPOCON_IS_GPO7          0x00000000
+#define IFX_SSC_GPOCON_IS_CSB_ALL       0x0000FF00
+#define IFX_SSC_GPOCON_IS_GPO_ALL       0x00000000
+
+/* GPOSTAT register */
+#define IFX_SSC_GPOSTAT_OUT0            0x00000001
+#define IFX_SSC_GPOSTAT_OUT1            0x00000002
+#define IFX_SSC_GPOSTAT_OUT2            0x00000004
+#define IFX_SSC_GPOSTAT_OUT3            0x00000008
+#define IFX_SSC_GPOSTAT_OUT4            0x00000010
+#define IFX_SSC_GPOSTAT_OUT5            0x00000020
+#define IFX_SSC_GPOSTAT_OUT6            0x00000040
+#define IFX_SSC_GPOSTAT_OUT7            0x00000080
+#define IFX_SSC_GPOSTAT_OUT_ALL         0x000000FF
+
+/* WHBGPOSTAT register */
+#define IFX_SSC_WHBGPOSTAT_CLROUT0_POS  0
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT0     0x00000001
+#define IFX_SSC_WHBGPOSTAT_CLROUT1_POS  1
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT1     0x00000002
+#define IFX_SSC_WHBGPOSTAT_CLROUT2_POS  2
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT2     0x00000004
+#define IFX_SSC_WHBGPOSTAT_CLROUT3_POS  3
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT3     0x00000008
+#define IFX_SSC_WHBGPOSTAT_CLROUT4_POS  4
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT4     0x00000010
+#define IFX_SSC_WHBGPOSTAT_CLROUT5_POS  5
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT5     0x00000020
+#define IFX_SSC_WHBGPOSTAT_CLROUT6_POS  6
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT6     0x00000040
+#define IFX_SSC_WHBGPOSTAT_CLROUT7_POS  7
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT7     0x00000080
+#define IFX_SSC_WHBGPOSTAT_CLR_OUT_ALL  0x000000FF
+
+#define IFX_SSC_WHBGPOSTAT_OUT0_POS  0
+#define IFX_SSC_WHBGPOSTAT_OUT1_POS  1
+#define IFX_SSC_WHBGPOSTAT_OUT2_POS  2
+#define IFX_SSC_WHBGPOSTAT_OUT3_POS  3
+#define IFX_SSC_WHBGPOSTAT_OUT4_POS  4
+#define IFX_SSC_WHBGPOSTAT_OUT5_POS  5
+#define IFX_SSC_WHBGPOSTAT_OUT6_POS  6
+#define IFX_SSC_WHBGPOSTAT_OUT7_POS  7
+
+#define IFX_SSC_WHBGPOSTAT_SETOUT0_POS  8
+#define IFX_SSC_WHBGPOSTAT_SET_OUT0     0x00000100
+#define IFX_SSC_WHBGPOSTAT_SETOUT1_POS  9
+#define IFX_SSC_WHBGPOSTAT_SET_OUT1     0x00000200
+#define IFX_SSC_WHBGPOSTAT_SETOUT2_POS  10
+#define IFX_SSC_WHBGPOSTAT_SET_OUT2     0x00000400
+#define IFX_SSC_WHBGPOSTAT_SETOUT3_POS  11
+#define IFX_SSC_WHBGPOSTAT_SET_OUT3     0x00000800
+#define IFX_SSC_WHBGPOSTAT_SETOUT4_POS  12
+#define IFX_SSC_WHBGPOSTAT_SET_OUT4     0x00001000
+#define IFX_SSC_WHBGPOSTAT_SETOUT5_POS  13
+#define IFX_SSC_WHBGPOSTAT_SET_OUT5     0x00002000
+#define IFX_SSC_WHBGPOSTAT_SETOUT6_POS  14
+#define IFX_SSC_WHBGPOSTAT_SET_OUT6     0x00004000
+#define IFX_SSC_WHBGPOSTAT_SETOUT7_POS  15
+#define IFX_SSC_WHBGPOSTAT_SET_OUT7     0x00008000
+#define IFX_SSC_WHBGPOSTAT_SET_OUT_ALL  0x0000FF00
+
+/* SFCON register */
+#define IFX_SSC_SFCON_SF_ENABLE                0x00000001
+#define IFX_SSC_SFCON_SF_DISABLE               0x00000000
+#define IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE  0x00000004
+#define IFX_SSC_SFCON_FIR_DISABLE_BEFORE_PAUSE 0x00000000
+#define IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE   0x00000008
+#define IFX_SSC_SFCON_FIR_DISABLE_AFTER_PAUSE  0x00000000
+#define IFX_SSC_SFCON_DATA_LENGTH_MASK         0x0000FFF0
+#define IFX_SSC_SFCON_DATA_LENGTH_OFFSET       4
+#define IFX_SSC_SFCON_PAUSE_DATA_MASK          0x00030000
+#define IFX_SSC_SFCON_PAUSE_DATA_OFFSET        16
+#define IFX_SSC_SFCON_PAUSE_DATA_0             0x00000000
+#define IFX_SSC_SFCON_PAUSE_DATA_1             0x00010000
+#define IFX_SSC_SFCON_PAUSE_DATA_IDLE          0x00020000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_MASK         0x000C0000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET       18
+#define IFX_SSC_SFCON_PAUSE_CLOCK_0            0x00000000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_1            0x00040000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_IDLE         0x00080000
+#define IFX_SSC_SFCON_PAUSE_CLOCK_RUN          0x000C0000
+#define IFX_SSC_SFCON_STOP_AFTER_PAUSE         0x00100000
+#define IFX_SSC_SFCON_CONTINUE_AFTER_PAUSE     0x00000000
+#define IFX_SSC_SFCON_PAUSE_LENGTH_MASK        0xFFC00000
+#define IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET      22
+#define IFX_SSC_SFCON_DATA_LENGTH_MAX         4096
+#define IFX_SSC_SFCON_PAUSE_LENGTH_MAX        1024
+
+#define IFX_SSC_SFCON_EXTRACT_DATA_LENGTH(sfcon)  ((sfcon & IFX_SSC_SFCON_DATA_LENGTH_MASK) >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET)
+#define IFX_SSC_SFCON_EXTRACT_PAUSE_LENGTH(sfcon) ((sfcon & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET)
+#define IFX_SSC_SFCON_SET_DATA_LENGTH(value)      ((value << IFX_SSC_SFCON_DATA_LENGTH_OFFSET) & IFX_SSC_SFCON_DATA_LENGTH_MASK)
+#define IFX_SSC_SFCON_SET_PAUSE_LENGTH(value)      ((value << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET) & IFX_SSC_SFCON_PAUSE_LENGTH_MASK)
+
+/* SFSTAT register */
+#define IFX_SSC_SFSTAT_IN_DATA            0x00000001
+#define IFX_SSC_SFSTAT_IN_PAUSE           0x00000002
+#define IFX_SSC_SFSTAT_DATA_COUNT_MASK    0x0000FFF0
+#define IFX_SSC_SFSTAT_DATA_COUNT_OFFSET  4
+#define IFX_SSC_SFSTAT_PAUSE_COUNT_MASK   0xFFF00000
+#define IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET 20
+
+#define IFX_SSC_SFSTAT_EXTRACT_DATA_COUNT(sfstat) ((sfstat & IFX_SSC_SFSTAT_DATA_COUNT_MASK) >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET)
+#define IFX_SSC_SFSTAT_EXTRACT_PAUSE_COUNT(sfstat) ((sfstat & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET)
+
+/* RXREQ register */
+#define IFX_SSC_RXREQ_RXCOUNT_MASK       0x0000FFFF
+#define IFX_SSC_RXREQ_RXCOUNT_OFFSET     0
+
+/* RXCNT register */
+#define IFX_SSC_RXCNT_TODO_MASK       0x0000FFFF
+#define IFX_SSC_RXCNT_TODO_OFFSET     0
+
+/* DMACON register */
+#define IFX_SSC_DMACON_RXON           0x00000001
+#define IFX_SSC_DMACON_RXOFF          0x00000000
+#define IFX_SSC_DMACON_TXON           0x00000002
+#define IFX_SSC_DMACON_TXOFF          0x00000000
+#define IFX_SSC_DMACON_DMAON          0x00000003
+#define IFX_SSC_DMACON_DMAOFF         0x00000000
+#define IFX_SSC_DMACON_CLASS_MASK     0x0000000C
+#define IFX_SSC_DMACON_CLASS_OFFSET   2
+
+/* register access macros */
+#define ifx_ssc_fstat_received_words(status)    (status & 0x003F)
+#define ifx_ssc_fstat_words_to_transmit(status) ((status & 0x3F00) >> 8)
+
+#define ifx_ssc_change_status(data, addr)  WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_WHBSTATE))
+#define ifx_ssc_set_config(data, addr)     WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_CON))
+#define ifx_ssc_get_config(addr)           READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_CON))
+#define ifx_ssc_get_status(addr)           READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_STATE))
+#define ifx_ssc_receive(addr)              READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_RB))
+#define ifx_ssc_transmit(data, addr)       WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_TB))
+#define ifx_ssc_fifo_status(addr)          READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_FSTAT))
+#define ifx_ssc_set_baudrate(data, addr)   WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_BR))
+
+#define ifx_ssc_extract_rx_fifo_size(id)   ((id & IFX_SSC_PERID_RXFS_MASK) >> IFX_SSC_PERID_RXFS_OFFSET)
+#define ifx_ssc_extract_tx_fifo_size(id)   ((id & IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET)
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips.h
new file mode 100644 (file)
index 0000000..2180f44
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2005 infineon
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+#ifndef _IFXMIPS_H__
+#define _IFXMIPS_H__
+
+#define ifxmips_r32(reg) __raw_readl(reg)
+#define ifxmips_w32(val,reg) __raw_writel(val,reg)
+#define ifxmips_w32_mask(clear,set,reg)        ifxmips_w32((ifxmips_r32(reg) & ~clear) | set, reg)
+
+/*------------ GENERAL */
+
+#define BOARD_SYSTEM_TYPE              "IFXMIPS"
+
+#define IOPORT_RESOURCE_START  0x10000000
+#define IOPORT_RESOURCE_END            0xffffffff
+#define IOMEM_RESOURCE_START   0x10000000
+#define IOMEM_RESOURCE_END             0xffffffff
+
+#define IFXMIPS_FLASH_START     0x10000000
+#define IFXMIPS_FLASH_MAX       0x2000000
+
+
+/*------------ ASC1 */
+
+#define IFXMIPS_ASC_BASE_ADDR  (KSEG1 + 0x1E100400)
+#define IFXMIPS_ASC_BASE_DIFF  (0x1E100C00 - 0x1E100400)
+
+#define IFXMIPS_ASC_FSTAT              0x0048
+#define IFXMIPS_ASC_TBUF               0x0020
+#define IFXMIPS_ASC_WHBSTATE   0x0018
+#define IFXMIPS_ASC_RBUF               0x0024
+#define IFXMIPS_ASC_STATE              0x0014
+#define IFXMIPS_ASC_IRNCR              0x00F8
+#define IFXMIPS_ASC_CLC                        0x0000
+#define IFXMIPS_ASC_PISEL              0x0004
+#define IFXMIPS_ASC_TXFCON             0x0044
+#define IFXMIPS_ASC_RXFCON             0x0040
+#define IFXMIPS_ASC_CON                        0x0010
+#define IFXMIPS_ASC_BG                 0x0050
+#define IFXMIPS_ASC_IRNREN             0x00F4
+
+#define IFXMIPS_ASC_CLC_DISS   0x2
+#define ASC_IRNREN_RX_BUF              0x8
+#define ASC_IRNREN_TX_BUF              0x4
+#define ASC_IRNREN_ERR                 0x2
+#define ASC_IRNREN_TX                  0x1
+#define ASC_IRNCR_TIR                  0x4
+#define ASC_IRNCR_RIR                  0x2
+#define ASC_IRNCR_EIR                  0x4
+#define ASCOPT_CSIZE                   0x3
+#define ASCOPT_CS7                             0x1
+#define ASCOPT_CS8                             0x2
+#define ASCOPT_PARENB                  0x4
+#define ASCOPT_STOPB                   0x8
+#define ASCOPT_PARODD                  0x0
+#define ASCOPT_CREAD                   0x20
+#define TXFIFO_FL                              1
+#define RXFIFO_FL                              1
+#define TXFIFO_FULL                            16
+#define ASCCLC_RMCMASK                 0x0000FF00
+#define ASCCLC_RMCOFFSET               8
+#define ASCCON_M_8ASYNC                        0x0
+#define ASCCON_M_7ASYNC                        0x2
+#define ASCCON_ODD                             0x00000020
+#define ASCCON_STP                             0x00000080
+#define ASCCON_BRS                             0x00000100
+#define ASCCON_FDE                             0x00000200
+#define ASCCON_R                               0x00008000
+#define ASCCON_FEN                             0x00020000
+#define ASCCON_ROEN                            0x00080000
+#define ASCCON_TOEN                            0x00100000
+#define ASCSTATE_PE                            0x00010000
+#define ASCSTATE_FE                            0x00020000
+#define ASCSTATE_ROE                   0x00080000
+#define ASCSTATE_ANY                   (ASCSTATE_ROE|ASCSTATE_PE|ASCSTATE_FE)
+#define ASCWHBSTATE_CLRREN             0x00000001
+#define ASCWHBSTATE_SETREN             0x00000002
+#define ASCWHBSTATE_CLRPE              0x00000004
+#define ASCWHBSTATE_CLRFE              0x00000008
+#define ASCWHBSTATE_CLRROE             0x00000020
+#define ASCTXFCON_TXFEN                        0x0001
+#define ASCTXFCON_TXFFLU               0x0002
+#define ASCTXFCON_TXFITLMASK    0x3F00
+#define ASCTXFCON_TXFITLOFF     8
+#define ASCRXFCON_RXFEN         0x0001
+#define ASCRXFCON_RXFFLU        0x0002
+#define ASCRXFCON_RXFITLMASK    0x3F00
+#define ASCRXFCON_RXFITLOFF     8
+#define ASCFSTAT_RXFFLMASK      0x003F
+#define ASCFSTAT_TXFFLMASK      0x3F00
+#define ASCFSTAT_TXFFLOFF       8
+
+
+
+/*------------ RCU */
+#define IFXMIPS_RCU_BASE_ADDR  0xBF203000
+
+/* reset request */
+#define IFXMIPS_RCU_RST                        ((u32*)(IFXMIPS_RCU_BASE_ADDR + 0x0010))
+#define IFXMIPS_RCU_RST_CPU1   (1 << 3)
+#define IFXMIPS_RCU_RST_ALL            0x40000000
+
+#define IFXMIPS_RCU_RST_REQ_DFE        (1 << 7)
+#define IFXMIPS_RCU_RST_REQ_AFE        (1 << 11)
+#define IFXMIPS_RCU_RST_REQ_ARC_JTAG   (1 << 20)
+
+
+/*------------ GPTU */
+
+#define IFXMIPS_GPTU_BASE_ADDR 0xB8000300
+
+/* clock control register */
+#define IFXMIPS_GPTU_GPT_CLC           ((u32*)(IFXMIPS_GPTU_BASE_ADDR + 0x0000))
+
+/* captur reload register */
+#define IFXMIPS_GPTU_GPT_CAPREL        ((u32*)(IFXMIPS_GPTU_BASE_ADDR + 0x0030))
+
+/* timer 6 control register */
+#define IFXMIPS_GPTU_GPT_T6CON ((u32*)(IFXMIPS_GPTU_BASE_ADDR + 0x0020))
+
+
+/*------------ EBU */
+
+#define IFXMIPS_EBU_BASE_ADDR  0xBE105300
+
+/* bus configuration register */
+#define IFXMIPS_EBU_BUSCON0            ((u32*)(IFXMIPS_EBU_BASE_ADDR + 0x0060))
+#define IFXMIPS_EBU_PCC_CON            ((u32*)(IFXMIPS_EBU_BASE_ADDR + 0x0090))
+#define IFXMIPS_EBU_PCC_IEN            ((u32*)(IFXMIPS_EBU_BASE_ADDR + 0x00A4))
+#define IFXMIPS_EBU_PCC_ISTAT  ((u32*)(IFXMIPS_EBU_BASE_ADDR + 0x00A0))
+
+
+/*------------ CGU */
+#define IFXMIPS_CGU_BASE_ADDR          (KSEG1 + 0x1F103000)
+#define IFXMIPS_CGU_PLL0_CFG           ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0004))
+#define IFXMIPS_CGU_PLL1_CFG           ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0008))
+#define IFXMIPS_CGU_PLL2_CFG           ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x000C))
+#define IFXMIPS_CGU_SYS                                ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0010))
+#define IFXMIPS_CGU_UPDATE                     ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0014))
+#define IFXMIPS_CGU_IF_CLK                     ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0018))
+#define IFXMIPS_CGU_OSC_CON                    ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x001C))
+#define IFXMIPS_CGU_SMD                                ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0020))
+#define IFXMIPS_CGU_CT1SR                      ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0028))
+#define IFXMIPS_CGU_CT2SR                      ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x002C))
+#define IFXMIPS_CGU_PCMCR                      ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0030))
+#define IFXMIPS_CGU_PCI_CR                     ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0034))
+#define IFXMIPS_CGU_PD_PC                      ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0038))
+#define IFXMIPS_CGU_FMR                                ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x003C))
+
+/* clock mux */
+#define IFXMIPS_CGU_SYS                        ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0010))
+#define IFXMIPS_CGU_IFCCR              ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0018))
+#define IFXMIPS_CGU_PCICR              ((u32*)(IFXMIPS_CGU_BASE_ADDR + 0x0034))
+
+#define CLOCK_60M                              60000000
+#define CLOCK_83M                              83333333
+#define CLOCK_111M                             111111111
+#define CLOCK_133M                             133333333
+#define CLOCK_167M                             166666667
+#define CLOCK_333M                             333333333
+
+
+/*------------ CGU */
+
+#define IFXMIPS_PMU_BASE_ADDR  (KSEG1 + 0x1F102000)
+
+#define IFXMIPS_PMU_PWDCR              ((u32*)(IFXMIPS_PMU_BASE_ADDR + 0x001C))
+#define IFXMIPS_PMU_PWDSR              ((u32*)(IFXMIPS_PMU_BASE_ADDR + 0x0020))
+
+
+/*------------ ICU */
+
+#define IFXMIPS_ICU_BASE_ADDR  0xBF880200
+
+
+#define IFXMIPS_ICU_IM0_ISR            ((u32*)(IFXMIPS_ICU_BASE_ADDR + 0x0000))
+#define IFXMIPS_ICU_IM0_IER            ((u32*)(IFXMIPS_ICU_BASE_ADDR + 0x0008))
+#define IFXMIPS_ICU_IM0_IOSR   ((u32*)(IFXMIPS_ICU_BASE_ADDR + 0x0010))
+#define IFXMIPS_ICU_IM0_IRSR   ((u32*)(IFXMIPS_ICU_BASE_ADDR + 0x0018))
+#define IFXMIPS_ICU_IM0_IMR            ((u32*)(IFXMIPS_ICU_BASE_ADDR + 0x0020))
+
+#define IFXMIPS_ICU_IM1_ISR            ((u32*)(IFXMIPS_ICU_BASE_ADDR + 0x0028))
+#define IFXMIPS_ICU_IM2_IER            ((u32*)(IFXMIPS_ICU_BASE_ADDR + 0x0058))
+#define IFXMIPS_ICU_IM5_IER            ((u32*)(IFXMIPS_ICU_BASE_ADDR + 0x00D0))
+
+#define IFXMIPS_ICU_OFFSET             (IFXMIPS_ICU_IM1_ISR - IFXMIPS_ICU_IM0_ISR)
+
+
+/*------------ ETOP */
+
+#define IFXMIPS_PPE32_BASE_ADDR        0xBE180000
+
+#define ETHERNET_PACKET_DMA_BUFFER_SIZE                0x600
+
+#define IFXMIPS_PPE32_MEM_MAP  ((u32*)(IFXMIPS_PPE32_BASE_ADDR + 0x10000))
+#define IFXMIPS_PPE32_SRST             ((u32*)(IFXMIPS_PPE32_BASE_ADDR + 0x10080))
+
+#define MII_MODE 1
+#define REV_MII_MODE 2
+
+/* mdio access */
+#define IFXMIPS_PPE32_MDIO_CFG ((u32*)(IFXMIPS_PPE32_BASE_ADDR + 0x11800))
+#define IFXMIPS_PPE32_MDIO_ACC ((u32*)(IFXMIPS_PPE32_BASE_ADDR + 0x11804))
+
+#define MDIO_ACC_REQUEST               0x80000000
+#define MDIO_ACC_READ                  0x40000000
+#define MDIO_ACC_ADDR_MASK             0x1f
+#define MDIO_ACC_ADDR_OFFSET   0x15
+#define MDIO_ACC_REG_MASK              0xff
+#define MDIO_ACC_REG_OFFSET            0x10
+#define MDIO_ACC_VAL_MASK              0xffff
+
+/* configuration */
+#define IFXMIPS_PPE32_CFG              ((u32*)(IFXMIPS_PPE32_MEM_MAP + 0x1808))
+
+#define PPE32_MII_MASK                 0xfffffffc
+#define PPE32_MII_NORMAL               0x8
+#define PPE32_MII_REVERSE              0xe
+
+/* packet length */
+#define IFXMIPS_PPE32_IG_PLEN_CTRL     ((u32*)(IFXMIPS_PPE32_MEM_MAP + 0x1820))
+
+#define PPE32_PLEN_OVER                        0x5ee
+#define PPE32_PLEN_UNDER               0x400000
+
+/* enet */
+#define IFXMIPS_PPE32_ENET_MAC_CFG     ((u32*)(IFXMIPS_PPE32_MEM_MAP + 0x1840))
+
+#define PPE32_CGEN                             0x800
+
+
+/*------------ DMA */
+#define IFXMIPS_DMA_BASE_ADDR  0xBE104100
+
+#define IFXMIPS_DMA_CS                 ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x18))
+#define IFXMIPS_DMA_CIE                        ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x2C))
+#define IFXMIPS_DMA_IRNEN              ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0xf4))
+#define IFXMIPS_DMA_CCTRL              ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x1C))
+#define IFXMIPS_DMA_CIS                        ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x28))
+#define IFXMIPS_DMA_CDLEN              ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x24))
+#define IFXMIPS_DMA_PS                 ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x40))
+#define IFXMIPS_DMA_PCTRL              ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x44))
+#define IFXMIPS_DMA_CTRL                       ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x10))
+#define IFXMIPS_DMA_CPOLL              ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x14))
+#define IFXMIPS_DMA_CDBA                       ((u32*)(IFXMIPS_DMA_BASE_ADDR + 0x20))
+
+
+/*------------ PCI */
+#define PCI_CR_PR_BASE_ADDR            (KSEG1 + 0x1E105400)
+
+#define PCI_CR_FCI_ADDR_MAP0   ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00C0))
+#define PCI_CR_FCI_ADDR_MAP1   ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00C4))
+#define PCI_CR_FCI_ADDR_MAP2   ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00C8))
+#define PCI_CR_FCI_ADDR_MAP3   ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00CC))
+#define PCI_CR_FCI_ADDR_MAP4   ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00D0))
+#define PCI_CR_FCI_ADDR_MAP5   ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00D4))
+#define PCI_CR_FCI_ADDR_MAP6   ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00D8))
+#define PCI_CR_FCI_ADDR_MAP7   ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00DC))
+#define PCI_CR_CLK_CTRL                        ((u32*)(PCI_CR_PR_BASE_ADDR + 0x0000))
+#define PCI_CR_PCI_MOD                 ((u32*)(PCI_CR_PR_BASE_ADDR + 0x0030))
+#define PCI_CR_PC_ARB                  ((u32*)(PCI_CR_PR_BASE_ADDR + 0x0080))
+#define PCI_CR_FCI_ADDR_MAP11hg        ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00E4))
+#define PCI_CR_BAR11MASK               ((u32*)(PCI_CR_PR_BASE_ADDR + 0x0044))
+#define PCI_CR_BAR12MASK               ((u32*)(PCI_CR_PR_BASE_ADDR + 0x0048))
+#define PCI_CR_BAR13MASK               ((u32*)(PCI_CR_PR_BASE_ADDR + 0x004C))
+#define PCI_CS_BASE_ADDR1              ((u32*)(PCI_CS_PR_BASE_ADDR + 0x0010))
+#define PCI_CR_PCI_ADDR_MAP11  ((u32*)(PCI_CR_PR_BASE_ADDR + 0x0064))
+#define PCI_CR_FCI_BURST_LENGTH        ((u32*)(PCI_CR_PR_BASE_ADDR + 0x00E8))
+#define PCI_CR_PCI_EOI                 ((u32*)(PCI_CR_PR_BASE_ADDR + 0x002C))
+
+#define PCI_CS_PR_BASE_ADDR            (KSEG1 + 0x17000000)
+
+#define PCI_CS_STS_CMD                 ((u32*)(PCI_CS_PR_BASE_ADDR + 0x0004))
+
+#define PCI_MASTER0_REQ_MASK_2BITS     8
+#define PCI_MASTER1_REQ_MASK_2BITS     10
+#define PCI_MASTER2_REQ_MASK_2BITS     12
+#define INTERNAL_ARB_ENABLE_BIT                0
+
+
+/*------------ WDT */
+
+#define IFXMIPS_WDT_BASE_ADDR  (KSEG1 + 0x1F880000)
+
+#define IFXMIPS_BIU_WDT_CR             ((u32*)(IFXMIPS_WDT_BASE_ADDR + 0x03F0))
+#define IFXMIPS_BIU_WDT_SR             ((u32*)(IFXMIPS_WDT_BASE_ADDR + 0x03F8))
+
+
+/*------------ LED */
+
+#define IFXMIPS_LED_BASE_ADDR  (KSEG1 + 0x1E100BB0)
+#define IFXMIPS_LED_CON0                       ((u32*)(IFXMIPS_LED_BASE_ADDR + 0x0000))
+#define IFXMIPS_LED_CON1                       ((u32*)(IFXMIPS_LED_BASE_ADDR + 0x0004))
+#define IFXMIPS_LED_CPU0                       ((u32*)(IFXMIPS_LED_BASE_ADDR + 0x0008))
+#define IFXMIPS_LED_CPU1                       ((u32*)(IFXMIPS_LED_BASE_ADDR + 0x000C))
+#define IFXMIPS_LED_AR                 ((u32*)(IFXMIPS_LED_BASE_ADDR + 0x0010))
+
+#define LED_CON0_SWU                   (1 << 31)
+#define LED_CON0_AD1                   (1 << 25)
+#define LED_CON0_AD0                   (1 << 24)
+
+#define IFXMIPS_LED_2HZ          (0)
+#define IFXMIPS_LED_4HZ          (1 << 23)
+#define IFXMIPS_LED_8HZ          (2 << 23)
+#define IFXMIPS_LED_10HZ         (3 << 23)
+#define IFXMIPS_LED_MASK         (0xf << 23)
+
+#define IFXMIPS_LED_UPD_SRC_FPI  (1 << 31)
+#define IFXMIPS_LED_UPD_MASK     (3 << 30)
+#define IFXMIPS_LED_ADSL_SRC           (3 << 24)
+
+#define IFXMIPS_LED_GROUP0             (1 << 0)
+#define IFXMIPS_LED_GROUP1             (1 << 1)
+#define IFXMIPS_LED_GROUP2             (1 << 2)
+
+#define IFXMIPS_LED_RISING             0
+#define IFXMIPS_LED_FALLING            (1 << 26)
+#define IFXMIPS_LED_EDGE_MASK  (1 << 26)
+
+
+/*------------ GPIO */
+
+#define IFXMIPS_GPIO_BASE_ADDR (0xBE100B00)
+
+#define IFXMIPS_GPIO_P0_OUT            ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0010))
+#define IFXMIPS_GPIO_P1_OUT            ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0040))
+#define IFXMIPS_GPIO_P0_IN             ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0014))
+#define IFXMIPS_GPIO_P1_IN             ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0044))
+#define IFXMIPS_GPIO_P0_DIR            ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0018))
+#define IFXMIPS_GPIO_P1_DIR            ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0048))
+#define IFXMIPS_GPIO_P0_ALTSEL0        ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x001C))
+#define IFXMIPS_GPIO_P1_ALTSEL0        ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x004C))
+#define IFXMIPS_GPIO_P0_ALTSEL1        ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0020))
+#define IFXMIPS_GPIO_P1_ALTSEL1        ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0050))
+#define IFXMIPS_GPIO_P0_OD             ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0024))
+#define IFXMIPS_GPIO_P1_OD             ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0054))
+#define IFXMIPS_GPIO_P0_STOFF  ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0028))
+#define IFXMIPS_GPIO_P1_STOFF  ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0058))
+#define IFXMIPS_GPIO_P0_PUDSEL ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x002C))
+#define IFXMIPS_GPIO_P1_PUDSEL ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x005C))
+#define IFXMIPS_GPIO_P0_PUDEN  ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0030))
+#define IFXMIPS_GPIO_P1_PUDEN  ((u32*)(IFXMIPS_GPIO_BASE_ADDR + 0x0060))
+
+
+/*------------ SSC */
+
+#define IFXMIPS_SSC_BASE_ADDR  (KSEG1 + 0x1e100800)
+
+
+#define IFXMIPS_SSC_CLC                        ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0000))
+#define IFXMIPS_SSC_IRN                        ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x00F4))
+#define IFXMIPS_SSC_SFCON              ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0060))
+#define IFXMIPS_SSC_WHBGPOSTAT ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0078))
+#define IFXMIPS_SSC_STATE              ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0014))
+#define IFXMIPS_SSC_WHBSTATE   ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0018))
+#define IFXMIPS_SSC_FSTAT              ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0038))
+#define IFXMIPS_SSC_ID                 ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0008))
+#define IFXMIPS_SSC_TB                 ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0020))
+#define IFXMIPS_SSC_RXFCON             ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0030))
+#define IFXMIPS_SSC_TXFCON             ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0034))
+#define IFXMIPS_SSC_CON                        ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0010))
+#define IFXMIPS_SSC_GPOSTAT            ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0074))
+#define IFXMIPS_SSC_RB                 ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0024))
+#define IFXMIPS_SSC_RXCNT              ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0084))
+#define IFXMIPS_SSC_GPOCON             ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0070))
+#define IFXMIPS_SSC_BR                 ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0040))
+#define IFXMIPS_SSC_RXREQ              ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0080))
+#define IFXMIPS_SSC_SFSTAT             ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0064))
+#define IFXMIPS_SSC_RXCNT              ((u32*)(IFXMIPS_SSC_BASE_ADDR + 0x0084))
+
+
+/*------------ MEI */
+
+#define IFXMIPS_MEI_BASE_ADDR  (0xBE116000)
+
+#define MEI_DATA_XFR                   ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0000))
+#define MEI_VERSION                            ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0004))
+#define MEI_ARC_GP_STAT                        ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0008))
+#define MEI_DATA_XFR_STAT              ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x000C))
+#define MEI_XFR_ADDR                   ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0010))
+#define MEI_MAX_WAIT                   ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0014))
+#define MEI_TO_ARC_INT                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0018))
+#define ARC_TO_MEI_INT                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x001C))
+#define ARC_TO_MEI_INT_MASK            ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0020))
+#define MEI_DEBUG_WAD                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0024))
+#define MEI_DEBUG_RAD                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0028))
+#define MEI_DEBUG_DATA                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x002C))
+#define MEI_DEBUG_DEC                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0030))
+#define MEI_CONFIG                             ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0034))
+#define MEI_RST_CONTROL                        ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0038))
+#define MEI_DBG_MASTER                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x003C))
+#define MEI_CLK_CONTROL                        ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0040))
+#define MEI_BIST_CONTROL               ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0044))
+#define MEI_BIST_STAT                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0048))
+#define MEI_XDATA_BASE_SH              ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x004c))
+#define MEI_XDATA_BASE                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0050))
+#define MEI_XMEM_BAR_BASE              ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0054))
+#define MEI_XMEM_BAR0                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0054))
+#define MEI_XMEM_BAR1                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0058))
+#define MEI_XMEM_BAR2                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x005C))
+#define MEI_XMEM_BAR3                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0060))
+#define MEI_XMEM_BAR4                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0064))
+#define MEI_XMEM_BAR5                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0068))
+#define MEI_XMEM_BAR6                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x006C))
+#define MEI_XMEM_BAR7                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0070))
+#define MEI_XMEM_BAR8                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0074))
+#define MEI_XMEM_BAR9                  ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0078))
+#define MEI_XMEM_BAR10                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x007C))
+#define MEI_XMEM_BAR11                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0080))
+#define MEI_XMEM_BAR12                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0084))
+#define MEI_XMEM_BAR13                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0088))
+#define MEI_XMEM_BAR14                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x008C))
+#define MEI_XMEM_BAR15                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0090))
+#define MEI_XMEM_BAR16                 ((u32*)(IFXMIPS_MEI_BASE_ADDR + 0x0094))
+
+
+/*------------ DEU */
+
+#define IFXMIPS_DEU_BASE     (KSEG1 + 0x1E103100)
+#define IFXMIPS_DEU_CLK                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0000))
+#define IFXMIPS_DEU_ID                 ((u32 *)(IFXMIPS_DEU_BASE + 0x0008))
+
+#define IFXMIPS_DES_CON                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0010))
+#define IFXMIPS_DES_IHR                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0014))
+#define IFXMIPS_DES_ILR                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0018))
+#define IFXMIPS_DES_K1HR               ((u32 *)(IFXMIPS_DEU_BASE + 0x001C))
+#define IFXMIPS_DES_K1LR               ((u32 *)(IFXMIPS_DEU_BASE + 0x0020))
+#define IFXMIPS_DES_K3HR               ((u32 *)(IFXMIPS_DEU_BASE + 0x0024))
+#define IFXMIPS_DES_K3LR               ((u32 *)(IFXMIPS_DEU_BASE + 0x0028))
+#define IFXMIPS_DES_IVHR               ((u32 *)(IFXMIPS_DEU_BASE + 0x002C))
+#define IFXMIPS_DES_IVLR               ((u32 *)(IFXMIPS_DEU_BASE + 0x0030))
+#define IFXMIPS_DES_OHR                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0040))
+#define IFXMIPS_DES_OLR                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0050))
+#define IFXMIPS_AES_CON                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0050))
+#define IFXMIPS_AES_ID3R               ((u32 *)(IFXMIPS_DEU_BASE + 0x0054))
+#define IFXMIPS_AES_ID2R               ((u32 *)(IFXMIPS_DEU_BASE + 0x0058))
+#define IFXMIPS_AES_ID1R               ((u32 *)(IFXMIPS_DEU_BASE + 0x005C))
+#define IFXMIPS_AES_ID0R               ((u32 *)(IFXMIPS_DEU_BASE + 0x0060))
+#define IFXMIPS_AES_K7R                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0064))
+#define IFXMIPS_AES_K6R                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0068))
+#define IFXMIPS_AES_K5R                        ((u32 *)(IFXMIPS_DEU_BASE + 0x006C))
+#define IFXMIPS_AES_K4R                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0070))
+#define IFXMIPS_AES_K3R                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0074))
+#define IFXMIPS_AES_K2R                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0078))
+#define IFXMIPS_AES_K1R                        ((u32 *)(IFXMIPS_DEU_BASE + 0x007C))
+#define IFXMIPS_AES_K0R                        ((u32 *)(IFXMIPS_DEU_BASE + 0x0080))
+#define IFXMIPS_AES_IV3R               ((u32 *)(IFXMIPS_DEU_BASE + 0x0084))
+#define IFXMIPS_AES_IV2R               ((u32 *)(IFXMIPS_DEU_BASE + 0x0088))
+#define IFXMIPS_AES_IV1R               ((u32 *)(IFXMIPS_DEU_BASE + 0x008C))
+#define IFXMIPS_AES_IV0R               ((u32 *)(IFXMIPS_DEU_BASE + 0x0090))
+#define IFXMIPS_AES_0D3R               ((u32 *)(IFXMIPS_DEU_BASE + 0x0094))
+#define IFXMIPS_AES_0D2R               ((u32 *)(IFXMIPS_DEU_BASE + 0x0098))
+#define IFXMIPS_AES_OD1R               ((u32 *)(IFXMIPS_DEU_BASE + 0x009C))
+#define IFXMIPS_AES_OD0R               ((u32 *)(IFXMIPS_DEU_BASE + 0x00A0))
+
+/*------------ FUSE */
+
+#define IFXMIPS_FUSE_BASE_ADDR (KSEG1 + 0x1F107354)
+
+
+/*------------ MPS */
+
+#define IFXMIPS_MPS_BASE_ADDR  (KSEG1 + 0x1F107000)
+#define IFXMIPS_MPS_SRAM               ((u32*)(KSEG1 + 0x1F200000))
+
+#define IFXMIPS_MPS_CHIPID             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0344))
+#define IFXMIPS_MPS_VC0ENR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0000))
+#define IFXMIPS_MPS_VC1ENR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0004))
+#define IFXMIPS_MPS_VC2ENR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0008))
+#define IFXMIPS_MPS_VC3ENR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x000C))
+#define IFXMIPS_MPS_RVC0SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0010))
+#define IFXMIPS_MPS_RVC1SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0014))
+#define IFXMIPS_MPS_RVC2SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0018))
+#define IFXMIPS_MPS_RVC3SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x001C))
+#define IFXMIPS_MPS_SVC0SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0020))
+#define IFXMIPS_MPS_SVC1SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0024))
+#define IFXMIPS_MPS_SVC2SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0028))
+#define IFXMIPS_MPS_SVC3SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x002C))
+#define IFXMIPS_MPS_CVC0SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0030))
+#define IFXMIPS_MPS_CVC1SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0034))
+#define IFXMIPS_MPS_CVC2SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0038))
+#define IFXMIPS_MPS_CVC3SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x003C))
+#define IFXMIPS_MPS_RAD0SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0040))
+#define IFXMIPS_MPS_RAD1SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0044))
+#define IFXMIPS_MPS_SAD0SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0048))
+#define IFXMIPS_MPS_SAD1SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x004C))
+#define IFXMIPS_MPS_CAD0SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0050))
+#define IFXMIPS_MPS_CAD1SR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0054))
+#define IFXMIPS_MPS_AD0ENR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x0058))
+#define IFXMIPS_MPS_AD1ENR             ((u32*)(IFXMIPS_MPS_BASE_ADDR + 0x005C))
+
+#define IFXMIPS_MPS_CHIPID_VERSION_GET(value)  (((value) >> 28) & ((1 << 4) - 1))
+#define IFXMIPS_MPS_CHIPID_VERSION_SET(value)  (((( 1 << 4) - 1) & (value)) << 28)
+#define IFXMIPS_MPS_CHIPID_PARTNUM_GET(value)  (((value) >> 12) & ((1 << 16) - 1))
+#define IFXMIPS_MPS_CHIPID_PARTNUM_SET(value)  (((( 1 << 16) - 1) & (value)) << 12)
+#define IFXMIPS_MPS_CHIPID_MANID_GET(value)            (((value) >> 1) & ((1 << 10) - 1))
+#define IFXMIPS_MPS_CHIPID_MANID_SET(value)            (((( 1 << 10) - 1) & (value)) << 1)
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_cgu.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_cgu.h
new file mode 100644 (file)
index 0000000..899bbbc
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+#ifndef _IFXMIPS_CGU_H__
+#define _IFXMIPS_CGU_H__
+
+unsigned int cgu_get_mips_clock(int cpu);
+unsigned int cgu_get_io_region_clock(void);
+unsigned int cgu_get_fpi_bus_clock(int fpi);
+void cgu_setup_pci_clk(int internal_clock);
+unsigned int ifxmips_get_ddr_hz(void);
+unsigned int ifxmips_get_fpi_hz(void);
+unsigned int ifxmips_get_cpu_hz(void);
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_dma.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_dma.h
new file mode 100644 (file)
index 0000000..02c7aec
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2005 infineon
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ *
+ */
+#ifndef _IFXMIPS_DMA_H__
+#define _IFXMIPS_DMA_H__
+
+#define RCV_INT                                                        1
+#define TX_BUF_FULL_INT                                        2
+#define TRANSMIT_CPT_INT                               4
+#define IFXMIPS_DMA_CH_ON                              1
+#define IFXMIPS_DMA_CH_OFF                             0
+#define IFXMIPS_DMA_CH_DEFAULT_WEIGHT  100
+
+enum attr_t{
+       TX = 0,
+       RX = 1,
+       RESERVED = 2,
+       DEFAULT = 3,
+};
+
+#define DMA_OWN                                                        1
+#define CPU_OWN                                                        0
+#define DMA_MAJOR                                              250
+
+#define DMA_DESC_OWN_CPU                               0x0
+#define DMA_DESC_OWN_DMA                               0x80000000
+#define DMA_DESC_CPT_SET                               0x40000000
+#define DMA_DESC_SOP_SET                               0x20000000
+#define DMA_DESC_EOP_SET                               0x10000000
+
+#define MISCFG_MASK                                            0x40
+#define RDERR_MASK                                             0x20
+#define CHOFF_MASK                                             0x10
+#define DESCPT_MASK                                            0x8
+#define DUR_MASK                                               0x4
+#define EOP_MASK                                               0x2
+
+#define DMA_DROP_MASK                                  (1<<31)
+
+#define IFXMIPS_DMA_RX                                 -1
+#define IFXMIPS_DMA_TX                                 1
+
+typedef struct dma_chan_map {
+       char dev_name[15];
+       enum attr_t dir;
+       int pri;
+       int irq;
+       int rel_chan_no;
+} _dma_chan_map;
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+typedef struct rx_desc{
+       u32 data_length:16;
+       volatile u32 reserved:7;
+       volatile u32 byte_offset:2;
+       volatile u32 Burst_length_offset:3;
+       volatile u32 EoP:1;
+       volatile u32 Res:1;
+       volatile u32 C:1;
+       volatile u32 OWN:1;
+       volatile u32 Data_Pointer;
+       /*fix me:should be 28 bits here, 32 bits just for host simulatiuon purpose*/
+}_rx_desc;
+
+typedef struct tx_desc{
+       volatile u32 data_length:16;
+       volatile u32 reserved1:7;
+       volatile u32 byte_offset:5;
+       volatile u32 EoP:1;
+       volatile u32 SoP:1;
+       volatile u32 C:1;
+       volatile u32 OWN:1;
+       volatile u32 Data_Pointer;//fix me:should be 28 bits here
+}_tx_desc;
+#else //BIG
+typedef struct rx_desc{
+       union
+       {
+               struct
+               {
+                       volatile u32 OWN:1;
+                       volatile u32 C:1;
+                       volatile u32 SoP:1;
+                       volatile u32 EoP:1;
+                       volatile u32 Burst_length_offset:3;
+                       volatile u32 byte_offset:2;
+                       volatile u32 reserve:7;
+                       volatile u32 data_length:16;
+               }field;
+               volatile u32 word;
+       }status;
+       volatile u32 Data_Pointer;
+}_rx_desc;
+
+typedef struct tx_desc{
+       union
+       {
+               struct
+               {
+                       volatile u32 OWN:1;
+                       volatile u32 C:1;
+                       volatile u32 SoP:1;
+                       volatile u32 EoP:1;
+                       volatile u32 byte_offset:5;
+                       volatile u32 reserved:7;
+                       volatile u32 data_length:16;
+               }field;
+               volatile u32 word;
+       }status;
+       volatile u32 Data_Pointer;
+}_tx_desc;
+#endif //ENDIAN
+
+typedef struct dma_channel_info{
+   /*relative channel number*/
+   int rel_chan_no;
+   /*class for this channel for QoS*/
+   int pri;
+   /*specify byte_offset*/
+   int byte_offset;
+   /*direction*/
+   int dir;
+   /*irq number*/
+   int irq;
+   /*descriptor parameter*/
+   int desc_base;
+   int desc_len;
+   int curr_desc;
+   int prev_desc;/*only used if it is a tx channel*/
+   /*weight setting for WFQ algorithm*/
+   int weight;
+   int default_weight;
+   int packet_size;
+   int burst_len;
+   /*on or off of this channel*/
+   int control;
+   /**optional information for the upper layer devices*/
+#if defined(CONFIG_IFXMIPS_ETHERNET_D2) || defined(CONFIG_IFXMIPS_PPA)
+   void* opt[64];
+#else
+   void* opt[25];
+#endif
+   /*Pointer to the peripheral device who is using this channel*/
+   void* dma_dev;
+   /*channel operations*/
+   void (*open)(struct dma_channel_info* pCh);
+   void (*close)(struct dma_channel_info* pCh);
+   void (*reset)(struct dma_channel_info* pCh);
+   void (*enable_irq)(struct dma_channel_info* pCh);
+   void (*disable_irq)(struct dma_channel_info* pCh);
+}_dma_channel_info;
+
+typedef struct dma_device_info{
+    /*device name of this peripheral*/
+    char device_name[15];
+    int reserved;
+    int tx_burst_len;
+    int rx_burst_len;
+    int default_weight;
+    int  current_tx_chan;
+       int  current_rx_chan;
+    int  num_tx_chan;
+    int  num_rx_chan;
+    int  max_rx_chan_num;
+    int  max_tx_chan_num;
+    _dma_channel_info* tx_chan[20];
+    _dma_channel_info* rx_chan[20];
+    /*functions, optional*/
+    u8* (*buffer_alloc)(int len,int* offset, void** opt);
+    void (*buffer_free)(u8* dataptr, void* opt);
+    int (*intr_handler)(struct dma_device_info* info, int status);
+    void * priv;               /* used by peripheral driver only */
+}_dma_device_info;
+
+_dma_device_info* dma_device_reserve(char* dev_name);
+
+void dma_device_release(_dma_device_info* dev);
+
+void dma_device_register(_dma_device_info* info);
+
+void dma_device_unregister(_dma_device_info* info);
+
+int dma_device_read(struct dma_device_info* info, u8** dataptr, void** opt);
+
+int dma_device_write(struct dma_device_info* info, u8* dataptr, int len, void* opt);
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_ebu.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_ebu.h
new file mode 100644 (file)
index 0000000..f9278ed
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+#ifndef _IFXMIPS_EBU_H__
+#define _IFXMIPS_EBU_H__
+
+extern spinlock_t ebu_lock;
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_gpio.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_gpio.h
new file mode 100644 (file)
index 0000000..237db01
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *   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.
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+#ifndef _IFXMIPS_GPIO_H__
+#define _IFXMIPS_GPIO_H__
+
+extern int ifxmips_port_reserve_pin (unsigned int port, unsigned int pin);
+extern int ifxmips_port_free_pin (unsigned int port, unsigned int pin);
+extern int ifxmips_port_set_open_drain (unsigned int port, unsigned int pin);
+extern int ifxmips_port_clear_open_drain (unsigned int port, unsigned int pin);
+extern int ifxmips_port_set_pudsel (unsigned int port, unsigned int pin);
+extern int ifxmips_port_clear_pudsel (unsigned int port, unsigned int pin);
+extern int ifxmips_port_set_puden (unsigned int port, unsigned int pin);
+extern int ifxmips_port_clear_puden (unsigned int port, unsigned int pin);
+extern int ifxmips_port_set_stoff (unsigned int port, unsigned int pin);
+extern int ifxmips_port_clear_stoff (unsigned int port, unsigned int pin);
+extern int ifxmips_port_set_dir_out (unsigned int port, unsigned int pin);
+extern int ifxmips_port_set_dir_in (unsigned int port, unsigned int pin);
+extern int ifxmips_port_set_output (unsigned int port, unsigned int pin);
+extern int ifxmips_port_clear_output (unsigned int port, unsigned int pin);
+extern int ifxmips_port_get_input (unsigned int port, unsigned int pin);
+extern int ifxmips_port_set_altsel0 (unsigned int port, unsigned int pin);
+extern int ifxmips_port_clear_altsel0 (unsigned int port, unsigned int pin);
+extern int ifxmips_port_set_altsel1 (unsigned int port, unsigned int pin);
+extern int ifxmips_port_clear_altsel1 (unsigned int port, unsigned int pin);
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_gptu.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_gptu.h
new file mode 100644 (file)
index 0000000..6ad4cc5
--- /dev/null
@@ -0,0 +1,161 @@
+#ifndef __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
+#define __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
+
+
+/******************************************************************************
+       Copyright (c) 2002, Infineon Technologies.  All rights reserved.
+
+                               No Warranty
+   Because the program is licensed free of charge, there is no warranty for
+   the program, to the extent permitted by applicable law.  Except when
+   otherwise stated in writing the copyright holders and/or other parties
+   provide the program "as is" without warranty of any kind, either
+   expressed or implied, including, but not limited to, the implied
+   warranties of merchantability and fitness for a particular purpose. The
+   entire risk as to the quality and performance of the program is with
+   you.  should the program prove defective, you assume the cost of all
+   necessary servicing, repair or correction.
+
+   In no event unless required by applicable law or agreed to in writing
+   will any copyright holder, or any other party who may modify and/or
+   redistribute the program as permitted above, be liable to you for
+   damages, including any general, special, incidental or consequential
+   damages arising out of the use or inability to use the program
+   (including but not limited to loss of data or data being rendered
+   inaccurate or losses sustained by you or third parties or a failure of
+   the program to operate with any other programs), even if such holder or
+   other party has been advised of the possibility of such damages.
+******************************************************************************/
+
+
+/*
+ * ####################################
+ *              Definition
+ * ####################################
+ */
+
+/*
+ *  Available Timer/Counter Index
+ */
+#define TIMER(n, X)                     (n * 2 + (X ? 1 : 0))
+#define TIMER_ANY                       0x00
+#define TIMER1A                         TIMER(1, 0)
+#define TIMER1B                         TIMER(1, 1)
+#define TIMER2A                         TIMER(2, 0)
+#define TIMER2B                         TIMER(2, 1)
+#define TIMER3A                         TIMER(3, 0)
+#define TIMER3B                         TIMER(3, 1)
+
+/*
+ *  Flag of Timer/Counter
+ *  These flags specify the way in which timer is configured.
+ */
+/*  Bit size of timer/counter.                      */
+#define TIMER_FLAG_16BIT                0x0000
+#define TIMER_FLAG_32BIT                0x0001
+/*  Switch between timer and counter.               */
+#define TIMER_FLAG_TIMER                0x0000
+#define TIMER_FLAG_COUNTER              0x0002
+/*  Stop or continue when overflowing/underflowing. */
+#define TIMER_FLAG_ONCE                 0x0000
+#define TIMER_FLAG_CYCLIC               0x0004
+/*  Count up or counter down.                       */
+#define TIMER_FLAG_UP                   0x0000
+#define TIMER_FLAG_DOWN                 0x0008
+/*  Count on specific level or edge.                */
+#define TIMER_FLAG_HIGH_LEVEL_SENSITIVE 0x0000
+#define TIMER_FLAG_LOW_LEVEL_SENSITIVE  0x0040
+#define TIMER_FLAG_RISE_EDGE            0x0010
+#define TIMER_FLAG_FALL_EDGE            0x0020
+#define TIMER_FLAG_ANY_EDGE             0x0030
+/*  Signal is syncronous to module clock or not.    */
+#define TIMER_FLAG_UNSYNC               0x0000
+#define TIMER_FLAG_SYNC                 0x0080
+/*  Different interrupt handle type.                */
+#define TIMER_FLAG_NO_HANDLE            0x0000
+#if defined(__KERNEL__)
+    #define TIMER_FLAG_CALLBACK_IN_IRQ  0x0100
+#endif  //  defined(__KERNEL__)
+#define TIMER_FLAG_SIGNAL               0x0300
+/*  Internal clock source or external clock source  */
+#define TIMER_FLAG_INT_SRC              0x0000
+#define TIMER_FLAG_EXT_SRC              0x1000
+
+
+/*
+ *  ioctl Command
+ */
+#define GPTU_REQUEST_TIMER              0x01    /*  General method to setup timer/counter.  */
+#define GPTU_FREE_TIMER                 0x02    /*  Free timer/counter.                     */
+#define GPTU_START_TIMER                0x03    /*  Start or resume timer/counter.          */
+#define GPTU_STOP_TIMER                 0x04    /*  Suspend timer/counter.                  */
+#define GPTU_GET_COUNT_VALUE            0x05    /*  Get current count value.                */
+#define GPTU_CALCULATE_DIVIDER          0x06    /*  Calculate timer divider from given freq.*/
+#define GPTU_SET_TIMER                  0x07    /*  Simplified method to setup timer.       */
+#define GPTU_SET_COUNTER                0x08    /*  Simplified method to setup counter.     */
+
+/*
+ *  Data Type Used to Call ioctl
+ */
+struct gptu_ioctl_param {
+    unsigned int                        timer;  /*  In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and  *
+                                                 *  GPTU_SET_COUNTER, this field is ID of expected      *
+                                                 *  timer/counter. If it's zero, a timer/counter would  *
+                                                 *  be dynamically allocated and ID would be stored in  *
+                                                 *  this field.                                         *
+                                                 *  In command GPTU_GET_COUNT_VALUE, this field is      *
+                                                 *  ignored.                                            *
+                                                 *  In other command, this field is ID of timer/counter *
+                                                 *  allocated.                                          */
+    unsigned int                        flag;   /*  In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and  *
+                                                 *  GPTU_SET_COUNTER, this field contains flags to      *
+                                                 *  specify how to configure timer/counter.             *
+                                                 *  In command GPTU_START_TIMER, zero indicate start    *
+                                                 *  and non-zero indicate resume timer/counter.         *
+                                                 *  In other command, this field is ignored.            */
+    unsigned long                       value;  /*  In command GPTU_REQUEST_TIMER, this field contains  *
+                                                 *  init/reload value.                                  *
+                                                 *  In command GPTU_SET_TIMER, this field contains      *
+                                                 *  frequency (0.001Hz) of timer.                       *
+                                                 *  In command GPTU_GET_COUNT_VALUE, current count      *
+                                                 *  value would be stored in this field.                *
+                                                 *  In command GPTU_CALCULATE_DIVIDER, this field       *
+                                                 *  contains frequency wanted, and after calculation,   *
+                                                 *  divider would be stored in this field to overwrite  *
+                                                 *  the frequency.                                      *
+                                                 *  In other command, this field is ignored.            */
+    int                                 pid;    /*  In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER,   *
+                                                 *  if signal is required, this field contains process  *
+                                                 *  ID to which signal would be sent.                   *
+                                                 *  In other command, this field is ignored.            */
+    int                                 sig;    /*  In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER,   *
+                                                 *  if signal is required, this field contains signal   *
+                                                 *  number which would be sent.                         *
+                                                 *  In other command, this field is ignored.            */
+};
+
+/*
+ * ####################################
+ *              Data Type
+ * ####################################
+ */
+typedef void (*timer_callback)(unsigned long arg);
+
+
+#if defined(__KERNEL__)
+    extern int ifxmips_request_timer(unsigned int, unsigned int, unsigned long, unsigned long, unsigned long);
+    extern int ifxmips_free_timer(unsigned int);
+    extern int ifxmips_start_timer(unsigned int, int);
+    extern int ifxmips_stop_timer(unsigned int);
+    extern int ifxmips_reset_counter_flags(u32 timer, u32 flags);
+    extern int ifxmips_get_count_value(unsigned int, unsigned long *);
+
+    extern u32 cal_divider(unsigned long);
+
+    extern int set_timer(unsigned int, unsigned int, int, int, unsigned int, unsigned long, unsigned long);
+extern int set_counter (unsigned int timer, unsigned int flag, u32 reload, unsigned long arg1, unsigned long arg2);
+//    extern int set_counter(unsigned int, int, int, int, unsigned int, unsigned int, unsigned long, unsigned long);
+#endif  //  defined(__KERNEL__)
+
+
+#endif  //  __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_irq.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_irq.h
new file mode 100644 (file)
index 0000000..694a646
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2005 infineon
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+#ifndef _IFXMIPS_IRQ__
+#define _IFXMIPS_IRQ__
+
+#define INT_NUM_IRQ0                   8
+#define INT_NUM_IM0_IRL0               (INT_NUM_IRQ0 + 0)
+#define INT_NUM_IM1_IRL0               (INT_NUM_IRQ0 + 32)
+#define INT_NUM_IM2_IRL0               (INT_NUM_IRQ0 + 64)
+#define INT_NUM_IM3_IRL0               (INT_NUM_IRQ0 + 96)
+#define INT_NUM_IM4_IRL0               (INT_NUM_IRQ0 + 128)
+#define INT_NUM_IM_OFFSET              (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
+
+#define IFXMIPSASC_TIR(x)              (INT_NUM_IM3_IRL0 + (x * 7))
+#define IFXMIPSASC_RIR(x)              (INT_NUM_IM3_IRL0 + (x * 7) + 2)
+#define IFXMIPSASC_EIR(x)              (INT_NUM_IM3_IRL0 + (x * 7) + 3)
+
+#define IFXMIPS_SSC_TIR                        (INT_NUM_IM0_IRL0 + 15)
+#define IFXMIPS_SSC_RIR                        (INT_NUM_IM0_IRL0 + 14)
+#define IFXMIPS_SSC_EIR                        (INT_NUM_IM0_IRL0 + 16)
+
+#define IFXMIPS_MEI_INT                        (INT_NUM_IM1_IRL0 + 23)
+
+#define IFXMIPS_TIMER6_INT             (INT_NUM_IM1_IRL0 + 23)
+#define IFXMIPS_USB_OC_INT             (INT_NUM_IM4_IRL0 + 23)
+
+#define MIPS_CPU_TIMER_IRQ             7
+
+#define IFXMIPS_DMA_CH0_INT            (INT_NUM_IM2_IRL0)
+#define IFXMIPS_DMA_CH1_INT            (INT_NUM_IM2_IRL0 + 1)
+#define IFXMIPS_DMA_CH2_INT            (INT_NUM_IM2_IRL0 + 2)
+#define IFXMIPS_DMA_CH3_INT            (INT_NUM_IM2_IRL0 + 3)
+#define IFXMIPS_DMA_CH4_INT            (INT_NUM_IM2_IRL0 + 4)
+#define IFXMIPS_DMA_CH5_INT            (INT_NUM_IM2_IRL0 + 5)
+#define IFXMIPS_DMA_CH6_INT            (INT_NUM_IM2_IRL0 + 6)
+#define IFXMIPS_DMA_CH7_INT            (INT_NUM_IM2_IRL0 + 7)
+#define IFXMIPS_DMA_CH8_INT            (INT_NUM_IM2_IRL0 + 8)
+#define IFXMIPS_DMA_CH9_INT            (INT_NUM_IM2_IRL0 + 9)
+#define IFXMIPS_DMA_CH10_INT           (INT_NUM_IM2_IRL0 + 10)
+#define IFXMIPS_DMA_CH11_INT           (INT_NUM_IM2_IRL0 + 11)
+#define IFXMIPS_DMA_CH12_INT           (INT_NUM_IM2_IRL0 + 25)
+#define IFXMIPS_DMA_CH13_INT           (INT_NUM_IM2_IRL0 + 26)
+#define IFXMIPS_DMA_CH14_INT           (INT_NUM_IM2_IRL0 + 27)
+#define IFXMIPS_DMA_CH15_INT           (INT_NUM_IM2_IRL0 + 28)
+#define IFXMIPS_DMA_CH16_INT           (INT_NUM_IM2_IRL0 + 29)
+#define IFXMIPS_DMA_CH17_INT           (INT_NUM_IM2_IRL0 + 30)
+#define IFXMIPS_DMA_CH18_INT           (INT_NUM_IM2_IRL0 + 16)
+#define IFXMIPS_DMA_CH19_INT           (INT_NUM_IM2_IRL0 + 21)
+
+#define IFXMIPS_USB_INT                                (INT_NUM_IM4_IRL0 + 22)
+#define IFXMIPS_USB_OC_INT                     (INT_NUM_IM4_IRL0 + 23)
+
+
+extern void ifxmips_mask_and_ack_irq(unsigned int irq_nr);
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_led.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_led.h
new file mode 100644 (file)
index 0000000..5e0d7f3
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+#ifndef _IFXMIPS_LED_H__ 
+#define _IFXMIPS_LED_H__
+
+extern void ifxmips_led_set(unsigned int led);
+extern void ifxmips_led_clear(unsigned int led);
+extern void ifxmips_led_blink_set(unsigned int led);
+extern void ifxmips_led_blink_clear(unsigned int led);
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei.h
new file mode 100644 (file)
index 0000000..d8a4b88
--- /dev/null
@@ -0,0 +1,270 @@
+/******************************************************************************
+**
+** FILE NAME    : danube_mei.h
+** PROJECT      : Danube
+** MODULES      : MEI
+**
+** DATE         : 1 Jan 2006
+** AUTHOR       : TC Chen
+** DESCRIPTION  : MEI Driver
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Version $Date      $Author     $Comment
+*******************************************************************************/
+#ifndef                _IFXMIPS_MEI_H
+#define                _IFXMIPS_MEI_H
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "ifxmips_mei_app.h"
+
+#define IFXMIPS_MEI_DEBUG
+#define IFXMIPS_MEI_CMV_EXTRA
+#define IFXMIPS_MEI_MAJOR      106
+
+/*
+**     Define where in ME Processor's memory map the Stratify chip lives
+*/
+
+#define MAXSWAPSIZE            8 * 1024        //8k *(32bits)
+
+//      Mailboxes
+#define MSG_LENGTH             16      // x16 bits
+#define YES_REPLY                      1
+#define NO_REPLY               0
+
+#define CMV_TIMEOUT            100     //jiffies
+#define MIB_INTERVAL           10000   //msec
+
+/***  Bit definitions ***/
+
+#define FALSE  0
+#define TRUE   1
+#define BIT0   1<<0
+#define BIT1   1<<1
+#define BIT2   1<<2
+#define BIT3   1<<3
+#define BIT4   1<<4
+#define BIT5   1<<5
+#define BIT6   1<<6
+#define BIT7   1<<7
+#define BIT8   1<<8
+#define BIT9   1<<9
+#define BIT10  1<<10
+#define BIT11  1<<11
+#define BIT12  1<<12
+#define BIT13  1<<13
+#define BIT14  1<<14
+#define BIT15  1<<15
+#define BIT16  1<<16
+#define BIT17  1<<17
+#define BIT18  1<<18
+#define BIT19  1<<19
+#define BIT20  1<<20
+#define BIT21  1<<21
+#define BIT22  1<<22
+#define BIT23  1<<23
+#define BIT24  1<<24
+#define BIT25  1<<25
+#define BIT26  1<<26
+#define BIT27  1<<27
+#define BIT28  1<<28
+#define BIT29  1<<29
+#define BIT30  1<<30
+#define BIT31  1<<31
+
+// ARC register addresss 
+#define ARC_STATUS                             0x0
+#define ARC_LP_START                           0x2
+#define ARC_LP_END                             0x3
+#define ARC_DEBUG                              0x5
+#define ARC_INT_MASK                           0x10A
+
+#define IRAM0_BASE                             (0x00000)
+#define IRAM1_BASE                             (0x04000)
+#define BRAM_BASE                              (0x0A000)
+
+#define ADSL_BASE                              (0x20000)
+#define CRI_BASE                               (ADSL_BASE + 0x11F00)
+#define CRI_CCR0                               (CRI_BASE + 0x00)
+#define CRI_RST                                        (CRI_BASE + 0x04*4)
+#define ADSL_DILV_BASE                                 (ADSL_BASE+0x20000)
+
+//
+#define IRAM0_ADDR_BIT_MASK   0xFFF
+#define IRAM1_ADDR_BIT_MASK   0xFFF
+#define BRAM_ADDR_BIT_MASK    0xFFF
+#define RX_DILV_ADDR_BIT_MASK 0x1FFF
+
+// CRI_CCR0 Register definitions        
+#define CLK_2M_MODE_ENABLE                     BIT6
+#define        ACL_CLK_MODE_ENABLE                     BIT4
+#define FDF_CLK_MODE_ENABLE                    BIT2
+#define STM_CLK_MODE_ENABLE                    BIT0
+
+// CRI_RST Register definitions 
+#define FDF_SRST                               BIT3
+#define MTE_SRST                               BIT2
+#define FCI_SRST                               BIT1
+#define AAI_SRST                               BIT0
+
+//      MEI_TO_ARC_INTERRUPT Register definitions
+#define        MEI_TO_ARC_INT1                 BIT3
+#define        MEI_TO_ARC_INT0                 BIT2
+#define MEI_TO_ARC_CS_DONE             BIT1    //need to check
+#define        MEI_TO_ARC_MSGAV                BIT0
+
+//      ARC_TO_MEI_INTERRUPT Register definitions
+#define        ARC_TO_MEI_INT1                 BIT8
+#define        ARC_TO_MEI_INT0                 BIT7
+#define        ARC_TO_MEI_CS_REQ               BIT6
+#define        ARC_TO_MEI_DBG_DONE             BIT5
+#define        ARC_TO_MEI_MSGACK               BIT4
+#define        ARC_TO_MEI_NO_ACCESS            BIT3
+#define        ARC_TO_MEI_CHECK_AAITX          BIT2
+#define        ARC_TO_MEI_CHECK_AAIRX          BIT1
+#define        ARC_TO_MEI_MSGAV                BIT0
+
+//      ARC_TO_MEI_INTERRUPT_MASK Register definitions
+#define        GP_INT1_EN                      BIT8
+#define        GP_INT0_EN                      BIT7
+#define        CS_REQ_EN                       BIT6
+#define        DBG_DONE_EN                     BIT5
+#define        MSGACK_EN                       BIT4
+#define        NO_ACC_EN                       BIT3
+#define        AAITX_EN                        BIT2
+#define        AAIRX_EN                        BIT1
+#define        MSGAV_EN                        BIT0
+
+#define        MEI_SOFT_RESET                  BIT0
+
+#define        HOST_MSTR                       BIT0
+
+#define JTAG_MASTER_MODE               0x0
+#define MEI_MASTER_MODE                        HOST_MSTR
+
+//      MEI_DEBUG_DECODE Register definitions
+#define MEI_DEBUG_DEC_MASK             (0x3)
+#define MEI_DEBUG_DEC_AUX_MASK         (0x0)
+#define MEI_DEBUG_DEC_DMP1_MASK                (0x1)
+#define MEI_DEBUG_DEC_DMP2_MASK                (0x2)
+#define MEI_DEBUG_DEC_CORE_MASK         (0x3)
+
+#define AUX_STATUS                     (0x0)
+//      ARC_TO_MEI_MAILBOX[11] is a special location used to indicate
+//      page swap requests.
+#define MEI_TO_ARC_MAILBOX             (0xDFD0)
+#define MEI_TO_ARC_MAILBOXR            (MEI_TO_ARC_MAILBOX + 0x2C)
+
+#define        ARC_TO_MEI_MAILBOX              (0xDFA0)
+#define ARC_MEI_MAILBOXR               (ARC_TO_MEI_MAILBOX + 0x2C)
+
+// Codeswap request messages are indicated by setting BIT31 
+#define OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK     (0x80000000)
+
+// Clear Eoc messages received are indicated by setting BIT17 
+#define OMB_CLEAREOC_INTERRUPT_CODE    (0x00020000)
+
+/*
+**     Swap page header
+*/
+//      Page must be loaded at boot time if size field has BIT31 set
+#define BOOT_FLAG      (BIT31)
+#define BOOT_FLAG_MASK ~BOOT_FLAG
+
+#define FREE_RELOAD            1
+#define FREE_SHOWTIME          2
+#define FREE_ALL               3
+
+#define IFX_POP_EOC_DONE       0
+#define IFX_POP_EOC_FAIL       -1
+
+#define CLREOC_BUFF_SIZE       12      //number of clreoc commands being buffered
+
+// marcos
+#define        IFXMIPS_WRITE_REGISTER_L(data,addr)     do{ *((volatile u32*)(addr)) = (u32)(data);} while (0)
+#define IFXMIPS_READ_REGISTER_L(addr)  (*((volatile u32*)(addr)))
+#define SET_BIT(reg, mask)                  reg |= (mask)
+#define CLEAR_BIT(reg, mask)                reg &= (~mask)
+#define CLEAR_BITS(reg, mask)               CLEAR_BIT(reg, mask)
+#define SET_BITS(reg, mask)                 SET_BIT(reg, mask)
+#define SET_BITFIELD(reg, mask, off, val)   {reg &= (~mask); reg |= (val << off);}
+
+#define ALIGN_SIZE                         ( 1L<<10 )  //1K size align
+#define MEM_ALIGN(addr)                    (((addr) + ALIGN_SIZE - 1) & ~ (ALIGN_SIZE -1) )
+
+// swap marco
+#define MEI_HALF_WORD_SWAP(data) {data = ((data & 0xffff)<<16) + ((data & 0xffff0000)>>16);}
+#define MEI_BYTE_SWAP(data) {data = ((data & 0xff)<<24) + ((data & 0xff00)<<8)+ ((data & 0xff0000)>>8)+ ((data & 0xff000000)>>24);}
+
+//      Swap page header describes size in 32-bit words, load location, and image offset
+//      for program and/or data segments
+typedef struct _arc_swp_page_hdr {
+       u32 p_offset;           //Offset bytes of progseg from beginning of image
+       u32 p_dest;             //Destination addr of progseg on processor
+       u32 p_size;             //Size in 32-bitwords of program segment
+       u32 d_offset;           //Offset bytes of dataseg from beginning of image
+       u32 d_dest;             //Destination addr of dataseg on processor
+       u32 d_size;             //Size in 32-bitwords of data segment
+} ARC_SWP_PAGE_HDR;
+
+#ifdef CONFIG_PROC_FS
+typedef struct reg_entry {
+       int *flag;
+       char name[30];          // big enough to hold names
+       char description[100];  // big enough to hold description
+       unsigned short low_ino;
+} reg_entry_t;
+#endif
+
+/*
+**     Swap image header
+*/
+#define GET_PROG       0       //      Flag used for program mem segment
+#define GET_DATA       1       //      Flag used for data mem segment
+
+//      Image header contains size of image, checksum for image, and count of
+//      page headers. Following that are 'count' page headers followed by
+//      the code and/or data segments to be loaded
+typedef struct _arc_img_hdr {
+       u32 size;               //      Size of binary image in bytes
+       u32 checksum;           //      Checksum for image
+       u32 count;              //      Count of swp pages in image
+       ARC_SWP_PAGE_HDR page[1];       //      Should be "count" pages - '1' to make compiler happy
+} ARC_IMG_HDR;
+
+typedef struct smmu_mem_info {
+       int type;
+       unsigned long nCopy;
+       unsigned long size;
+       unsigned char *address;
+       unsigned char *org_address;
+} smmu_mem_info_t;
+
+/*
+**     Native size for the Stratiphy interface is 32-bits. All reads and writes
+**     MUST be aligned on 32-bit boundaries. Trickery must be invoked to read word and/or
+**     byte data. Read routines are provided. Write routines are probably a bad idea, as the
+**     Arc has unrestrained, unseen access to the same memory, so a read-modify-write cycle
+**     could very well have unintended results.
+*/
+MEI_ERROR meiCMV (u16 *, int, u16 *);  // first arg is CMV to ARC, second to indicate whether need reply
+
+MEI_ERROR meiDebugWrite (u32 destaddr, u32 * databuff, u32 databuffsize);
+extern int ifx_mei_hdlc_send (char *hdlc_pkt, int hdlc_pkt_len);
+extern int ifx_mei_hdlc_read (char *hdlc_pkt, int max_hdlc_pkt_len);
+#if defined(__KERNEL__) || defined (IFXMIPS_PORT_RTEMS)
+extern void makeCMV (u8 opcode, u8 group, u16 address, u16 index, int size,
+                    u16 * data, u16 * CMVMSG);
+int ifx_mei_hdlc_send (char *, int);
+int ifx_mei_hdlc_read (char *, int);
+#endif
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_app.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_app.h
new file mode 100644 (file)
index 0000000..cba742e
--- /dev/null
@@ -0,0 +1,116 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_mei_app.h
+** PROJECT      : Danube
+** MODULES      : MEI
+**
+** DATE         : 1 Jan 2006
+** AUTHOR       : TC Chen
+** DESCRIPTION  : MEI Driver
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Version $Date      $Author     $Comment
+*******************************************************************************/
+#ifndef        _IFXMIPS_MEI_APP_H
+#define                _IFXMIPS_MEI_APP_H
+               //  ioctl control
+#define IFXMIPS_MEI_START                              300
+#define IFXMIPS_MEI_REPLY                              301
+#define IFXMIPS_MEI_NOREPLY                            302
+
+#define IFXMIPS_MEI_RESET                              303
+#define IFXMIPS_MEI_REBOOT                             304
+#define IFXMIPS_MEI_HALT                                       305
+#define IFXMIPS_MEI_CMV_WINHOST                                306
+#define IFXMIPS_MEI_CMV_READ                           307
+#define IFXMIPS_MEI_CMV_WRITE                          308
+#define IFXMIPS_MEI_MIB_DAEMON                         309
+#define IFXMIPS_MEI_SHOWTIME                           310
+#define IFXMIPS_MEI_REMOTE                             311
+#define IFXMIPS_MEI_READDEBUG                          312
+#define IFXMIPS_MEI_WRITEDEBUG                         313
+#define IFXMIPS_MEI_LOP                                        314
+
+#define IFXMIPS_MEI_PCM_SETUP                          315
+#define IFXMIPS_MEI_PCM_START_TIMER                    316
+#define IFXMIPS_MEI_PCM_STOP_TIMER                     317
+#define IFXMIPS_MEI_PCM_CHECK                          318
+#define IFXMIPS_MEI_GET_EOC_LEN                                319
+#define IFXMIPS_MEI_GET_EOC_DATA                               320
+#define IFXMIPS_MEI_PCM_GETDATA                                321
+#define IFXMIPS_MEI_PCM_GPIO                           322
+#define IFXMIPS_MEI_EOC_SEND                           323
+#define IFXMIPS_MEI_DOWNLOAD                           326
+#define IFXMIPS_MEI_JTAG_ENABLE                                327
+#define IFXMIPS_MEI_RUN                                        328
+#define IFXMIPS_MEI_DEBUG_MODE                         329
+
+/* Loop diagnostics mode of the ADSL line related constants */
+#define SET_ADSL_LOOP_DIAGNOSTICS_MODE                         330
+#define GET_ADSL_LOOP_DIAGNOSTICS_MODE                         331
+#define LOOP_DIAGNOSTIC_MODE_COMPLETE                   332
+#define IS_ADSL_LOOP_DIAGNOSTICS_MODE_COMPLETE         333
+
+/* L3 Power Mode */
+/* Get current Power Moaagement Mode Status*/
+#define GET_POWER_MANAGEMENT_MODE                      334
+/* Set L3 Power Mode /disable L3 power mode */
+#define SET_L3_POWER_MODE                              335
+
+/* get current dual latency configuration */
+#define GET_ADSL_DUAL_LATENCY                          336
+/* enable/disable dual latency path */
+#define SET_ADSL_DUAL_LATENCY                          337
+
+/* Enable/Disable autoboot mode. */
+/* When the autoboot mode is disabled, the driver will excute some cmv 
+   commands for led control and dual latency when DSL startup.*/
+#define AUTOBOOT_ENABLE_SET                            338
+
+/* Enable/Disable Quiet Mode*/
+/* Quiet mode is used for firmware debug. if the quiet mode enable, the autoboot daemon will not reset arc when the arc need to reboot */
+#define QUIET_MODE_GET                                 339
+#define QUIET_MODE_SET                                 340
+
+/* Enable/Disable showtime lock*/
+/* showtime lock is used for firmware debug. if the showtime lock enable, the autoboot daemon will not reset arc when the arc reach showtime and need to reboot */
+#define SHOWTIME_LOCK_GET                              341
+#define SHOWTIME_LOCK_SET                              342
+
+#define L0_POWER_MODE 0
+#define L2_POWER_MODE 2
+#define L3_POWER_MODE 3
+
+#define DUAL_LATENCY_US_DS_DISABLE                     0
+#define DUAL_LATENCY_US_ENABLE                         (1<<0)
+#define DUAL_LATENCY_DS_ENABLE                         (1<<1)
+#define DUAL_LATENCY_US_DS_ENABLE                      (DUAL_LATENCY_US_ENABLE|DUAL_LATENCY_DS_ENABLE)
+
+#define ME_HDLC_IDLE 0
+#define ME_HDLC_INVALID_MSG 1
+#define ME_HDLC_MSG_QUEUED 2
+#define ME_HDLC_MSG_SENT 3
+#define ME_HDLC_RESP_RCVD 4
+#define ME_HDLC_RESP_TIMEOUT 5
+#define ME_HDLC_RX_BUF_OVERFLOW 6
+#define ME_HDLC_UNRESOLVED 1
+#define ME_HDLC_RESOLVED 2
+
+/***   Enums    ***/
+typedef enum mei_error {
+       MEI_SUCCESS = 0,
+       MEI_FAILURE = -1,
+       MEI_MAILBOX_FULL = -2,
+       MEI_MAILBOX_EMPTY = -3,
+       MEI_MAILBOX_TIMEOUT = -4,
+} MEI_ERROR;
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_app_ioctl.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_app_ioctl.h
new file mode 100644 (file)
index 0000000..08c3dd3
--- /dev/null
@@ -0,0 +1,1191 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_mei_app_ioctl.h
+** PROJECT      : Danube
+** MODULES      : MEI
+**
+** DATE         : 1 Jan 2006
+** AUTHOR       : TC Chen
+** DESCRIPTION  : MEI Driver
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Version $Date      $Author     $Comment
+*******************************************************************************/
+#ifndef __IFXMIPS_MEI_APP_IOCTL_H
+#define __IFXMIPS_MEI_APP_IOCTL_H
+
+#ifdef __KERNEL__
+#include "ifxmips_mei_ioctl.h"
+#endif
+
+/* Interface Name */
+//#define INTERFACE_NAME <define the interface>
+
+/* adslLineTable constants */
+#define GET_ADSL_LINE_CODE             1
+
+/* adslAtucPhysTable constants */
+#define GET_ADSL_ATUC_PHY              4
+
+/* adslAturPhysTable constants */
+#define GET_ADSL_ATUR_PHY              10
+
+/* adslAtucChanTable constants */
+#define GET_ADSL_ATUC_CHAN_INFO        15
+
+/* adslAturChanTable constants */
+#define GET_ADSL_ATUR_CHAN_INFO                18
+
+/* adslAtucPerfDataTable constants */
+#define GET_ADSL_ATUC_PERF_DATA                21
+
+/* adslAturPerfDataTable constants */
+#define GET_ADSL_ATUR_PERF_DATA                40
+
+/* adslAtucIntervalTable constants */
+#define GET_ADSL_ATUC_INTVL_INFO       60
+
+/* adslAturIntervalTable constants */
+#define GET_ADSL_ATUR_INTVL_INFO       65
+
+/* adslAtucChanPerfDataTable constants */
+#define GET_ADSL_ATUC_CHAN_PERF_DATA   70
+
+/* adslAturChanPerfDataTable constants */
+#define GET_ADSL_ATUR_CHAN_PERF_DATA   90
+
+/* adslAtucChanIntervalTable constants */
+#define GET_ADSL_ATUC_CHAN_INTVL_INFO  110
+
+/* adslAturChanIntervalTable constants */
+#define GET_ADSL_ATUR_CHAN_INTVL_INFO  115
+
+/* adslLineAlarmConfProfileTable constants */
+#define GET_ADSL_ALRM_CONF_PROF                120
+#define SET_ADSL_ALRM_CONF_PROF                121
+
+/* adslAturTrap constants */
+#define ADSL_ATUR_TRAPS                        135
+
+//////////////////  RFC-3440 //////////////
+
+#ifdef IFXMIPS_MEI_MIB_RFC3440
+/* adslLineExtTable */
+#define GET_ADSL_ATUC_LINE_EXT         201
+#define SET_ADSL_ATUC_LINE_EXT         203
+
+/* adslAtucPerfDateExtTable */
+#define GET_ADSL_ATUC_PERF_DATA_EXT    205
+
+/* adslAtucIntervalExtTable */
+#define GET_ADSL_ATUC_INTVL_EXT_INFO   221
+
+/* adslAturPerfDataExtTable */
+#define GET_ADSL_ATUR_PERF_DATA_EXT    225
+
+/* adslAturIntervalExtTable */
+#define GET_ADSL_ATUR_INTVL_EXT_INFO   233
+
+/* adslAlarmConfProfileExtTable */
+#define GET_ADSL_ALRM_CONF_PROF_EXT    235
+#define SET_ADSL_ALRM_CONF_PROF_EXT    236
+
+/* adslAturExtTrap */
+#define ADSL_ATUR_EXT_TRAPS            240
+
+#endif
+
+/* The following constants are added to support the WEB related ADSL Statistics */
+
+/* adslLineStatus constants */
+#define GET_ADSL_LINE_STATUS           245
+
+/* adslLineRate constants */
+#define GET_ADSL_LINE_RATE             250
+
+/* adslLineInformation constants */
+#define GET_ADSL_LINE_INFO             255
+
+/* adslNearEndPerformanceStats constants */
+#define GET_ADSL_NEAREND_STATS 270
+
+/* adslFarEndPerformanceStats constants */
+#define GET_ADSL_FAREND_STATS  290
+
+/* Sub-carrier related parameters */
+#define GET_ADSL_LINE_INIT_STATS       150
+#define GET_ADSL_POWER_SPECTRAL_DENSITY        151
+
+#define IFXMIPS_MIB_LO_ATUC            295
+#define IFXMIPS_MIB_LO_ATUR            296
+
+#define GET_ADSL_ATUC_SUBCARRIER_STATS 297
+#define GET_ADSL_ATUR_SUBCARRIER_STATS 298
+
+
+
+///////////////////////////////////////////////////////////
+// makeCMV(Opcode, Group, Address, Index, Size, Data)
+
+/* adslLineCode Flags */
+#define LINE_CODE_FLAG                 0x1     /* BIT 0th position */
+
+/* adslAtucPhysTable Flags */
+#define ATUC_PHY_SER_NUM_FLAG          0x1     /* BIT 0th position */
+#define ATUC_PHY_SER_NUM_FLAG_MAKECMV1 makeCMV(H2D_CMV_READ, INFO, 57, 0, 12, data,TxMessage) 
+#define ATUC_PHY_SER_NUM_FLAG_MAKECMV2 makeCMV(H2D_CMV_READ, INFO, 57, 12, 4, data,TxMessage) 
+
+#define ATUC_PHY_VENDOR_ID_FLAG                0x2     /* BIT 1 */
+#define ATUC_PHY_VENDOR_ID_FLAG_MAKECMV        makeCMV(H2D_CMV_READ, INFO, 64, 0, 4, data,TxMessage)
+
+#define ATUC_PHY_VER_NUM_FLAG          0x4     /* BIT 2 */
+#define ATUC_PHY_VER_NUM_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 58, 0, 8, data,TxMessage)
+
+#define ATUC_CURR_STAT_FLAG            0x8     /* BIT 3 */
+
+#define ATUC_CURR_OUT_PWR_FLAG         0x10    /* BIT 4 */
+#define ATUC_CURR_OUT_PWR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 5, 1, data,TxMessage)
+
+#define ATUC_CURR_ATTR_FLAG            0x20    /* BIT 5 */
+#define ATUC_CURR_ATTR_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, INFO, 69, 0, 2, data,TxMessage)
+
+
+/* adslAturPhysTable   Flags */
+#define ATUR_PHY_SER_NUM_FLAG          0x1     /* BIT 0th position */
+#define ATUR_PHY_SER_NUM_FLAG_MAKECMV1 makeCMV(H2D_CMV_READ, INFO, 62, 0, 12, data,TxMessage)
+#define ATUR_PHY_SER_NUM_FLAG_MAKECMV2 makeCMV(H2D_CMV_READ, INFO, 62, 12, 4, data,TxMessage)
+
+#define ATUR_PHY_VENDOR_ID_FLAG                0x2     /* BIT 1 */
+#define ATUR_PHY_VENDOR_ID_FLAG_MAKECMV        makeCMV(H2D_CMV_READ, INFO, 65, 0, 4, data,TxMessage)
+
+#define ATUR_PHY_VER_NUM_FLAG          0x4     /* BIT 2 */
+#define ATUR_PHY_VER_NUM_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 61, 0, 8, data,TxMessage)
+
+#define ATUR_SNRMGN_FLAG               0x8
+#if 0 /* [ Ritesh. Use PLAM 45 0 for 0.1dB resolution rather than INFO 68 3 */
+#define ATUR_SNRMGN_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, INFO, 68, 4, 1, data,TxMessage)
+#else
+#define ATUR_SNRMGN_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, PLAM_SNRMargin_0_1db, 0, 1, data, TxMessage)
+#endif
+
+#define ATUR_ATTN_FLAG                 0x10
+#define ATUR_ATTN_FLAG_MAKECMV         makeCMV(H2D_CMV_READ, INFO, 68, 2, 1, data,TxMessage)
+
+#define ATUR_CURR_STAT_FLAG            0x20    /* BIT 3 */
+
+#define ATUR_CURR_OUT_PWR_FLAG         0x40    /* BIT 4 */
+#define ATUR_CURR_OUT_PWR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 5, 1, data,TxMessage)
+
+#define ATUR_CURR_ATTR_FLAG            0x80    /* BIT 5 */
+#define ATUR_CURR_ATTR_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, INFO, 68, 0, 2, data,TxMessage)
+
+/* adslAtucChanTable Flags */
+#define ATUC_CHAN_INTLV_DELAY_FLAG     0x1     /* BIT 0th position */
+//KD #define ATUC_CHAN_INTLV_DELAY_FLAG_MAKECMV        makeCMV(H2D_CMV_READ, RATE, 3, 1, 1, data,TxMessage)
+#define ATUC_CHAN_INTLV_DELAY_FLAG_MAKECMV     makeCMV(H2D_CMV_READ, INFO, 92, 1, 1, data,TxMessage)
+
+#define ATUC_CHAN_CURR_TX_RATE_FLAG    0x2     /* BIT 1 */
+#define ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, RATE, 1, 0, 2, data,TxMessage)
+
+#define ATUC_CHAN_PREV_TX_RATE_FLAG    0x4     /* BIT 2 */
+
+/* adslAturChanTable Flags */
+#define ATUR_CHAN_INTLV_DELAY_FLAG     0x1     /* BIT 0th position */
+//KD #define ATUR_CHAN_INTLV_DELAY_FLAG_MAKECMV        makeCMV(H2D_CMV_READ, RATE, 2, 1, 1, data,TxMessage)
+#define ATUR_CHAN_INTLV_DELAY_FLAG_MAKECMV     makeCMV(H2D_CMV_READ, INFO, 93, 1, 1, data,TxMessage)
+
+#define ATUR_CHAN_CURR_TX_RATE_FLAG    0x2     /* BIT 1 */
+#define ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, RATE, 0, 0, 2, data,TxMessage)
+
+#define ATUR_CHAN_PREV_TX_RATE_FLAG    0x4     /* BIT 2 */
+
+#define ATUR_CHAN_CRC_BLK_LEN_FLAG     0x8     /* BIT 3 */
+
+/* adslAtucPerfDataTable Flags */
+#define ATUC_PERF_LOFS_FLAG            0x1     /* BIT 0th position */
+#define ATUC_PERF_LOSS_FLAG            0x2     /* BIT 1 */
+#define ATUC_PERF_LO_FLAG_MAKECMV              makeCMV(H2D_CMV_READ, PLAM, 0, 0, 1, data,TxMessage)
+#define ATUC_PERF_ESS_FLAG             0x4     /* BIT 2 */
+#define ATUC_PERF_ESS_FLAG_MAKECMV             makeCMV(H2D_CMV_READ, PLAM, 7, 0, 1, data,TxMessage) 
+#define ATUC_PERF_INITS_FLAG   0x8     /* BIT 3 */
+#define ATUC_PERF_VALID_INTVLS_FLAG    0x10 /* BIT 4 */
+#define ATUC_PERF_INVALID_INTVLS_FLAG  0x20 /* BIT 5 */
+#define ATUC_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */
+#define ATUC_PERF_CURR_15MIN_LOFS_FLAG         0x80     /* BIT 7 */
+#define ATUC_PERF_CURR_15MIN_LOSS_FLAG         0x100 /* BIT 8 */
+#define ATUC_PERF_CURR_15MIN_ESS_FLAG          0x200   /* BIT 9 */
+#define ATUC_PERF_CURR_15MIN_INIT_FLAG         0x400 /* BIT 10 */
+#define ATUC_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */
+#define ATUC_PERF_CURR_1DAY_LOFS_FLAG          0x1000 /* BIT 12 */
+#define ATUC_PERF_CURR_1DAY_LOSS_FLAG          0x2000 /* BIT 13 */
+#define ATUC_PERF_CURR_1DAY_ESS_FLAG           0x4000 /* BIT 14 */
+#define ATUC_PERF_CURR_1DAY_INIT_FLAG          0x8000 /* BIT 15 */
+#define ATUC_PERF_PREV_1DAY_MON_SEC_FLAG       0x10000 /* BIT 16 */
+#define ATUC_PERF_PREV_1DAY_LOFS_FLAG          0x20000 /* BIT 17 */
+#define ATUC_PERF_PREV_1DAY_LOSS_FLAG          0x40000 /* BIT 18 */
+#define ATUC_PERF_PREV_1DAY_ESS_FLAG           0x80000 /* BIT 19 */
+#define ATUC_PERF_PREV_1DAY_INITS_FLAG         0x100000 /* BIT 20 */
+
+/* adslAturPerfDataTable Flags */
+#define ATUR_PERF_LOFS_FLAG            0x1     /* BIT 0th position */
+#define ATUR_PERF_LOSS_FLAG            0x2     /* BIT 1 */
+#define ATUR_PERF_LPR_FLAG             0x4     /* BIT 2 */
+#define ATUR_PERF_LO_FLAG_MAKECMV              makeCMV(H2D_CMV_READ, PLAM, 1, 0, 1, data,TxMessage)
+#define ATUR_PERF_ESS_FLAG             0x8     /* BIT 3 */
+#define ATUR_PERF_ESS_FLAG_MAKECMV             makeCMV(H2D_CMV_READ, PLAM, 33, 0, 1, data,TxMessage)
+#define ATUR_PERF_VALID_INTVLS_FLAG    0x10 /* BIT 4 */
+#define ATUR_PERF_INVALID_INTVLS_FLAG  0x20 /* BIT 5 */
+#define ATUR_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */
+#define ATUR_PERF_CURR_15MIN_LOFS_FLAG         0x80     /* BIT 7 */
+#define ATUR_PERF_CURR_15MIN_LOSS_FLAG         0x100 /* BIT 8 */
+#define ATUR_PERF_CURR_15MIN_LPR_FLAG          0x200 /* BIT 9 */
+#define ATUR_PERF_CURR_15MIN_ESS_FLAG          0x400   /* BIT 10 */
+#define ATUR_PERF_CURR_1DAY_TIME_ELAPSED_FLAG  0x800 /* BIT 11 */
+#define ATUR_PERF_CURR_1DAY_LOFS_FLAG          0x1000 /* BIT 12 */
+#define ATUR_PERF_CURR_1DAY_LOSS_FLAG          0x2000 /* BIT 13 */
+#define ATUR_PERF_CURR_1DAY_LPR_FLAG           0x4000 /* BIT 14 */
+#define ATUR_PERF_CURR_1DAY_ESS_FLAG           0x8000 /* BIT 15 */
+#define ATUR_PERF_PREV_1DAY_MON_SEC_FLAG       0x10000 /* BIT 16 */
+#define ATUR_PERF_PREV_1DAY_LOFS_FLAG          0x20000 /* BIT 17 */
+#define ATUR_PERF_PREV_1DAY_LOSS_FLAG          0x40000 /* BIT 18 */
+#define ATUR_PERF_PREV_1DAY_LPR_FLAG           0x80000 /* BIT 19 */
+#define ATUR_PERF_PREV_1DAY_ESS_FLAG           0x100000 /* BIT 20 */
+
+/* adslAtucIntervalTable Flags */
+#define ATUC_INTVL_LOF_FLAG            0x1     /* BIT 0th position */
+#define ATUC_INTVL_LOS_FLAG            0x2     /* BIT 1 */
+#define ATUC_INTVL_ESS_FLAG            0x4     /* BIT 2 */
+#define ATUC_INTVL_INIT_FLAG           0x8   /* BIT 3 */
+#define ATUC_INTVL_VALID_DATA_FLAG     0x10 /* BIT 4 */
+
+/* adslAturIntervalTable Flags */
+#define ATUR_INTVL_LOF_FLAG            0x1     /* BIT 0th position */
+#define ATUR_INTVL_LOS_FLAG            0x2     /* BIT 1 */
+#define ATUR_INTVL_LPR_FLAG            0x4     /* BIT 2 */
+#define ATUR_INTVL_ESS_FLAG            0x8     /* BIT 3 */
+#define ATUR_INTVL_VALID_DATA_FLAG     0x10 /* BIT 4 */
+
+/* adslAtucChanPerfDataTable Flags */
+#define ATUC_CHAN_RECV_BLK_FLAG        0x01    /* BIT 0th position */
+#define ATUC_CHAN_TX_BLK_FLAG  0x02    /* BIT 1 */
+#define ATUC_CHAN_CORR_BLK_FLAG        0x04    /* BIT 2 */
+#define ATUC_CHAN_UNCORR_BLK_FLAG 0x08 /* BIT 3 */
+#define ATUC_CHAN_PERF_VALID_INTVL_FLAG 0x10 /* BIT 4 */
+#define ATUC_CHAN_PERF_INVALID_INTVL_FLAG 0x20 /* BIT 5 */
+#define ATUC_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */
+#define ATUC_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG        0x80 /* BIT 7 */
+#define ATUC_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG 0x100 /* BIT 8 */
+#define ATUC_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG 0x200 /* BIT 9 */
+#define ATUC_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG 0x400 /* BIT 10 */
+#define ATUC_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11*/
+#define ATUC_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG 0x1000 /* BIT 12 */
+#define ATUC_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG 0x2000 /* BIT 13 */
+#define ATUC_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG 0x4000 /* BIT 14 */
+#define ATUC_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG 0x8000 /* BIT 15 */
+#define ATUC_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG 0x10000 /* BIT 16 */
+#define ATUC_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG 0x20000 /* BIT 17 */
+#define ATUC_CHAN_PERF_PREV_1DAY_TX_BLK_FLAG 0x40000 /* BIT 18 */
+#define ATUC_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG 0x80000 /* BIT 19 */
+#define ATUC_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG 0x100000 /* BIT 20 */
+
+
+/* adslAturChanPerfDataTable Flags */
+#define ATUR_CHAN_RECV_BLK_FLAG   0x01         /* BIT 0th position */ 
+#define ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW            makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data,TxMessage)
+#define ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW            makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data,TxMessage)
+#define ATUR_CHAN_TX_BLK_FLAG     0x02         /* BIT 1 */
+#define ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW              makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data,TxMessage)
+#define ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW              makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data,TxMessage)
+#define ATUR_CHAN_CORR_BLK_FLAG   0x04         /* BIT 2 */
+#define ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL           makeCMV(H2D_CMV_READ, PLAM, 3, 0, 1, data,TxMessage)
+#define ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST           makeCMV(H2D_CMV_READ, PLAM, 3, 1, 1, data,TxMessage)
+#define ATUR_CHAN_UNCORR_BLK_FLAG 0x08         /* BIT 3 */
+#define ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL         makeCMV(H2D_CMV_READ, PLAM, 2, 0, 1, data,TxMessage)
+#define ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST         makeCMV(H2D_CMV_READ, PLAM, 2, 1, 1, data,TxMessage)
+#define ATUR_CHAN_PERF_VALID_INTVL_FLAG   0x10         /* BIT 4 */
+#define ATUR_CHAN_PERF_INVALID_INTVL_FLAG 0x20         /* BIT 5 */
+#define ATUR_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */
+#define ATUR_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG    0x80   /* BIT 7 */
+#define ATUR_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG      0x100 /* BIT 8 */
+#define ATUR_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG    0x200 /* BIT 9 */
+#define ATUR_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG  0x400 /* BIT 10 */
+#define ATUR_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */
+#define ATUR_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG     0x1000 /* BIT 12 */
+#define ATUR_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG       0x2000 /* BIT 13 */
+#define ATUR_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG     0x4000 /* BIT 14 */
+#define ATUR_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG   0x8000 /* BIT 15 */
+#define ATUR_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG     0x10000 /* BIT 16 */
+#define ATUR_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG     0x20000 /* BIT 17 */
+#define ATUR_CHAN_PERF_PREV_1DAY_TRANS_BLK_FLAG    0x40000 /* BIT 18 */
+#define ATUR_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG     0x80000 /* BIT 19 */
+#define ATUR_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG   0x100000 /* BIT 20 */
+
+/* adslAtucChanIntervalTable Flags */
+#define ATUC_CHAN_INTVL_NUM_FLAG               0x1     /* BIT 0th position */
+#define ATUC_CHAN_INTVL_RECV_BLK_FLAG                  0x2     /* BIT 1 */
+#define ATUC_CHAN_INTVL_TX_BLK_FLAG            0x4     /* BIT 2 */
+#define ATUC_CHAN_INTVL_CORR_BLK_FLAG          0x8     /* BIT 3 */
+#define ATUC_CHAN_INTVL_UNCORR_BLK_FLAG        0x10    /* BIT 4 */
+#define ATUC_CHAN_INTVL_VALID_DATA_FLAG        0x20    /* BIT 5 */
+
+/* adslAturChanIntervalTable Flags */
+#define ATUR_CHAN_INTVL_NUM_FLAG               0x1     /* BIT 0th Position */
+#define ATUR_CHAN_INTVL_RECV_BLK_FLAG                  0x2     /* BIT 1 */
+#define ATUR_CHAN_INTVL_TX_BLK_FLAG            0x4     /* BIT 2 */
+#define ATUR_CHAN_INTVL_CORR_BLK_FLAG          0x8     /* BIT 3 */
+#define ATUR_CHAN_INTVL_UNCORR_BLK_FLAG        0x10    /* BIT 4 */
+#define ATUR_CHAN_INTVL_VALID_DATA_FLAG        0x20    /* BIT 5 */
+
+/* adslLineAlarmConfProfileTable Flags */
+#define ATUC_THRESH_15MIN_LOFS_FLAG            0x01   /* BIT 0th position */
+#define ATUC_THRESH_15MIN_LOSS_FLAG            0x02   /* BIT 1 */
+#define ATUC_THRESH_15MIN_ESS_FLAG             0x04   /* BIT 2 */
+#define ATUC_THRESH_FAST_RATEUP_FLAG           0x08   /* BIT 3 */
+#define ATUC_THRESH_INTERLEAVE_RATEUP_FLAG     0x10   /* BIT 4 */
+#define ATUC_THRESH_FAST_RATEDOWN_FLAG         0x20     /* BIT 5 */
+#define ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG           0x40    /* BIT 6 */
+#define ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG     0x80    /* BIT 7 */
+#define ATUR_THRESH_15MIN_LOFS_FLAG            0x100   /* BIT 8 */
+#define ATUR_THRESH_15MIN_LOSS_FLAG            0x200   /* BIT 9 */
+#define ATUR_THRESH_15MIN_LPRS_FLAG                    0x400   /* BIT 10 */
+#define ATUR_THRESH_15MIN_ESS_FLAG             0x800           /* BIT 11 */
+#define ATUR_THRESH_FAST_RATEUP_FLAG           0x1000          /* BIT 12 */
+#define ATUR_THRESH_INTERLEAVE_RATEUP_FLAG     0x2000          /* BIT 13 */
+#define ATUR_THRESH_FAST_RATEDOWN_FLAG         0x4000  /* BIT 14 */
+#define ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG   0x8000          /* BIT 15 */
+#define LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG  0x10000        /* BIT 16 */
+
+
+/* adslAturTraps Flags */
+#define ATUC_PERF_LOFS_THRESH_FLAG             0x1     /* BIT 0th position */
+#define ATUC_PERF_LOSS_THRESH_FLAG             0x2     /* BIT 1 */
+#define ATUC_PERF_ESS_THRESH_FLAG              0x4     /* BIT 2 */
+#define ATUC_RATE_CHANGE_FLAG                  0x8     /* BIT 3 */
+#define ATUR_PERF_LOFS_THRESH_FLAG             0x10    /* BIT 4 */
+#define ATUR_PERF_LOSS_THRESH_FLAG             0x20    /* BIT 5 */
+#define ATUR_PERF_LPRS_THRESH_FLAG             0x40    /* BIT 6 */
+#define ATUR_PERF_ESS_THRESH_FLAG              0x80    /* BIT 7 */
+#define ATUR_RATE_CHANGE_FLAG                  0x100   /* BIT 8 */
+
+//RFC- 3440 FLAG DEFINITIONS
+
+#ifdef IFXMIPS_MEI_MIB_RFC3440
+/* adslLineExtTable flags */
+#define ATUC_LINE_TRANS_CAP_FLAG               0x1             /* BIT 0th position */
+#define ATUC_LINE_TRANS_CAP_FLAG_MAKECMV       makeCMV(H2D_CMV_READ,INFO, 67, 0, 1, data,TxMessage)
+#define ATUC_LINE_TRANS_CONFIG_FLAG            0x2             /* BIT 1 */
+#define ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV    makeCMV(H2D_CMV_READ,INFO, 67, 0, 1, data,TxMessage)
+#define ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV_WR makeCMV(H2D_CMV_WRITE,INFO, 67, 0, 1, data,TxMessage)
+#define ATUC_LINE_TRANS_ACTUAL_FLAG            0x4             /* BIT 2 */
+#define ATUC_LINE_TRANS_ACTUAL_FLAG_MAKECMV    makeCMV(H2D_CMV_READ,STAT, 1, 0, 1, data,TxMessage)
+#define LINE_GLITE_POWER_STATE_FLAG            0x8             /* BIT 3 */
+#define LINE_GLITE_POWER_STATE_FLAG_MAKECMV    makeCMV(H2D_CMV_READ,STAT, 0, 0, 1, data,TxMessage) 
+
+/* adslAtucPerfDataExtTable flags */
+#define ATUC_PERF_STAT_FASTR_FLAG         0x1 /* BIT 0th position */
+#define ATUC_PERF_STAT_FASTR_FLAG_MAKECMV      makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data, TxMessage)
+#define ATUC_PERF_STAT_FAILED_FASTR_FLAG 0x2 /* BIT 1 */
+#define ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data, TxMessage)
+#define ATUC_PERF_STAT_SESL_FLAG          0X4  /* BIT 2 */
+#define ATUC_PERF_STAT_SESL_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 8, 0, 1, data, TxMessage)
+#define ATUC_PERF_STAT_UASL_FLAG                  0X8  /* BIT 3 */
+#define ATUC_PERF_STAT_UASL_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 10, 0, 1, data, TxMessage)
+#define ATUC_PERF_CURR_15MIN_FASTR_FLAG           0X10 /* BIT 4 */
+#define ATUC_PERF_CURR_15MIN_FAILED_FASTR_FLAG 0X20    /* BIT 5 */
+#define ATUC_PERF_CURR_15MIN_SESL_FLAG          0X40   /* BIT 6 */
+#define ATUC_PERF_CURR_15MIN_UASL_FLAG             0X80        /* BIT 7 */
+#define ATUC_PERF_CURR_1DAY_FASTR_FLAG             0X100       /* BIT 8 */
+#define ATUC_PERF_CURR_1DAY_FAILED_FASTR_FLAG  0X200   /* BIT 9 */
+#define ATUC_PERF_CURR_1DAY_SESL_FLAG                  0X400   /* BIT 10 */
+#define ATUC_PERF_CURR_1DAY_UASL_FLAG                  0X800   /* BIT 11 */
+#define ATUC_PERF_PREV_1DAY_FASTR_FLAG              0X1000 /* BIT 12 */
+#define ATUC_PERF_PREV_1DAY_FAILED_FASTR_FLAG  0X2000 /* BIT 13 */
+#define ATUC_PERF_PREV_1DAY_SESL_FLAG                  0X4000 /* BIT 14 */
+#define ATUC_PERF_PREV_1DAY_UASL_FLAG                  0X8000 /* BIT 15 */
+
+/* adslAturPerfDataExtTable */
+#define ATUR_PERF_STAT_SESL_FLAG               0X1 /* BIT 0th position */
+#define ATUR_PERF_STAT_SESL_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 34, 0, 1, data, TxMessage)  
+#define ATUR_PERF_STAT_UASL_FLAG               0X2 /* BIT 1 */
+#define ATUR_PERF_STAT_UASL_FLAG_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 36, 0, 1, data, TxMessage)
+#define ATUR_PERF_CURR_15MIN_SESL_FLAG         0X4 /* BIT 2 */
+#define ATUR_PERF_CURR_15MIN_UASL_FLAG         0X8 /* BIT 3 */
+#define ATUR_PERF_CURR_1DAY_SESL_FLAG          0X10 /* BIT 4 */
+#define ATUR_PERF_CURR_1DAY_UASL_FLAG          0X20 /* BIT 5 */
+#define ATUR_PERF_PREV_1DAY_SESL_FLAG          0X40 /* BIT 6 */
+#define ATUR_PERF_PREV_1DAY_UASL_FLAG          0X80 /* BIT 7 */
+
+/* adslAutcIntervalExtTable flags */
+#define ATUC_INTERVAL_FASTR_FLAG               0x1 /* Bit 0 */         
+#define ATUC_INTERVAL_FAILED_FASTR_FLAG                0x2 /* Bit 1 */         
+#define ATUC_INTERVAL_SESL_FLAG                        0x4 /* Bit 2 */         
+#define ATUC_INTERVAL_UASL_FLAG                        0x8 /* Bit 3 */         
+
+/* adslAturIntervalExtTable */
+#define ATUR_INTERVAL_SESL_FLAG                0X1 /* BIT 0th position */
+#define ATUR_INTERVAL_UASL_FLAG                0X2 /* BIT 1 */
+
+/* adslAlarmConfProfileExtTable */
+#define ATUC_THRESH_15MIN_FAILED_FASTR_FLAG 0X1/* BIT 0th position */
+#define ATUC_THRESH_15MIN_SESL_FLAG             0X2 /* BIT 1 */
+#define ATUC_THRESH_15MIN_UASL_FLAG             0X4 /* BIT 2 */
+#define ATUR_THRESH_15MIN_SESL_FLAG             0X8 /* BIT 3 */
+#define ATUR_THRESH_15MIN_UASL_FLAG             0X10 /* BIT 4 */
+
+/* adslAturExtTraps */
+#define ATUC_15MIN_FAILED_FASTR_TRAP_FLAG      0X1 /* BIT 0th position */
+#define ATUC_15MIN_SESL_TRAP_FLAG               0X2 /* BIT 1 */
+#define ATUC_15MIN_UASL_TRAP_FLAG               0X4 /* BIT 2 */
+#define ATUR_15MIN_SESL_TRAP_FLAG               0X8 /* BIT 3 */
+#define ATUR_15MIN_UASL_TRAP_FLAG               0X10 /* BIT 4 */
+
+#endif
+
+/* adslLineStatus Flags */
+#define LINE_STAT_MODEM_STATUS_FLAG     0x1 /* BIT 0th position */
+#define LINE_STAT_MODEM_STATUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data, TxMessage)
+#define LINE_STAT_MODE_SEL_FLAG         0x2 /* BIT 1 */
+#define LINE_STAT_MODE_SEL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 1, 0, 1, data, TxMessage)
+#define LINE_STAT_TRELLCOD_ENABLE_FLAG 0x4 /* BIT 2 */
+#define LINE_STAT_TRELLCOD_ENABLE_FLAG_MAKECMV makeCMV(H2D_CMV_READ, OPTN, 2, 0, 1, data, TxMessage)
+#define LINE_STAT_LATENCY_FLAG          0x8 /* BIT 3 */
+#define LINE_STAT_LATENCY_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 12, 0, 1, data, TxMessage)
+
+/* adslLineRate Flags */
+#define LINE_RATE_DATA_RATEDS_FLAG     0x1 /* BIT 0th position */
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP0_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 0, 2, data, TxMessage)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP1_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 2, 2, data, TxMessage)
+
+
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 12, 0, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 13, 0, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 14, 0, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 15, 0, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 17, 0, 2, data, TxMessage)
+
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 12, 1, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 13, 1, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 14, 1, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 15, 1, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 17, 2, 2, data, TxMessage)
+
+#define LINE_RATE_DATA_RATEUS_FLAG     0x2 /* BIT 1 */
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP0_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 0, 2, data, TxMessage)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP1_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 2, 2, data, TxMessage)
+
+
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 23, 0, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 24, 0, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 25, 0, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 26, 0, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 28, 0, 2, data, TxMessage)
+
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 23, 1, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 24, 1, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 25, 1, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 26, 1, 1, data, TxMessage)
+#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 28, 2, 2, data, TxMessage)
+
+#define LINE_RATE_ATTNDRDS_FLAG        0x4 /* BIT 2 */
+#define LINE_RATE_ATTNDRDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 4, 2, data, TxMessage)
+
+#define LINE_RATE_ATTNDRUS_FLAG                0x8 /* BIT 3 */
+#define LINE_RATE_ATTNDRUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 4, 2, data, TxMessage)
+
+/* adslLineInformation Flags */
+#define LINE_INFO_INTLV_DEPTHDS_FLAG   0x1 /* BIT 0th position */
+#define LINE_INFO_INTLV_DEPTHDS_FLAG_LP0_MAKECMV       makeCMV(H2D_CMV_READ, CNFG, 27, 0, 1, data, TxMessage)
+#define LINE_INFO_INTLV_DEPTHDS_FLAG_LP1_MAKECMV       makeCMV(H2D_CMV_READ, CNFG, 27, 1, 1, data, TxMessage)
+#define LINE_INFO_INTLV_DEPTHUS_FLAG   0x2 /* BIT 1 */
+#define LINE_INFO_INTLV_DEPTHUS_FLAG_LP0_MAKECMV       makeCMV(H2D_CMV_READ, CNFG, 16, 0, 1, data, TxMessage)
+#define LINE_INFO_INTLV_DEPTHUS_FLAG_LP1_MAKECMV       makeCMV(H2D_CMV_READ, CNFG, 16, 1, 1, data, TxMessage)
+#define LINE_INFO_LATNDS_FLAG          0x4 /* BIT 2 */
+#define LINE_INFO_LATNDS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 68, 1, 1, data, TxMessage)
+#define LINE_INFO_LATNUS_FLAG          0x8 /* BIT 3 */
+#define LINE_INFO_LATNUS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 69, 1, 1, data, TxMessage)
+#define LINE_INFO_SATNDS_FLAG                  0x10 /* BIT 4 */
+#define LINE_INFO_SATNDS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 68, 2, 1, data, TxMessage)
+#define LINE_INFO_SATNUS_FLAG                  0x20 /* BIT 5 */
+#define LINE_INFO_SATNUS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, INFO, 69, 2, 1, data, TxMessage)
+#define LINE_INFO_SNRMNDS_FLAG                 0x40 /* BIT 6 */
+#define LINE_INFO_SNRMNDS_FLAG_ADSL1_MAKECMV   makeCMV(H2D_CMV_READ, INFO, 68, 3, 1, data, TxMessage)
+#define LINE_INFO_SNRMNDS_FLAG_ADSL2_MAKECMV   makeCMV(H2D_CMV_READ, RATE, 3, 0, 1, data, TxMessage)
+#define LINE_INFO_SNRMNDS_FLAG_ADSL2PLUS_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 46, 0, 1, data, TxMessage)
+#define LINE_INFO_SNRMNUS_FLAG                 0x80 /* BIT 7 */
+#define LINE_INFO_SNRMNUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 3, 1, data, TxMessage)
+#define LINE_INFO_ACATPDS_FLAG         0x100 /* BIT 8 */
+#define LINE_INFO_ACATPDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 6, 1, data, TxMessage)
+#define LINE_INFO_ACATPUS_FLAG         0x200 /* BIT 9 */
+#define LINE_INFO_ACATPUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 6, 1, data, TxMessage)
+
+/* adslNearEndPerformanceStats Flags */
+#define NEAREND_PERF_SUPERFRAME_FLAG_LSW_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data, TxMessage)
+#define NEAREND_PERF_SUPERFRAME_FLAG_MSW_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data, TxMessage)
+#define NEAREND_PERF_SUPERFRAME_FLAG   0x1 /* BIT 0th position */
+#define NEAREND_PERF_LOS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 0, 0, 1, data, TxMessage)
+#define NEAREND_PERF_LOS_FLAG          0x2 /* BIT 1 */
+#define NEAREND_PERF_LOF_FLAG          0x4 /* BIT 2 */
+#define NEAREND_PERF_LPR_FLAG          0x8 /* BIT 3 */
+#define NEAREND_PERF_NCD_FLAG          0x10 /* BIT 4 */
+#define NEAREND_PERF_LCD_FLAG          0x20 /* BIT 5 */
+#define NEAREND_PERF_CRC_FLAG          0x40 /* BIT 6 */
+#define NEAREND_PERF_CRC_FLAG_LP0_MAKECMV      makeCMV(H2D_CMV_READ, PLAM, 2, 0, 1, data, TxMessage)
+#define NEAREND_PERF_CRC_FLAG_LP1_MAKECMV      makeCMV(H2D_CMV_READ, PLAM, 2, 1, 1, data, TxMessage)
+#define NEAREND_PERF_RSCORR_FLAG_LP0_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 3, 0, 1, data, TxMessage)
+#define NEAREND_PERF_RSCORR_FLAG_LP1_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 3, 1, 1, data, TxMessage)
+#define NEAREND_PERF_RSCORR_FLAG       0x80 /* BIT 7 */
+#define NEAREND_PERF_FECS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 6, 0, 1, data, TxMessage)
+#define NEAREND_PERF_FECS_FLAG         0x100 /* BIT 8 */
+#define NEAREND_PERF_ES_FLAG_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 7, 0, 1, data, TxMessage)
+#define NEAREND_PERF_ES_FLAG           0x200 /* BIT 9 */
+#define NEAREND_PERF_SES_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 8, 0, 1, data, TxMessage)
+#define NEAREND_PERF_SES_FLAG          0x400 /* BIT 10 */
+#define NEAREND_PERF_LOSS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 9, 0, 1, data, TxMessage)
+#define NEAREND_PERF_LOSS_FLAG         0x800 /* BIT 11 */
+#define NEAREND_PERF_UAS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 10, 0, 1, data, TxMessage)
+#define NEAREND_PERF_UAS_FLAG          0x1000 /* BIT 12 */
+#define NEAREND_PERF_HECERR_FLAG_BC0_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 11, 0, 2, data, TxMessage)
+#define NEAREND_PERF_HECERR_FLAG_BC1_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 11, 2, 2, data, TxMessage)
+#define NEAREND_PERF_HECERR_FLAG               0x2000 /* BIT 13 */
+
+/* adslFarEndPerformanceStats Flags */
+#define FAREND_PERF_LOS_FLAG_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 1, 0, 1, data, TxMessage)
+#define FAREND_PERF_LOS_FLAG   0x1 /* BIT 0th position */
+#define FAREND_PERF_LOF_FLAG   0x2 /* BIT 1 */
+#define FAREND_PERF_LPR_FLAG   0x4 /* BIT 2 */
+#define FAREND_PERF_NCD_FLAG   0x8 /* BIT 3 */
+#define FAREND_PERF_LCD_FLAG   0x10 /* BIT 4 */
+#define FAREND_PERF_CRC_FLAG_LP0_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 24, 0, 1, data, TxMessage)
+#define FAREND_PERF_CRC_FLAG_LP1_MAKECMV       makeCMV(H2D_CMV_READ, PLAM, 24, 1, 1, data, TxMessage)
+#define FAREND_PERF_CRC_FLAG   0x20 /* BIT 5 */
+#define FAREND_PERF_RSCORR_FLAG_LP0_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 28, 0, 1, data, TxMessage)
+#define FAREND_PERF_RSCORR_FLAG_LP1_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 28, 1, 1, data, TxMessage)
+#define FAREND_PERF_RSCORR_FLAG        0x40 /* BIT 6 */
+#define FAREND_PERF_FECS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 32, 0, 1, data, TxMessage)
+#define FAREND_PERF_FECS_FLAG  0x80 /* BIT 7 */
+#define FAREND_PERF_ES_FLAG_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 33, 0, 1, data, TxMessage)
+#define FAREND_PERF_ES_FLAG    0x100 /* BIT 8 */
+#define FAREND_PERF_SES_FLAG_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 34, 0, 1, data, TxMessage)
+#define FAREND_PERF_SES_FLAG   0x200 /* BIT 9 */
+#define FAREND_PERF_LOSS_FLAG_MAKECMV  makeCMV(H2D_CMV_READ, PLAM, 35, 0, 1, data, TxMessage)
+#define FAREND_PERF_LOSS_FLAG  0x400 /* BIT 10 */
+#define FAREND_PERF_UAS_FLAG_MAKECMV   makeCMV(H2D_CMV_READ, PLAM, 36, 0, 1, data, TxMessage)
+#define FAREND_PERF_UAS_FLAG   0x800 /* BIT 11 */
+#define FAREND_PERF_HECERR_FLAG_BC0_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 37, 0, 2, data, TxMessage)
+#define FAREND_PERF_HECERR_FLAG_BC1_MAKECMV    makeCMV(H2D_CMV_READ, PLAM, 37, 2, 2, data, TxMessage)
+#define FAREND_PERF_HECERR_FLAG        0x1000 /* BIT 12 */
+// 603221:tc.chen end
+/* TR-69 related additional parameters - defines */
+/* Defines for  struct adslATURSubcarrierInfo */
+#define        NEAREND_HLINSC  0x1
+#define NEAREND_HLINSC_MAKECMV(mode)           makeCMV(mode, INFO, 71, 2, 1, data, TxMessage)
+#define        NEAREND_HLINPS  0x2
+#define NEAREND_HLINPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 73, idx, size, data, TxMessage)
+#define        NEAREND_HLOGMT  0x4
+#define NEAREND_HLOGMT_MAKECMV(mode)           makeCMV(mode, INFO, 80, 0, 1, data, TxMessage)
+#define NEAREND_HLOGPS 0x8
+#define NEAREND_HLOGPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 75, idx, size, data, TxMessage)
+#define NEAREND_QLNMT  0x10
+#define NEAREND_QLNMT_MAKECMV(mode)            makeCMV(mode, INFO, 80, 1, 1, data, TxMessage)
+#define        NEAREND_QLNPS   0x20
+#define NEAREND_QLNPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 77, idx, size, data, TxMessage)
+#define        NEAREND_SNRMT   0x40
+#define NEAREND_SNRMT_MAKECMV(mode)            makeCMV(mode, INFO, 80, 2, 1, data, TxMessage)
+#define        NEAREND_SNRPS   0x80
+#define NEAREND_SNRPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 78, idx, size, data, TxMessage)
+#define        NEAREND_BITPS   0x100
+#define NEAREND_BITPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 22, idx, size, data, TxMessage)
+#define        NEAREND_GAINPS  0x200
+#define NEAREND_GAINPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 24, idx, size, data, TxMessage)
+
+/* Defines for  struct adslATUCSubcarrierInfo */
+#define         FAREND_HLINSC  0x1
+
+/* As per the feedback from Knut on 21/08/2006, the cmv command of HLINSC should be INFO 70 2 */
+#define  FAREND_HLINSC_MAKECMV(mode)           makeCMV(mode, INFO, 70, 2, 1, data, TxMessage)
+#define         FAREND_HLINPS  0x2
+#define  FAREND_HLINPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 72, idx, size, data, TxMessage)
+#define         FAREND_HLOGMT  0x4
+#define  FAREND_HLOGMT_MAKECMV(mode)           makeCMV(mode, INFO, 79, 0, 1, data, TxMessage)
+#define  FAREND_HLOGPS 0x8
+#define  FAREND_HLOGPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 74, idx, size, data, TxMessage)
+#define  FAREND_QLNMT  0x10
+#define  FAREND_QLNMT_MAKECMV(mode)            makeCMV(mode, INFO, 79, 1, 1, data, TxMessage)
+#define         FAREND_QLNPS   0x20
+#define  FAREND_QLNPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 76, idx, size, data, TxMessage)
+#define         FAREND_SNRMT   0x40
+#define  FAREND_SNRMT_MAKECMV(mode)            makeCMV(mode, INFO, 79, 2, 1, data, TxMessage)
+#define         FAREND_SNRPS   0x80
+#define  FAREND_SNRPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 11, idx, size, data, TxMessage)
+#define  FAREND_SNRPS_DIAG_MAKECMV(mode,idx,size)      makeCMV(mode, INFO, 10, idx, size, data, TxMessage)
+#define         FAREND_BITPS   0x100
+#define  FAREND_BITPS_MAKECMV(mode,idx,size)   makeCMV(mode, INFO, 23, idx, size, data, TxMessage)
+#define         FAREND_GAINPS  0x200
+#define  FAREND_GAINPS_MAKECMV(mode,idx,size)  makeCMV(mode, INFO, 25, idx, size, data, TxMessage)
+
+
+// GET_ADSL_POWER_SPECTRAL_DENSITY
+#define NOMPSD_US_MAKECMV      makeCMV(H2D_CMV_READ, INFO, 102, 0, 1, data, TxMessage)
+#define NOMPSD_DS_MAKECMV      makeCMV(H2D_CMV_READ, INFO, 102, 1, 1, data, TxMessage)
+#define PCB_US_MAKECMV         makeCMV(H2D_CMV_READ, INFO, 102, 6, 1, data, TxMessage)
+#define PCB_DS_MAKECMV         makeCMV(H2D_CMV_READ, INFO, 102, 7, 1, data, TxMessage)
+#define        RMSGI_US_MAKECMV        makeCMV(H2D_CMV_READ, INFO, 102, 10, 1, data, TxMessage)
+#define        RMSGI_DS_MAKECMV        makeCMV(H2D_CMV_READ, INFO, 102, 11, 1, data, TxMessage)
+
+/////////////////////////////////////////////////Macro Definitions ? FLAG Setting & Testing
+
+#define SET_FLAG(flags, flag_val)   ((*flags) = ((*flags) | flag_val))
+//     -- This macro sets the flags with the flag_val. Here flags is passed as a pointer
+
+#define IS_FLAG_SET(flags, test_flag)  (((*flags) & (test_flag)) == (test_flag)? test_flag:0)
+//     -- This macro verifies whether test_flag has been set in flags. Here flags is passed as a pointer
+
+
+#define CLR_FLAG(flags, flag_bit)      ((*flags) = (*flags) & (~flag_bit))
+//     -- This macro resets the specified flag_bit in the flags. Here flags is passed as a pointer
+
+
+////////////////////////////////////////////////DATA STRUCTURES ORGANIZATION
+       
+//Here are the data structures used for accessing mib parameters. The ioctl call includes the third parameter as a void pointer. This parameter has to be type-casted in the driver code to the corresponding structure depending upon the command type. For Ex: consider the ioctl used to get the adslLineCode type, ioctl(fd,GET_ADSL_LINE_CODE,void *struct_adslLineTableEntry). In the driver code we check on the type of the command, i.e GET_ADSL_LINE_CODE and type-cast the void pointer to struct adslLineTableEntry type.
+       //
+#define u32 unsigned int
+#define u16 unsigned short
+#define s16 short
+#define u8 unsigned char
+
+
+typedef u32 AdslPerfTimeElapsed;
+typedef u32 AdslPerfPrevDayCount;
+typedef u32 PerfCurrentCount;
+typedef u32 PerfIntervalCount;
+typedef u32 AdslPerfCurrDayCount;
+
+
+//ioctl(int fd, GET_ADSL_LINE_CODE, void *struct_adslLineTableEntry)
+
+typedef struct adslLineTableEntry {
+       int ifIndex;
+       int adslLineCode;
+       u8 flags;
+} adslLineTableEntry;
+
+#ifdef IFXMIPS_MEI_MIB_RFC3440
+typedef struct adslLineExtTableEntry {
+       int ifIndex;
+       u16 adslLineTransAtucCap;
+       u16 adslLineTransAtucConfig;
+       u16 adslLineTransAtucActual;
+       int adslLineGlitePowerState;
+       u32 flags;
+}adslLineExtTableEntry;
+#endif
+//ioctl(int fd, GET_ADSL_ATUC_PHY, void  *struct_adslAtucPhysEntry)
+#ifndef u_char 
+#define u_char u8
+#endif
+
+typedef struct adslVendorId {
+       u16     country_code;
+       u_char  provider_id[4];  /* Ascii characters */
+       u_char  revision_info[2];
+}adslVendorId;
+
+typedef struct adslAtucPhysEntry {
+       int ifIndex;
+       char serial_no[32];
+       union {
+       char vendor_id[16];
+               adslVendorId vendor_info;
+       } vendor_id;
+       char version_no[16];
+       u32 status;
+       int outputPwr;
+       u32 attainableRate;
+       u8 flags;
+} adslAtucPhysEntry;
+
+
+//ioctl(int fd, GET_ADSL_ATUR_PHY, void  *struct_adslAturPhysEntry)
+
+typedef struct adslAturPhysEntry {
+       int ifIndex;
+       char serial_no[32];
+       union {
+       char vendor_id[16];
+               adslVendorId vendor_info;
+       } vendor_id;
+       char version_no[16];
+       int SnrMgn;
+       u32 Attn;
+       u32 status;
+       int outputPwr;
+       u32 attainableRate;
+       u8 flags;
+} adslAturPhysEntry;
+
+
+//ioctl(int fd, GET_ADSL_ATUC_CHAN_INFO, void *struct_adslAtucChanInfo)
+
+typedef struct adslAtucChanInfo {
+       int ifIndex;
+       u32 interleaveDelay;
+       u32 currTxRate;
+       u32 prevTxRate;
+       u8 flags;
+} adslAtucChanInfo;
+
+
+//ioctl(int fd, GET_ADSL_ATUR_CHAN_INFO, void *struct_adslAturChanInfo)
+
+typedef struct adslAturChanInfo {
+       int ifIndex;
+       u32 interleaveDelay;
+       u32 currTxRate;
+       u32 prevTxRate;
+       u32 crcBlkLen;
+       u8 flags;
+} adslAturChanInfo;
+
+
+//ioctl(int fd, GET_ADSL_ATUC_PERF_DATA,  void *struct_atucPerfDataEntry)
+
+typedef struct atucPerfDataEntry
+{
+   int                 ifIndex;
+   u32                         adslAtucPerfLofs;             
+   u32                         adslAtucPerfLoss;             
+   u32                         adslAtucPerfESs;                 
+   u32                         adslAtucPerfInits;
+   int                         adslAtucPerfValidIntervals;
+   int                         adslAtucPerfInvalidIntervals;
+   AdslPerfTimeElapsed         adslAtucPerfCurr15MinTimeElapsed;
+   PerfCurrentCount    adslAtucPerfCurr15MinLofs;
+   PerfCurrentCount    adslAtucPerfCurr15MinLoss;
+   PerfCurrentCount    adslAtucPerfCurr15MinESs;
+   PerfCurrentCount    adslAtucPerfCurr15MinInits;
+   AdslPerfTimeElapsed         adslAtucPerfCurr1DayTimeElapsed;
+   AdslPerfCurrDayCount adslAtucPerfCurr1DayLofs;
+   AdslPerfCurrDayCount adslAtucPerfCurr1DayLoss;
+   AdslPerfCurrDayCount adslAtucPerfCurr1DayESs;
+   AdslPerfCurrDayCount adslAtucPerfCurr1DayInits;
+   int                         adslAtucPerfPrev1DayMoniSecs;
+   AdslPerfPrevDayCount adslAtucPerfPrev1DayLofs;
+   AdslPerfPrevDayCount adslAtucPerfPrev1DayLoss;
+   AdslPerfPrevDayCount adslAtucPerfPrev1DayESs;
+   AdslPerfPrevDayCount adslAtucPerfPrev1DayInits;
+   u32                 flags;
+} atucPerfDataEntry;
+
+#ifdef IFXMIPS_MEI_MIB_RFC3440
+typedef struct atucPerfDataExtEntry
+ {
+  int ifIndex;
+  u32 adslAtucPerfStatFastR;
+  u32 adslAtucPerfStatFailedFastR;
+  u32 adslAtucPerfStatSesL;
+  u32 adslAtucPerfStatUasL;
+  u32 adslAtucPerfCurr15MinFastR;
+  u32 adslAtucPerfCurr15MinFailedFastR;
+  u32 adslAtucPerfCurr15MinSesL;
+  u32 adslAtucPerfCurr15MinUasL;
+  u32 adslAtucPerfCurr1DayFastR;
+  u32 adslAtucPerfCurr1DayFailedFastR;
+  u32 adslAtucPerfCurr1DaySesL;
+  u32 adslAtucPerfCurr1DayUasL;
+  u32 adslAtucPerfPrev1DayFastR;
+  u32 adslAtucPerfPrev1DayFailedFastR;
+  u32 adslAtucPerfPrev1DaySesL;
+  u32 adslAtucPerfPrev1DayUasL;
+  u32  flags;
+} atucPerfDataExtEntry; 
+
+#endif
+//ioctl(int fd, GET_ADSL_ATUR_PERF_DATA, void *struct_aturPerfDataEntry)
+
+typedef struct aturPerfDataEntry
+{
+   int                 ifIndex;
+   u32                         adslAturPerfLofs;             
+   u32                         adslAturPerfLoss;             
+   u32                         adslAturPerfLprs;                 
+   u32                         adslAturPerfESs;
+   int                         adslAturPerfValidIntervals;
+   int                         adslAturPerfInvalidIntervals;
+   AdslPerfTimeElapsed         adslAturPerfCurr15MinTimeElapsed;
+   PerfCurrentCount    adslAturPerfCurr15MinLofs;
+   PerfCurrentCount    adslAturPerfCurr15MinLoss;
+   PerfCurrentCount    adslAturPerfCurr15MinLprs;
+   PerfCurrentCount    adslAturPerfCurr15MinESs;
+   AdslPerfTimeElapsed         adslAturPerfCurr1DayTimeElapsed;
+   AdslPerfCurrDayCount adslAturPerfCurr1DayLofs;
+   AdslPerfCurrDayCount adslAturPerfCurr1DayLoss;
+   AdslPerfCurrDayCount adslAturPerfCurr1DayLprs;
+   AdslPerfCurrDayCount adslAturPerfCurr1DayESs;
+   int                         adslAturPerfPrev1DayMoniSecs;
+   AdslPerfPrevDayCount adslAturPerfPrev1DayLofs;
+   AdslPerfPrevDayCount adslAturPerfPrev1DayLoss;
+   AdslPerfPrevDayCount adslAturPerfPrev1DayLprs;
+   AdslPerfPrevDayCount adslAturPerfPrev1DayESs;
+   u32                 flags;
+} aturPerfDataEntry;
+
+#ifdef IFXMIPS_MEI_MIB_RFC3440
+typedef struct aturPerfDataExtEntry
+ {
+  int ifIndex;
+  u32 adslAturPerfStatSesL;
+  u32 adslAturPerfStatUasL;
+  u32 adslAturPerfCurr15MinSesL;
+  u32 adslAturPerfCurr15MinUasL;
+  u32 adslAturPerfCurr1DaySesL;
+  u32 adslAturPerfCurr1DayUasL;
+  u32 adslAturPerfPrev1DaySesL;
+  u32 adslAturPerfPrev1DayUasL;
+  u32  flags;
+} aturPerfDataExtEntry;
+#endif
+//ioctl(int fd, GET_ADSL_ATUC_INTVL_INFO, void *struct_adslAtucInvtInfo)
+
+typedef struct adslAtucIntvlInfo {
+       int ifIndex;
+        int IntervalNumber;
+       PerfIntervalCount intervalLOF;
+       PerfIntervalCount intervalLOS;
+       PerfIntervalCount intervalES;
+       PerfIntervalCount intervalInits; 
+       int intervalValidData;
+       u8 flags;
+} adslAtucIntvlInfo;
+
+#ifdef IFXMIPS_MEI_MIB_RFC3440
+typedef struct adslAtucInvtlExtInfo
+ {
+  int ifIndex;
+  int IntervalNumber;
+  u32 adslAtucIntervalFastR;
+  u32 adslAtucIntervalFailedFastR;
+  u32 adslAtucIntervalSesL;
+  u32 adslAtucIntervalUasL;
+  u32  flags;
+} adslAtucInvtlExtInfo;
+#endif
+//ioctl(int fd, GET_ADSL_ATUR_INTVL_INFO, void *struct_adslAturInvtlInfo)
+
+typedef struct adslAturIntvlInfo {
+       int ifIndex;
+        int IntervalNumber;
+       PerfIntervalCount intervalLOF;
+       PerfIntervalCount intervalLOS;
+       PerfIntervalCount intervalLPR;
+       PerfIntervalCount intervalES;
+       int intervalValidData;
+       u8 flags;
+} adslAturIntvlInfo;
+
+#ifdef IFXMIPS_MEI_MIB_RFC3440
+typedef struct adslAturInvtlExtInfo
+ {
+  int ifIndex;
+  int IntervalNumber;
+  u32 adslAturIntervalSesL;
+  u32 adslAturIntervalUasL;
+  u32  flags;
+} adslAturInvtlExtInfo;
+#endif
+//ioctl(int fd, GET_ADSL_ATUC_CHAN_PERF_DATA,  void *struct_atucChannelPerfDataEntry)
+
+typedef struct atucChannelPerfDataEntry
+{
+   int                 ifIndex;
+   u32                         adslAtucChanReceivedBlks;             
+   u32                         adslAtucChanTransmittedBlks;             
+   u32                         adslAtucChanCorrectedBlks;                 
+   u32                         adslAtucChanUncorrectBlks;
+   int                         adslAtucChanPerfValidIntervals;
+   int                         adslAtucChanPerfInvalidIntervals;
+   AdslPerfTimeElapsed         adslAtucChanPerfCurr15MinTimeElapsed;
+   PerfCurrentCount    adslAtucChanPerfCurr15MinReceivedBlks;
+   PerfCurrentCount    adslAtucChanPerfCurr15MinTransmittedBlks;
+   PerfCurrentCount    adslAtucChanPerfCurr15MinCorrectedBlks;
+   PerfCurrentCount    adslAtucChanPerfCurr15MinUncorrectBlks;
+   AdslPerfTimeElapsed  adslAtucChanPerfCurr1DayTimeElapsed;
+   AdslPerfCurrDayCount adslAtucChanPerfCurr1DayReceivedBlks;
+   AdslPerfCurrDayCount adslAtucChanPerfCurr1DayTransmittedBlks;
+   AdslPerfCurrDayCount adslAtucChanPerfCurr1DayCorrectedBlks;
+   AdslPerfCurrDayCount adslAtucChanPerfCurr1DayUncorrectBlks;
+   int                  adslAtucChanPerfPrev1DayMoniSecs;
+   AdslPerfPrevDayCount adslAtucChanPerfPrev1DayReceivedBlks;
+   AdslPerfPrevDayCount adslAtucChanPerfPrev1DayTransmittedBlks;
+   AdslPerfPrevDayCount adslAtucChanPerfPrev1DayCorrectedBlks;
+   AdslPerfPrevDayCount adslAtucChanPerfPrev1DayUncorrectBlks;
+   u32                 flags;
+}atucChannelPerfDataEntry;
+
+
+//ioctl(int fd, GET_ADSL_ATUR_CHAN_PERF_DATA,  void *struct_aturChannelPerfDataEntry)
+
+typedef struct aturChannelPerfDataEntry
+{
+   int                 ifIndex;
+   u32                         adslAturChanReceivedBlks;             
+   u32                         adslAturChanTransmittedBlks;             
+   u32                         adslAturChanCorrectedBlks;                 
+   u32                         adslAturChanUncorrectBlks;
+   int                         adslAturChanPerfValidIntervals;
+   int                         adslAturChanPerfInvalidIntervals;
+   AdslPerfTimeElapsed         adslAturChanPerfCurr15MinTimeElapsed;
+   PerfCurrentCount    adslAturChanPerfCurr15MinReceivedBlks;
+   PerfCurrentCount    adslAturChanPerfCurr15MinTransmittedBlks;
+   PerfCurrentCount    adslAturChanPerfCurr15MinCorrectedBlks;
+   PerfCurrentCount    adslAturChanPerfCurr15MinUncorrectBlks;
+   AdslPerfTimeElapsed  adslAturChanPerfCurr1DayTimeElapsed;
+   AdslPerfCurrDayCount adslAturChanPerfCurr1DayReceivedBlks;
+   AdslPerfCurrDayCount adslAturChanPerfCurr1DayTransmittedBlks;
+   AdslPerfCurrDayCount adslAturChanPerfCurr1DayCorrectedBlks;
+   AdslPerfCurrDayCount adslAturChanPerfCurr1DayUncorrectBlks;
+   int                  adslAturChanPerfPrev1DayMoniSecs;
+   AdslPerfPrevDayCount adslAturChanPerfPrev1DayReceivedBlks;
+   AdslPerfPrevDayCount adslAturChanPerfPrev1DayTransmittedBlks;
+   AdslPerfPrevDayCount adslAturChanPerfPrev1DayCorrectedBlks;
+   AdslPerfPrevDayCount adslAturChanPerfPrev1DayUncorrectBlks;
+   u32                 flags;
+} aturChannelPerfDataEntry;
+
+
+//ioctl(int fd, GET_ADSL_ATUC_CHAN_INTVL_INFO, void *struct_adslAtucChanIntvlInfo)
+
+typedef struct adslAtucChanIntvlInfo {
+       int ifIndex;
+        int IntervalNumber;
+       PerfIntervalCount chanIntervalRecvdBlks;
+       PerfIntervalCount chanIntervalXmitBlks;
+       PerfIntervalCount chanIntervalCorrectedBlks;
+       PerfIntervalCount chanIntervalUncorrectBlks;
+       int intervalValidData;
+       u8 flags;
+} adslAtucChanIntvlInfo;
+
+
+//ioctl(int fd, GET_ADSL_ATUR_CHAN_INTVL_INFO, void *struct_adslAturChanIntvlInfo)
+
+typedef struct adslAturChanIntvlInfo {
+       int ifIndex;
+        int IntervalNumber;
+       PerfIntervalCount chanIntervalRecvdBlks;
+       PerfIntervalCount chanIntervalXmitBlks;
+       PerfIntervalCount chanIntervalCorrectedBlks;
+       PerfIntervalCount chanIntervalUncorrectBlks;
+       int intervalValidData;
+       u8 flags;
+} adslAturChanIntvlInfo;
+
+
+//ioctl(int fd, GET_ADSL_ALRM_CONF_PROF,  void *struct_adslLineAlarmConfProfileEntry)
+//ioctl(int fd, SET_ADSL_ALRM_CONF_PROF,  void *struct_adslLineAlarmConfProfileEntry)
+
+typedef struct  adslLineAlarmConfProfileEntry
+ {
+  unsigned char adslLineAlarmConfProfileName[32];
+    int        adslAtucThresh15MinLofs;
+    int        adslAtucThresh15MinLoss;
+    int        adslAtucThresh15MinESs;
+    u32        adslAtucThreshFastRateUp;
+    u32        adslAtucThreshInterleaveRateUp;
+    u32        adslAtucThreshFastRateDown;
+    u32        adslAtucThreshInterleaveRateDown;
+    int        adslAtucInitFailureTrapEnable;
+    int        adslAturThresh15MinLofs;
+    int        adslAturThresh15MinLoss;
+    int        adslAturThresh15MinLprs;
+    int        adslAturThresh15MinESs;
+    u32        adslAturThreshFastRateUp;
+    u32        adslAturThreshInterleaveRateUp;
+    u32        adslAturThreshFastRateDown;
+    u32        adslAturThreshInterleaveRateDown;
+    int        adslLineAlarmConfProfileRowStatus;
+    u32        flags;
+} adslLineAlarmConfProfileEntry;
+
+#ifdef IFXMIPS_MEI_MIB_RFC3440
+typedef struct adslLineAlarmConfProfileExtEntry
+ {
+  u8  adslLineAlarmConfProfileExtName[32];
+  u32 adslAtucThreshold15MinFailedFastR;
+  u32 adslAtucThreshold15MinSesL;
+  u32 adslAtucThreshold15MinUasL;
+  u32 adslAturThreshold15MinSesL;
+  u32 adslAturThreshold15MinUasL;
+  u32  flags;
+} adslLineAlarmConfProfileExtEntry;
+#endif
+//TRAPS
+
+/* The following Data Sturctures are added to support the WEB related parameters for ADSL Statistics */
+typedef struct  adslLineStatus
+ {
+    int        adslModemStatus;
+    u32        adslModeSelected;
+    int        adslAtucThresh15MinESs;
+    int        adslTrellisCodeEnable;
+    int        adslLatency;
+    u8 flags;
+ } adslLineStatusInfo;
+
+typedef struct  adslLineRate
+ {
+    u32        adslDataRateds;
+    u32        adslDataRateus;
+    u32        adslATTNDRds;   
+    u32        adslATTNDRus;   
+    u8         flags;
+ } adslLineRateInfo;
+
+typedef struct  adslLineInfo
+ {
+    u32        adslInterleaveDepthds;
+    u32        adslInterleaveDepthus;
+    u32        adslLATNds;
+    u32        adslLATNus;
+    u32        adslSATNds;
+    u32        adslSATNus;
+    int                adslSNRMds;
+    int                adslSNRMus;
+    int                adslACATPds;
+    int                adslACATPus;
+    u32        flags;
+ } adslLineInfo;
+
+typedef struct  adslNearEndPerfStats
+ {
+    u32        adslSuperFrames; 
+    u32        adslneLOS;
+    u32        adslneLOF;
+    u32        adslneLPR;
+    u32        adslneNCD;
+    u32        adslneLCD;
+    u32        adslneCRC;
+    u32                adslneRSCorr;
+    u32                adslneFECS;
+    u32                adslneES;
+    u32                adslneSES;
+    u32                adslneLOSS;
+    u32                adslneUAS;
+    u32                adslneHECErrors;
+    u32                flags;
+ } adslNearEndPerfStats;
+
+typedef struct  adslFarEndPerfStats
+ {
+    u32        adslfeLOS;
+    u32        adslfeLOF;
+    u32        adslfeLPR;
+    u32        adslfeNCD;
+    u32        adslfeLCD;
+    u32        adslfeCRC;
+    u32                adslfeRSCorr;
+    u32                adslfeFECS;
+    u32                adslfeES;
+    u32                adslfeSES;
+    u32                adslfeLOSS;
+    u32                adslfeUAS;
+    u32                adslfeHECErrors;
+    u32                flags;
+ } adslFarEndPerfStats;
+
+/* The number of tones (and hence indexes) is dependent on the ADSL mode - G.992.1, G.992.2, G.992.3, * G.992.4 and G.992.5 */
+typedef struct adslATURSubcarrierInfo {
+       int     ifindex;
+       u16     HLINSCds;
+       u16     HLINpsds[1024];/* Even index = real part; Odd Index
+                                   = imaginary part for each tone */
+       u16     HLOGMTds;
+       u16     HLOGpsds[512];
+       u16     QLNMTds;
+       u16     QLNpsds[512];
+       u16     SNRMTds;
+       u16     SNRpsds[512];  
+       u16     BITpsds[512];
+       s16     GAINpsds[512]; /* Signed value in 0.1dB units. i.e dB * 10.
+                               Needs to be converted into linear scale*/
+       u16     flags;
+}adslATURSubcarrierInfo;
+
+typedef struct adslATUCSubcarrierInfo {
+       int     ifindex;
+       u16     HLINSCus;
+       u16     HLINpsus[128];/* Even index = real part; Odd Index
+                                   = imaginary part for each tone */
+       u16     HLOGMTus;
+       u16     HLOGpsus[64];
+       u16     QLNMTus;
+       u16     QLNpsus[64]; 
+       u16     SNRMTus;
+       u16     SNRpsus[64];  
+       u16     BITpsus[64];
+       s16     GAINpsus[64]; /* Signed value in 0.1dB units. i.e dB * 10.
+                               Needs to be converted into linear scale*/
+       u16     flags;
+}adslATUCSubcarrierInfo;
+
+#ifndef u_int16
+#define u_int16 u16
+#endif
+
+typedef struct adslInitStats {
+       u_int16 FullInitializationCount;
+       u_int16 FailedFullInitializationCount;
+       u_int16 LINIT_Errors;
+       u_int16 Init_Timeouts;
+}adslInitStats;
+
+typedef struct adslPowerSpectralDensity {
+       int     ACTPSDds;
+       int     ACTPSDus;
+}adslPowerSpectralDensity;
+
+//ioctl(int fd, ADSL_ATUR_TRAPS, void  *uint16_flags)
+typedef union structpts {
+       adslLineTableEntry * adslLineTableEntry_pt;
+       adslAtucPhysEntry * adslAtucPhysEntry_pt;
+       adslAturPhysEntry * adslAturPhysEntry_pt;
+       adslAtucChanInfo * adslAtucChanInfo_pt;
+       adslAturChanInfo * adslAturChanInfo_pt;
+       atucPerfDataEntry * atucPerfDataEntry_pt;
+       aturPerfDataEntry * aturPerfDataEntry_pt;
+       adslAtucIntvlInfo * adslAtucIntvlInfo_pt;
+       adslAturIntvlInfo * adslAturIntvlInfo_pt;
+       atucChannelPerfDataEntry * atucChannelPerfDataEntry_pt;
+       aturChannelPerfDataEntry * aturChannelPerfDataEntry_pt;
+       adslAtucChanIntvlInfo * adslAtucChanIntvlInfo_pt;
+       adslAturChanIntvlInfo * adslAturChanIntvlInfo_pt;
+       adslLineAlarmConfProfileEntry * adslLineAlarmConfProfileEntry_pt;
+       // RFC 3440
+       
+    #ifdef IFXMIPS_MEI_MIB_RFC3440
+       adslLineExtTableEntry * adslLineExtTableEntry_pt;
+       atucPerfDataExtEntry * atucPerfDataExtEntry_pt;
+       adslAtucInvtlExtInfo * adslAtucInvtlExtInfo_pt;
+       aturPerfDataExtEntry * aturPerfDataExtEntry_pt;
+       adslAturInvtlExtInfo * adslAturInvtlExtInfo_pt;
+       adslLineAlarmConfProfileExtEntry * adslLineAlarmConfProfileExtEntry_pt;
+    #endif 
+       adslLineStatusInfo      * adslLineStatusInfo_pt;
+       adslLineRateInfo        * adslLineRateInfo_pt;
+       adslLineInfo            * adslLineInfo_pt;
+       adslNearEndPerfStats    * adslNearEndPerfStats_pt;
+       adslFarEndPerfStats     * adslFarEndPerfStats_pt;
+       adslATUCSubcarrierInfo  * adslATUCSubcarrierInfo_pt;
+       adslATURSubcarrierInfo  * adslATURSubcarrierInfo_pt;
+       adslPowerSpectralDensity * adslPowerSpectralDensity_pt;
+}structpts;
+
+#endif /* ] __IFXMIPS_MEI_APP_IOCTL_H */
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_bsp.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_bsp.h
new file mode 100644 (file)
index 0000000..c346620
--- /dev/null
@@ -0,0 +1,308 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_mei_bsp.h
+** PROJECT      : Danube
+** MODULES      : MEI
+**
+** DATE         : 1 Jan 2006
+** AUTHOR       : TC Chen
+** DESCRIPTION  : MEI Driver
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Version $Date      $Author     $Comment
+*******************************************************************************/
+#ifndef _IFXMIPS_MEI_BSP_H_
+#define _IFXMIPS_MEI_BSP_H_
+
+/***   Register address offsets, relative to MEI_SPACE_ADDRESS ***/
+#define MEI_DATA_XFR_OFFSET                            (0x0000)
+#define        MEI_VERSION_OFFSET                              (0x0004)
+#define        MEI_ARC_GP_STAT_OFFSET                          (0x0008)
+#define MEI_DATA_XFR_STAT_OFFSET                       (0x000C)
+#define        MEI_XFR_ADDR_OFFSET                             (0x0010)
+#define MEI_MAX_WAIT_OFFSET                            (0x0014)
+#define        MEI_TO_ARC_INT_OFFSET                           (0x0018)
+#define        ARC_TO_MEI_INT_OFFSET                           (0x001C)
+#define        ARC_TO_MEI_INT_MASK_OFFSET                      (0x0020)
+#define        MEI_DEBUG_WAD_OFFSET                            (0x0024)
+#define MEI_DEBUG_RAD_OFFSET                           (0x0028)
+#define        MEI_DEBUG_DATA_OFFSET                           (0x002C)
+#define        MEI_DEBUG_DEC_OFFSET                            (0x0030)
+#define MEI_CONFIG_OFFSET                              (0x0034)
+#define        MEI_RST_CONTROL_OFFSET                          (0x0038)
+#define        MEI_DBG_MASTER_OFFSET                           (0x003C)
+#define        MEI_CLK_CONTROL_OFFSET                          (0x0040)
+#define        MEI_BIST_CONTROL_OFFSET                         (0x0044)
+#define        MEI_BIST_STAT_OFFSET                            (0x0048)
+#define MEI_XDATA_BASE_SH_OFFSET                       (0x004c)
+#define MEI_XDATA_BASE_OFFSET                          (0x0050)
+#define MEI_XMEM_BAR_BASE_OFFSET                       (0x0054)
+#define MEI_XMEM_BAR0_OFFSET                           (0x0054)
+#define MEI_XMEM_BAR1_OFFSET                           (0x0058)
+#define MEI_XMEM_BAR2_OFFSET                           (0x005C)
+#define MEI_XMEM_BAR3_OFFSET                           (0x0060)
+#define MEI_XMEM_BAR4_OFFSET                           (0x0064)
+#define MEI_XMEM_BAR5_OFFSET                           (0x0068)
+#define MEI_XMEM_BAR6_OFFSET                           (0x006C))
+#define MEI_XMEM_BAR7_OFFSET                           (0x0070)
+#define MEI_XMEM_BAR8_OFFSET                           (0x0074)
+#define MEI_XMEM_BAR9_OFFSET                           (0x0078)
+#define MEI_XMEM_BAR10_OFFSET                          (0x007C)
+#define MEI_XMEM_BAR11_OFFSET                          (0x0080)
+#define MEI_XMEM_BAR12_OFFSET                          (0x0084)
+#define MEI_XMEM_BAR13_OFFSET                          (0x0088)
+#define MEI_XMEM_BAR14_OFFSET                          (0x008C)
+#define MEI_XMEM_BAR15_OFFSET                          (0x0090)
+#define MEI_XMEM_BAR16_OFFSET                          (0x0094)
+
+#define WHILE_DELAY 20000
+/*
+**     Define where in ME Processor's memory map the Stratify chip lives
+*/
+
+#define MAXSWAPSIZE            8 * 1024        //8k *(32bits)
+
+//      Mailboxes
+#define MSG_LENGTH             16      // x16 bits
+#define YES_REPLY                      1
+#define NO_REPLY               0
+
+#define CMV_TIMEOUT            1000    //jiffies
+
+//  Block size per BAR
+#define SDRAM_SEGMENT_SIZE     (64*1024)
+// Number of Bar registers
+#define MAX_BAR_REGISTERS      (17)
+
+#define XDATA_REGISTER         (15)
+
+#define IFXMIPS_MEI_IOCTL_CMV_WINHOST          IFX_ADSL_IOC_CMV_WINHOST
+
+#define IFXMIPS_MEI_IOCTL_CMV_READ             IFX_ADSL_IOC_CMV_READ
+#define IFXMIPS_MEI_IOCTL_CMV_WRITE            IFX_ADSL_IOC_CMV_WRITE
+
+#define IFXMIPS_MEI_IOCTL_GET_BASE_ADDRESS     IFX_ADSL_IOC_GET_BASE_ADDRESS
+
+// ARC register addresss
+#define ARC_STATUS                             0x0
+#define ARC_LP_START                           0x2
+#define ARC_LP_END                             0x3
+#define ARC_DEBUG                              0x5
+#define ARC_INT_MASK                           0x10A
+
+#define IRAM0_BASE                             (0x00000)
+#define IRAM1_BASE                             (0x04000)
+#define BRAM_BASE                              (0x0A000)
+
+#define ADSL_BASE                              (0x20000)
+#define CRI_BASE                               (ADSL_BASE + 0x11F00)
+#define CRI_CCR0                               (CRI_BASE + 0x00)
+#define CRI_RST                                        (CRI_BASE + 0x04*4)
+#define ADSL_DILV_BASE                                 (ADSL_BASE+0x20000)
+
+//
+#define IRAM0_ADDR_BIT_MASK   0xFFF
+#define IRAM1_ADDR_BIT_MASK   0xFFF
+#define BRAM_ADDR_BIT_MASK    0xFFF
+#define RX_DILV_ADDR_BIT_MASK 0x1FFF
+
+/***  Bit definitions ***/
+
+#define FALSE  0
+#define TRUE   1
+#define BIT0   1<<0
+#define BIT1   1<<1
+#define BIT2   1<<2
+#define BIT3   1<<3
+#define BIT4   1<<4
+#define BIT5   1<<5
+#define BIT6   1<<6
+#define BIT7   1<<7
+#define BIT8   1<<8
+#define BIT9   1<<9
+#define BIT10  1<<10
+#define BIT11  1<<11
+#define BIT12  1<<12
+#define BIT13  1<<13
+#define BIT14  1<<14
+#define BIT15  1<<15
+#define BIT16  1<<16
+#define BIT17  1<<17
+#define BIT18  1<<18
+#define BIT19  1<<19
+#define BIT20  1<<20
+#define BIT21  1<<21
+#define BIT22  1<<22
+#define BIT23  1<<23
+#define BIT24  1<<24
+#define BIT25  1<<25
+#define BIT26  1<<26
+#define BIT27  1<<27
+#define BIT28  1<<28
+#define BIT29  1<<29
+#define BIT30  1<<30
+#define BIT31  1<<31
+
+// CRI_CCR0 Register definitions
+#define CLK_2M_MODE_ENABLE                     BIT6
+#define        ACL_CLK_MODE_ENABLE                     BIT4
+#define FDF_CLK_MODE_ENABLE                    BIT2
+#define STM_CLK_MODE_ENABLE                    BIT0
+
+// CRI_RST Register definitions
+#define FDF_SRST                               BIT3
+#define MTE_SRST                               BIT2
+#define FCI_SRST                               BIT1
+#define AAI_SRST                               BIT0
+
+//      MEI_TO_ARC_INTERRUPT Register definitions
+#define        MEI_TO_ARC_INT1                 BIT3
+#define        MEI_TO_ARC_INT0                 BIT2
+#define MEI_TO_ARC_CS_DONE             BIT1    //need to check
+#define        MEI_TO_ARC_MSGAV                BIT0
+
+//      ARC_TO_MEI_INTERRUPT Register definitions
+#define        ARC_TO_MEI_INT1                 BIT8
+#define        ARC_TO_MEI_INT0                 BIT7
+#define        ARC_TO_MEI_CS_REQ               BIT6
+#define        ARC_TO_MEI_DBG_DONE             BIT5
+#define        ARC_TO_MEI_MSGACK               BIT4
+#define        ARC_TO_MEI_NO_ACCESS            BIT3
+#define        ARC_TO_MEI_CHECK_AAITX          BIT2
+#define        ARC_TO_MEI_CHECK_AAIRX          BIT1
+#define        ARC_TO_MEI_MSGAV                BIT0
+
+//      ARC_TO_MEI_INTERRUPT_MASK Register definitions
+#define        GP_INT1_EN                      BIT8
+#define        GP_INT0_EN                      BIT7
+#define        CS_REQ_EN                       BIT6
+#define        DBG_DONE_EN                     BIT5
+#define        MSGACK_EN                       BIT4
+#define        NO_ACC_EN                       BIT3
+#define        AAITX_EN                        BIT2
+#define        AAIRX_EN                        BIT1
+#define        MSGAV_EN                        BIT0
+
+#define        MEI_SOFT_RESET                  BIT0
+
+#define        HOST_MSTR                       BIT0
+
+#define JTAG_MASTER_MODE               0x0
+#define MEI_MASTER_MODE                        HOST_MSTR
+
+//      MEI_DEBUG_DECODE Register definitions
+#define MEI_DEBUG_DEC_MASK             (0x3)
+#define MEI_DEBUG_DEC_AUX_MASK         (0x0)
+#define MEI_DEBUG_DEC_DMP1_MASK                (0x1)
+#define MEI_DEBUG_DEC_DMP2_MASK                (0x2)
+#define MEI_DEBUG_DEC_CORE_MASK         (0x3)
+
+#define AUX_STATUS                     (0x0)
+//      ARC_TO_MEI_MAILBOX[11] is a special location used to indicate
+//      page swap requests.
+#define MEI_TO_ARC_MAILBOX             (0xDFD0)
+#define MEI_TO_ARC_MAILBOXR            (MEI_TO_ARC_MAILBOX + 0x2C)
+
+#define        ARC_TO_MEI_MAILBOX              (0xDFA0)
+#define ARC_MEI_MAILBOXR               (ARC_TO_MEI_MAILBOX + 0x2C)
+
+// Codeswap request messages are indicated by setting BIT31
+#define OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK     (0x80000000)
+
+// Clear Eoc messages received are indicated by setting BIT17 
+#define OMB_CLEAREOC_INTERRUPT_CODE    (0x00020000)
+
+/*
+**     Swap page header
+*/
+//      Page must be loaded at boot time if size field has BIT31 set
+#define BOOT_FLAG      (BIT31)
+#define BOOT_FLAG_MASK ~BOOT_FLAG
+
+#define FREE_RELOAD            1
+#define FREE_SHOWTIME          2
+#define FREE_ALL               3
+
+// marcos
+#define        IFXMIPS_WRITE_REGISTER_L(data,addr)     do{ *((volatile u32*)(addr)) = (u32)(data);} while (0)
+#define IFXMIPS_READ_REGISTER_L(addr)  (*((volatile u32*)(addr)))
+#define SET_BIT(reg, mask)                  reg |= (mask)
+#define CLEAR_BIT(reg, mask)                reg &= (~mask)
+#define CLEAR_BITS(reg, mask)               CLEAR_BIT(reg, mask)
+#define SET_BITS(reg, mask)                 SET_BIT(reg, mask)
+#define SET_BITFIELD(reg, mask, off, val)   {reg &= (~mask); reg |= (val << off);}
+
+#define ALIGN_SIZE                         ( 1L<<10 )  //1K size align
+#define MEM_ALIGN(addr)                    (((addr) + ALIGN_SIZE - 1) & ~ (ALIGN_SIZE -1) )
+
+// swap marco
+#define MEI_HALF_WORD_SWAP(data) {data = ((data & 0xffff)<<16) + ((data & 0xffff0000)>>16);}
+#define MEI_BYTE_SWAP(data) {data = ((data & 0xff)<<24) + ((data & 0xff00)<<8)+ ((data & 0xff0000)>>8)+ ((data & 0xff000000)>>24);}
+
+//      Swap page header describes size in 32-bit words, load location, and image offset
+//      for program and/or data segments
+typedef struct _arc_swp_page_hdr {
+       u32 p_offset;           //Offset bytes of progseg from beginning of image
+       u32 p_dest;             //Destination addr of progseg on processor
+       u32 p_size;             //Size in 32-bitwords of program segment
+       u32 d_offset;           //Offset bytes of dataseg from beginning of image
+       u32 d_dest;             //Destination addr of dataseg on processor
+       u32 d_size;             //Size in 32-bitwords of data segment
+} ARC_SWP_PAGE_HDR;
+
+/*
+**     Swap image header
+*/
+#define GET_PROG       0       //      Flag used for program mem segment
+#define GET_DATA       1       //      Flag used for data mem segment
+
+//      Image header contains size of image, checksum for image, and count of
+//      page headers. Following that are 'count' page headers followed by
+//      the code and/or data segments to be loaded
+typedef struct _arc_img_hdr {
+       u32 size;               //      Size of binary image in bytes
+       u32 checksum;           //      Checksum for image
+       u32 count;              //      Count of swp pages in image
+       ARC_SWP_PAGE_HDR page[1];       //      Should be "count" pages - '1' to make compiler happy
+} ARC_IMG_HDR;
+
+typedef struct smmu_mem_info {
+       int type;
+       unsigned long nCopy;
+       unsigned long size;
+       unsigned char *address;
+       unsigned char *org_address;
+} smmu_mem_info_t;
+
+typedef struct ifxmips_mei_device_private {
+       int modem_ready;
+       int arcmsgav;
+       int cmv_reply;
+       int cmv_waiting;
+       // Mei to ARC CMV count, reply count, ARC Indicator count       
+       int indicator_count;
+       int cmv_count;
+       int reply_count;
+       unsigned long image_size;
+       int nBar;
+       u16 Recent_indicator[MSG_LENGTH];
+
+       u16 CMV_RxMsg[MSG_LENGTH] __attribute__ ((aligned (4)));
+
+       smmu_mem_info_t adsl_mem_info[MAX_BAR_REGISTERS];
+       ARC_IMG_HDR *img_hdr;
+       //  to wait for arc cmv reply, sleep on wait_queue_arcmsgav;
+       wait_queue_head_t wait_queue_arcmsgav;
+       wait_queue_head_t wait_queue_modemready;
+       MEI_mutex_t mei_cmv_sema;
+} ifxmips_mei_device_private_t;
+
+#endif //_IFXMIPS_MEI_BSP_H_
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_ioctl.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_ioctl.h
new file mode 100644 (file)
index 0000000..d11f04e
--- /dev/null
@@ -0,0 +1,734 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_mei_ioctl.h
+** PROJECT      : Danube
+** MODULES      : MEI
+**
+** DATE         : 1 Jan 2006
+** AUTHOR       : TC Chen
+** DESCRIPTION  : MEI Driver
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Version $Date      $Author     $Comment
+*******************************************************************************/
+#ifndef         _IFXMIPS_MEI_IOCTL_H
+#define                _IFXMIPS_MEI_IOCTL_H
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+#define PCM_BUFF_SIZE          1024    //bytes
+//  interrupt numbers
+
+#if !(defined(_IFXMIPS_ADSL_APP) || defined (_AMAZON_ADSL_APP))
+
+// Number of intervals
+#define INTERVAL_NUM                                   192     //two days
+typedef struct ifxmips_mei_mib {
+       struct list_head list;
+       struct timeval start_time;      //start of current interval
+
+       int AtucPerfLof;
+       int AtucPerfLos;
+       int AtucPerfEs;
+       int AtucPerfInit;
+
+       int AturPerfLof;
+       int AturPerfLos;
+       int AturPerfLpr;
+       int AturPerfEs;
+
+       int AturChanPerfRxBlk;
+       int AturChanPerfTxBlk;
+       int AturChanPerfCorrBlk;
+       int AturChanPerfUncorrBlk;
+
+       //RFC-3440
+       int AtucPerfStatFastR;
+       int AtucPerfStatFailedFastR;
+       int AtucPerfStatSesL;
+       int AtucPerfStatUasL;
+       int AturPerfStatSesL;
+       int AturPerfStatUasL;
+} ifxmips_mei_mib;
+
+typedef struct adslChanPrevTxRate {
+       u32 adslAtucChanPrevTxRate;
+       u32 adslAturChanPrevTxRate;
+} adslChanPrevTxRate;
+
+typedef struct adslPhysCurrStatus {
+       u32 adslAtucCurrStatus;
+       u32 adslAturCurrStatus;
+} adslPhysCurrStatus;
+
+typedef struct ChanType {
+       int interleave;
+       int fast;
+       int bearchannel0;
+       int bearchannel1;
+} ChanType;
+
+typedef struct mib_previous_read {
+       u16 ATUC_PERF_ESS;
+       u16 ATUR_PERF_ESS;
+       u32 ATUR_CHAN_RECV_BLK;
+       u16 ATUR_CHAN_CORR_BLK_INTL;
+       u16 ATUR_CHAN_CORR_BLK_FAST;
+       u16 ATUR_CHAN_UNCORR_BLK_INTL;
+       u16 ATUR_CHAN_UNCORR_BLK_FAST;
+       u16 ATUC_PERF_STAT_FASTR;
+       u16 ATUC_PERF_STAT_FAILED_FASTR;
+       u16 ATUC_PERF_STAT_SESL;
+       u16 ATUC_PERF_STAT_UASL;
+       u16 ATUR_PERF_STAT_SESL;
+} mib_previous_read;
+
+typedef struct mib_flags_pretime {
+       struct timeval ATUC_PERF_LOSS_PTIME;
+       struct timeval ATUC_PERF_LOFS_PTIME;
+       struct timeval ATUR_PERF_LOSS_PTIME;
+       struct timeval ATUR_PERF_LOFS_PTIME;
+       struct timeval ATUR_PERF_LPR_PTIME;
+} mib_flags_pretime;
+
+               //  cmv message structures
+#define        MP_PAYLOAD_SIZE                                 12
+typedef struct mpmessage {
+       u16 iFunction;
+       u16 iGroup;
+       u16 iAddress;
+       u16 iIndex;
+       u16 iPayload[MP_PAYLOAD_SIZE];
+} MPMessage;
+#endif
+
+typedef struct meireg {
+       u32 iAddress;
+       u32 iData;
+} meireg;
+
+#define MEIDEBUG_BUFFER_SIZES 50
+typedef struct meidebug {
+       u32 iAddress;
+       u32 iCount;
+       u32 buffer[MEIDEBUG_BUFFER_SIZES];
+} meidebug;
+
+//==============================================================================
+// Group definitions                                                              
+//==============================================================================
+#define OPTN                    5
+#define CNFG                    8
+#define CNTL                    1
+#define STAT                    2
+#define RATE                    6
+#define PLAM                    7
+#define INFO                    3
+#define TEST                   4
+//==============================================================================
+// Opcode definitions
+//==============================================================================
+#define H2D_CMV_READ                            0x00
+#define H2D_CMV_WRITE                           0x04
+#define H2D_CMV_INDICATE_REPLY                  0x10
+#define H2D_ERROR_OPCODE_UNKNOWN               0x20
+#define H2D_ERROR_CMV_UNKNOWN                  0x30
+
+#define D2H_CMV_READ_REPLY                             0x01
+#define D2H_CMV_WRITE_REPLY                     0x05
+#define D2H_CMV_INDICATE                        0x11
+#define D2H_ERROR_OPCODE_UNKNOWN                0x21
+#define D2H_ERROR_CMV_UNKNOWN                   0x31
+#define D2H_ERROR_CMV_READ_NOT_AVAILABLE        0x41
+#define D2H_ERROR_CMV_WRITE_ONLY                0x51
+#define D2H_ERROR_CMV_READ_ONLY                 0x61
+
+#define H2D_DEBUG_READ_DM                       0x02
+#define H2D_DEBUG_READ_PM                       0x06
+#define H2D_DEBUG_WRITE_DM                      0x0a
+#define H2D_DEBUG_WRITE_PM                      0x0e
+
+#define D2H_DEBUG_READ_DM_REPLY                0x03
+#define D2H_DEBUG_READ_FM_REPLY                0x07
+#define D2H_DEBUG_WRITE_DM_REPLY               0x0b
+#define D2H_DEBUG_WRITE_FM_REPLY               0x0f
+#define D2H_ERROR_ADDR_UNKNOWN                 0x33
+
+#define D2H_AUTONOMOUS_MODEM_READY_MSG         0xf1
+//==============================================================================
+// INFO register address field definitions
+//==============================================================================
+
+#define INFO_TxState                                   0
+#define INFO_RxState                                   1
+#define INFO_TxNextState                               2
+#define INFO_RxNextState                               3
+#define INFO_TxStateJumpFrom                           4
+#define INFO_RxStateJumpFrom                           5
+
+#define INFO_ReverbSnrBuf                              8
+#define INFO_ReverbEchoSnrBuf                          9
+#define INFO_MedleySnrBuf                              10
+#define INFO_RxShowtimeSnrBuf                          11
+#define INFO_DECdelay                                  12
+#define INFO_DECExponent                               13
+#define INFO_DECTaps                                   14
+#define INFO_AECdelay                                  15
+#define INFO_AECExponent                               16
+#define INFO_AECTaps                                   17
+#define INFO_TDQExponent                               18
+#define INFO_TDQTaps                                   19
+#define INFO_FDQExponent                               20
+#define INFO_FDQTaps                                   21
+#define INFO_USBat                                     22
+#define INFO_DSBat                                     23
+#define INFO_USFineGains                               24
+#define INFO_DSFineGains                               25
+#define INFO_BitloadFirstChannel                       26
+#define INFO_BitloadLastChannel                                27
+#define INFO_PollEOCData                               28      // CO specific
+#define INFO_CSNRMargin                                        29      // CO specific
+#define INFO_RCMsgs1                                   30
+#define INFO_RMsgs1                                    31
+#define INFO_RMsgRA                                    32
+#define INFO_RCMsgRA                                   33
+#define INFO_RMsg2                                     34
+#define INFO_RCMsg2                                    35
+#define INFO_BitLoadOK                                 36
+#define INFO_RCRates1                                  37
+#define INFO_RRates1Tab                                        38
+#define INFO_RMsgs1Tab                                 39
+#define INFO_RMsgRATab                                 40
+#define INFO_RRatesRA                                  41
+#define INFO_RCRatesRA                                 42
+#define INFO_RRates2                                   43
+#define INFO_RCRates2                                  44
+#define INFO_PackedRMsg2                               45
+#define INFO_RxBitSwapFlag                             46
+#define INFO_TxBitSwapFlag                             47
+#define INFO_ShowtimeSNRUpdateCount                    48
+#define INFO_ShowtimeFDQUpdateCount                    49
+#define INFO_ShowtimeDECUpdateCount                    50
+#define INFO_CopyRxBuffer                              51
+#define INFO_RxToneBuf                                 52
+#define INFO_TxToneBuf                                  53
+#define INFO_Version                                   54
+#define INFO_TimeStamp                                  55
+#define INFO_feVendorID                                        56
+#define INFO_feSerialNum                               57
+#define INFO_feVersionNum                              58
+#define INFO_BulkMemory                                        59      //Points to start of bulk memory
+#define INFO_neVendorID                                 60
+#define INFO_neVersionNum                              61
+#define INFO_neSerialNum                               62
+
+//==============================================================================
+// RATE register address field definitions
+//==============================================================================
+
+#define RATE_UsRate                                    0
+#define RATE_DsRate                                    1
+
+//==============================================================================
+// PLAM (Physical Layer Management) register address field definitions
+//      (See G997.1 for reference)
+//==============================================================================
+
+       //                                      ///
+       // Failure Flags        ///
+       //                                      ///
+
+#define PLAM_NearEndFailureFlags               0
+#define PLAM_FarEndFailureFlags                        1
+
+       //                                                                      ///
+       // Near End Failure Flags Bit Definitions       ///
+       //                                                                      ///
+
+// ADSL Failures ///
+#define PLAM_LOS_FailureBit                            0x0001
+#define PLAM_LOF_FailureBit                            0x0002
+#define PLAM_LPR_FailureBit                            0x0004
+#define PLAM_RFI_FailureBit                            0x0008
+
+// ATM Failures ///
+#define PLAM_NCD_LP0_FailureBit                                0x0010
+#define PLAM_NCD_LP1_FailureBit                                0x0020
+#define PLAM_LCD_LP0_FailureBit                                0x0040
+#define PLAM_LCD_LP1_FailureBit                                0x0080
+
+#define PLAM_NCD_BC0_FailureBit                                0x0100
+#define PLAM_NCD_BC1_FailureBit                                0x0200
+#define PLAM_LCD_BC0_FailureBit                                0x0400
+#define PLAM_LCD_BC1_FailureBit                                0x0800
+       //                                              ///
+       // Performance Counts   ///
+       //                                              ///
+
+#define PLAM_NearEndCrcCnt                             2
+#define PLAM_CorrectedRSErrors                         3
+
+#define PLAM_NearEndECSCnt                             6
+#define PLAM_NearEndESCnt                              7
+#define PLAM_NearEndSESCnt                             8
+#define PLAM_NearEndLOSSCnt                            9
+#define PLAM_NearEndUASLCnt                            10
+
+#define PLAM_NearEndHECErrCnt                          11
+
+#define PLAM_NearEndHECTotCnt                          16
+#define PLAM_NearEndCellTotCnt                         18
+#define PLAM_NearEndSfCntLSW                           20
+#define PLAM_NearEndSfCntMSW                           21
+
+#define PLAM_FarEndFebeCnt                             24
+
+#define PLAM_FarEndFecCnt                              28
+
+#define PLAM_FarEndFECSCnt                             32
+#define PLAM_FarEndESCnt                               33
+#define PLAM_FarEndSESCnt                              34
+#define PLAM_FarEndLOSSCnt                             35
+#define PLAM_FarEndUASLCnt                             36
+
+#define PLAM_FarEndHECErrCnt                           37
+
+#define PLAM_FarEndHECTotCnt                           41
+
+#define PLAM_FarEndCellTotCnt                          43
+
+#define PLAM_SNRMargin_0_1db                           45
+
+#define PLAM_SNRMargin                                 46
+
+//==============================================================================
+// CNTL register address and bit field definitions
+//==============================================================================
+
+#define CNTL_ModemControl                              0
+
+#define CNTL_ModemReset                                        0x0
+#define CNTL_ModemStart                                        0x2
+
+//==============================================================================
+// STAT register address and bit field definitions
+//==============================================================================
+
+#define STAT_MacroState                                        0
+#define STAT_Mode                                      1
+#define STAT_DMTFramingMode                            2
+#define STAT_SleepState                                        3
+#define STAT_Misc                                      4
+#define STAT_FailureState                              5
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STAT_OLRStatus provides status of OLR
+ //16-bit STAT_OLRStatus_DS
+ //  [1:0]      :       OLR status 00=IDLE,  01=OLR_IN_PROGRESS, 10=OLR_Completed, 11=OLR_Aborted
+ //  [3:2]:             Reserved
+ //  [5:4]:             OLR_Type (1:bitswap; 2: DRR; 3: SRA)
+ //  [7:6]:             Reserved
+ //  [10:8]:            >0=Request. 0=not.   For DS, # of request transmissions/retransmissions (3 bits).
+ //  [11]:              1=Receive Response, 0=not
+ //  [15:12]:   Reserved
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ///
+#define STAT_OLRStatus_DS                              6
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STAT_OLRStatus provides status of OLR
+ // 16-bit STAT_OLRStatus_US CMV
+ //  [1:0]      :       OLR status 00=IDLE,  01=OLR_IN_PROGRESS, 10=OLR_Completed, 11=OLR_Aborted
+ //  [3:2]:             Reserved
+ //  [5:4]:             OLR_Type (1:bitswap; 2: DRR; 3: SRA)
+ //  [7:6]:             Reserved
+ //  [8]:               1=Request Received. 0=not.
+ //  [10:9]:     Reserved
+ //  [11]:              1=Response Sent, 0=not
+ //  [15:12]:   Reserved
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///
+#define STAT_OLRStatus_US                              7
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STAT_PMStatus provides status of PM
+ // 16-bit STAT_PMStatus CMV
+ //  [1:0]      :       PM Status 00=IDLE,  01=PM_IN_PROGRESS, 10=PM_Completed, 11=PM_Aborted
+ //  [2] :              0=ATU_R initiated PM; 1 = ATU_C initiated PM
+ //  [3]:               Reserved
+ //  [5:4]:             PM_Type (1:Simple Request; 2: L2 request; 3: L2 trim)
+ //  [7:6]:             Reserved
+ //  [10:8]:            >0=Request. 0=not.   # of request transmissions/retransmissions (3 bits).
+ //  [11]:              1=Response, 0=not
+ //  [15:12]:   Reserved
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ///
+#define STAT_PMStatus                                  8
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // 16-bit STAT_OLRError_DS, STAT_OLRError_US, STAT_PMError
+ // [3:0]:          OLR/PM response reason code
+ // [7:4]:             OLR/PM Internal error code
+ // [15:8]:         OLR/PM Reserved for future
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ///
+#define STAT_OLRError_DS                               9
+#define STAT_OLRError_US                               10
+#define STAT_PMError                                   11
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_MacroState
+// MacroState reflects the high level state of the modem
+
+#define STAT_InitState                         0x0000
+#define STAT_ReadyState                                0x0001
+#define STAT_FailState                         0x0002
+#define STAT_IdleState                         0x0003
+#define STAT_QuietState                                0x0004
+#define STAT_GhsState                          0x0005
+#define STAT_FullInitState                     0x0006
+#define STAT_ShowTimeState                     0x0007
+#define STAT_FastRetrainState                  0x0008
+#define STAT_LoopDiagMode                      0x0009
+#define STAT_ShortInit                         0x000A  // Bis short initialization ///
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_Mode
+// ConfigurationMode indicates the mode of the current ADSL Link. In general, a modem may use
+// G.Hs or some other mechanism to negotiate the specific mode of operation.
+// The OPTN_modeControl CMV is used to select a set of desired modes.
+// The STAT_Mode CMV indicates which mode was actually selected.
+
+#define STAT_ConfigMode_T1413                  0x0001
+#define STAT_ConfigMode_G992_2_AB              0x0002
+#define STAT_ConfigMode_G992_1_A               0x0004
+#define STAT_ConfigMode_G992_1_B               0x0008
+#define STAT_ConfigMode_G992_1_C               0x0010
+#define STAT_ConfigMode_G992_2_C               0x0020
+
+#define STAT_ConfigMode_G992_3_A               0x0100
+#define STAT_ConfigMode_G992_3_B               0x0200
+#define STAT_ConfigMode_G992_3_I               0x0400
+#define STAT_ConfigMode_G992_3_J               0x0800
+#define STAT_ConfigMode_G992_3_L               0x1000
+
+#define STAT_ConfigMode_G992_4_A               0x2000
+#define STAT_ConfigMode_G992_4_I               0x4000
+
+#define STAT_ConfigMode_G992_5                 0x8000
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_DMTFramingMode
+// FramingMode indicates the DMT framing mde negotiated during initialization. The framing mode
+// status is not applicable in BIS mode and its value is undefined
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define STAT_FramingModeMask                   0x0003
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_Misc
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define STAT_OverlappedSpectrum                0x0008
+#define STAT_TCM                       0x0010
+#define STAT_TDQ_at_1104               0x0020
+#define STAT_T1413_Signal_Detected     0x0040
+#define STAT_AnnexL_US_Mask1_PSD       0x1000  //indicate we actually selected G992.3 AnnexL US PSD mask1
+#define STAT_AnnexL_US_Mask2_PSD       0x2000  //indicate we actually selected G992.3 AnnexL US PSD mask2
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STAT_FailureState
+// when the MacroSTate indicates the fail state, FailureState provides a failure code
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define E_CODE_NO_ERROR                                                                0
+#define E_CODE_BAT_TX                                                          1       // TX BAT table is incorrect */
+#define E_CODE_BAT_RX                                                          2       //  RX BAT table is incorrect */
+#define E_CODE_PROFILE                                                         3       //  profile is not selected in fast retrain */
+#define E_CODE_TX_AOC_FIFO_OVERFLOW                                            4
+#define E_CODE_TRUNCATE_FR                                                     5       //Fast Retrain truncated due to no stored profiles*/
+#define E_CODE_BITLOAD                                                         6       //  bit loading fails */
+#define E_CODE_ST_ERROR                                                                7       //  showtime CRC error */
+#define E_CODE_RESERVED                                                                8       //  using parameters reserved by the ITU-T */
+#define E_CODE_C_TONES                                                         9       //  detected C_TONES */
+#define E_CODE_CODESWAP_ERR                                                    10      //  codeswap not finished in time */
+#define E_CODE_FIFO_OVERFLOW                                                   11      // we have run out of fifo space */
+#define E_CODE_C_BG_DECODE_ERR                                                 12      // error in decoding C-BG message */
+#define E_CODE_C_RATES2_DECODE_ERR                                             13      // error in decoding C-MSGS2 and C-RATES2 */
+#define E_CODE_RCMedleyRx_C_SEGUE2_Failure                                     14      //  Timeout after RCMedleyRx waiting for C_SEGUE2 */
+#define E_CODE_RReverbRATx_C_SEGUE2_Failure                                    15      //  Timeout after RReverbRATx waiting for C_SEGUE2 */
+#define E_CODE_RReverb3Tx_C_SEGUE1_Failure                                     16      //  Timeout after RReverb3Tx waiting for C_SEGUE1 */
+#define E_CODE_RCCRC2Rx_C_RATES1_DECOD_ERR                                     17      //  Received CRC not equal to computed CRC */
+#define E_CODE_RCCRC1Rx_C_RATES1_DECOD_ERR                                     18      //  Received CRC not equal to computed CRC */
+#define E_CODE_RReverb5Tx_C_SEGUE2_Failure                                     19      //  Timeout after RReverb5Tx waiting for C_SEGUE2 */
+#define E_CODE_RReverb6Tx_C_SEGUE3_Failure                                     20      //  Timeout after RReverb6Tx waiting for C_SEGUE3 */
+#define E_CODE_RSegue5Tx_C_SEGUE3_Failure                                      21      //  Timeout after RSegue5Tx waiting for C_SEGUE3 */
+#define E_CODE_RCReverb5Rx_C_SEGUE_Failure                                     22      //  Timeout after RCReverb5Rx waiting for C_SEGUE */
+#define E_CODE_RCReverbRARx_C_SEGUE2_Failure                                   23      //  Timeout after RCReverbRARx waiting for C_SEGUE2 */
+#define E_CODE_RCCRC4Rx_CMSGS2_DECOD_ERR                                       24      //  Received CRC not equal to computed CRC */
+#define E_CODE_RCCRC5Rx_C_BG_DECOD_ERR                                         25      //  Received CRC not equal to computed CRC */
+#define E_CODE_RCCRC3Rx_DECOD_ERR                                              26      //  Received CRC not equal to computed CRC */
+#define E_CODE_RCPilot3_DEC_PATH_DEL_TIMEOUT                                   27      //  DEC Path Delay timeout */
+#define E_CODE_RCPilot3_DEC_TRAINING_TIMEOUT                                   28      //  DEC Training timeout */
+#define E_CODE_RCReverb3Rx_C_SEGUE1_Failure                                    29      //  Timeout after RCReverb3Rx waiting for C_SEGUE1 */
+#define E_CODE_RCReverb2Rx_SignalEnd_Failure                                   30      //  Timeout waiting for the end of RCReverb2Rx signal */
+#define E_CODE_RQuiet2_SignalEnd_Failure                                       31      //  Timeout waiting for the end of RQuiet2 signal */
+#define E_CODE_RCReverbFR1Rx_Failure                                           32      //  Timeout waiting for the end of RCReverbFR1Rx signal */
+#define E_CODE_RCPilotFR1Rx_SignalEnd_Failure                                  33      //  Timeout waiting for the end of RCPilotFR1Rx signal */
+#define E_CODE_RCReverbFR2Rx_C_Segue_Failure                                   34      //  Timeout after RCReverbFR2Rx waiting for C_SEGUE */
+#define E_CODE_RCReverbFR5Rx_SignalEnd_TIMEOUT                                 35      //  Timeout waiting for the end of RCReverbFR5Rx signal */
+#define E_CODE_RCReverbFR6Rx_C_SEGUE_Failure                                   36      //  Timeout after RCReverbFR6Rx waiting for C_SEGUE */
+#define E_CODE_RCReverbFR8Rx_C_SEGUE_FR4_Failure                               37      //  Timeout after RCReverbFR8Rx waiting for C_SEGUE_FR4 */
+#define E_CODE_RCReverbFR8Rx_No_PROFILE                                                38      //  Timeout since no profile was selected */
+#define E_CODE_RCReverbFR8Rx_SignalEnd_TIMEOUT                                 39      //  Timeout waiting for the end of RCReverbFR8Rx signal */
+#define E_CODE_RCCRCFR1_DECOD_ERR                                              40      //  Received CRC not equal to computed CRC */
+#define E_CODE_RCRecovRx_SingnalEnd_TIMEOUT                                    41      //  Timeout waiting for the end of RCRecovRx signal */
+#define E_CODE_RSegueFR5Tx_TX_Not_Ready_TIMEOUT                                        42      //  Timeout after RSegueFR5Tx waiting for C_SEGUE2 */
+#define E_CODE_RRecovTx_SignalEnd_TIMEOUT                                      43      //  Timeout waiting for the end of RRecovTx signal */
+#define E_CODE_RCMedleyFRRx_C_SEGUE2_Failure                                   44      //  Timeout after RCMedleyFRRx waiting for C_SEGUE2 */
+#define E_CODE_CONFIGURATION_PARAMETERS_ERROR                                  45      // one of the configuration parameters do not meet the standard */
+#define E_CODE_BAD_MEM_ACCESS                                                  46
+#define E_CODE_BAD_INSTRUCTION_ACCESS                                          47
+#define E_CODE_TX_EOC_FIFO_OVERFLOW                                            48
+#define E_CODE_RX_EOC_FIFO_OVERFLOW                                            49
+#define E_CODE_GHS_CD_FLAG_TIME_OUT                                            50      // Timeout when transmitting Flag in handshake cleardown */
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//STAT_OLRStatus:
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define STAT_OLRPM_IDLE                                 0x0000
+#define STAT_OLRPM_IN_PROGRESS                          0x0001
+#define STAT_OLRPM_COMPLETE                             0x0002
+#define STAT_OLRPM_ABORTED                              0x0003
+#define STAT_OLRPM_RESPONSE                            0x0800
+
+#define STAT_OLR_BITSWAP                                0x0010
+#define STAT_OLR_DRR                                   0x0020
+#define STAT_OLR_SRA                                   0x0030
+
+//STAT_PMStatus_US:
+#define STAT_PM_CO_REQ                                  0x0004
+#define STAT_PM_SIMPLE_REQ                              0x0010
+#define STAT_PM_L2_REQ                                 0x0020
+#define STAT_PM_L2_TRIM_REQ                            0x0030
+
+// STAT_OLRError_DS, STAT_OLRError_US
+//4 bit response reason code:
+#define RESP_BUSY                                      0x01
+#define RESP_INVALID_PARAMETERS                                0x02
+#define RESP_NOT_ENABLED                               0x03
+#define RESP_NOT_SUPPORTED                             0x04
+
+//4 bit internal error code (common for OLR and PM)
+#define REQ_INVALID_BiGi                               0x10
+#define REQ_INVALID_Lp                                 0x20
+#define REQ_INVALID_Bpn                                        0x30
+#define REQ_INVALID_FRAMING_CONSTRAINT                 0x40
+#define REQ_NOT_IN_L0_STATE                            0x50
+#define REQ_NOT_IN_L2_STATE                            0x60
+#define REQ_INVALID_PCB                                        0x70
+#define REQ_VIOLATES_MARGIN                            0x80
+
+//STAT_PMError
+//4 bit response reason code:
+#define RESP_STATE_NOT_DESIRED                          0x03
+#define RESP_INFEASIBLE_PARAMETERS                      0x04
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// OPTN register address and bit field definitions
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define OPTN_ModeControl                               0
+#define OPTN_DMTLnkCtl                                 1
+// Reserved                                             2
+#define OPTN_GhsControl                                        3
+// Reserved                                             4
+#define OPTN_PwrManControl                             5
+#define OPTN_AnnexControl                              6
+#define OPTN_ModeControl1                              7
+// Reserved                                             8
+#define OPTN_StateMachineCtrl                          9
+// Reserved                                             10
+// Reserved                                             11
+#define OPTN_BisLinkControl                            12
+#define OPTN_ATMAddrConfig                             13
+#define OPTN_ATMNumCellConfig                          14
+
+// Mode control defines the allowable operating modes of an ADSL link. In general, a modem may ///
+// use G.Hs or some other mechanism to negotiate the specific mode of operation. ///
+// The OPTN_ModeControl CMV is used to select a set of desired modes ///
+// The STAT_ModeControl CMV indicates which mode was actually selected ///
+
+// OPTN_ModeControl
+#define OPTN_ConfigMode_T1413                  0x0001
+#define OPTN_ConfigMode_G992_2_AB              0x0002
+#define OPTN_ConfigMode_G992_1_A               0x0004
+#define OPTN_ConfigMode_G992_1_B               0x0008
+#define OPTN_ConfigMode_G992_1_C               0x0010
+#define OPTN_ConfigMode_G992_2_C               0x0020
+
+#define OPTN_ConfigMode_G992_3_A               0x0100
+#define OPTN_ConfigMode_G992_3_B               0x0200
+#define OPTN_ConfigMode_G992_3_I               0x0400
+#define OPTN_ConfigMode_G992_3_J               0x0800
+#define OPTN_ConfigMode_G992_3_L               0x1000
+
+#define OPTN_ConfigMode_G992_4_A               0x2000
+#define OPTN_ConfigMode_G992_4_I               0x4000
+
+#define OPTN_ConfigMode_G992_5                 0x8000
+
+// OPTN_PwrManControl
+#define OPTN_PwrManWakeUpGhs                   0x1
+#define OPTN_PwrManWakeUpFR                    0x2
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// OPTN_DMT Link Control
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#define OPTN_DMT_DualLatency_Dis                0x200
+#define OPTN_DMT_S_Dis                          0x100
+#define OPTN_DMT_FRAMINGMODE                   0x1
+#define OPTN_DMT_FRAMINGMODE_MASK              0x7
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// OPTN_BIS Link Control
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#define OPTN_BisLinkContrl_LineProbeDis         0x1
+#define OPTN_BisLinkContrl_DSBlackBitsEn        0x2
+#define OPTN_BisLinkContrl_DiagnosticModeEn     0x4
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// OPTN_GhsControl
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// for OPTN_GhsControl, we will assign 16bit word as follows
+// bit 0~3: set the control over which start(initial) message CPE will send:
+//
+//              BIT: 2  1  0
+//                       0  0  1  CLR
+//                       0  1  0  MR
+//                       0  1  1  MS
+//                       1  0  0  MP
+//
+//  // bit 4~6: set the control over which message will be sent when we get at lease one CL/CLR exchange
+//        BIT: 5  4
+//                   0  1  MS
+//                       1  0  MR
+//                       1  1  MP
+//
+//  // bit 15: RT initiated G.hs sample sessions one through eight.  Session one is default.
+//        BIT: 15
+//                        1  means session one
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define OPTN_GHS_ST_GHS                                        0x8000
+#define OPTN_GHS_INIT_MASK                             0x000F
+#define OPTN_GHS_RESP_MASK                             0x00F0
+
+#define OPTN_RTInitTxMsg_CLR                           0x0001
+#define OPTN_RTInitTxMsg_MR                            0x0002
+#define OPTN_RTInitTxMsg_MS                            0x0003
+#define OPTN_RTInitTxMsg_MP                            0x0004
+
+#define OPTN_RTRespTxMsg_MS                            0x0010
+#define OPTN_RTRespTxMsg_MR                            0x0020
+#define OPTN_RTRespTxMsg_MP                            0x0030
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//      OPTN_AnnexControl
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// G.992.3 Annex A/L1/L2 US PSD Mask preferred
+
+#define OPTN_G992_3_AnnexA_PreferredModeMask           0x3000
+#define OPTN_G992_3_AnnexA_PreferredModeA              0x0000  // default AnnexA PSD mask ///
+#define OPTN_G992_3_AnnexA_PreferredModeL1             0x1000  // AnnexL wide spectrum upstream PSD mask ///
+#define OPTN_G992_3_AnnexA_PreferredModeL2             0x2000  // AnnexL narrow spectrum upstream PSD mask ///
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//OPTN_ATMAddrConfig
+// Bits 4:0             are Utopia address for BC1
+// Bits 9:5             are Utopia address for BC0
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define OPTN_UTPADDR_BC1                               0x001F
+#define OPTN_UTPADDR_BC0                               0x03E0
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//OPTN_ATMNumCellConfig
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define OPTN_BC1_NUM_CELL_PAGES                                0x000F  // Bits 0:3 ///
+#define OPTN_BC0_NUM_CELL_PAGES                                0x00F0  // Bits 4:7 ///
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// CNFG register address field ///
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////
+// these cmvs are used by bis handshake ///
+///////////////////////////////////////////
+
+// Each of the CNFG_TPS entries points to a structure of type (TPS_TC_BearerChannel_t)
+#define CNFG_TPS_TC_DS0                                        0
+#define CNFG_TPS_TC_DS1                                        1
+#define CNFG_TPS_TC_US0                                        2
+#define CNFG_TPS_TC_US1                                        3
+
+#define CNFG_HDLC_Overhead_Requirements                        4
+
+// Each of the CNFG_PMS entries points to a structure of type (PMS_TC_LatencyPath_t)
+#define CNFG_PMS_TC_DS0                                        5
+#define CNFG_PMS_TC_DS1                                        6
+#define CNFG_PMS_TC_US0                                        7
+#define CNFG_PMS_TC_US1                                        8
+
+// CNFG_PMD_PARAMETERS points to a structure of type (PMD_params_t)
+#define CNFG_PMD_PARAMETERS                            9
+
+////////////////////////////////////////////////////////////
+// these cmvs are used by bis training and showtime code ///
+////////////////////////////////////////////////////////////
+
+////////////////
+// Tx Config ///
+////////////////
+#define CNFG_tx_Cnfg_Nbc                               10
+#define CNFG_tx_Cnfg_Nlp                               11
+#define CNFG_tx_Cnfg_Rp                                        12
+#define CNFG_tx_Cnfg_Mp                                        13
+#define CNFG_tx_Cnfg_Lp                                        14
+#define CNFG_tx_Cnfg_Tp                                        15
+#define CNFG_tx_Cnfg_Dp                                        16
+#define CNFG_tx_Cnfg_Bpn                               17
+#define CNFG_tx_Cnfg_FramingMode                       18
+#define CNFG_tx_Cnfg_MSGLp                             19
+#define CNFG_tx_Cnfg_MSGc                              20
+
+////////////////
+// Rx Config ///
+////////////////
+#define CNFG_rx_Cnfg_Nbc                               21
+#define CNFG_rx_Cnfg_Nlp                               22
+#define CNFG_rx_Cnfg_Rp                                        23
+#define CNFG_rx_Cnfg_Mp                                        24
+#define CNFG_rx_Cnfg_Lp                                        25
+#define CNFG_rx_Cnfg_Tp                                        26
+#define CNFG_rx_Cnfg_Dp                                        27
+#define CNFG_rx_Cnfg_Bpn                               28
+#define CNFG_rx_Cnfg_FramingMode                       29
+#define CNFG_rx_Cnfg_MSGLp                             30
+#define CNFG_rx_Cnfg_MSGc                              31
+
+#define CNFG_tx_Cnfg_BCnToLPp                          32
+#define CNFG_rx_Cnfg_BCnToLPp                          33
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_linux.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_mei_linux.h
new file mode 100644 (file)
index 0000000..79849ae
--- /dev/null
@@ -0,0 +1,112 @@
+/******************************************************************************
+**
+** FILE NAME    : ifxmips_mei_linux.h
+** PROJECT      : Danube
+** MODULES      : MEI
+**
+** DATE         : 1 Jan 2006
+** AUTHOR       : TC Chen
+** DESCRIPTION  : MEI Driver
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    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.
+**
+** HISTORY
+** $Version $Date      $Author     $Comment
+*******************************************************************************/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <asm/semaphore.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+
+#undef CONFIG_DEVFS_FS         //165204:henryhsu devfs will make mei open file fail.
+
+#ifdef CONFIG_DEVFS_FS
+#include <linux/devfs_fs_kernel.h>
+#endif
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif
+
+#include <linux/list.h>
+#include <linux/delay.h>
+#define __LINUX__
+
+#ifdef CONFIG_PROC_FS
+#define PROC_ITEMS 8
+#define MEI_DIRNAME     "mei"
+#endif
+
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+#include <asm/ifxmips/ifxmips_mei.h>
+#include <asm/ifxmips/ifxmips_mei_app.h>
+#include <asm/ifxmips/ifxmips_mei_ioctl.h>
+#include <asm/ifxmips/ifxmips_mei_app_ioctl.h>
+#include <asm/ifxmips/ifxmips_gpio.h>
+#include <asm/ifxmips/ifxmips_led.h>
+#include <asm/ifxmips/ifxmips_irq.h>
+
+#ifdef CONFIG_DEVFS_FS
+#define IFXMIPS_DEVNAME  "ifxmips"
+#endif //ifdef CONFIG_DEVFS_FS
+
+#define MEI_LOCKINT(var) \
+        local_save_flags(var);\
+        local_irq_disable()
+#define MEI_UNLOCKINT(var) \
+        local_irq_restore(var)
+
+#define MEI_MUTEX_INIT(id,flag) \
+        sema_init(&id,flag)
+#define MEI_MUTEX_LOCK(id) \
+        down_interruptible(&id)
+#define MEI_MUTEX_UNLOCK(id) \
+        up(&id)
+
+#define MEI_MASK_AND_ACK_IRQ \
+        ifxmips_mask_and_ack_irq
+
+#define MEI_DISABLE_IRQ \
+        disable_irq
+#define MEI_ENABLE_IRQ \
+        enable_irq
+
+#define MEI_WAIT(ms) \
+        {\
+                set_current_state(TASK_INTERRUPTIBLE);\
+                schedule_timeout(ms);\
+        }
+
+#define MEI_INIT_WAKELIST(name,queue) \
+        init_waitqueue_head(&queue)
+
+#define MEI_WAIT_EVENT_TIMEOUT(ev,timeout)\
+        interruptible_sleep_on_timeout(&ev,timeout)
+
+#define MEI_WAIT_EVENT(ev)\
+        interruptible_sleep_on(&ev)
+#define MEI_WAKEUP_EVENT(ev)\
+        wake_up_interruptible(&ev)
+
+typedef unsigned long MEI_intstat_t;
+typedef struct semaphore MEI_mutex_t;
+typedef struct file MEI_file_t;
+typedef struct inode MEI_inode_t;
+
+extern void mask_and_ack_ifxmips_irq (unsigned int irq_nr);
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_pmu.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_pmu.h
new file mode 100644 (file)
index 0000000..b842734
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ */
+#ifndef _IFXMIPS_PMU_H__
+#define _IFXMIPS_PMU_H__
+
+#define IFXMIPS_PMU_PWDCR_DMA    0x20
+#define IFXMIPS_PMU_PWDCR_LED    0x800
+#define IFXMIPS_PMU_PWDCR_GPT    0x1000
+#define IFXMIPS_PMU_PWDCR_PPE    0x2000
+#define IFXMIPS_PMU_PWDCR_FPI    0x4000
+
+void ifxmips_pmu_enable (unsigned int module);
+void ifxmips_pmu_disable (unsigned int module);
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_prom.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips_prom.h
new file mode 100644 (file)
index 0000000..822ff0b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *   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.
+ *
+ *   Copyright (C) 2008 John Crispin <blogic@openwrt.org> 
+ */
+#ifndef _IFXPROM_H__
+#define _IFXPROM_H__
+
+extern void prom_printf(const char * fmt, ...);
+extern u32 *prom_get_cp1_base(void);
+extern u32 prom_get_cp1_size(void);
+extern int ifxmips_has_brn_block(void);
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/gpio.h b/target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/gpio.h
new file mode 100644 (file)
index 0000000..0dece37
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *   include/asm-mips/mach-ifxmips/gpio.h 
+ *
+ *   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.
+ *
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ *
+ */
+
+
+#ifndef _IFXMIPS_GPIO_H_
+#define _IFXMIPS_GPIO_H_
+
+#include <asm/ifxmips/ifxmips.h>
+#include <asm/ifxmips/ifxmips_gpio.h>
+
+#define GPIO_TO_PORT(x) ((x > 15)?(1):(0))
+#define GPIO_TO_GPIO(x) ((x > 15)?(x-16):(x))
+
+static inline int gpio_direction_input(unsigned gpio) {
+       ifxmips_port_set_open_drain(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_clear_altsel0(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+    ifxmips_port_clear_altsel1(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_set_dir_in(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       return 0;
+}
+
+static inline int gpio_direction_output(unsigned gpio, int value) {
+       ifxmips_port_clear_open_drain(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_clear_altsel0(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_clear_altsel1(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_set_dir_out(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       return 0;
+}
+
+static inline int gpio_get_value(unsigned gpio) {
+       ifxmips_port_get_input(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       return 0;
+}
+
+static inline void gpio_set_value(unsigned gpio, int value) {
+       if(value)
+               ifxmips_port_set_output(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       else
+               ifxmips_port_clear_output(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+}
+
+static inline int gpio_request(unsigned gpio, const char *label) {
+       return 0;
+}
+
+static inline void gpio_free(unsigned gpio) {
+}
+
+static inline int gpio_to_irq(unsigned gpio) {
+       return 0;
+}
+
+static inline int irq_to_gpio(unsigned irq) {
+       return 0;
+}
+
+static inline int gpio_cansleep(unsigned gpio) {
+        return 0;
+}
+
+static inline int gpio_get_value_cansleep(unsigned gpio) {
+        might_sleep();
+        return gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value_cansleep(unsigned gpio, int value) {
+        might_sleep();
+        gpio_set_value(gpio, value);
+}
+
+static inline int gpio_is_valid(int number)
+{
+       return ((unsigned)number) < 8;
+}
+
+#endif
diff --git a/target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/irq.h b/target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/irq.h
new file mode 100644 (file)
index 0000000..f178abf
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *   include/asm-mips/mach-ifxmips/irq.h 
+ *
+ *   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.
+ *
+ *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
+ *
+ */
+
+#ifndef __IFXMIPS_IRQ_H
+#define __IFXMIPS_IRQ_H
+
+#define NR_IRQS    256
+#include_next <irq.h>
+
+#endif
+
diff --git a/target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/war.h b/target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/war.h
new file mode 100644 (file)
index 0000000..de3584e
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#ifndef __ASM_MIPS_MACH_IFXMIPS_WAR_H
+#define __ASM_MIPS_MACH_IFXMIPS_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR     0
+#define R4600_V1_HIT_CACHEOP_WAR        0
+#define R4600_V2_HIT_CACHEOP_WAR        0
+#define R5432_CP0_INTERRUPT_WAR         0
+#define BCM1250_M3_WAR                  0
+#define SIBYTE_1956_WAR                 0
+#define MIPS4K_ICACHE_REFILL_WAR        0
+#define MIPS_CACHE_SYNC_WAR             0
+#define TX49XX_ICACHE_INDEX_INV_WAR     0
+#define RM9000_CDEX_SMP_WAR             0
+#define ICACHE_REFILLS_WORKAROUND_WAR   0
+#define R10000_LLSC_WAR                 0
+#define MIPS34K_MISSED_ITLB_WAR         0
+
+#endif
diff --git a/target/linux/ifxmips/image/Makefile b/target/linux/ifxmips/image/Makefile
new file mode 100644 (file)
index 0000000..15e0bc5
--- /dev/null
@@ -0,0 +1,34 @@
+# 
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+define Image/BuildKernel
+       $(STAGING_DIR_HOST)/bin/lzma e $(KDIR)/vmlinux $(KDIR)/vmlinux.lzma
+       mkimage -A mips -O linux -T kernel -a 0x80002000 -C lzma -e \
+               0x80002000 \
+               -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)' \
+               -d $(KDIR)/vmlinux.lzma $(KDIR)/uImage
+
+       cp $(KDIR)/uImage $(BIN_DIR)/openwrt-$(BOARD)-uImage
+endef
+
+define Image/Build/squashfs
+       cat $(KDIR)/uImage $(KDIR)/root.$(1) > $(BIN_DIR)/openwrt-$(BOARD)-$(1).image
+       $(call prepare_generic_squashfs,$(BIN_DIR)/openwrt-$(BOARD)-$(1).image)
+endef
+
+define Image/Build/jffs2-64k
+       dd if=$(KDIR)/uImage of=$(KDIR)/uImage.$(1) bs=64k conv=sync
+       cat $(KDIR)/uImage.$(1) $(KDIR)/root.$(1) > $(BIN_DIR)/openwrt-$(BOARD)-$(1).image
+endef
+
+define Image/Build
+       $(call Image/Build/$(1),$(1))
+endef
+
+$(eval $(call BuildImage))
diff --git a/target/linux/ifxmips/patches/100-board.patch b/target/linux/ifxmips/patches/100-board.patch
new file mode 100644 (file)
index 0000000..db43c90
--- /dev/null
@@ -0,0 +1,80 @@
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -78,6 +78,21 @@
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select GENERIC_HARDIRQS_NO__DO_IRQ
++config IFXMIPS
++      bool "Infineon Twinpass, Danube, Amazon-SE"
++      select DMA_NONCOHERENT
++      select IRQ_CPU
++      select CEVT_R4K
++      select CSRC_R4K
++      select SYS_HAS_CPU_MIPS32_R1
++      select HAVE_STD_PC_SERIAL_PORT
++      select SYS_SUPPORTS_BIG_ENDIAN
++      select SYS_SUPPORTS_32BIT_KERNEL
++      select SYS_HAS_EARLY_PRINTK
++      select HW_HAS_PCI
++      select GENERIC_GPIO
++      select SWAP_IO_SPACE
++
+ config MACH_DECSTATION
+       bool "DECstations"
+       select BOOT_ELF32
+@@ -697,6 +712,7 @@
+ source "arch/mips/tx4927/Kconfig"
+ source "arch/mips/tx4938/Kconfig"
+ source "arch/mips/vr41xx/Kconfig"
++source "arch/mips/ifxmips/Kconfig"
+ endmenu
+--- a/arch/mips/Makefile
++++ b/arch/mips/Makefile
+@@ -283,6 +283,13 @@
+ load-$(CONFIG_MIPS_COBALT)    += 0xffffffff80080000
+ #
++# Infineon IFXMIPS
++#
++core-$(CONFIG_IFXMIPS) += arch/mips/ifxmips/
++cflags-$(CONFIG_IFXMIPS)   += -Iinclude/asm-mips/mach-ifxmips
++load-$(CONFIG_IFXMIPS) += 0xffffffff80002000
++
++#
+ # DECstation family
+ #
+ core-$(CONFIG_MACH_DECSTATION)        += arch/mips/dec/
+--- a/include/asm-mips/bootinfo.h
++++ b/include/asm-mips/bootinfo.h
+@@ -94,6 +94,12 @@
+ #define MACH_MSP7120_FPGA       5     /* PMC-Sierra MSP7120 Emulation */
+ #define MACH_MSP_OTHER        255     /* PMC-Sierra unknown board type */
++/*
++ * Valid machtype for group IFXMIPS
++ */
++#define MACH_GROUP_IFXMIPS     29
++#define MACH_INFINEON_IFXMIPS  0
++
+ #define CL_SIZE                       COMMAND_LINE_SIZE
+ extern char *system_type;
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -1464,6 +1464,7 @@
+        */
+       if (cpu_has_mips_r2) {
+               cp0_compare_irq = (read_c0_intctl() >> 29) & 7;
++              cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
+               cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7;
+               if (cp0_perfcount_irq == cp0_compare_irq)
+                       cp0_perfcount_irq = -1;
+--- a/arch/mips/pci/Makefile
++++ b/arch/mips/pci/Makefile
+@@ -48,3 +48,4 @@
+ obj-$(CONFIG_VICTOR_MPC30X)   += fixup-mpc30x.o
+ obj-$(CONFIG_ZAO_CAPCELLA)    += fixup-capcella.o
+ obj-$(CONFIG_WR_PPMC)         += fixup-wrppmc.o
++obj-$(CONFIG_IFXMIPS)         += pci-ifxmips.o ops-ifxmips.o
diff --git a/target/linux/ifxmips/patches/110-drivers.patch b/target/linux/ifxmips/patches/110-drivers.patch
new file mode 100644 (file)
index 0000000..a25c570
--- /dev/null
@@ -0,0 +1,149 @@
+--- a/drivers/char/Makefile
++++ b/drivers/char/Makefile
+@@ -114,6 +114,10 @@
+ obj-$(CONFIG_JS_RTC)          += js-rtc.o
+ js-rtc-y = rtc.o
++obj-$(CONFIG_IFXMIPS_SSC)  += ifxmips_ssc.o
++obj-$(CONFIG_IFXMIPS_EEPROM)   += ifxmips_eeprom.o
++obj-$(CONFIG_IFXMIPS_MEI)  += ifxmips_mei_core.o
++
+ # Files generated that shall be removed upon make clean
+ clean-files := consolemap_deftbl.c defkeymap.c
+--- a/drivers/mtd/maps/Makefile
++++ b/drivers/mtd/maps/Makefile
+@@ -67,3 +67,4 @@
+ obj-$(CONFIG_MTD_OMAP_NOR)    += omap_nor.o
+ obj-$(CONFIG_MTD_MTX1)                += mtx-1_flash.o
+ obj-$(CONFIG_MTD_INTEL_VR_NOR)        += intel_vr_nor.o
++obj-$(CONFIG_MTD_IFXMIPS)  += ifxmips.o
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -351,6 +351,12 @@
+ source "drivers/net/arm/Kconfig"
++config IFXMIPS_MII0
++      tristate "Infineon IFXMips eth0 driver"
++      depends on IFXMIPS
++      help
++        Support for the MII0 inside the IFXMips SOC
++
+ config AX88796
+       tristate "ASIX AX88796 NE2000 clone support"
+       depends on ARM || MIPS || SUPERH
+--- a/drivers/serial/Kconfig
++++ b/drivers/serial/Kconfig
+@@ -1334,6 +1334,14 @@
+         Currently, only 8250 compatible ports are supported, but
+         others can easily be added.
++config SERIAL_IFXMIPS
++      bool "IFXMips serial driver"
++      depends on IFXMIPS
++      select SERIAL_CORE
++      select SERIAL_CORE_CONSOLE
++      help
++        Driver for the ifxmipss built in ASC hardware
++
+ config SERIAL_QE
+       tristate "Freescale QUICC Engine serial port support"
+       depends on QUICC_ENGINE
+--- a/drivers/serial/Makefile
++++ b/drivers/serial/Makefile
+@@ -68,3 +68,4 @@
+ obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
+ obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
+ obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
++obj-$(CONFIG_SERIAL_IFXMIPS) += ifxmips_asc.o
+--- a/drivers/watchdog/Makefile
++++ b/drivers/watchdog/Makefile
+@@ -97,6 +97,7 @@
+ obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
+ obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
+ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
++obj-$(CONFIG_IFXMIPS_WDT) += ifxmips_wdt.o
+ # PARISC Architecture
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -256,4 +256,4 @@
+ obj-$(CONFIG_NIU) += niu.o
+ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
+ obj-$(CONFIG_SFC) += sfc/
+-
++obj-$(CONFIG_IFXMIPS_MII0) += ifxmips_mii0.o
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -9,6 +9,9 @@
+         If you say N, all options in this submenu will be skipped and disabled.
+ if CRYPTO_HW
++config CRYPTO_DEV_IFXMIPS
++      tristate "Support for IFXMIPS Data Encryption Unit"
++      depends on IFXMIPS
+ config CRYPTO_DEV_PADLOCK
+       tristate "Support for VIA PadLock ACE"
+--- a/drivers/crypto/Makefile
++++ b/drivers/crypto/Makefile
+@@ -4,3 +4,4 @@
+ obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
+ obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
+ obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
++obj-$(CONFIG_CRYPTO_DEV_IFXMIPS) += ifxdeu-aes.o ifxdeu-des.o ifxdeu-dma.o ifxdeu-generic.o ifxdeu-md5.o ifxdeu-sha1.o
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -305,3 +305,10 @@
+       help
+          This driver enables support for the on-chip R8A66597 in the
+          SH7366 and SH7723 processors.
++
++config USB_DWC_HCD
++      tristate "IFXMIPS USB Host Controller Driver"
++      depends on USB && IFXMIPS 
++      default y
++      help
++       Danube USB Host Controller
+--- a/drivers/leds/Kconfig
++++ b/drivers/leds/Kconfig
+@@ -153,6 +153,12 @@
+         To compile this driver as a module, choose M here: the
+         module will be called leds-clevo-mail.
++config LEDS_IFXMIPS
++      tristate "LED Support for IFXMIPS  LEDs"
++      depends on LEDS_CLASS && IFXMIPS
++      help
++        This option enables support for the CM-X270 LEDs.
++
+ comment "LED Triggers"
+ config LEDS_TRIGGERS
+--- a/drivers/leds/Makefile
++++ b/drivers/leds/Makefile
+@@ -22,6 +22,7 @@
+ obj-$(CONFIG_LEDS_CLEVO_MAIL)         += leds-clevo-mail.o
+ obj-$(CONFIG_LEDS_HP6XX)              += leds-hp6xx.o
+ obj-$(CONFIG_LEDS_FSG)                        += leds-fsg.o
++obj-$(CONFIG_LEDS_IFXMIPS)            += leds-ifxmips.o
+ # LED Triggers
+ obj-$(CONFIG_LEDS_TRIGGER_TIMER)      += ledtrig-timer.o
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -683,6 +683,12 @@
+       help
+         Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs.
++config IFXMIPS_WDT
++      bool "IFXMips watchdog"
++      depends on IFXMIPS
++      help
++        Hardware driver for the IFXMIPS Watchdog Timer.
++
+ # PARISC Architecture
+ # POWERPC Architecture
diff --git a/target/linux/ifxmips/patches/160-cfi-swap.patch b/target/linux/ifxmips/patches/160-cfi-swap.patch
new file mode 100644 (file)
index 0000000..7649ec1
--- /dev/null
@@ -0,0 +1,13 @@
+--- a/drivers/mtd/chips/cfi_cmdset_0002.c
++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
+@@ -1041,7 +1041,9 @@
+       int retry_cnt = 0;
+       adr += chip->start;
+-
++#ifdef CONFIG_IFXMIPS
++      adr ^= 2;
++#endif
+       spin_lock(chip->mutex);
+       ret = get_chip(map, chip, adr, FL_WRITING);
+       if (ret) {
diff --git a/target/linux/ifxmips/patches/170-dma_hack.patch b/target/linux/ifxmips/patches/170-dma_hack.patch
new file mode 100644 (file)
index 0000000..38c58bb
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/arch/mips/mm/cache.c
++++ b/arch/mips/mm/cache.c
+@@ -50,6 +50,8 @@
+ void (*_dma_cache_inv)(unsigned long start, unsigned long size);
+ EXPORT_SYMBOL(_dma_cache_wback_inv);
++EXPORT_SYMBOL(_dma_cache_wback);
++EXPORT_SYMBOL(_dma_cache_inv);
+ #endif /* CONFIG_DMA_NONCOHERENT */
diff --git a/target/linux/ifxmips/profiles/100-Atheros.mk b/target/linux/ifxmips/profiles/100-Atheros.mk
new file mode 100644 (file)
index 0000000..71804b2
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/Atheros
+  NAME:=Atheros WiFi (default)
+  PACKAGES:=kmod-madwifi
+endef
+
+define Profile/Atheros/Description
+       Package set compatible with hardware using Atheros WiFi cards
+endef
+$(eval $(call Profile,Atheros))
+
diff --git a/target/linux/ifxmips/profiles/200-Ralink.mk b/target/linux/ifxmips/profiles/200-Ralink.mk
new file mode 100644 (file)
index 0000000..dd9716a
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/Ralink
+  NAME:=Ralink RT61 Wifi (ARV452)
+  PACKAGES:=kmod-rt61-pci
+endef
+
+define Profile/Ralink/Description
+       Package set compatible with hardware using Ralink WiFi cards
+endef
+$(eval $(call Profile,Ralink))
+
diff --git a/target/linux/ifxmips/series b/target/linux/ifxmips/series
new file mode 100644 (file)
index 0000000..19bcf21
--- /dev/null
@@ -0,0 +1,88 @@
+Makefile
+base-files/etc/config/network
+config-2.6.23
+files/arch/mips/danube/Kconfig
+files/arch/mips/danube/Makefile
+files/arch/mips/danube/built-in.o
+files/arch/mips/danube/dma-core.c
+files/arch/mips/danube/dma-core.h
+files/arch/mips/danube/dma-core.o
+files/arch/mips/danube/interrupt.c
+files/arch/mips/danube/interrupt.o
+files/arch/mips/danube/kgdb_serial.c
+files/arch/mips/danube/pci.c
+files/arch/mips/danube/prom.c
+files/arch/mips/danube/prom.o
+files/arch/mips/danube/reset.c
+files/arch/mips/danube/reset.o
+files/arch/mips/danube/setup.c
+files/arch/mips/danube/setup.o
+files/drivers/mtd/maps/danube.c
+files/drivers/serial/danube_asc.c
+files/drivers/serial/danube_asc.c~
+files/drivers/serial/danube_asc.o
+files/include/asm-mips/danube/adm6996.h
+files/include/asm-mips/danube/atm_mib.h
+files/include/asm-mips/danube/danube.h
+files/include/asm-mips/danube/danube_bcu.h
+files/include/asm-mips/danube/danube_cgu.h
+files/include/asm-mips/danube/danube_deu.h
+files/include/asm-mips/danube/danube_deu_structs.h
+files/include/asm-mips/danube/danube_dma.h
+files/include/asm-mips/danube/danube_eth2.h
+files/include/asm-mips/danube/danube_eth2_fw.h
+files/include/asm-mips/danube/danube_eth2_fw_with_dplus.h
+files/include/asm-mips/danube/danube_eth2_fw_with_dplus_sb.h
+files/include/asm-mips/danube/danube_eth_d2.h
+files/include/asm-mips/danube/danube_eth_fw_d2.h
+files/include/asm-mips/danube/danube_gpio.h
+files/include/asm-mips/danube/danube_gptu.h
+files/include/asm-mips/danube/danube_icu.h
+files/include/asm-mips/danube/danube_led.h
+files/include/asm-mips/danube/danube_mei.h
+files/include/asm-mips/danube/danube_mei_app.h
+files/include/asm-mips/danube/danube_mei_app_ioctl.h
+files/include/asm-mips/danube/danube_mei_bsp.h
+files/include/asm-mips/danube/danube_mei_ioctl.h
+files/include/asm-mips/danube/danube_mei_linux.h
+files/include/asm-mips/danube/danube_misc.h
+files/include/asm-mips/danube/danube_pmu.h
+files/include/asm-mips/danube/danube_ppa_api.h
+files/include/asm-mips/danube/danube_ppa_eth_fw_d2.h
+files/include/asm-mips/danube/danube_ppa_eth_fw_d3.h
+files/include/asm-mips/danube/danube_ppa_hook.h
+files/include/asm-mips/danube/danube_ppa_ppe_d3_hal.h
+files/include/asm-mips/danube/danube_ppa_ppe_hal.h
+files/include/asm-mips/danube/danube_ppa_stack_al.h
+files/include/asm-mips/danube/danube_ppe.h
+files/include/asm-mips/danube/danube_ppe_fw.h
+files/include/asm-mips/danube/danube_ppe_fw_fix_for_pci.h
+files/include/asm-mips/danube/danube_rcu.h
+files/include/asm-mips/danube/danube_sdio_controller.h
+files/include/asm-mips/danube/danube_sdio_controller_registers.h
+files/include/asm-mips/danube/danube_ssc.h
+files/include/asm-mips/danube/danube_sw.h
+files/include/asm-mips/danube/danube_wdt.h
+files/include/asm-mips/danube/danube_ws.h
+files/include/asm-mips/danube/emulation.h
+files/include/asm-mips/danube/ifx_mps.h
+files/include/asm-mips/danube/ifx_peripheral_definitions.h
+files/include/asm-mips/danube/ifx_sd_card.h
+files/include/asm-mips/danube/ifx_serial.h
+files/include/asm-mips/danube/ifx_ssc.h
+files/include/asm-mips/danube/ifx_ssc_defines.h
+files/include/asm-mips/danube/ifx_types.h
+files/include/asm-mips/danube/infineon_sdio.h
+files/include/asm-mips/danube/infineon_sdio_card.h
+files/include/asm-mips/danube/infineon_sdio_cmds.h
+files/include/asm-mips/danube/infineon_sdio_controller.h
+files/include/asm-mips/danube/irq.h
+files/include/asm-mips/danube/memcopy.h
+files/include/asm-mips/danube/mps.h
+files/include/asm-mips/danube/port.h
+files/include/asm-mips/danube/ppe.h
+files/include/asm-mips/danube/serial.h
+files/include/asm-mips/mach-danube/irq.h
+image/Makefile
+patches/100-board.patch
+patches/110-drivers.patch
diff --git a/target/linux/ifxmips/wget-log b/target/linux/ifxmips/wget-log
new file mode 100644 (file)
index 0000000..83f0d55
--- /dev/null
@@ -0,0 +1,25 @@
+HTTP request sent, awaiting response... 200 OK
+Length: 49450713 (47M) [application/x-tar]
+Saving to: `STDOUT'
+
+
+
+2008-09-28 21:04:13 (10.2 KB/s) - Read error at byte 519095/49450713 (Connection timed out). Retrying.
+
+--2008-09-28 21:04:14--  (try: 2)  http://ftp.de.kernel.org/pub/linux/kernel/v2.6/linux-2.6.26.5.tar.bz2
+Connecting to ftp.de.kernel.org|195.71.9.196|:80... connected.
+HTTP request sent, awaiting response... 206 Partial Content
+Length: 49450713 (47M), 48931618 (47M) remaining [application/x-tar]
+Saving to: `STDOUT'
+
+
+
+2008-09-28 21:06:22 (12.7 KB/s) - Read error at byte 2177730/49450713 (Connection timed out). Retrying.
+
+--2008-09-28 21:06:24--  (try: 3)  http://ftp.de.kernel.org/pub/linux/kernel/v2.6/linux-2.6.26.5.tar.bz2
+Connecting to ftp.de.kernel.org|195.71.9.196|:80... connected.
+HTTP request sent, awaiting response... 206 Partial Content
+Length: 49450713 (47M), 47272983 (45M) remaining [application/x-tar]
+Saving to: `STDOUT'
+
+\r 5% [++                                                  ] 2,836,764   16.7K/s  eta 1h 55m  \r 5% [++                                                  ] 2,836,764   15.5K/s  eta 1h 55m  \r 5% [++                                                  ] 2,836,764   14.4K/s  eta 1h 57m  \r 5% [++                                                  ] 2,836,764   --.-K/s  eta 1h 57m  \r 5% [++                                                  ] 2,836,764   --.-K/s  eta 1h 59m  \r 5% [++                                                  ] 2,836,764   --.-K/s  eta 1h 59m  \r 5% [++                                                  ] 2,836,764   --.-K/s  eta 2h 2m   
\ No newline at end of file