From 1cee0bf2050fcf06a0794e6f360399fcae909cd4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 1 Jul 2007 21:41:40 +0000 Subject: [PATCH] 7.07 will add support for avr32, amcc and adm5120 targets SVN-Revision: 7839 --- target/linux/adm5120-2.6/Makefile | 27 + .../base-files/default/sbin/wget2nand | 72 + target/linux/adm5120-2.6/config/default | 283 + .../files/arch/mips/adm5120/Kconfig | 16 + .../files/arch/mips/adm5120/Makefile | 9 + .../files/arch/mips/adm5120/adm5120_info.c | 1119 ++ .../files/arch/mips/adm5120/gpio.c | 357 + .../adm5120-2.6/files/arch/mips/adm5120/irq.c | 203 + .../files/arch/mips/adm5120/memory.c | 90 + .../files/arch/mips/adm5120/prom.c | 126 + .../files/arch/mips/adm5120/setup.c | 91 + .../files/arch/mips/adm5120/time.c | 54 + .../files/arch/mips/pci/fixup-adm5120.c | 177 + .../files/arch/mips/pci/ops-adm5120.c | 134 + .../files/arch/mips/pci/pci-adm5120.c | 80 + .../files/drivers/leds/leds-adm5120.c | 328 + .../files/drivers/leds/leds-gpio.c | 209 + .../files/drivers/mtd/maps/adm5120_mtd.c | 493 + .../adm5120-2.6/files/drivers/mtd/myloader.c | 176 + .../files/drivers/mtd/nand/rbmipsnand.c | 122 + .../adm5120-2.6/files/drivers/net/adm5120sw.c | 541 + .../adm5120-2.6/files/drivers/net/adm5120sw.h | 109 + .../files/drivers/serial/adm5120_uart.c | 520 + .../files/drivers/usb/host/adm5120-hcd.c | 848 ++ .../asm-mips/mach-adm5120/adm5120_defs.h | 60 + .../asm-mips/mach-adm5120/adm5120_info.h | 88 + .../asm-mips/mach-adm5120/adm5120_intc.h | 73 + .../asm-mips/mach-adm5120/adm5120_irq.h | 55 + .../asm-mips/mach-adm5120/adm5120_mpmc.h | 87 + .../asm-mips/mach-adm5120/adm5120_switch.h | 148 + .../include/asm-mips/mach-adm5120/gpio.h | 109 + .../include/asm-mips/mach-adm5120/myloader.h | 167 + .../asm-mips/mach-adm5120/routerboot.h | 123 + .../include/asm-mips/mach-adm5120/zynos.h | 78 + .../files/include/linux/gpio_leds.h | 37 + target/linux/adm5120-2.6/image/Makefile | 163 + .../adm5120-2.6/image/lzma-loader/Makefile | 63 + .../image/lzma-loader/src/LzmaDecode.c | 663 + .../image/lzma-loader/src/LzmaDecode.h | 100 + .../image/lzma-loader/src/Makefile | 98 + .../adm5120-2.6/image/lzma-loader/src/README | 55 + .../adm5120-2.6/image/lzma-loader/src/board.c | 184 + .../image/lzma-loader/src/config.h | 83 + .../image/lzma-loader/src/decompress.c | 329 + .../adm5120-2.6/image/lzma-loader/src/head.S | 209 + .../image/lzma-loader/src/loader.lds | 29 + .../image/lzma-loader/src/lzma-data.lds | 8 + .../patches-2.6.22/001-adm5120.patch | 111 + .../patches-2.6.22/002-adm5120_flash.patch | 27 + .../patches-2.6.22/003-adm5120_switch.patch | 27 + .../patches-2.6.22/004-adm5120_uart.patch | 53 + .../patches-2.6.22/005-adm5120_usb.patch | 232 + .../patches-2.6.22/006-adm5120_leds.patch | 45 + .../patches-2.6.22/007-adm5120_pci.patch | 23 + .../008-adm5120_hardware_swab.patch | 40 + .../100-mtd-myloder-partition-parser.patch | 39 + .../101-cfi-fixup-macronix-bootloc.patch | 87 + .../patches-2.6.22/140-cmdline_hack.patch | 26 + .../adm5120-2.6/patches-2.6.22/500-Nand.patch | 29 + .../adm5120-2.6/patches/001-adm5120.patch | 111 + .../patches/002-adm5120_flash.patch | 27 + .../patches/003-adm5120_switch.patch | 27 + .../patches/004-adm5120_uart.patch | 53 + .../adm5120-2.6/patches/005-adm5120_usb.patch | 58 + .../patches/006-adm5120_leds.patch | 45 + .../adm5120-2.6/patches/007-adm5120_pci.patch | 23 + .../patches/008-adm5120_hardware_swab.patch | 38 + .../100-mtd-myloder-partition-parser.patch | 39 + .../101-cfi-fixup-macronix-bootloc.patch | 87 + .../patches/140-cmdline_hack.patch | 26 + .../linux/adm5120-2.6/patches/500-Nand.patch | 29 + .../linux/adm5120-2.6/profiles/100-Atheros.mk | 17 + .../linux/adm5120-2.6/profiles/105-Texas.mk | 17 + .../linux/adm5120-2.6/profiles/110-Ralink.mk | 16 + target/linux/adm5120-2.6/profiles/200-None.mk | 17 + .../linux/adm5120-2.6/profiles/Cellvision.mk | 16 + target/linux/adm5120-2.6/profiles/RB1xx.mk | 17 + target/linux/amcc-2.6/Makefile | 25 + .../amcc-2.6/base-files/default/etc/inittab | 5 + target/linux/amcc-2.6/config/default | 173 + target/linux/amcc-2.6/image/Makefile | 37 + .../amcc-2.6/patches/100-taishan_emac.patch | 71 + .../patches/110-openwrt_mtd_mapping.patch | 29 + .../patches/120-uncompressed_uImage.patch | 17 + target/linux/avr32-2.6/Makefile | 27 + target/linux/avr32-2.6/config/default | 89 + target/linux/avr32-2.6/image/Makefile | 37 + .../avr32-2.6/patches/100-git_sync.patch | 11252 ++++++++++++++++ .../patches/110-openwrt_flashmap.patch | 20 + 89 files changed, 22377 insertions(+) create mode 100644 target/linux/adm5120-2.6/Makefile create mode 100755 target/linux/adm5120-2.6/base-files/default/sbin/wget2nand create mode 100644 target/linux/adm5120-2.6/config/default create mode 100644 target/linux/adm5120-2.6/files/arch/mips/adm5120/Kconfig create mode 100644 target/linux/adm5120-2.6/files/arch/mips/adm5120/Makefile create mode 100644 target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c create mode 100644 target/linux/adm5120-2.6/files/arch/mips/adm5120/gpio.c create mode 100644 target/linux/adm5120-2.6/files/arch/mips/adm5120/irq.c create mode 100644 target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c create mode 100644 target/linux/adm5120-2.6/files/arch/mips/adm5120/prom.c create mode 100644 target/linux/adm5120-2.6/files/arch/mips/adm5120/setup.c create mode 100644 target/linux/adm5120-2.6/files/arch/mips/adm5120/time.c create mode 100644 target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c create mode 100644 target/linux/adm5120-2.6/files/arch/mips/pci/ops-adm5120.c create mode 100644 target/linux/adm5120-2.6/files/arch/mips/pci/pci-adm5120.c create mode 100644 target/linux/adm5120-2.6/files/drivers/leds/leds-adm5120.c create mode 100755 target/linux/adm5120-2.6/files/drivers/leds/leds-gpio.c create mode 100644 target/linux/adm5120-2.6/files/drivers/mtd/maps/adm5120_mtd.c create mode 100644 target/linux/adm5120-2.6/files/drivers/mtd/myloader.c create mode 100644 target/linux/adm5120-2.6/files/drivers/mtd/nand/rbmipsnand.c create mode 100644 target/linux/adm5120-2.6/files/drivers/net/adm5120sw.c create mode 100644 target/linux/adm5120-2.6/files/drivers/net/adm5120sw.h create mode 100644 target/linux/adm5120-2.6/files/drivers/serial/adm5120_uart.c create mode 100644 target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_defs.h create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_intc.h create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_irq.h create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_mpmc.h create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_switch.h create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/gpio.h create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/myloader.h create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/routerboot.h create mode 100644 target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/zynos.h create mode 100644 target/linux/adm5120-2.6/files/include/linux/gpio_leds.h create mode 100644 target/linux/adm5120-2.6/image/Makefile create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/Makefile create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/LzmaDecode.c create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/LzmaDecode.h create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/Makefile create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/README create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/board.c create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/config.h create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/decompress.c create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/head.S create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/loader.lds create mode 100644 target/linux/adm5120-2.6/image/lzma-loader/src/lzma-data.lds create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/001-adm5120.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/002-adm5120_flash.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/003-adm5120_switch.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/004-adm5120_uart.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/005-adm5120_usb.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/006-adm5120_leds.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/007-adm5120_pci.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/008-adm5120_hardware_swab.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/100-mtd-myloder-partition-parser.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/101-cfi-fixup-macronix-bootloc.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/140-cmdline_hack.patch create mode 100644 target/linux/adm5120-2.6/patches-2.6.22/500-Nand.patch create mode 100644 target/linux/adm5120-2.6/patches/001-adm5120.patch create mode 100644 target/linux/adm5120-2.6/patches/002-adm5120_flash.patch create mode 100644 target/linux/adm5120-2.6/patches/003-adm5120_switch.patch create mode 100644 target/linux/adm5120-2.6/patches/004-adm5120_uart.patch create mode 100644 target/linux/adm5120-2.6/patches/005-adm5120_usb.patch create mode 100644 target/linux/adm5120-2.6/patches/006-adm5120_leds.patch create mode 100644 target/linux/adm5120-2.6/patches/007-adm5120_pci.patch create mode 100644 target/linux/adm5120-2.6/patches/008-adm5120_hardware_swab.patch create mode 100644 target/linux/adm5120-2.6/patches/100-mtd-myloder-partition-parser.patch create mode 100644 target/linux/adm5120-2.6/patches/101-cfi-fixup-macronix-bootloc.patch create mode 100644 target/linux/adm5120-2.6/patches/140-cmdline_hack.patch create mode 100644 target/linux/adm5120-2.6/patches/500-Nand.patch create mode 100644 target/linux/adm5120-2.6/profiles/100-Atheros.mk create mode 100644 target/linux/adm5120-2.6/profiles/105-Texas.mk create mode 100644 target/linux/adm5120-2.6/profiles/110-Ralink.mk create mode 100644 target/linux/adm5120-2.6/profiles/200-None.mk create mode 100644 target/linux/adm5120-2.6/profiles/Cellvision.mk create mode 100644 target/linux/adm5120-2.6/profiles/RB1xx.mk create mode 100644 target/linux/amcc-2.6/Makefile create mode 100644 target/linux/amcc-2.6/base-files/default/etc/inittab create mode 100644 target/linux/amcc-2.6/config/default create mode 100644 target/linux/amcc-2.6/image/Makefile create mode 100644 target/linux/amcc-2.6/patches/100-taishan_emac.patch create mode 100644 target/linux/amcc-2.6/patches/110-openwrt_mtd_mapping.patch create mode 100644 target/linux/amcc-2.6/patches/120-uncompressed_uImage.patch create mode 100644 target/linux/avr32-2.6/Makefile create mode 100644 target/linux/avr32-2.6/config/default create mode 100644 target/linux/avr32-2.6/image/Makefile create mode 100644 target/linux/avr32-2.6/patches/100-git_sync.patch create mode 100644 target/linux/avr32-2.6/patches/110-openwrt_flashmap.patch diff --git a/target/linux/adm5120-2.6/Makefile b/target/linux/adm5120-2.6/Makefile new file mode 100644 index 0000000000..c748c751e5 --- /dev/null +++ b/target/linux/adm5120-2.6/Makefile @@ -0,0 +1,27 @@ +# +# 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:=mipsel +BOARD:=adm5120 +BOARDNAME:=ADM5120 (Little Endian) +FEATURES:=squashfs jffs2 pci usb + +LINUX_VERSION:=2.6.22-rc6 + +define Target/Description + Build firmware images for Infineon/ADMtek ADM5120 based boards + (e.g : RouterBoard RB1xx, Compex WP54G-WRT ...) +endef + +include $(INCLUDE_DIR)/kernel-build.mk +DEFAULT_PACKAGES += admswconfig + +# include the profiles +-include profiles/*.mk + +$(eval $(call BuildKernel)) diff --git a/target/linux/adm5120-2.6/base-files/default/sbin/wget2nand b/target/linux/adm5120-2.6/base-files/default/sbin/wget2nand new file mode 100755 index 0000000000..1f7548aa06 --- /dev/null +++ b/target/linux/adm5120-2.6/base-files/default/sbin/wget2nand @@ -0,0 +1,72 @@ +#!/bin/sh +# wget2nand +# This script can be used to download a TGZ file from your build system which +# contains the files to be installed on the NAND flash on your RB1xx card. +# The one parameter is the URL of the TGZ file to be downloaded. +# Licence GPL V2 +# Author david.goodenough@linkchoose.co.uk +# Based on cf2nand from RB532 support +. /etc/functions.sh + +[ -d /tmp/wget2nand ] && { + echo "/tmp/wget2nand already exists" + exit 1 +} + +# first get an address for br-lan using udhcpc +killall udhcpc +/sbin/udhcpc -i br-lan + +# need to find the wget server from the command line +url=$1 +[ -z "$url" ] && { + echo "No URL specified for image TGZ" + echo "Usage : $0 URL" + exit 1 +} + +boot="$(find_mtd_part 'RouterBoard NAND Boot')" +main="$(find_mtd_part 'rootfs')" +[ -z "$boot" -o -z "$main" ] && { + echo "Cannot find NAND Flash partitions" + exit 1 +} + +echo "Erasing filesystem." +mtd erase Boot 2>/dev/null >/dev/null +mtd erase Main 2>/dev/null >/dev/null + +echo "Mounting $main as new root and $boot as boot partition" + +mkdir /tmp/wget2nand/ +mkdir /tmp/wget2nand-boot +mount -t yaffs2 "$main" /tmp/wget2nand/ +mount -t yaffs2 "$boot" /tmp/wget2nand-boot + +echo "Copying filesystem..." +( wget -O - $url/openwrt-adm5120-2.6-rootfs.tgz) | ( cd /tmp/wget2nand/; tar xvz ) +wget -O /tmp/wget2nand-boot/kernel $url/openwrt-adm5120-2.6-vmlinux.elf + +# update the command line on the kernel to boot from the right place +[ ! -e /sbin/patch-cmdline ] && { + echo "Cannot find patch-cmdline" + exit 1 +} + +echo "Patching the kernel command line" +/sbin/patch-cmdline /tmp/wget2nand-boot/kernel "root=/dev/mtdblock1 rootfstype=yaffs2 init=/etc/preinit " +chmod +x /tmp/wget2nand-boot/kernel + +# make sure everything is written before we unmount the partitions +echo "chmod ugo+x /" > /tmp/wget2nand/etc/uci-defaults/set_root_permission +sync +ls /tmp/wget2nand-boot/ +ls /tmp/wget2nand/ +# unmount the partitions and remove the directories into which they were mounted +umount /tmp/wget2nand-boot +umount /tmp/wget2nand +rmdir /tmp/wget2nand-boot +rmdir /tmp/wget2nand + +# all done +echo "Image written, you can now reboot. Remember to change the boot source to Boot from Nand" diff --git a/target/linux/adm5120-2.6/config/default b/target/linux/adm5120-2.6/config/default new file mode 100644 index 0000000000..f22330490f --- /dev/null +++ b/target/linux/adm5120-2.6/config/default @@ -0,0 +1,283 @@ +CONFIG_32BIT=y +# CONFIG_64BIT is not set +# CONFIG_64BIT_PHYS_ADDR is not set +CONFIG_ADM5120_HARDWARE_SWAB=y +CONFIG_ADM5120_NR_UARTS=2 +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_ATM_DRIVERS is not set +CONFIG_BASE_SMALL=0 +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_CIFS_DEBUG2=y +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_XATTR=y +CONFIG_CMDLINE="console=ttyS0,115200 rootfs=jffs2,squashfs,yaffs2 init=/etc/preinit" +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_CPU_LITTLE_ENDIAN=y +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_SHA1=y +# CONFIG_DDB5477 is not set +CONFIG_DEVPORT=y +# CONFIG_DM9000 is not set +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_ELF_CORE=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_FS_MBCACHE=m +CONFIG_FS_POSIX_ACL=y +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_GPIO=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +# CONFIG_GEN_RTC is not set +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HID=m +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HW_HAS_PCI=y +CONFIG_HW_RANDOM=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_I2C is not set +# CONFIG_IDE is not set +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +# CONFIG_INPUT_EVDEV is not set +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IRQ_CPU=y +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JOLIET is not set +CONFIG_LEDS_ADM5120=y +CONFIG_LEDS_ADM5120_DIAG=y +# CONFIG_LEDS_ADM5120_EXPERIMENTAL is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# 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_MII=m +# CONFIG_MINIX_FS is not set +CONFIG_MIPS=y +CONFIG_MIPS_ADM5120=y +CONFIG_MIPS_ADM5120_ENET=y +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MIPS_EV64120 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_MIPS_VPE_LOADER is not set +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_3 is not set +# CONFIG_MOMENCO_OCELOT_C is not set +CONFIG_MTD=y +# CONFIG_MTD_ABSENT is not set +CONFIG_MTD_ADM5120=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_BLOCK2MTD=y +CONFIG_MTD_CFI=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC=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_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_CMDLINE_PARTS=y +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_JEDECPROBE is not set +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 is not set +CONFIG_MTD_MYLOADER_PARTS=y +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_RB100=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_ONENAND is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_PHYSMAP is not set +# 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_NETDEV_1000 is not set +CONFIG_NET_KEY=y +# CONFIG_NET_PCI is not set +# CONFIG_NET_PKTGEN is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_NET_VENDOR_3COM is not set +# 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_PARTITION_ADVANCED is not set +# CONFIG_PCIPCWATCHDOG is not set +CONFIG_PCI_ADM5120=y +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_PNPACPI is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_RTC is not set +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_ADM5120=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 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_PTSWARM is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_SWARM is not set +CONFIG_SOFT_WATCHDOG=m +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +CONFIG_TRAD_SIGNALS=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_USB=y +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_ADM5120_HCD=y +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_V4L1=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_YAFFS_9BYTE_TAGS=y +# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set +CONFIG_YAFFS_AUTO_YAFFS2=y +CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 +# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_YAFFS1=y +CONFIG_YAFFS_YAFFS2=y +# CONFIG_ZD1211RW is not set +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/Kconfig b/target/linux/adm5120-2.6/files/arch/mips/adm5120/Kconfig new file mode 100644 index 0000000000..1b73a370b4 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/Kconfig @@ -0,0 +1,16 @@ +if MIPS_ADM5120 + +menu "ADM5120 Implementation Options" + +config PCI_ADM5120 + bool "Enable PCI support" + select PCI + default y + +config ADM5120_HARDWARE_SWAB + bool "Enable hardware accelerated byte-swapping" + default y + +endmenu + +endif diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/Makefile b/target/linux/adm5120-2.6/files/arch/mips/adm5120/Makefile new file mode 100644 index 0000000000..deb1adf7e1 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for the ADMtek ADM5120 SoC specific parts of the kernel +# + +obj-y := setup.o prom.o irq.o memory.o adm5120_info.o +obj-y += gpio.o +obj-y += time.o + +EXTRA_AFLAGS := $(CFLAGS) diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c new file mode 100644 index 0000000000..c34dbd0095 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c @@ -0,0 +1,1119 @@ +/* + * $Id$ + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +extern char *prom_getenv(char *envname); +/* + * Globals + */ +struct adm5120_board adm5120_board; +EXPORT_SYMBOL_GPL(adm5120_board); + +unsigned int adm5120_boot_loader; + +unsigned int adm5120_product_code; +unsigned int adm5120_revision; +unsigned int adm5120_package; +unsigned int adm5120_nand_boot; +unsigned long adm5120_speed; +unsigned long adm5120_memsize; + +/* + * Locals + */ +static char *boot_loader_names[BOOT_LOADER_LAST+1] = { + [BOOT_LOADER_UNKNOWN] = "Unknown", + [BOOT_LOADER_CFE] = "CFE", + [BOOT_LOADER_UBOOT] = "U-Boot", + [BOOT_LOADER_MYLOADER] = "MyLoader", + [BOOT_LOADER_ROUTERBOOT]= "RouterBOOT", + [BOOT_LOADER_BOOTBASE] = "Bootbase" +}; + +static struct adm5120_board __initdata adm5120_boards[] = { + /* FIXME: some boards have invalid fields */ + { + .name = "Cellvision CAS-630/630W", + .mach_type = MACH_ADM5120_CAS630, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 4*1024*1024, + }, + { + .name = "Cellvision CAS-670/670W", + .mach_type = MACH_ADM5120_CAS670, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 4*1024*1024, + }, + { + .name = "Cellvision CAS-700/700W", + .mach_type = MACH_ADM5120_CAS700, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 4*1024*1024, + }, + { + .name = "Cellvision CAS-771/771W", + .mach_type = MACH_ADM5120_CAS771, + .has_usb = 0, + .iface_num = 5, + .mem_size = (32 << 20), + .flash0_size = 4*1024*1024, + }, + { + .name = "Cellvision CAS-790", + .mach_type = MACH_ADM5120_CAS790, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 4*1024*1024, + }, + { + .name = "Cellvision CAS-861/861W", + .mach_type = MACH_ADM5120_CAS861, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 4*1024*1024, + }, + { + .name = "Cellvision NFS-101U/101WU", + .mach_type = MACH_ADM5120_NFS101U, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 4*1024*1024, + }, + { + .name = "Cellvision NFS-202U/202WU", + .mach_type = MACH_ADM5120_NFS202U, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 4*1024*1024, + }, + { + .name = "Compex NetPassage 27G", + .mach_type = MACH_ADM5120_NP27G, + .has_usb = 1, + .iface_num = 5, + .flash0_size = 4*1024*1024, + }, + { + .name = "Compex NetPassage 28G", + .mach_type = MACH_ADM5120_NP28G, + .has_usb = 0, + .iface_num = 4, + .flash0_size = 4*1024*1024, + }, + { + .name = "Compex NP28G (HotSpot)", + .mach_type = MACH_ADM5120_NP28GHS, + .has_usb = 0, + .iface_num = 4, + .flash0_size = 4*1024*1024, + }, + { + .name = "Compex WP54AG", + .mach_type = MACH_ADM5120_WP54AG, + .has_usb = 0, + .iface_num = 2, + .mem_size = (16 << 20), + .flash0_size = 4*1024*1024, + }, + { + .name = "Compex WP54G", + .mach_type = MACH_ADM5120_WP54G, + .has_usb = 0, + .iface_num = 2, + .flash0_size = 4*1024*1024, + }, + { + .name = "Compex WP54G-WRT", + .mach_type = MACH_ADM5120_WP54G_WRT, + .has_usb = 0, + .iface_num = 2, + .flash0_size = 4*1024*1024, + }, + { + .name = "Compex WP54G v1C", + .mach_type = MACH_ADM5120_WP54Gv1C, + .has_usb = 0, + .iface_num = 2, + .flash0_size = 2*1024*1024, + }, + { + .name = "Compex WPP54AG", + .mach_type = MACH_ADM5120_WPP54AG, + .has_usb = 0, + .iface_num = 2, + .flash0_size = 4*1024*1024, + }, + { + .name = "Compex WPP54G", + .mach_type = MACH_ADM5120_WPP54G, + .has_usb = 0, + .iface_num = 2, + .flash0_size = 4*1024*1024, + }, + { + .name = "Edimax BR-6104K", + .mach_type = MACH_ADM5120_BR6104K, + .has_usb = 0, + .iface_num = 5, + .mem_size = (16 << 20), + .flash0_size = 2*1024*1024, + }, + { + .name = "Infineon EASY 5120", + .mach_type = MACH_ADM5120_EASY5120, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 2*1024*1024, + }, + { + .name = "Infineon EASY 5120-RT", + .mach_type = MACH_ADM5120_EASY5120RT, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 2*1024*1024, + }, + { + .name = "Infineon EASY 5120P-ATA", + .mach_type = MACH_ADM5120_EASY5120PATA, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 2*1024*1024, + }, + { + .name = "Infineon EASY 83000", + .mach_type = MACH_ADM5120_EASY83000, + .has_usb = 0, + .iface_num = 6, + .flash0_size = 4*1024*1024, + }, + { + .name = "RouterBOARD 111", + .mach_type = MACH_ADM5120_RB_111, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 128*1024, + }, + { + .name = "RouterBOARD 112", + .mach_type = MACH_ADM5120_RB_112, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 128*1024, + }, + { + .name = "RouterBOARD 133", + .mach_type = MACH_ADM5120_RB_133, + .has_usb = 0, + .iface_num = 3, + .flash0_size = 128*1024, + }, + { + .name = "RouterBOARD 133C", + .mach_type = MACH_ADM5120_RB_133C, + .has_usb = 0, + .iface_num = 1, + .flash0_size = 128*1024, + }, + { + .name = "RouterBOARD 150", + .mach_type = MACH_ADM5120_RB_150, + .has_usb = 0, + .iface_num = 5, + .flash0_size = 128*1024, + }, + { + .name = "RouterBOARD 153", + .mach_type = MACH_ADM5120_RB_153, + .has_usb = 0, + .iface_num = 5, + .flash0_size = 128*1024, + }, + { + .name = "ZyXEL ES-2024A", + .mach_type = MACH_ADM5120_ES2024A, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL ES-2024PWR", + .mach_type = MACH_ADM5120_ES2024PWR, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL ES-2108", + .mach_type = MACH_ADM5120_ES2108, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL ES-2108-F", + .mach_type = MACH_ADM5120_ES2108F, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL ES-2108-G", + .mach_type = MACH_ADM5120_ES2108G, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL ES-2108-LC", + .mach_type = MACH_ADM5120_ES2108LC, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL ES-2108-PWR", + .mach_type = MACH_ADM5120_ES2108PWR, + .has_usb = 0, + .iface_num = 0, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL HomeSafe 100/100W", + .mach_type = MACH_ADM5120_HS100, + .has_usb = 0, + .iface_num = 5, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL Prestige 334", + .mach_type = MACH_ADM5120_P334, + .has_usb = 0, + .iface_num = 5, + .flash0_size = 2*1024*1024, + }, + { + .name = "ZyXEL Prestige 334U", + .mach_type = MACH_ADM5120_P334U, + .has_usb = 0, + .iface_num = 5, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL Prestige 334W", + .mach_type = MACH_ADM5120_P334W, + .has_usb = 0, + .iface_num = 5, + .flash0_size = 2*1024*1024, + }, + { + .name = "ZyXEL Prestige 334WH", + .mach_type = MACH_ADM5120_P334WH, + .has_usb = 0, + .iface_num = 5, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL Prestige 334WHD", + .mach_type = MACH_ADM5120_P334WHD, + .has_usb = 0, + .iface_num = 5, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL Prestige 334WT", + .mach_type = MACH_ADM5120_P334WT, + .has_usb = 1, + .iface_num = 5, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL Prestige 335/335WT", + .mach_type = MACH_ADM5120_P335, + .has_usb = 1, + .iface_num = 5, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL Prestige 335Plus", + .mach_type = MACH_ADM5120_P335PLUS, + .has_usb = 1, + .iface_num = 5, + .flash0_size = 4*1024*1024, + }, + { + .name = "ZyXEL Prestige 335U", + .mach_type = MACH_ADM5120_P335U, + .has_usb = 1, + .iface_num = 5, + .flash0_size = 4*1024*1024, + }, + { + .name = "Unknown ADM5120 board", + .mach_type = MACH_ADM5120_UNKNOWN, + .has_usb = 1, + .iface_num = 5, + .flash0_size = 4*1024*1024, + } +}; + +#define DUMMY_BOARD() {.mach_type = MACH_ADM5120_UNKNOWN} + +struct mylo_board { + u16 vid; + u16 did; + u16 svid; + u16 sdid; + unsigned long mach_type; +}; + + +#define MYLO_BOARD(v,d,sv,sd,mt) { .vid = (v), .did = (d), .svid = (sv), \ + .sdid = (sd), .mach_type = (mt) } + +#define COMPEX_BOARD(d,mt) MYLO_BOARD(VENID_COMPEX,(d),VENID_COMPEX,(d),(mt)) + +static struct mylo_board mylo_boards[] __initdata = { + COMPEX_BOARD(DEVID_COMPEX_NP27G, MACH_ADM5120_NP27G), + COMPEX_BOARD(DEVID_COMPEX_NP28G, MACH_ADM5120_NP28G), + COMPEX_BOARD(DEVID_COMPEX_NP28GHS, MACH_ADM5120_NP28GHS), + COMPEX_BOARD(DEVID_COMPEX_WP54G, MACH_ADM5120_WP54G), + COMPEX_BOARD(DEVID_COMPEX_WP54Gv1C, MACH_ADM5120_WP54Gv1C), + COMPEX_BOARD(DEVID_COMPEX_WP54AG, MACH_ADM5120_WP54AG), + COMPEX_BOARD(DEVID_COMPEX_WPP54G, MACH_ADM5120_WPP54G), + COMPEX_BOARD(DEVID_COMPEX_WPP54AG, MACH_ADM5120_WPP54AG), + DUMMY_BOARD() +}; + +#define ROUTERBOARD_NAME_LEN 16 + +struct routerboard { + unsigned long mach_type; + char name[ROUTERBOARD_NAME_LEN]; +}; + +#define ROUTERBOARD(n, mt) { .name = (n), .mach_type = (mt) } +static struct routerboard routerboards[] __initdata = { + ROUTERBOARD("111", MACH_ADM5120_RB_111), + ROUTERBOARD("112", MACH_ADM5120_RB_112), + ROUTERBOARD("133", MACH_ADM5120_RB_133), + ROUTERBOARD("133C", MACH_ADM5120_RB_133C), + ROUTERBOARD("miniROUTER", MACH_ADM5120_RB_150), + ROUTERBOARD("153", MACH_ADM5120_RB_150), + DUMMY_BOARD() +}; + +struct zynos_board { + unsigned long mach_type; + unsigned int vendor_id; + u16 board_id; +}; + +#define ZYNOS_BOARD(vi, bi, mt) { .vendor_id = (vi), .board_id = (bi), \ + .mach_type = (mt) } + +#define ZYXEL_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_ZYXEL, bi, mt) +#define DLINK_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_DLINK, bi, mt) +#define LUCENT_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_LUCENT, bi, mt) + +static struct zynos_board zynos_boards[] __initdata = { + ZYXEL_BOARD(ZYNOS_BOARD_HS100, MACH_ADM5120_HS100), + ZYXEL_BOARD(ZYNOS_BOARD_P334, MACH_ADM5120_P334), + ZYXEL_BOARD(ZYNOS_BOARD_P334U, MACH_ADM5120_P334U), + ZYXEL_BOARD(ZYNOS_BOARD_P334W, MACH_ADM5120_P334W), + ZYXEL_BOARD(ZYNOS_BOARD_P334WH, MACH_ADM5120_P334WH), + ZYXEL_BOARD(ZYNOS_BOARD_P334WHD, MACH_ADM5120_P334WHD), + ZYXEL_BOARD(ZYNOS_BOARD_P334WT, MACH_ADM5120_P334WT), + ZYXEL_BOARD(ZYNOS_BOARD_P335, MACH_ADM5120_P335), + ZYXEL_BOARD(ZYNOS_BOARD_P335PLUS, MACH_ADM5120_P335PLUS), + ZYXEL_BOARD(ZYNOS_BOARD_P335U, MACH_ADM5120_P335U), + DUMMY_BOARD() +}; + +struct common_board { + char *name; + unsigned long mach_type; +}; + +#define DEFBOARD(n, mt) { .name = (n), .mach_type = (mt) } +static struct common_board common_boards[] __initdata = { + DEFBOARD("CAS-630", MACH_ADM5120_CAS630), + DEFBOARD("CAS-670", MACH_ADM5120_CAS670), + DEFBOARD("CAS-700", MACH_ADM5120_CAS700), + DEFBOARD("CAS-771", MACH_ADM5120_CAS771), + DEFBOARD("CAS-790", MACH_ADM5120_CAS790), + DEFBOARD("CAS-861", MACH_ADM5120_CAS861), + DEFBOARD("NFS-101U", MACH_ADM5120_NFS101U), + DEFBOARD("NFS-202U", MACH_ADM5120_NFS202U), + DEFBOARD("EASY 5120", MACH_ADM5120_EASY5120), + DEFBOARD("EASY 5120-RT", MACH_ADM5120_EASY5120RT), + DEFBOARD("EASY 5120P-ATA", MACH_ADM5120_EASY5120PATA), + DEFBOARD("EASY 83000", MACH_ADM5120_EASY83000), + DEFBOARD("BR-6104K", MACH_ADM5120_BR6104K), + DEFBOARD("WP54G-WRT", MACH_ADM5120_WP54G_WRT), + DEFBOARD("P-334WT", MACH_ADM5120_P334WT), + DEFBOARD("P-335", MACH_ADM5120_P335), +}; + +/* + * Helper routines + */ +static inline u16 read_le16(void *buf) +{ + u8 *p; + + p = buf; + return ((u16)p[0] + ((u16)p[1] << 8)); +} + +static inline u32 read_le32(void *buf) +{ + u8 *p; + + p = buf; + return ((u32)p[0] + ((u32)p[1] << 8) + ((u32)p[2] << 16) + + ((u32)p[3] << 24)); +} + +static inline u16 read_be16(void *buf) +{ + u8 *p; + + p = buf; + return (((u16)p[0] << 8) + (u16)p[1]); +} + +static inline u32 read_be32(void *buf) +{ + u8 *p; + + p = buf; + return (((u32)p[0] << 24) + ((u32)p[1] << 16) + ((u32)p[2] << 8) + + ((u32)p[3])); +} + +/* + * CFE based boards + */ +#define CFE_EPTSEAL 0x43464531 /* CFE1 is the magic number to recognize CFE +from other bootloaders */ + +static int __init cfe_present(void) +{ + /* + * This method only works, when we are booted directly from the CFE. + */ + u32 cfe_handle = (u32) fw_arg0; + u32 cfe_a1_val = (u32) fw_arg1; + u32 cfe_entry = (u32) fw_arg2; + u32 cfe_seal = (u32) fw_arg3; + + /* Check for CFE by finding the CFE magic number */ + if (cfe_seal != CFE_EPTSEAL) { + /* We are not booted from CFE */ + return 0; + } + + /* cfe_a1_val must be 0, because only one CPU present in the ADM5120 */ + if (cfe_a1_val != 0) { + return 0; + } + + /* The cfe_handle, and the cfe_entry must be kernel mode addresses */ + if ((cfe_handle < KSEG0) || (cfe_entry < KSEG0)) { + return 0; + } + + return 1; +} + +static unsigned long __init cfe_detect_board(void) +{ + return MACH_ADM5120_WP54G_WRT; +} + +/* + * MyLoader based boards + */ +#define SYS_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F000) +#define BOARD_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F800) +#define PART_TABLE_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x10000) + +static unsigned long __init myloader_detect_board(void) +{ + struct mylo_system_params *sysp; + struct mylo_board_params *boardp; + struct mylo_partition_table *parts; + struct mylo_board *board; + unsigned long ret; + + ret = MACH_ADM5120_UNKNOWN; + + sysp = (struct mylo_system_params *)(SYS_PARAMS_ADDR); + boardp = (struct mylo_board_params *)(BOARD_PARAMS_ADDR); + parts = (struct mylo_partition_table *)(PART_TABLE_ADDR); + + /* Check for some magic numbers */ + if ((le32_to_cpu(sysp->magic) != MYLO_MAGIC_SYS_PARAMS) || + (le32_to_cpu(boardp->magic) != MYLO_MAGIC_BOARD_PARAMS) || + (le32_to_cpu(parts->magic) != MYLO_MAGIC_PARTITIONS)) + goto out; + + for (board = mylo_boards; board->mach_type != MACH_ADM5120_UNKNOWN; + board++) { + if ((le16_to_cpu(sysp->vid) == board->vid) && + (le16_to_cpu(sysp->did) == board->did) && + (le16_to_cpu(sysp->svid) == board->svid) && + (le16_to_cpu(sysp->sdid) == board->sdid)) { + ret = board->mach_type; + break; + } + } + + /* assume MyLoader as the boot-loader */ + adm5120_boot_loader = BOOT_LOADER_MYLOADER; + +out: + return ret; +} + +/* + * RouterBOOT based boards + */ +static int __init routerboot_load_hs(u8 *buf, u16 buflen, + struct rb_hard_settings *hs) +{ + u16 id,len; + u8 *mac; + int i,j; + + if (buflen < 4) + return -1; + + if (read_le32(buf) != RB_MAGIC_HARD) + return -1; + + /* skip magic value */ + buf += 4; + buflen -= 4; + + while (buflen > 2) { + id = read_le16(buf); + buf += 2; + buflen -= 2; + if (id == RB_ID_TERMINATOR || buflen < 2) + break; + + len = read_le16(buf); + buf += 2; + buflen -= 2; + + if (buflen < len) + break; + + switch (id) { + case RB_ID_BIOS_VERSION: + hs->bios_ver = (char *)buf; + break; + case RB_ID_BOARD_NAME: + hs->name = (char *)buf; + break; + case RB_ID_MEMORY_SIZE: + hs->mem_size = read_le32(buf); + break; + case RB_ID_MAC_ADDRESS_COUNT: + hs->mac_count = read_le32(buf); + break; + case RB_ID_MAC_ADDRESS_PACK: + hs->mac_count = len/RB_MAC_SIZE; + if (hs->mac_count > RB_MAX_MAC_COUNT) + hs->mac_count = RB_MAX_MAC_COUNT; + mac = buf; + for (i=0; i < hs->mac_count; i++) { + for (j=0; j < RB_MAC_SIZE; j++) + hs->macs[i][j] = mac[j]; + mac += RB_MAC_SIZE; + } + break; + } + + buf += len; + buflen -= len; + + } + + return 0; +} + +#define RB_BS_OFFS 0x14 +#define RB_OFFS_MAX (128*1024) + +static unsigned long __init routerboot_detect_board(void) +{ + struct routerboard *board; + struct rb_hard_settings hs; + struct rb_bios_settings *bs; + u8 *base; + u32 off,len; + unsigned long ret; + + ret = MACH_ADM5120_UNKNOWN; + + base = (u8 *)KSEG1ADDR(ADM5120_SRAM0_BASE); + bs = (struct rb_bios_settings *)(base + RB_BS_OFFS); + + off = read_le32(&bs->hs_offs); + len = read_le32(&bs->hs_size); + if (off > RB_OFFS_MAX) + return ret; + + memset(&hs, 0, sizeof(hs)); + if (routerboot_load_hs(base+off, len, &hs) != 0) + return ret; + + /* assume RouterBOOT as the boot-loader */ + adm5120_boot_loader = BOOT_LOADER_ROUTERBOOT; + + if (hs.name == NULL) + return ret; + + for (board = routerboards; board->mach_type != MACH_ADM5120_UNKNOWN; + board++) { + if (strncmp(board->name, hs.name, strlen(board->name)) == 0) { + ret = board->mach_type; + break; + } + } + + return ret; +} + +/* + * ZyNOS based boards + */ +static inline u32 zynos_dbgarea_present(u8 *data) +{ + u32 t; + + t = read_be32(data+5); + if (t != ZYNOS_MAGIC_DBGAREA1) + return 0; + + t = read_be32(data+9); + if (t != ZYNOS_MAGIC_DBGAREA2) + return 0; + + return 1; +} + +#define CHECK_VENDOR(n) (strnicmp(vendor,(n),strlen(n)) == 0) + +static inline unsigned int zynos_get_vendor_id(struct zynos_board_info *info) +{ + unsigned char vendor[ZYNOS_NAME_LEN]; + int i; + + for (i=0; ivendor[i]; + + if CHECK_VENDOR(ZYNOS_VENDOR_ZYXEL) + return ZYNOS_VENDOR_ID_ZYXEL; +#if 0 + /* TODO: there are no known ADM5120 based boards from other vendors */ + if CHECK_VENDOR(ZYNOS_VENDOR_DLINK) + return ZYNOS_VENDOR_ID_DLINK; + + if CHECK_VENDOR(ZYNOS_VENDOR_LUCENT) + return ZYNOS_VENDOR_ID_LUCENT; + + if CHECK_VENDOR(ZYNOS_VENDOR_NETGEAR) + return ZYNOS_VENDOR_ID_NETGEAR; +#endif + + return ZYNOS_VENDOR_ID_OTHER; +} + +static inline u16 zynos_get_board_id(struct zynos_board_info *info) +{ + return read_be16(&info->board_id); +} + +static inline u32 zynos_get_bootext_addr(struct zynos_board_info *info) +{ + return read_be32(&info->bootext_addr); +} + + +#define ZYNOS_INFO_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x3F90) +#define ZYNOS_HDBG_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x4000) +#define BOOTEXT_ADDR_MIN KSEG1ADDR(ADM5120_SRAM0_BASE) +#define BOOTEXT_ADDR_MAX (BOOTEXT_ADDR_MIN + (2*1024*1024)) + +static unsigned long __init zynos_detect_board(void) +{ + struct zynos_board_info *info; + struct zynos_board *board; + unsigned int vendor_id; + u16 board_id; + u32 t; + unsigned long ret; + + ret = MACH_ADM5120_UNKNOWN; + /* check presence of the dbgarea */ + if (zynos_dbgarea_present((u8 *)ZYNOS_HDBG_ADDR) == 0) + goto out; + + info = (struct zynos_board_info *)(ZYNOS_INFO_ADDR); + + /* check for a valid BootExt address */ + t = zynos_get_bootext_addr(info); + if ((t < BOOTEXT_ADDR_MIN) || (t > BOOTEXT_ADDR_MAX)) + goto out; + + vendor_id = zynos_get_vendor_id(info); + board_id = zynos_get_board_id(info); + + for (board = zynos_boards; board->mach_type != MACH_ADM5120_UNKNOWN; + board++) { + if ((board->vendor_id == vendor_id) && + (board->board_id == board_id)) { + ret = board->mach_type; + break; + } + } + + /* assume Bootbase as the boot-loader */ + adm5120_boot_loader = BOOT_LOADER_BOOTBASE; + +out: + return ret; +} + +/* + * U-Boot based boards + */ +static int __init uboot_present(void) +{ + /* FIXME: not yet implemented */ + return 0; +} + +static unsigned long __init uboot_detect_board(void) +{ + /* FIXME: not yet implemented */ + return MACH_ADM5120_UNKNOWN; +} + +/* + * Misc boards + */ +static unsigned long __init prom_detect_board(void) +{ + char *name; + unsigned long ret; + int i; + + ret = MACH_ADM5120_UNKNOWN; + name = prom_getenv("board_name"); + if (name == NULL) + goto out; + + if (*name == '\0') + goto out; + + for (i=0; imach_type != MACH_ADM5120_UNKNOWN; + board++) { + if (board->mach_type == t) + break; + } + + memcpy(&adm5120_board, board, sizeof(adm5120_board)); +} + +#define SWITCH_READ(r) *(u32 *)(KSEG1ADDR(ADM5120_SWITCH_BASE)+(r)) +#define SWITCH_WRITE(r,v) *(u32 *)(KSEG1ADDR(ADM5120_SWITCH_BASE)+(r))=(v) + +/* + * CPU settings detection + */ +#define CODE_GET_PC(c) ((c) & CODE_PC_MASK) +#define CODE_GET_REV(c) (((c) >> CODE_REV_SHIFT) & CODE_REV_MASK) +#define CODE_GET_PK(c) (((c) >> CODE_PK_SHIFT) & CODE_PK_MASK) +#define CODE_GET_CLKS(c) (((c) >> CODE_CLKS_SHIFT) & CODE_CLKS_MASK) +#define CODE_GET_NAB(c) (((c) & CODE_NAB) != 0) + +static void __init adm5120_detect_cpuinfo(void) +{ + u32 code; + u32 clks; + + code = SWITCH_READ(SWITCH_REG_CODE); + + adm5120_product_code = CODE_GET_PC(code); + adm5120_revision = CODE_GET_REV(code); + adm5120_package = (CODE_GET_PK(code) == CODE_PK_BGA) ? + ADM5120_PACKAGE_BGA : ADM5120_PACKAGE_PQFP; + adm5120_nand_boot = CODE_GET_NAB(code); + + clks = CODE_GET_CLKS(code); + adm5120_speed = ADM5120_SPEED_175; + if (clks & 1) + adm5120_speed += 25000000; + if (clks & 2) + adm5120_speed += 50000000; +} + +static void adm5120_ndelay(u32 ns) +{ + u32 t; + + SWITCH_WRITE(SWITCH_REG_TIMER, TIMER_PERIOD_DEFAULT); + SWITCH_WRITE(SWITCH_REG_TIMER_INT, (TIMER_INT_TOS | TIMER_INT_TOM)); + + t = (ns+640) / 640; + t &= TIMER_PERIOD_MASK; + SWITCH_WRITE(SWITCH_REG_TIMER, t | TIMER_TE); + + /* wait until the timer expires */ + do { + t = SWITCH_READ(SWITCH_REG_TIMER_INT); + } while ((t & TIMER_INT_TOS) == 0); + + /* leave the timer disabled */ + SWITCH_WRITE(SWITCH_REG_TIMER, TIMER_PERIOD_DEFAULT); + SWITCH_WRITE(SWITCH_REG_TIMER_INT, (TIMER_INT_TOS | TIMER_INT_TOM)); +} + +#define MPMC_READ(r) *(u32 *)(KSEG1ADDR(ADM5120_SWITCH_BASE)+(r)) +#define MPMC_WRITE(r,v) *(u32 *)(KSEG1ADDR(ADM5120_SWITCH_BASE)+(r))=(v) + +extern void prom_printf(char *, ...); +#if 1 +# define mem_dbg(f, a...) prom_printf("mem_detect: " f, ## a) +#else +# define mem_dbg(f, a...) +#endif + +#define MEM_WR_DELAY 10000 /* 0.01 usec */ + +static int mem_check_pattern(u8 *addr, unsigned long offs) +{ + volatile u32 *p1 = (volatile u32 *)addr; + volatile u32 *p2 = (volatile u32 *)(addr+offs); + u32 t,u,v; + + /* save original value */ + t = *p1; + u = *p2; + + if (t != u) + return 0; + + v = 0x55555555; + if (u == v) + v = 0xAAAAAAAA; + + mem_dbg("write 0x%08lX to 0x%08lX\n", v, (unsigned long)p1); + + *p1 = v; + mem_dbg("delay %d ns\n", MEM_WR_DELAY); + adm5120_ndelay(MEM_WR_DELAY); + u = *p2; + + mem_dbg("pattern at 0x%08lX is 0x%08lX\n", (unsigned long)p2, u); + + /* restore original value */ + *p1 = t; + + return (v == u); +} + +static void __init adm5120_detect_memsize(void) +{ + u32 memctrl; + u32 size, maxsize; + u8 *p; + + memctrl = SWITCH_READ(SWITCH_REG_MEMCTRL); + switch (memctrl & MEMCTRL_SDRS_MASK) { + case MEMCTRL_SDRS_4M: + maxsize = 4 << 20; + break; + case MEMCTRL_SDRS_8M: + maxsize = 8 << 20; + break; + case MEMCTRL_SDRS_16M: + maxsize = 16 << 20; + break; + default: + maxsize = 64 << 20; + break; + } + + /* disable buffers for both SDRAM banks */ + mem_dbg("disable buffers for both banks\n"); + MPMC_WRITE(MPMC_REG_DC0, MPMC_READ(MPMC_REG_DC0) & ~DC_BE); + MPMC_WRITE(MPMC_REG_DC1, MPMC_READ(MPMC_REG_DC1) & ~DC_BE); + + mem_dbg("checking for %ldMB chip in 1st bank\n", maxsize >> 20); + + /* detect size of the 1st SDRAM bank */ + p = (u8 *)KSEG1ADDR(0); + for (size = 2<<20; size <= (maxsize >> 1); size <<= 1) { + if (mem_check_pattern(p, size)) { + /* mirrored address */ + mem_dbg("mirrored data found at offset 0x%lX\n", size); + break; + } + } + + mem_dbg("chip size in 1st bank is %ldMB\n", size >> 20); + adm5120_memsize = size; + + if (size != maxsize) + /* 2nd bank is not supported */ + goto out; + + if ((memctrl & MEMCTRL_SDR1_ENABLE) == 0) + /* 2nd bank is disabled */ + goto out; + + /* + * some bootloaders enable 2nd bank, even if the 2nd SDRAM chip + * are missing. + */ + mem_dbg("check presence of 2nd bank\n"); + + p = (u8 *)KSEG1ADDR(maxsize+size-4); + if (mem_check_pattern(p, 0)) { + adm5120_memsize += size; + } + + if (maxsize != size) { + /* adjusting MECTRL register */ + memctrl &= ~(MEMCTRL_SDRS_MASK); + switch (size>>20) { + case 4: + memctrl |= MEMCTRL_SDRS_4M; + break; + case 8: + memctrl |= MEMCTRL_SDRS_8M; + break; + case 16: + memctrl |= MEMCTRL_SDRS_16M; + break; + default: + memctrl |= MEMCTRL_SDRS_64M; + break; + } + SWITCH_WRITE(SWITCH_REG_MEMCTRL, memctrl); + } + +out: + /* reenable buffer for both SDRAM banks */ + mem_dbg("enable buffers for both banks\n"); + MPMC_WRITE(MPMC_REG_DC0, MPMC_READ(MPMC_REG_DC0) | DC_BE); + MPMC_WRITE(MPMC_REG_DC1, MPMC_READ(MPMC_REG_DC1) | DC_BE); + + mem_dbg("%dx%ldMB memory found\n", (adm5120_memsize == size) ? 1 : 2 , + size >>20); + + size = adm5120_board_memsize(); + if (size > 0 && size != adm5120_memsize) { + mem_dbg("wrong memory size detected, board settings will be used\n"); + adm5120_memsize = size; + } +} + +void __init adm5120_info_show(void) +{ + /* FIXME: move this somewhere else */ + printk(KERN_INFO "ADM%04X%s revision %d, running at %ldMHz\n", + adm5120_product_code, + (adm5120_package == ADM5120_PACKAGE_BGA) ? "" : "P", + adm5120_revision, (adm5120_speed / 1000000) + ); + printk(KERN_INFO "Boot loader is: %s\n", boot_loader_names[adm5120_boot_loader]); + printk(KERN_INFO "Booted from : %s flash\n", adm5120_nand_boot ? "NAND":"NOR"); + printk(KERN_INFO "Board is : %s\n", adm5120_board_name()); + printk(KERN_INFO "Memory size : %ldMB\n", adm5120_memsize >> 20); +} + +void __init adm5120_info_init(void) +{ + adm5120_detect_cpuinfo(); + adm5120_detect_board(); + adm5120_detect_memsize(); + + adm5120_info_show(); +} diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/gpio.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/gpio.c new file mode 100644 index 0000000000..5ae5d74940 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/gpio.c @@ -0,0 +1,357 @@ +/* + * $Id$ + * + * ADM5120 GPIO support + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +typedef void __iomem * gpio_reg_t; +#define GPIO_READ(r) readl((r)) +#define GPIO_WRITE(v,r) writel((v),(r)) +#define GPIO_REG(r) (gpio_reg_t)(KSEG1ADDR(ADM5120_SWITCH_BASE)+r) + +struct adm5120_gpio_line { + u32 flags; + const char *label; +}; + +#define GPIO_FLAG_VALID 0x01 +#define GPIO_FLAG_USED 0x02 + +struct led_desc { + gpio_reg_t reg; /* LED register address */ + u8 iv_shift; /* shift amount for input bit */ + u8 mode_shift; /* shift amount for mode bits */ +}; + +#define LED_DESC(_port,_led) { \ + .reg = GPIO_REG(SWITCH_REG_PORT0_LED+_port*4), \ + .iv_shift = LED0_IV_SHIFT+_led, \ + .mode_shift = _led*4 \ + } + +static struct led_desc led_table[15] = { + LED_DESC(0, 0), LED_DESC(0, 1), LED_DESC(0, 2), + LED_DESC(1, 0), LED_DESC(1, 1), LED_DESC(1, 2), + LED_DESC(2, 0), LED_DESC(2, 1), LED_DESC(2, 2), + LED_DESC(3, 0), LED_DESC(3, 1), LED_DESC(3, 2), + LED_DESC(4, 0), LED_DESC(4, 1), LED_DESC(4, 2) +}; + +static struct adm5120_gpio_line adm5120_gpio_map[ADM5120_GPIO_COUNT] = { + [ADM5120_GPIO_PIN0] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_PIN1] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_PIN2] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_PIN3] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_PIN4] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_PIN5] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_PIN6] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_PIN7] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P0L0] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P0L1] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P0L2] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P1L0] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P1L1] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P1L2] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P2L0] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P2L1] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P2L2] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P3L0] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P3L1] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P3L2] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P4L0] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P4L1] = {.flags = GPIO_FLAG_VALID}, + [ADM5120_GPIO_P4L2] = {.flags = GPIO_FLAG_VALID} +}; + +#define gpio_is_invalid(g) ( \ + (g) > ADM5120_GPIO_MAX || \ + ((adm5120_gpio_map[(g)].flags & GPIO_FLAG_VALID) == 0) \ + ) + +#define gpio_is_used(g) ((adm5120_gpio_map[(g)].flags & GPIO_FLAG_USED) != 0) + +/* + * Helpers for GPIO lines in GPIO_CONF0 register + */ +#define PIN_IM(p) ((1 << GPIO_CONF0_IM_SHIFT) << p) +#define PIN_IV(p) ((1 << GPIO_CONF0_IV_SHIFT) << p) +#define PIN_OE(p) ((1 << GPIO_CONF0_OE_SHIFT) << p) +#define PIN_OV(p) ((1 << GPIO_CONF0_OV_SHIFT) << p) + +static inline int pins_direction_input(unsigned pin) +{ + gpio_reg_t *reg; + u32 t; + + reg = GPIO_REG(SWITCH_REG_GPIO_CONF0); + + t = GPIO_READ(reg); + t &= ~(PIN_OE(pin)); + t |= PIN_IM(pin); + GPIO_WRITE(t,reg); + + return 0; +} + +static inline int pins_direction_output(unsigned pin, int value) +{ + gpio_reg_t *reg; + u32 t; + + reg = GPIO_REG(SWITCH_REG_GPIO_CONF0); + + t = GPIO_READ(reg); + t &= ~(PIN_IM(pin) | PIN_OV(pin)); + t |= PIN_OE(pin); + + if (value) + t |= PIN_OV(pin); + + GPIO_WRITE(t,reg); + + return 0; +} + +static inline int pins_get_value(unsigned pin) +{ + gpio_reg_t *reg; + u32 t; + + reg = GPIO_REG(SWITCH_REG_GPIO_CONF0); + + t = GPIO_READ(reg); + if ((t & PIN_IM(pin)) != 0) + t &= PIN_IV(pin); + else + t &= PIN_OV(pin); + + return (t) ? 1 : 0; +} + +static inline void pins_set_value(unsigned pin, int value) +{ + gpio_reg_t *reg; + u32 t; + + reg = GPIO_REG(SWITCH_REG_GPIO_CONF0); + + t = GPIO_READ(reg); + if (value == 0) + t &= ~(PIN_OV(pin)); + else + t |= PIN_OV(pin); + + GPIO_WRITE(t,reg); +} + +/* + * Helpers for GPIO lines in PORTx_LED registers + */ +static inline int leds_direction_input(unsigned led) +{ + gpio_reg_t *reg; + u32 t; + + reg = led_table[led].reg; + t = GPIO_READ(reg); + t &= ~(LED_MODE_MASK << led_table[led].mode_shift); + GPIO_WRITE(t,reg); + + return 0; +} + +static inline int leds_direction_output(unsigned led, int value) +{ + gpio_reg_t *reg; + u32 t, s; + + reg = led_table[led].reg; + s = led_table[led].mode_shift; + + t = GPIO_READ(reg); + t &= ~(LED_MODE_MASK << s); + if (value) + t |= (LED_MODE_OUT_HIGH << s); + else + t |= (LED_MODE_OUT_LOW << s); + + GPIO_WRITE(t,reg); + + return 0; +} + +static inline int leds_get_value(unsigned led) +{ + gpio_reg_t *reg; + u32 t, m; + + reg = led_table[led].reg; + + t = GPIO_READ(reg); + m = (t >> led_table[led].mode_shift) & LED_MODE_MASK; + if (m == LED_MODE_INPUT) + return (t >> led_table[led].iv_shift) & 1; + + if (m == LED_MODE_OUT_LOW) + return 0; + + return 1; +} + +static inline void leds_set_value(unsigned led, int value) +{ + gpio_reg_t *reg; + u32 s,t; + + reg = led_table[led].reg; + s = led_table[led].mode_shift; + + t = GPIO_READ(reg); + t &= ~(LED_MODE_MASK << s); + if (value) + t |= (LED_MODE_OUT_HIGH << s); + else + t |= (LED_MODE_OUT_LOW << s); + + GPIO_WRITE(t,reg); +} + +/* + * Main GPIO support routines + */ +int adm5120_gpio_direction_input(unsigned gpio) +{ + if (gpio_is_invalid(gpio)) + return -EINVAL; + + if (gpio < ADM5120_GPIO_P0L0) + return pins_direction_input(gpio); + + gpio -= ADM5120_GPIO_P0L0; + return leds_direction_input(gpio); +} + +int adm5120_gpio_direction_output(unsigned gpio, int value) +{ + if (gpio_is_invalid(gpio)) + return -EINVAL; + + if (gpio < ADM5120_GPIO_P0L0) + return pins_direction_output(gpio, value); + + gpio -= ADM5120_GPIO_P0L0; + return leds_direction_output(gpio, value); +} + +int adm5120_gpio_get_value(unsigned gpio) +{ + if (gpio < ADM5120_GPIO_P0L0) + return pins_get_value(gpio); + + gpio -= ADM5120_GPIO_P0L0; + return leds_get_value(gpio); +} + +void adm5120_gpio_set_value(unsigned gpio, int value) +{ + if (gpio < ADM5120_GPIO_P0L0) { + pins_set_value(gpio, value); + return; + } + + gpio -= ADM5120_GPIO_P0L0; + leds_set_value(gpio, value); +} + +int adm5120_gpio_request(unsigned gpio, const char *label) +{ + if (gpio_is_invalid(gpio)) + return -EINVAL; + + if (gpio_is_used(gpio)) + return -EBUSY; + + adm5120_gpio_map[gpio].flags |= GPIO_FLAG_USED; + adm5120_gpio_map[gpio].label = label; + + return 0; +} + +void adm5120_gpio_free(unsigned gpio) +{ + if (gpio_is_invalid(gpio)) + return; + + adm5120_gpio_map[gpio].flags &= ~GPIO_FLAG_USED; + adm5120_gpio_map[gpio].label = NULL; +} + +int adm5120_gpio_to_irq(unsigned gpio) +{ + /* FIXME: not yet implemented */ + return -EINVAL; +} + +int adm5120_irq_to_gpio(unsigned irq) +{ + /* FIXME: not yet implemented */ + return -EINVAL; +} + +static int __init adm5120_gpio_init(void) +{ + int i; + + if (adm5120_package_pqfp()) { + /* GPIO pins 4-7 are unavailable in ADM5120P */ + for (i=ADM5120_GPIO_PIN4; i<=ADM5120_GPIO_PIN7; i++) + adm5120_gpio_map[i].flags &= ~GPIO_FLAG_VALID; + } + + return 0; +} + +subsys_initcall(adm5120_gpio_init); + +EXPORT_SYMBOL(adm5120_gpio_direction_output); +EXPORT_SYMBOL(adm5120_gpio_direction_input); +EXPORT_SYMBOL(adm5120_gpio_get_value); +EXPORT_SYMBOL(adm5120_gpio_set_value); +EXPORT_SYMBOL(adm5120_gpio_request); +EXPORT_SYMBOL(adm5120_gpio_free); +EXPORT_SYMBOL(adm5120_gpio_to_irq); +EXPORT_SYMBOL(adm5120_irq_to_gpio); diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/irq.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/irq.c new file mode 100644 index 0000000000..3e14c92f11 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/irq.c @@ -0,0 +1,203 @@ +/* + * $Id$ + * + * ADM5120 specific interrupt handlers + * + * Copyright (C) 2007 Gabor Juhos + * Copyright (C) 2007 OpenWrt.org + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define INTC_REG(r) (*(volatile u32 *)(KSEG1ADDR(ADM5120_INTC_BASE) + r)) + +static void adm5120_intc_irq_unmask(unsigned int irq); +static void adm5120_intc_irq_mask(unsigned int irq); +static int adm5120_intc_irq_set_type(unsigned int irq, unsigned int flow_type); + +static struct irq_chip adm5120_intc_irq_chip = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + .name = "INTC", +#else + .typename = "INTC", +#endif + .unmask = adm5120_intc_irq_unmask, + .mask = adm5120_intc_irq_mask, + .mask_ack = adm5120_intc_irq_mask, + .set_type = adm5120_intc_irq_set_type +}; + +static struct irqaction adm5120_intc_irq_action = { + .handler = no_action, + .name = "cascade [INTC]" +}; + +static void adm5120_intc_irq_unmask(unsigned int irq) +{ + unsigned long flags; + + irq -= ADM5120_INTC_IRQ_BASE; + local_irq_save(flags); + INTC_REG(INTC_REG_IRQ_ENABLE) = (1 << irq); + local_irq_restore(flags); +} + +static void adm5120_intc_irq_mask(unsigned int irq) +{ + unsigned long flags; + + irq -= ADM5120_INTC_IRQ_BASE; + local_irq_save(flags); + INTC_REG(INTC_REG_IRQ_DISABLE) = (1 << irq); + local_irq_restore(flags); +} + +static int adm5120_intc_irq_set_type(unsigned int irq, unsigned int flow_type) +{ + /* TODO: not yet tested */ +#if 1 + unsigned int sense; + unsigned long mode; + int err; + + err = 0; + sense = flow_type & (IRQ_TYPE_SENSE_MASK); + switch (sense) { + case IRQ_TYPE_NONE: + case IRQ_TYPE_LEVEL_HIGH: + break; + case IRQ_TYPE_LEVEL_LOW: + switch (irq) { + case ADM5120_IRQ_GPIO2: + case ADM5120_IRQ_GPIO4: + break; + default: + err = -EINVAL; + break; + } + break; + default: + err = -EINVAL; + break; + } + + if (err) + return err; + + switch (irq) { + case ADM5120_IRQ_GPIO2: + case ADM5120_IRQ_GPIO4: + mode = INTC_REG(INTC_REG_INT_MODE); + if (sense == IRQ_TYPE_LEVEL_LOW) + mode |= (1 << (irq-ADM5120_INTC_IRQ_BASE)); + else + mode &= (1 << (irq-ADM5120_INTC_IRQ_BASE)); + + INTC_REG(INTC_REG_INT_MODE) = mode; + /* fallthrogh */ + default: + irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; + irq_desc[irq].status |= sense; + break; + } +#endif + return 0; +} + +static void adm5120_intc_irq_dispatch(void) +{ + unsigned long status; + int irq; + +#if 1 + /* dispatch only one IRQ at a time */ + status = INTC_REG(INTC_REG_IRQ_STATUS) & INTC_INT_ALL; + + if (status) { + irq = ADM5120_INTC_IRQ_BASE+fls(status)-1; + do_IRQ(irq); + } else + spurious_interrupt(); +#else + status = INTC_REG(INTC_REG_IRQ_STATUS) & INTC_INT_ALL; + if (status) { + for (irq=ADM5120_INTC_IRQ_BASE; irq <= ADM5120_INTC_IRQ_BASE + + INTC_IRQ_LAST; irq++, status >>=1) { + if ((status & 1) == 1) + do_IRQ(irq); + } + } else + spurious_interrupt(); +#endif +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned long pending; + + pending = read_c0_status() & read_c0_cause(); + + if (pending & STATUSF_IP7) + do_IRQ(ADM5120_IRQ_COUNTER); + else if (pending & STATUSF_IP2) + adm5120_intc_irq_dispatch(); + else + spurious_interrupt(); +} + +#define INTC_IRQ_STATUS (IRQ_LEVEL | IRQ_TYPE_LEVEL_HIGH | IRQ_DISABLED) +static void __init adm5120_intc_irq_init(int base) +{ + int i; + + /* disable all interrupts */ + INTC_REG(INTC_REG_IRQ_DISABLE) = INTC_INT_ALL; + /* setup all interrupts to generate IRQ instead of FIQ */ + INTC_REG(INTC_REG_INT_MODE) = 0; + /* set active level for all external interrupts to HIGH */ + INTC_REG(INTC_REG_INT_LEVEL) = 0; + /* disable usage of the TEST_SOURCE register */ + INTC_REG(INTC_REG_IRQ_SOURCE_SELECT) = 0; + + for(i=ADM5120_INTC_IRQ_BASE; i <= ADM5120_INTC_IRQ_BASE+INTC_IRQ_LAST; + i++) { + irq_desc[i].status = INTC_IRQ_STATUS; + set_irq_chip_and_handler(i, &adm5120_intc_irq_chip, + handle_level_irq); + } + + setup_irq(ADM5120_IRQ_INTC, &adm5120_intc_irq_action); +} + +void __init arch_init_irq(void) { + mips_cpu_irq_init(); + adm5120_intc_irq_init(ADM5120_INTC_IRQ_BASE); +} diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c new file mode 100644 index 0000000000..190a0788fc --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c @@ -0,0 +1,90 @@ +/***************************************************************************** + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2003 ADMtek Incorporated. + * daniell@admtek.com.tw + * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org) + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) + +struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; + +struct prom_pmemblock * __init prom_getmdesc(void) +{ + unsigned int memsize; + char cmdline[CL_SIZE], *ptr; + + memsize = adm5120_memsize; + /* Check the command line for a memsize directive that overrides + * the physical/default amount */ + strcpy(cmdline, arcs_cmdline); + ptr = strstr(cmdline, "memsize="); + if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) + ptr = strstr(ptr, " memsize="); + + if (ptr) + memsize = memparse(ptr + 8, &ptr); + + memset(mdesc, 0, sizeof(mdesc)); + mdesc[0].type = BOOT_MEM_RAM; + mdesc[0].base = CPHYSADDR(PFN_ALIGN(&_end)); + mdesc[0].size = memsize - mdesc[0].base; + + return &mdesc[0]; +} + +void __init prom_meminit(void) +{ + struct prom_pmemblock *p; + + p = prom_getmdesc(); + + while (p->size) + { + long type; + unsigned long base, size; + base = p->base; + type = p->type, + size = p->size; + add_memory_region(base, size, type); + p++; + } +} + +void __init prom_free_prom_memory(void) +{ + /* We do not have to prom memory to free */ +} diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/prom.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/prom.c new file mode 100644 index 0000000000..c2e1dcbae1 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/prom.c @@ -0,0 +1,126 @@ +/***************************************************************************** + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2003 ADMtek Incorporated. + * daniell@admtek.com.tw + * Copyright (C) 2007 OpenWrt.org + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +static char **prom_envp = NULL; + +void setup_prom_printf(int); +void prom_printf(char *, ...); +void prom_meminit(void); + + +#define READCSR(r) *(volatile unsigned long *)(0xB2600000+(r)) +#define WRITECSR(r,v) *(volatile unsigned long *)(0xB2600000+(r)) = v + +#define UART_DR_REG 0x00 +#define UART_FR_REG 0x18 +#define UART_TX_FIFO_FULL 0x20 + +int putPromChar(char c) +{ + WRITECSR(UART_DR_REG, c); + while ( (READCSR(UART_FR_REG) & UART_TX_FIFO_FULL) ); + return 0; +} + +/* + * Ugly prom_printf used for debugging + */ + +void prom_printf(char *fmt, ...) +{ + va_list args; + int l; + char *p, *buf_end; + char buf[1024]; + + va_start(args, fmt); + l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ + va_end(args); + + buf_end = buf + l; + + for (p = buf; p < buf_end; p++) { + /* Crude cr/nl handling is better than none */ + if (*p == '\n') + putPromChar('\r'); + putPromChar(*p); + } +} + +char *prom_getenv(char *envname) +{ + char **env; + char *ret; + + ret = NULL; + + if (prom_envp== NULL) + return NULL; + + for (env = prom_envp; *env != NULL; env++) { + if (strcmp(envname, *env++) == 0) { + ret = *env; + break; + } + } + + return ret; +} + +extern char _image_cmdline; +/* + * initialize the prom module. + */ +void __init prom_init(void) +{ + char *cmd; + + if ((fw_arg2 & 3) == 0) { + prom_envp = (char **)fw_arg2; + } + + adm5120_info_init(); + + /* you should these macros defined in include/asm/bootinfo.h */ + mips_machgroup = MACH_GROUP_ADM5120; + mips_machtype = adm5120_board.mach_type; + + /* init command line, register a default kernel command line */ + cmd = &_image_cmdline + 8; + if( strlen(cmd) > 0) strcpy( &(arcs_cmdline[0]), cmd); + else strcpy(&(arcs_cmdline[0]), CONFIG_CMDLINE); + + /* init memory map */ + prom_meminit(); +} diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/setup.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/setup.c new file mode 100644 index 0000000000..aa30dc5c83 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/setup.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) ADMtek Incorporated. + * Creator : daniell@admtek.com.tw + * Copyright 1999, 2000 MIPS Technologies, Inc. + * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005 + * Copyright (C) 2007 OpenWrt.org + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +extern void adm5120_time_init(void) __init; + +#define ADM5120_SOFTRESET 0x12000004 + +void adm5120_restart(char *command) +{ + *(u32*)KSEG1ADDR(ADM5120_SOFTRESET)=1; +} + + +void adm5120_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + while (1); +} + + +void adm5120_power_off(void) +{ + adm5120_halt(); +} + +void __init plat_mem_setup(void) +{ + printk(KERN_INFO "ADM5120 board setup\n"); + + board_time_init = adm5120_time_init; + + _machine_restart = adm5120_restart; + _machine_halt = adm5120_halt; + pm_power_off = adm5120_power_off; + + set_io_port_base(KSEG1); +} + +const char *get_system_type(void) +{ + return adm5120_board_name(); +} + +static struct resource adm5120_hcd_resources[] = { + [0] = { + .start = ADM5120_USBC_BASE, + .end = ADM5120_USBC_BASE+ADM5120_USBC_SIZE-1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = ADM5120_IRQ_USBC, + .end = ADM5120_IRQ_USBC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device adm5120hcd_device = { + .name = "adm5120-hcd", + .id = -1, + .num_resources = ARRAY_SIZE(adm5120_hcd_resources), + .resource = adm5120_hcd_resources, +}; + +static struct platform_device *devices[] __initdata = { + &adm5120hcd_device, +}; + +static int __init adm5120_init(void) +{ + return platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +subsys_initcall(adm5120_init); diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/time.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/time.c new file mode 100644 index 0000000000..edf261e7f7 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/time.c @@ -0,0 +1,54 @@ +/* + * $Id$ + * + * ADM5120 specific hooks for MIPS CPU Counter/Compare timer + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * This file was based on: arch/mips/gt64120/wrppmc/time.c + * Original author: Mark.Zhan + * Copyright (C) 1996, 1997, 2004 by Ralf Baechle + * Copyright (C) 2006, Wind River System Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +void __init adm5120_time_init(void) +{ + mips_hpt_frequency = adm5120_speed / 2; +} + +void __init plat_timer_setup(struct irqaction *irq) +{ + clear_c0_status(ST0_BEV); + + /* Install ISR for CPU Counter interrupt */ + setup_irq(ADM5120_IRQ_COUNTER, irq); +} diff --git a/target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c b/target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c new file mode 100644 index 0000000000..e67064d645 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c @@ -0,0 +1,177 @@ +/* + * $Id$ + * + * ADM5120 specific PCI fixups + * + * Copyright (C) ADMtek Incorporated. + * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org) + * Copyright (C) 2007 Gabor Juhos + * Copyright (C) 2007 OpenWrt.org + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +struct adm5120_pci_irq { + u8 slot; + u8 func; + u8 pin; + unsigned irq; +}; + +#define PCIIRQ(s,f,p,i) { \ + .slot = (s), \ + .func = (f), \ + .pin = (p), \ + .irq = (i) \ + } + +static struct adm5120_pci_irq default_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), +}; + +static struct adm5120_pci_irq rb1xx_pci_irqs[] __initdata = { + PCIIRQ(1, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI1), + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI2) +}; + +static struct adm5120_pci_irq cas771_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI1), + PCIIRQ(3, 2, 3, ADM5120_IRQ_PCI2) +}; + +static struct adm5120_pci_irq np28g_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(3, 1, 2, ADM5120_IRQ_PCI1), + PCIIRQ(3, 2, 3, ADM5120_IRQ_PCI2) +}; + +#define GETMAP(n) do { \ + nr_irqs = ARRAY_SIZE(n ## _pci_irqs); \ + p = n ## _pci_irqs; \ + } while (0) + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + struct adm5120_pci_irq *p; + int nr_irqs; + int i; + int irq; + + irq = -1; + if (slot < 1 || slot > 3) { + printk(KERN_ALERT "PCI: slot number %u is not supported\n", + slot); + goto out; + } + + GETMAP(default); + + switch (mips_machtype) { + case MACH_ADM5120_RB_111: + case MACH_ADM5120_RB_112: + case MACH_ADM5120_RB_133: + case MACH_ADM5120_RB_133C: + case MACH_ADM5120_RB_153: + GETMAP(rb1xx); + break; + case MACH_ADM5120_NP28G: + GETMAP(np28g); + break; + case MACH_ADM5120_P335: + case MACH_ADM5120_P334WT: + /* using default mapping */ + break; + case MACH_ADM5120_CAS771: + GETMAP(cas771); + break; + + case MACH_ADM5120_NP27G: + case MACH_ADM5120_NP28GHS: + case MACH_ADM5120_WP54AG: + case MACH_ADM5120_WP54G: + case MACH_ADM5120_WP54G_WRT: + case MACH_ADM5120_WPP54AG: + case MACH_ADM5120_WPP54G: + default: + printk(KERN_ALERT "PCI: irq map is unknown for %s, using " + "defaults.\n", adm5120_board_name()); + break; + } + + for (i=0; islot == slot) && (PCI_FUNC(dev->devfn) == p->func) && + (p->pin == pin)) { + irq = p->irq; + break; + } + } + + if (irq < 0) { + printk(KERN_ALERT "PCI: no irq found for %s pin:%u\n", + pci_name(dev), pin); + } else { + printk(KERN_INFO "PCI: mapping irq for %s pin:%u, irq:%d\n", + pci_name(dev), pin, irq); + } + +out: + return irq; +} + +static void adm5120_pci_fixup(struct pci_dev *dev) +{ + if (dev->devfn != 0) + return; + + /* setup COMMAND register */ + pci_write_config_word(dev, PCI_COMMAND, + (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)); + + /* setup CACHE_LINE_SIZE register */ + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4); + + /* setting up BARS */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_ADM5120, + adm5120_pci_fixup); + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + diff --git a/target/linux/adm5120-2.6/files/arch/mips/pci/ops-adm5120.c b/target/linux/adm5120-2.6/files/arch/mips/pci/ops-adm5120.c new file mode 100644 index 0000000000..f7e4e6686f --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/pci/ops-adm5120.c @@ -0,0 +1,134 @@ +/* + * $Id$ + * + * ADM5120 specific PCI operations + * + * Copyright (C) ADMtek Incorporated. + * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org) + * Copyright (C) 2007 Gabor Juhos + * Copyright (C) 2007 OpenWrt.org + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include + +#include + +#define DEBUG 0 +#if DEBUG +#define DBG(f, ...) printk(f, ## __VA_ARGS__ ) +#else +#define DBG(f, ...) +#endif + +#define PCI_ENABLE 0x80000000 + +static inline void write_cfgaddr(u32 addr) +{ + *(volatile u32*)KSEG1ADDR(ADM5120_PCICFG_ADDR) = (addr | PCI_ENABLE); +} + +static inline void write_cfgdata(u32 data) +{ + *(volatile u32*)KSEG1ADDR(ADM5120_PCICFG_DATA) = data; + +} + +static inline u32 read_cfgdata(void) +{ + return (*(volatile u32*)KSEG1ADDR(ADM5120_PCICFG_DATA)); +} + +static inline u32 mkaddr(struct pci_bus *bus, unsigned int devfn, int where) +{ + return (((bus->number & 0xFF) << 16) | ((devfn & 0xFF) << 8) | \ + (where & 0xFC)); +} + +static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *val) +{ + u32 data; + + write_cfgaddr(mkaddr(bus,devfn,where)); + data = read_cfgdata(); + + DBG("PCI: cfg_read %02u.%02u.%01u/%02X:%01d, cfg:0x%08X", + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, data); + + switch (size) { + case 1: + if (where & 1) + data >>= 8; + if (where & 2) + data >>= 16; + data &= 0xFF; + break; + case 2: + if (where & 2) + data >>= 16; + data &= 0xFFFF; + break; + } + + *val = data; + DBG(", 0x%08X returned\n", data); + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 val) +{ + u32 data; + int s; + + write_cfgaddr(mkaddr(bus,devfn,where)); + data = read_cfgdata(); + + DBG("PCI: cfg_write %02u.%02u.%01u/%02X:%01d, cfg:0x%08X", + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, data); + + switch (size) { + case 1: + s = ((where & 3) << 3); + data &= ~(0xFF << s); + data |= ((val & 0xFF) << s); + break; + case 2: + s = ((where & 2) << 4); + data &= ~(0xFFFF << s); + data |= ((val & 0xFFFF) << s); + break; + case 4: + data = val; + break; + } + + write_cfgdata(data); + DBG(", 0x%08X written\n", data); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops adm5120_pci_ops = { + .read = pci_config_read, + .write = pci_config_write, +}; diff --git a/target/linux/adm5120-2.6/files/arch/mips/pci/pci-adm5120.c b/target/linux/adm5120-2.6/files/arch/mips/pci/pci-adm5120.c new file mode 100644 index 0000000000..f104221046 --- /dev/null +++ b/target/linux/adm5120-2.6/files/arch/mips/pci/pci-adm5120.c @@ -0,0 +1,80 @@ +/* + * $Id$ + * + * ADM5120 PCI Host Controller driver + * + * Copyright (C) ADMtek Incorporated. + * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org) + * Copyright (C) 2007 Gabor Juhos + * Copyright (C) 2007 OpenWrt.org + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#include +#include +#include +#include + +#include +#include +#include + +extern struct pci_ops adm5120_pci_ops; + +static struct resource pci_io_resource = { + .name = "ADM5120 PCI I/O", + .start = ADM5120_PCIIO_BASE, + .end = ADM5120_PCICFG_ADDR-1, + .flags = IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + .name = "ADM5120 PCI MEM", + .start = ADM5120_PCIMEM_BASE, + .end = ADM5120_PCIIO_BASE-1, + .flags = IORESOURCE_MEM +}; + +static struct pci_controller adm5120_controller = { + .pci_ops = &adm5120_pci_ops, + .io_resource = &pci_io_resource, + .mem_resource = &pci_mem_resource, +}; + +static int __init adm5120_pci_setup(void) +{ + int pci_bios; + + pci_bios = adm5120_has_pci(); + + printk("adm5120: system has %sPCI BIOS\n", pci_bios ? "" : "no "); + if (pci_bios == 0) + return -1; + + /* Avoid ISA compat ranges. */ + PCIBIOS_MIN_IO = 0x00000000; + PCIBIOS_MIN_MEM = 0x00000000; + + /* Set I/O resource limits. */ + ioport_resource.end = 0x1fffffff; + iomem_resource.end = 0xffffffff; + + register_pci_controller(&adm5120_controller); + return 0; +} + +arch_initcall(adm5120_pci_setup); diff --git a/target/linux/adm5120-2.6/files/drivers/leds/leds-adm5120.c b/target/linux/adm5120-2.6/files/drivers/leds/leds-adm5120.c new file mode 100644 index 0000000000..ba0269d128 --- /dev/null +++ b/target/linux/adm5120-2.6/files/drivers/leds/leds-adm5120.c @@ -0,0 +1,328 @@ +/* + * $Id$ + * + * ADM5120 GPIO LED devices + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#define NUM_LEDS_MAX 23 + +#define ADM5120_GPIO_xxxx 0x100 /* an unknown pin */ + +struct mach_data { + unsigned long machtype; + unsigned count; + struct gpio_led_platform_data *data; +}; + +struct adm5120_leddev { + struct platform_device pdev; + struct gpio_led_platform_data pdata; +}; + +static int led_count = 0; +static struct adm5120_leddev *led_devs[NUM_LEDS_MAX]; + +#define LED_ARRAY(n) \ +static struct gpio_led_platform_data \ +n ## _leds [] __initdata = + +#define LED_DATA(n,t,g,off,on) { \ + .name = (n), \ + .trigger = (t), \ + .gpio = (g), \ + .value_off = (off), \ + .value_on = (on) \ + } + +#define LED_STD(g,n,t) LED_DATA((n),(t),(g), 0, 1) +#define LED_INV(g,n,t) LED_DATA((n),(t),(g), 1, 0) + +/* + * ZyXEL boards + */ +#if defined(CONFIG_LEDS_ADM5120_EXPERIMENTAL) +LED_ARRAY(p334) { /* FIXME: untested */ + LED_INV(ADM5120_GPIO_xxxx, "power", NULL ), + LED_INV(ADM5120_GPIO_xxxx, "lan1", NULL ), + LED_INV(ADM5120_GPIO_xxxx, "lan2", NULL ), + LED_INV(ADM5120_GPIO_xxxx, "lan3", NULL ), + LED_INV(ADM5120_GPIO_xxxx, "lan4", NULL ), + LED_INV(ADM5120_GPIO_xxxx, "wan", NULL ), +}; +#endif + +LED_ARRAY(p334wt) { + LED_INV(ADM5120_GPIO_PIN2, "power", NULL ), + LED_INV(ADM5120_GPIO_P3L0, "lan1", NULL ), + LED_INV(ADM5120_GPIO_P2L0, "lan2", NULL ), + LED_INV(ADM5120_GPIO_P1L0, "lan3", NULL ), + LED_INV(ADM5120_GPIO_P0L0, "lan4", NULL ), + LED_INV(ADM5120_GPIO_P4L0, "wan", NULL ), + LED_INV(ADM5120_GPIO_P4L2, "wlan", NULL ), + LED_INV(ADM5120_GPIO_P2L2, "otist", NULL ), + LED_INV(ADM5120_GPIO_P1L2, "hidden", NULL ), +}; + +#if defined(CONFIG_LEDS_ADM5120_EXPERIMENTAL) +LED_ARRAY(p335) { /* FIXME: untested */ + LED_INV(ADM5120_GPIO_PIN2, "power", NULL ), + LED_INV(ADM5120_GPIO_P3L0, "lan1", NULL ), + LED_INV(ADM5120_GPIO_P2L0, "lan2", NULL ), + LED_INV(ADM5120_GPIO_P1L0, "lan3", NULL ), + LED_INV(ADM5120_GPIO_P0L0, "lan4", NULL ), + LED_INV(ADM5120_GPIO_P4L0, "wan", NULL ), + LED_INV(ADM5120_GPIO_P4L2, "wlan", NULL ), + LED_INV(ADM5120_GPIO_P2L2, "otist", NULL ), + LED_INV(ADM5120_GPIO_xxxx, "usb", NULL ), +}; +#endif + +/* + * Mikrotik boards + */ +#if defined(CONFIG_LEDS_ADM5120_EXPERIMENTAL) +LED_ARRAY(rb100) { /* FIXME: untested */ + LED_STD(ADM5120_GPIO_PIN6, "power", NULL ), + LED_STD(ADM5120_GPIO_PIN3, "user", NULL ), +}; +#endif + +/* + * Compex boards + */ +#if defined(CONFIG_LEDS_ADM5120_EXPERIMENTAL) +LED_ARRAY(np27g) { /* FIXME: untested */ + LED_STD(ADM5120_GPIO_xxxx, "lan1", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "lan2", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "lan3", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "lan4", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "wan_cond", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "wlan", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "wan_act", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "usb1", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "usb2", NULL ), + LED_INV(ADM5120_GPIO_PIN2, "power", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "diag", NULL ), +}; +#endif + +#if defined(CONFIG_LEDS_ADM5120_EXPERIMENTAL) +LED_ARRAY(np28g) { /* FIXME: untested */ + LED_STD(ADM5120_GPIO_xxxx, "lan1", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "lan2", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "lan3", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "wan", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "wlan", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "usb1", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "usb2", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "usb3", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "usb4", NULL ), + LED_INV(ADM5120_GPIO_PIN2, "power", NULL ), + LED_STD(ADM5120_GPIO_xxxx, "diag", NULL ), +}; +#endif + +LED_ARRAY(wp54g) { + LED_INV(ADM5120_GPIO_PIN2, "diag", NULL ), + LED_INV(ADM5120_GPIO_PIN6, "wlan", NULL ), + LED_INV(ADM5120_GPIO_PIN7, "wan", NULL ), + LED_INV(ADM5120_GPIO_P0L0, "lan1", NULL ), + LED_INV(ADM5120_GPIO_P1L0, "lan2", NULL ), +}; + +LED_ARRAY(unknown) { +#if defined(CONFIG_LEDS_ADM5120_DIAG) + LED_STD(ADM5120_GPIO_PIN0, "gpio0", NULL ), + LED_STD(ADM5120_GPIO_PIN1, "gpio1", NULL ), + LED_STD(ADM5120_GPIO_PIN2, "gpio2", NULL ), + LED_STD(ADM5120_GPIO_PIN3, "gpio3", NULL ), + LED_STD(ADM5120_GPIO_PIN4, "gpio4", NULL ), + LED_STD(ADM5120_GPIO_PIN5, "gpio5", NULL ), + LED_STD(ADM5120_GPIO_PIN6, "gpio6", NULL ), + LED_STD(ADM5120_GPIO_PIN7, "gpio7", NULL ), + LED_STD(ADM5120_GPIO_P0L0, "port0led0", NULL ), + LED_STD(ADM5120_GPIO_P0L1, "port0led1", NULL ), + LED_STD(ADM5120_GPIO_P0L2, "port0led2", NULL ), + LED_STD(ADM5120_GPIO_P1L0, "port1led0", NULL ), + LED_STD(ADM5120_GPIO_P1L1, "port1led1", NULL ), + LED_STD(ADM5120_GPIO_P1L2, "port1led2", NULL ), + LED_STD(ADM5120_GPIO_P2L0, "port2led0", NULL ), + LED_STD(ADM5120_GPIO_P2L1, "port2led1", NULL ), + LED_STD(ADM5120_GPIO_P2L2, "port2led2", NULL ), + LED_STD(ADM5120_GPIO_P3L0, "port3led0", NULL ), + LED_STD(ADM5120_GPIO_P3L1, "port3led1", NULL ), + LED_STD(ADM5120_GPIO_P3L2, "port3led2", NULL ), + LED_STD(ADM5120_GPIO_P4L0, "port4led0", NULL ), + LED_STD(ADM5120_GPIO_P4L1, "port4led1", NULL ), + LED_STD(ADM5120_GPIO_P4L2, "port4led2", NULL ), +#endif +}; + +#define MACH_DATA(m, n) { \ + .machtype = (m), \ + .count = ARRAY_SIZE(n ## _leds), \ + .data = n ## _leds \ +} + +static struct mach_data machines[] __initdata = { + MACH_DATA(MACH_ADM5120_UNKNOWN, unknown), + MACH_DATA(MACH_ADM5120_P334WT, p334wt), + MACH_DATA(MACH_ADM5120_WP54AG, wp54g), + MACH_DATA(MACH_ADM5120_WP54G, wp54g), + MACH_DATA(MACH_ADM5120_WP54G_WRT, wp54g), + MACH_DATA(MACH_ADM5120_WPP54AG, wp54g), + MACH_DATA(MACH_ADM5120_WPP54G, wp54g), +#if defined(CONFIG_LEDS_ADM5120_EXPERIMENTAL) + MACH_DATA(MACH_ADM5120_P334, p334), + MACH_DATA(MACH_ADM5120_P335, p335), + MACH_DATA(MACH_ADM5120_RB_111, rb100), + MACH_DATA(MACH_ADM5120_RB_112, rb100), + MACH_DATA(MACH_ADM5120_NP27G, np27g), + MACH_DATA(MACH_ADM5120_NP28G, np28g), + MACH_DATA(MACH_ADM5120_NP28GHS, np28g), +#endif +}; + +static struct adm5120_leddev * __init +create_leddev(struct gpio_led_platform_data *data) +{ + struct adm5120_leddev *p; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) + return NULL; + + memcpy(&p->pdata, data, sizeof(p->pdata)); + p->pdev.dev.platform_data = &p->pdata; + + return p; +} + +static void +destroy_leddev(struct adm5120_leddev *led) +{ + if (led) + kfree(led); +} + +static struct mach_data * __init +adm5120_leds_findmach(unsigned long machtype) +{ + struct mach_data *mach; + int i; + + mach = NULL; + for (i=0; icount; i++) { + led_devs[i] = create_leddev(&mach->data[i]); + if (led_devs[i] == NULL) { + ret = -ENOMEM; + goto err_destroy; + } + led_devs[i]->pdev.name = "gpio-led"; + led_devs[i]->pdev.id = i; + } + + for (i=0; i < mach->count; i++) { + ret = platform_device_register(&led_devs[i]->pdev); + if (ret) + goto err_unregister; + } + + led_count = mach->count; + return 0; + +err_unregister: + for (i--; i>=0; i--) + platform_device_unregister(&led_devs[i]->pdev); + +err_destroy: + for (i=0; ipdev); + destroy_leddev(led_devs[i]); + } +} + +module_init(adm5120_leds_init); +module_exit(adm5120_leds_exit); + +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION(DRV_DESC); +MODULE_LICENSE("GPL"); + diff --git a/target/linux/adm5120-2.6/files/drivers/leds/leds-gpio.c b/target/linux/adm5120-2.6/files/drivers/leds/leds-gpio.c new file mode 100755 index 0000000000..7ae1432791 --- /dev/null +++ b/target/linux/adm5120-2.6/files/drivers/leds/leds-gpio.c @@ -0,0 +1,209 @@ +/* + * $Id$ + * + * Driver for LEDs connected to GPIO lines + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * This file was derived from: + * /drivers/led/leds-s3c24xx.c + * (c) 2006 Simtec Electronics, Ben Dooks + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#define DRV_NAME "gpio-led" +#define DRV_DESC "GPIO LEDs driver" + +struct gpio_led_device { + struct led_classdev cdev; + struct gpio_led_platform_data *pdata; +}; + +static inline struct gpio_led_device *pdev_to_led(struct platform_device *dev) +{ + return platform_get_drvdata(dev); +} + +static inline struct gpio_led_device *class_to_led(struct led_classdev *led_cdev) +{ + return container_of(led_cdev, struct gpio_led_device, cdev); +} + +static void gpio_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct gpio_led_device *led; + struct gpio_led_platform_data *pdata; + + led = class_to_led(led_cdev); + pdata = led->pdata; + + switch (brightness) { + case LED_OFF: + gpio_direction_output(pdata->gpio, pdata->value_off); + break; + default: + gpio_direction_output(pdata->gpio, pdata->value_on); + break; + } +} + +static int __devinit gpio_led_probe(struct platform_device *dev) +{ + struct gpio_led_platform_data *pdata; + struct gpio_led_device *led; + int ret; + + pdata = dev->dev.platform_data; + if (pdata == NULL) { + dev_err(&dev->dev, "no platform data, id=%d\n", dev->id); + ret = -EINVAL; + goto err; + } + + if (pdata->name == NULL) { + dev_err(&dev->dev, "no led name specified\n"); + ret = -EINVAL; + goto err; + } + + ret = gpio_request(pdata->gpio, pdata->name); + if (ret) { + dev_err(&dev->dev, "gpio_request failed\n"); + goto err; + } + + led = kzalloc(sizeof(*led), GFP_KERNEL); + if (led == NULL) { + dev_err(&dev->dev, "no memory for device"); + ret = -ENOMEM; + goto err_free_gpio; + } + + platform_set_drvdata(dev, led); + led->pdata = pdata; + led->cdev.name = pdata->name; + led->cdev.brightness_set = gpio_led_set; +#ifdef CONFIG_LEDS_TRIGGERS + led->cdev.default_trigger = pdata->trigger; +#endif + + ret = led_classdev_register(&dev->dev, &led->cdev); + if (ret < 0) { + dev_err(&dev->dev, "led_classdev_register failed"); + goto err_free_led; + } + + return 0; + +err_free_led: + kfree(led); +err_free_gpio: + gpio_free(pdata->gpio); +err: + return ret; +} + +static int __devexit gpio_led_remove(struct platform_device *dev) +{ + struct gpio_led_device *led; + struct gpio_led_platform_data *pdata; + + pdata = dev->dev.platform_data; + + led = pdev_to_led(dev); + led_classdev_unregister(&led->cdev); + kfree(led); + + gpio_free(pdata->gpio); + + return 0; +} + +#ifdef CONFIG_PM +static int gpio_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + struct gpio_led_device *led; + + led = pdev_to_led(dev); + led_classdev_suspend(&led->cdev); + + return 0; +} + +static int gpio_led_resume(struct platform_device *dev) +{ + struct gpio_led_device *led; + + led = pdev_to_led(dev); + led_classdev_resume(&led->cdev); + + return 0; +} +#endif /* CONFIG_PM */ + +static struct platform_driver gpio_led_driver = { + .probe = gpio_led_probe, + .remove = __devexit_p(gpio_led_remove), +#ifdef CONFIG_PM + .suspend = gpio_led_suspend, + .resume = gpio_led_resume, +#endif + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init gpio_led_init(void) +{ + int ret; + + ret = platform_driver_register(&gpio_led_driver); + if (ret) + printk(KERN_ALERT DRV_DESC " register failed\n"); + else + printk(KERN_INFO DRV_DESC " registered\n"); + + return ret; +} + +static void __exit gpio_led_exit(void) +{ + platform_driver_unregister(&gpio_led_driver); +} + +module_init(gpio_led_init); +module_exit(gpio_led_exit); + +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION(DRV_DESC); +MODULE_LICENSE("GPL"); diff --git a/target/linux/adm5120-2.6/files/drivers/mtd/maps/adm5120_mtd.c b/target/linux/adm5120-2.6/files/drivers/mtd/maps/adm5120_mtd.c new file mode 100644 index 0000000000..230fceee21 --- /dev/null +++ b/target/linux/adm5120-2.6/files/drivers/mtd/maps/adm5120_mtd.c @@ -0,0 +1,493 @@ +/* + * Copyright (C) 2006 Felix Fietkau + * Copyright (C) 2005 Waldemar Brodkorb + * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) + * + * original functions for finding root filesystem from Mike Baker + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Copyright 2001-2003, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * Flash mapping for ADM5120 boards + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MTD_PARTITIONS +#include +#endif +#include +#include +#include +#include +#include +#include + +extern int parse_myloader_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + unsigned long origin); + +/* Macros for switching flash bank + ADM5120 only support 2MB flash address space + so GPIO5 is used as A20 + */ +#define GPIO_IO ((volatile unsigned long *)0xb20000b8) +#define FLASH_A20_GPIO 5 +#define FLASH_BOUNDARY 0x200000 + + +#define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_VERSION 1 +#define TRX_MAX_LEN 0x3A0000 +#define TRX_NO_HEADER 1 /* Do not write TRX header */ +#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ +#define TRX_MAX_OFFSET 3 + +struct trx_header { + u32 magic; /* "HDR0" */ + u32 len; /* Length of file including header */ + u32 crc32; /* 32-bit CRC from flag_version to end of file */ + u32 flag_version; /* 0:15 flags, 16:31 version */ + u32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ +}; + +#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) +#define NVRAM_SPACE 0x8000 +#define WINDOW_ADDR 0x1fc00000 +#define WINDOW_SIZE 0x400000 +#define BUSWIDTH 2 + +static struct mtd_info *adm5120_mtd; + +static struct map_info adm5120_map = { + name: "adm5120 physically mapped flash", + size: WINDOW_SIZE, + bankwidth: BUSWIDTH, + phys: WINDOW_ADDR, +}; + +#ifdef CONFIG_MTD_PARTITIONS + +static struct mtd_partition adm5120_cfe_parts[] = { + { name: "cfe", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, }, + { name: "linux", offset: 0, size: 0, }, + { name: "rootfs", offset: 0, size: 0, }, + { name: "nvram", offset: 0, size: 0, }, + { name: NULL, }, +}; + + +static void flash_switch_bank(unsigned long addr) +{ + unsigned long val; + + /* Set GPIO as output */ + val = *GPIO_IO | (1 << (FLASH_A20_GPIO+16)); + if ( addr & FLASH_BOUNDARY ) { + val |= 1 << (FLASH_A20_GPIO + 24); + } else { + val &= ~(1 << (FLASH_A20_GPIO + 24)); + } + *GPIO_IO = val; +} + +static map_word adm5120_map_read(struct map_info *map, unsigned long ofs) +{ + flash_switch_bank(ofs); + return inline_map_read(map, ofs); +} + +static void adm5120_map_write(struct map_info *map, const map_word datum, unsigned long ofs) +{ + flash_switch_bank(ofs); + inline_map_write(map, datum, ofs); +} + +static void adm5120_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +{ + ssize_t tmp; + + if (from < FLASH_BOUNDARY) { + tmp = (len < (FLASH_BOUNDARY - from)) ? len : (FLASH_BOUNDARY - from); + flash_switch_bank(0); + inline_map_copy_from(map, to, from, tmp); + to = (void *)((char *)to + tmp); + from += tmp; + len -= tmp; + } + if (len > 0) { + flash_switch_bank(FLASH_BOUNDARY); + inline_map_copy_from(map, to, from, len); + } + +} + +static int __init +find_cfe_size(struct mtd_info *mtd, size_t size) +{ + struct trx_header *trx; + unsigned char buf[512]; + int off; + size_t len; + int blocksize; + + trx = (struct trx_header *) buf; + + blocksize = mtd->erasesize; + if (blocksize < 0x10000) + blocksize = 0x10000; + + for (off = (128*1024); off < size; off += blocksize) { + memset(buf, 0xe5, sizeof(buf)); + + /* + * Read into buffer + */ + if (mtd->read(mtd, off, sizeof(buf), &len, buf) || + len != sizeof(buf)) + continue; + + /* found a TRX header */ + if (le32_to_cpu(trx->magic) == TRX_MAGIC) { + goto found; + } + } + + printk(KERN_NOTICE + "%s: Couldn't find bootloader size\n", + mtd->name); + return -1; + + found: + printk(KERN_NOTICE "bootloader size: %d\n", off); + return off; + +} + +/* + * Copied from mtdblock.c + * + * Cache stuff... + * + * Since typical flash erasable sectors are much larger than what Linux's + * buffer cache can handle, we must implement read-modify-write on flash + * sectors for each block write requests. To avoid over-erasing flash sectors + * and to speed things up, we locally cache a whole flash sector while it is + * being written to until a different sector is required. + */ + +static void erase_callback(struct erase_info *done) +{ + wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; + wake_up(wait_q); +} + +static int erase_write (struct mtd_info *mtd, unsigned long pos, + int len, const char *buf) +{ + struct erase_info erase; + DECLARE_WAITQUEUE(wait, current); + wait_queue_head_t wait_q; + size_t retlen; + int ret; + + /* + * First, let's erase the flash block. + */ + + init_waitqueue_head(&wait_q); + erase.mtd = mtd; + erase.callback = erase_callback; + erase.addr = pos; + erase.len = len; + erase.priv = (u_long)&wait_q; + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&wait_q, &wait); + + ret = mtd->erase(mtd, &erase); + if (ret) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&wait_q, &wait); + printk (KERN_WARNING "erase of region [0x%lx, 0x%x] " + "on \"%s\" failed\n", + pos, len, mtd->name); + return ret; + } + + schedule(); /* Wait for erase to finish. */ + remove_wait_queue(&wait_q, &wait); + + /* + * Next, writhe data to flash. + */ + + ret = mtd->write (mtd, pos, len, &retlen, buf); + if (ret) + return ret; + if (retlen != len) + return -EIO; + return 0; +} + + + + +static int __init +find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part) +{ + struct trx_header trx, *trx2; + unsigned char buf[512], *block; + int off, blocksize; + u32 i, crc = ~0; + size_t len; + struct squashfs_super_block *sb = (struct squashfs_super_block *) buf; + + blocksize = mtd->erasesize; + if (blocksize < 0x10000) + blocksize = 0x10000; + + for (off = (128*1024); off < size; off += blocksize) { + memset(&trx, 0xe5, sizeof(trx)); + + /* + * Read into buffer + */ + if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) || + len != sizeof(trx)) + continue; + + /* found a TRX header */ + if (le32_to_cpu(trx.magic) == TRX_MAGIC) { + part->offset = le32_to_cpu(trx.offsets[2]) ? : + le32_to_cpu(trx.offsets[1]); + part->size = le32_to_cpu(trx.len); + + part->size -= part->offset; + part->offset += off; + + goto found; + } + } + + printk(KERN_NOTICE + "%s: Couldn't find root filesystem\n", + mtd->name); + return -1; + + found: + if (part->size == 0) + return 0; + + if (mtd->read(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf)) + return 0; + + /* Move the fs outside of the trx */ + part->size = 0; + + if (trx.len != part->offset + part->size - off) { + /* Update the trx offsets and length */ + trx.len = part->offset + part->size - off; + + /* Update the trx crc32 */ + for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) { + if (mtd->read(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf)) + return 0; + crc = crc32_le(crc, buf, min(sizeof(buf), trx.len - i)); + } + trx.crc32 = crc; + + /* read first eraseblock from the trx */ + block = kmalloc(mtd->erasesize, GFP_KERNEL); + trx2 = (struct trx_header *) block; + if (mtd->read(mtd, off, mtd->erasesize, &len, block) || len != mtd->erasesize) { + printk("Error accessing the first trx eraseblock\n"); + return 0; + } + + printk("Updating TRX offsets and length:\n"); + printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32); + printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx.offsets[0], trx.offsets[1], trx.offsets[2], trx.len, trx.crc32); + + /* Write updated trx header to the flash */ + memcpy(block, &trx, sizeof(trx)); + if (mtd->unlock) + mtd->unlock(mtd, off, mtd->erasesize); + erase_write(mtd, off, mtd->erasesize, block); + if (mtd->sync) + mtd->sync(mtd); + kfree(block); + printk("Done\n"); + } + + return part->size; +} + +struct mtd_partition * __init +init_mtd_partitions(struct mtd_info *mtd, size_t size) +{ + int cfe_size; + + if ((cfe_size = find_cfe_size(mtd,size)) < 0) + return NULL; + + /* boot loader */ + adm5120_cfe_parts[0].offset = 0; + adm5120_cfe_parts[0].size = cfe_size; + + /* nvram */ + if (cfe_size != 384 * 1024) { + adm5120_cfe_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize); + adm5120_cfe_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize); + } else { + /* nvram (old 128kb config partition on netgear wgt634u) */ + adm5120_cfe_parts[3].offset = adm5120_cfe_parts[0].size; + adm5120_cfe_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize); + } + + /* linux (kernel and rootfs) */ + if (cfe_size != 384 * 1024) { + adm5120_cfe_parts[1].offset = adm5120_cfe_parts[0].size; + adm5120_cfe_parts[1].size = adm5120_cfe_parts[3].offset - + adm5120_cfe_parts[1].offset; + } else { + /* do not count the elf loader, which is on one block */ + adm5120_cfe_parts[1].offset = adm5120_cfe_parts[0].size + + adm5120_cfe_parts[3].size + mtd->erasesize; + adm5120_cfe_parts[1].size = size - + adm5120_cfe_parts[0].size - + (2*adm5120_cfe_parts[3].size) - + mtd->erasesize; + } + + /* find and size rootfs */ + find_root(mtd,size,&adm5120_cfe_parts[2]); + adm5120_cfe_parts[2].size = size - adm5120_cfe_parts[2].offset - adm5120_cfe_parts[3].size; + + return adm5120_cfe_parts; +} +#endif + +int __init init_adm5120_map(void) +{ + size_t size; + int ret = 0; +#if defined (CONFIG_MTD_PARTITIONS) || (CONFIG_MTD_MYLOADER_PARTS) + struct mtd_partition *parts; + int i, parsed_nr_parts = 0; +#endif + printk("adm5120 : flash init : 0x%08x 0x%08x\n", WINDOW_ADDR, adm5120_board.flash0_size); + adm5120_map.virt = ioremap_nocache(WINDOW_ADDR, adm5120_board.flash0_size); + + if (!adm5120_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } + simple_map_init(&adm5120_map); + adm5120_map.read = adm5120_map_read; + adm5120_map.write = adm5120_map_write; + adm5120_map.copy_from = adm5120_map_copy_from; + + if (!(adm5120_mtd = do_map_probe("cfi_probe", &adm5120_map))) { + printk("Failed to do_map_probe\n"); + iounmap((void *)adm5120_map.virt); + return -ENXIO; + } + + adm5120_mtd->owner = THIS_MODULE; + + size = adm5120_mtd->size; + + printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, WINDOW_ADDR); + +#ifdef CONFIG_MTD_PARTITIONS + + if (adm5120_boot_loader == BOOT_LOADER_CFE) + { + printk(KERN_NOTICE "adm5120 : using CFE flash mapping\n"); + parts = init_mtd_partitions(adm5120_mtd, size); + + for (i = 0; parts[i].name; i++); + ret = add_mtd_partitions(adm5120_mtd, parts, i); + + if (ret) { + printk(KERN_ERR "Flash: add_mtd_partitions failed\n"); + goto fail; + } + } +#endif +#ifdef CONFIG_MTD_MYLOADER_PARTS + if (adm5120_boot_loader == BOOT_LOADER_MYLOADER) + { + printk(KERN_NOTICE "adm5120 : using MyLoader flash mapping\n"); + char *part_type; + + if (parsed_nr_parts == 0) { + ret = parse_myloader_partitions(adm5120_mtd, &parts, 0); + + if (ret > 0) { + part_type ="MyLoader"; + parsed_nr_parts = ret; + } + } + ret = add_mtd_partitions(adm5120_mtd, parts, parsed_nr_parts); + + if (ret) { + printk(KERN_ERR "Flash: add_mtd_partitions failed\n"); + goto fail; + } + } +#endif + return 0; + + fail: + if (adm5120_mtd) + map_destroy(adm5120_mtd); + if (adm5120_map.virt) + iounmap((void *)adm5120_map.virt); + adm5120_map.virt = 0; + return ret; +} + +void __exit cleanup_adm5120_map(void) +{ +#ifdef CONFIG_MTD_PARTITIONS + del_mtd_partitions(adm5120_mtd); +#endif + map_destroy(adm5120_mtd); + iounmap((void *)adm5120_map.virt); +} + +module_init(init_adm5120_map); +module_exit(cleanup_adm5120_map); diff --git a/target/linux/adm5120-2.6/files/drivers/mtd/myloader.c b/target/linux/adm5120-2.6/files/drivers/mtd/myloader.c new file mode 100644 index 0000000000..ee916d7800 --- /dev/null +++ b/target/linux/adm5120-2.6/files/drivers/mtd/myloader.c @@ -0,0 +1,176 @@ +/* + * Parse MyLoader-style flash partition tables and produce a Linux partition + * array to match. + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * This file was based on drivers/mtd/redboot.c + * Author: Red Hat, Inc. - David Woodhouse + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define NAME_LEN_MAX 20 +#define NAME_MYLOADER "MyLoader" +#define NAME_PARTITION_TABLE "Partition Table" +#define BLOCK_LEN_MIN 0x10000 + +int parse_myloader_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + unsigned long origin) +{ + struct mylo_partition_table *tab; + struct mylo_partition *part; + struct mtd_partition *mtd_parts; + struct mtd_partition *mtd_part; + int num_parts; + int ret, i; + size_t retlen; + size_t parts_len; + char *names; + unsigned long offset; + unsigned long blocklen; + + tab = vmalloc(sizeof(*tab)); + if (!tab) { + return -ENOMEM; + goto out; + } + + blocklen = master->erasesize; + if (blocklen < BLOCK_LEN_MIN) + blocklen = BLOCK_LEN_MIN; + + /* Partition Table is always located on the second erase block */ + offset = blocklen; + printk(KERN_NOTICE "Searching for MyLoader partition table " + "in %s at offset 0x%lx\n", master->name, offset); + + ret = master->read(master, offset, sizeof(*tab), &retlen, + (void *)tab); + + if (ret) + goto out; + + if (retlen != sizeof(*tab)) { + ret = -EIO; + goto out_free_buf; + } + + /* Check for Partition Table magic number */ + if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) { + printk(KERN_NOTICE "No MyLoader partition table detected " + "in %s\n", master->name); + ret = 0; + goto out_free_buf; + } + + /* The MyLoader and the Partition Table is always present */ + num_parts = 2; + + /* Detect number of used partitions */ + for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { + part = &tab->partitions[i]; + + if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) + continue; + + num_parts++; + } + + + mtd_parts = kzalloc((num_parts*sizeof(*mtd_part) + num_parts*NAME_LEN_MAX), + GFP_KERNEL); + + if (!mtd_parts) { + ret = -ENOMEM; + goto out_free_buf; + } + + mtd_part = mtd_parts; + names = (char *)&mtd_parts[num_parts]; + + strncpy(names, NAME_MYLOADER, NAME_LEN_MAX-1); + mtd_part->name = names; + mtd_part->offset = 0; + mtd_part->size = blocklen; + mtd_part++; + names += NAME_LEN_MAX; + + strncpy(names, NAME_PARTITION_TABLE, NAME_LEN_MAX-1); + mtd_part->name = names; + mtd_part->offset = blocklen; + mtd_part->size = blocklen; + mtd_part++; + names += NAME_LEN_MAX; + + for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { + part = &tab->partitions[i]; + + if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) + continue; + + sprintf(names, "partition%d", i); + mtd_part->name = names; + mtd_part->offset = le32_to_cpu(part->addr); + mtd_part->size = le32_to_cpu(part->size); + mtd_part++; + names += NAME_LEN_MAX; + } + + *pparts = mtd_parts; + ret = num_parts; + +out_free_buf: + vfree(tab); +out: + return ret; +} + +static struct mtd_part_parser mylo_mtd_parser = { + .owner = THIS_MODULE, + .parse_fn = parse_myloader_partitions, + .name = NAME_MYLOADER, +}; + +static int __init mylo_mtd_parser_init(void) +{ + return register_mtd_parser(&mylo_mtd_parser); +} + +static void __exit mylo_mtd_parser_exit(void) +{ + deregister_mtd_parser(&mylo_mtd_parser); +} + +module_init(mylo_mtd_parser_init); +module_exit(mylo_mtd_parser_exit); + +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION("Parsing code for MyLoader partition tables"); +MODULE_LICENSE("GPL"); diff --git a/target/linux/adm5120-2.6/files/drivers/mtd/nand/rbmipsnand.c b/target/linux/adm5120-2.6/files/drivers/mtd/nand/rbmipsnand.c new file mode 100644 index 0000000000..306b97cc71 --- /dev/null +++ b/target/linux/adm5120-2.6/files/drivers/mtd/nand/rbmipsnand.c @@ -0,0 +1,122 @@ +/*==============================================================================*/ +/* rbmipsnand.c */ +/* This module is derived from the 2.4 driver shipped by Microtik for their */ +/* Routerboard 1xx and 5xx series boards. It provides support for the built in */ +/* NAND flash on the Routerboard 1xx series boards for Linux 2.6.19+. */ +/* Licence: Original Microtik code seems not to have a licence. */ +/* Rewritten code all GPL V2. */ +/* Copyright(C) 2007 david.goodenough@linkchoose.co.uk (for rewriten code) */ +/*==============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SMEM1_BASE 0x10000000 // from ADM5120 documentation +#define SMEM1(x) (*((volatile unsigned char *) (KSEG1ADDR(SMEM1_BASE) + x))) + +#define NAND_RW_REG 0x0 //data register +#define NAND_SET_CEn 0x1 //CE# low +#define NAND_CLR_CEn 0x2 //CE# high +#define NAND_CLR_CLE 0x3 //CLE low +#define NAND_SET_CLE 0x4 //CLE high +#define NAND_CLR_ALE 0x5 //ALE low +#define NAND_SET_ALE 0x6 //ALE high +#define NAND_SET_SPn 0x7 //SP# low (use spare area) +#define NAND_CLR_SPn 0x8 //SP# high (do not use spare area) +#define NAND_SET_WPn 0x9 //WP# low +#define NAND_CLR_WPn 0xA //WP# high +#define NAND_STS_REG 0xB //Status register + +#define MEM32(x) *((volatile unsigned *) (x)) +static void __iomem *p_nand; + +static int rb100_dev_ready(struct mtd_info *mtd) { + return SMEM1(NAND_STS_REG) & 0x80; +} + +static void rbmips_hwcontrol100(struct mtd_info *mtd, int cmd, unsigned int ctrl) { + struct nand_chip *chip = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { + SMEM1((( ctrl & NAND_CLE) ? NAND_SET_CLE : NAND_CLR_CLE)) = 0x01; + SMEM1((( ctrl & NAND_ALE) ? NAND_SET_ALE : NAND_CLR_ALE)) = 0x01; + SMEM1((( ctrl & NAND_NCE) ? NAND_SET_CEn : NAND_CLR_CEn)) = 0x01; + } + if( cmd != NAND_CMD_NONE) + writeb( cmd, chip->IO_ADDR_W); +} + +static struct mtd_partition partition_info[] = { + { + name: "RouterBoard NAND Boot", + offset: 0, + size: 4 * 1024 * 1024 + }, + { + name: "rootfs", + offset: MTDPART_OFS_NXTBLK, + size: MTDPART_SIZ_FULL + } +}; + +static struct mtd_info rmtd; +static struct nand_chip rnand; +/*========================================================================*/ +/* We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader */ +/* will not be able to find the kernel that we load. So set the oobinfo */ +/* when creating the partitions. */ +/*========================================================================*/ +static struct nand_ecclayout rb_ecclayout = { + .eccbytes = 6, + .eccpos = { 8, 9, 10, 13, 14, 15 }, + .oobavail = 9, + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1} } +}; +static unsigned init_ok = 0; + +unsigned get_rbnand_block_size(void) { + return init_ok ? rmtd.writesize : 0; +} + +EXPORT_SYMBOL(get_rbnand_block_size); + +int __init rbmips_init(void) { + memset(&rmtd, 0, sizeof(rmtd)); + memset(&rnand, 0, sizeof(rnand)); + printk(KERN_INFO "RB1xx nand\n"); + MEM32(0xB2000064) = 0x100; + MEM32(0xB2000008) = 0x1; + SMEM1(NAND_SET_SPn) = 0x01; + SMEM1(NAND_CLR_WPn) = 0x01; + rnand.IO_ADDR_R = (unsigned char *)KSEG1ADDR(SMEM1_BASE); + rnand.IO_ADDR_W = rnand.IO_ADDR_R; + rnand.cmd_ctrl = rbmips_hwcontrol100; + rnand.dev_ready = rb100_dev_ready; + p_nand = (void __iomem *)ioremap(( unsigned long)SMEM1_BASE, 0x1000); + if (!p_nand) { + printk(KERN_WARNING "RB1xx nand Unable ioremap buffer\n"); + return -ENXIO; + } + rnand.ecc.mode = NAND_ECC_SOFT; + rnand.ecc.layout = &rb_ecclayout; + rnand.chip_delay = 25; + rnand.options |= NAND_NO_AUTOINCR; + rmtd.priv = &rnand; + if (nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1) + && nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1)) { + printk(KERN_INFO "RB1xxx nand device not found\n"); + iounmap ((void *)p_nand); + return -ENXIO; + } + add_mtd_partitions(&rmtd, partition_info, 2); + init_ok = 1; + return 0; +} + +module_init(rbmips_init); + diff --git a/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.c b/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.c new file mode 100644 index 0000000000..dfc030ea1c --- /dev/null +++ b/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.c @@ -0,0 +1,541 @@ +/* + * ADM5120 built in ethernet switch driver + * + * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005 + * + * Inspiration for this driver came from the original ADMtek 2.4 + * driver, Copyright ADMtek Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "adm5120sw.h" + +#include +#include + +MODULE_AUTHOR("Jeroen Vreeken (pe1rxq@amsat.org)"); +MODULE_DESCRIPTION("ADM5120 ethernet switch driver"); +MODULE_LICENSE("GPL"); + +/* + * The ADM5120 uses an internal matrix to determine which ports + * belong to which VLAN. + * The default generates a VLAN (and device) for each port + * (including MII port) and the CPU port is part of all of them. + * + * Another example, one big switch and everything mapped to eth0: + * 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00 + */ +static unsigned char vlan_matrix[SW_DEVS] = { + 0x41, 0x42, 0x44, 0x48, 0x50, 0x60 +}; + +/* default settings - unlimited TX and RX on all ports, default shaper mode */ +static unsigned char bw_matrix[SW_DEVS] = { + 0, 0, 0, 0, 0, 0 +}; + +static int adm5120_nrdevs; + +static struct net_device *adm5120_devs[SW_DEVS]; +static struct adm5120_dma + adm5120_dma_txh_v[ADM5120_DMA_TXH] __attribute__((aligned(16))), + adm5120_dma_txl_v[ADM5120_DMA_TXL] __attribute__((aligned(16))), + adm5120_dma_rxh_v[ADM5120_DMA_RXH] __attribute__((aligned(16))), + adm5120_dma_rxl_v[ADM5120_DMA_RXL] __attribute__((aligned(16))), + *adm5120_dma_txh, + *adm5120_dma_txl, + *adm5120_dma_rxh, + *adm5120_dma_rxl; +static struct sk_buff + *adm5120_skb_rxh[ADM5120_DMA_RXH], + *adm5120_skb_rxl[ADM5120_DMA_RXL], + *adm5120_skb_txh[ADM5120_DMA_TXH], + *adm5120_skb_txl[ADM5120_DMA_TXL]; +static int adm5120_rxhi = 0; +static int adm5120_rxli = 0; +/* We don't use high priority tx for now */ +/*static int adm5120_txhi = 0;*/ +static int adm5120_txli = 0; +static int adm5120_txhit = 0; +static int adm5120_txlit = 0; +static int adm5120_if_open = 0; + +static inline void adm5120_set_reg(unsigned int reg, unsigned long val) +{ + *(volatile unsigned long*)(SW_BASE+reg) = val; +} + +static inline unsigned long adm5120_get_reg(unsigned int reg) +{ + return *(volatile unsigned long*)(SW_BASE+reg); +} + +static inline void adm5120_rxfixup(struct adm5120_dma *dma, + struct sk_buff **skbl, int num) +{ + int i; + + /* Resubmit the entire ring */ + for (i=0; idata) | + ADM5120_DMA_OWN | (i==num-1 ? ADM5120_DMA_RINGEND : 0); + } +} + +static inline void adm5120_rx(struct adm5120_dma *dma, struct sk_buff **skbl, + int *index, int num) +{ + struct sk_buff *skb, *skbn; + struct adm5120_sw *priv; + struct net_device *dev; + int port, vlan, len; + + while (!(dma[*index].data & ADM5120_DMA_OWN)) { + port = (dma[*index].status & ADM5120_DMA_PORTID); + port >>= ADM5120_DMA_PORTSHIFT; + for (vlan = 0; vlan < adm5120_nrdevs; vlan++) { + if ((1<>= ADM5120_DMA_LENSHIFT; + len -= ETH_FCS; + + priv = netdev_priv(dev); + if (len <= 0 || len > ADM5120_DMA_RXSIZE || + dma[*index].status & ADM5120_DMA_FCSERR) { + priv->stats.rx_errors++; + skbn = NULL; + } else { + skbn = dev_alloc_skb(ADM5120_DMA_RXSIZE+16); + if (skbn) { + skb_put(skb, len); + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + skb->ip_summed = CHECKSUM_UNNECESSARY; + dev->last_rx = jiffies; + priv->stats.rx_packets++; + priv->stats.rx_bytes+=len; + skb_reserve(skbn, 2); + skbl[*index] = skbn; + } else { + printk(KERN_INFO "%s recycling!\n", dev->name); + } + } + + dma[*index].status = 0; + dma[*index].cntl = 0; + dma[*index].len = ADM5120_DMA_RXSIZE; + dma[*index].data = ADM5120_DMA_ADDR(skbl[*index]->data) | + ADM5120_DMA_OWN | + (num-1==*index ? ADM5120_DMA_RINGEND : 0); + if (num == ++*index) + *index = 0; + if (skbn) + netif_rx(skb); + } +} + +static inline void adm5120_tx(struct adm5120_dma *dma, struct sk_buff **skbl, + int *index, int num) +{ + while((dma[*index].data & ADM5120_DMA_OWN) == 0 && skbl[*index]) { + dev_kfree_skb_irq(skbl[*index]); + skbl[*index] = NULL; + if (++*index == num) + *index = 0; + } +} + +static irqreturn_t adm5120_sw_irq(int irq, void *dev_id) +{ + unsigned long intreg; + + adm5120_set_reg(ADM5120_INT_MASK, + adm5120_get_reg(ADM5120_INT_MASK) | ADM5120_INTHANDLE); + + intreg = adm5120_get_reg(ADM5120_INT_ST); + adm5120_set_reg(ADM5120_INT_ST, intreg); + + if (intreg & ADM5120_INT_RXH) + adm5120_rx(adm5120_dma_rxh, adm5120_skb_rxh, &adm5120_rxhi, + ADM5120_DMA_RXH); + if (intreg & ADM5120_INT_HFULL) + adm5120_rxfixup(adm5120_dma_rxh, adm5120_skb_rxh, + ADM5120_DMA_RXH); + if (intreg & ADM5120_INT_RXL) + adm5120_rx(adm5120_dma_rxl, adm5120_skb_rxl, &adm5120_rxli, + ADM5120_DMA_RXL); + if (intreg & ADM5120_INT_LFULL) + adm5120_rxfixup(adm5120_dma_rxl, adm5120_skb_rxl, + ADM5120_DMA_RXL); + if (intreg & ADM5120_INT_TXH) + adm5120_tx(adm5120_dma_txh, adm5120_skb_txh, &adm5120_txhit, + ADM5120_DMA_TXH); + if (intreg & ADM5120_INT_TXL) + adm5120_tx(adm5120_dma_txl, adm5120_skb_txl, &adm5120_txlit, + ADM5120_DMA_TXL); + + adm5120_set_reg(ADM5120_INT_MASK, + adm5120_get_reg(ADM5120_INT_MASK) & ~ADM5120_INTHANDLE); + + return IRQ_HANDLED; +} + +static void adm5120_set_vlan(char *matrix) +{ + unsigned long val; + + val = matrix[0] + (matrix[1]<<8) + (matrix[2]<<16) + (matrix[3]<<24); + adm5120_set_reg(ADM5120_VLAN_GI, val); + val = matrix[4] + (matrix[5]<<8); + adm5120_set_reg(ADM5120_VLAN_GII, val); +} + +static void adm5120_set_bw(char *matrix) +{ + unsigned long val; + + /* Port 0 to 3 are set using the bandwidth control 0 register */ + val = matrix[0] + (matrix[1]<<8) + (matrix[2]<<16) + (matrix[3]<<24); + adm5120_set_reg(ADM5120_BW_CTL0, val); + + /* Port 4 and 5 are set using the bandwidth control 1 register */ + val = matrix[4]; + if (matrix[5] == 1) + adm5120_set_reg(ADM5120_BW_CTL1, val | 0x80000000); + else + adm5120_set_reg(ADM5120_BW_CTL1, val & ~0x8000000); + + printk(KERN_DEBUG "D: ctl0 0x%x, ctl1 0x%x\n", + adm5120_get_reg(ADM5120_BW_CTL0), + adm5120_get_reg(ADM5120_BW_CTL1)); +} + +static int adm5120_sw_open(struct net_device *dev) +{ + if (!adm5120_if_open++) + adm5120_set_reg(ADM5120_INT_MASK, + adm5120_get_reg(ADM5120_INT_MASK) & ~ADM5120_INTHANDLE); + netif_start_queue(dev); + return 0; +} + +static int adm5120_sw_stop(struct net_device *dev) +{ + netif_stop_queue(dev); + if (!--adm5120_if_open) + adm5120_set_reg(ADM5120_INT_MASK, + adm5120_get_reg(ADM5120_INT_MASK) | ADM5120_INTMASKALL); + return 0; +} + +static int adm5120_sw_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct adm5120_dma *dma = adm5120_dma_txl; + struct sk_buff **skbl = adm5120_skb_txl; + struct adm5120_sw *priv = netdev_priv(dev); + int *index = &adm5120_txli; + int num = ADM5120_DMA_TXL; + int trigger = ADM5120_SEND_TRIG_L; + + dev->trans_start = jiffies; + if (dma[*index].data & ADM5120_DMA_OWN) { + dev_kfree_skb(skb); + priv->stats.tx_dropped++; + return 0; + } + + dma[*index].data = ADM5120_DMA_ADDR(skb->data) | ADM5120_DMA_OWN; + if (*index == num-1) + dma[*index].data |= ADM5120_DMA_RINGEND; + dma[*index].status = + ((skb->lenlen) << ADM5120_DMA_LENSHIFT) | + (0x1 << priv->port); + dma[*index].len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; + priv->stats.tx_packets++; + priv->stats.tx_bytes += skb->len; + skbl[*index]=skb; + + if (++*index == num) + *index = 0; + adm5120_set_reg(ADM5120_SEND_TRIG, trigger); + + return 0; +} + +static void adm5120_tx_timeout(struct net_device *dev) +{ + netif_wake_queue(dev); +} + +static struct net_device_stats *adm5120_sw_stats(struct net_device *dev) +{ + return &((struct adm5120_sw *)netdev_priv(dev))->stats; +} + +static void adm5120_set_multicast_list(struct net_device *dev) +{ + struct adm5120_sw *priv = netdev_priv(dev); + int portmask; + + portmask = vlan_matrix[priv->port] & 0x3f; + + if (dev->flags & IFF_PROMISC) + adm5120_set_reg(ADM5120_CPUP_CONF, + adm5120_get_reg(ADM5120_CPUP_CONF) & + ~((portmask << ADM5120_DISUNSHIFT) & ADM5120_DISUNALL)); + else + adm5120_set_reg(ADM5120_CPUP_CONF, + adm5120_get_reg(ADM5120_CPUP_CONF) | + (portmask << ADM5120_DISUNSHIFT)); + + if (dev->flags & IFF_PROMISC || dev->flags & IFF_ALLMULTI || + dev->mc_count) + adm5120_set_reg(ADM5120_CPUP_CONF, + adm5120_get_reg(ADM5120_CPUP_CONF) & + ~((portmask << ADM5120_DISMCSHIFT) & ADM5120_DISMCALL)); + else + adm5120_set_reg(ADM5120_CPUP_CONF, + adm5120_get_reg(ADM5120_CPUP_CONF) | + (portmask << ADM5120_DISMCSHIFT)); +} + +static void adm5120_write_mac(struct net_device *dev) +{ + struct adm5120_sw *priv = netdev_priv(dev); + unsigned char *mac = dev->dev_addr; + + adm5120_set_reg(ADM5120_MAC_WT1, + mac[2] | (mac[3]<<8) | (mac[4]<<16) | (mac[5]<<24)); + adm5120_set_reg(ADM5120_MAC_WT0, (priv->port<<3) | + (mac[0]<<16) | (mac[1]<<24) | ADM5120_MAC_WRITE | ADM5120_VLAN_EN); + + while (!(adm5120_get_reg(ADM5120_MAC_WT0) & ADM5120_MAC_WRITE_DONE)); +} + +static int adm5120_sw_set_mac_address(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + adm5120_write_mac(dev); + return 0; +} + +static int adm5120_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + int err; + struct adm5120_sw_info info; + struct adm5120_sw *priv = netdev_priv(dev); + + switch(cmd) { + case SIOCGADMINFO: + info.magic = 0x5120; + info.ports = adm5120_nrdevs; + info.vlan = priv->port; + err = copy_to_user(rq->ifr_data, &info, sizeof(info)); + if (err) + return -EFAULT; + break; + case SIOCSMATRIX: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + err = copy_from_user(vlan_matrix, rq->ifr_data, + sizeof(vlan_matrix)); + if (err) + return -EFAULT; + adm5120_set_vlan(vlan_matrix); + break; + case SIOCGMATRIX: + err = copy_to_user(rq->ifr_data, vlan_matrix, + sizeof(vlan_matrix)); + if (err) + return -EFAULT; + break; + case SIOCGETBW: + err = copy_to_user(rq->ifr_data, bw_matrix, sizeof(bw_matrix)); + if (err) + return -EFAULT; + break; + case SIOCSETBW: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + err = copy_from_user(bw_matrix, rq->ifr_data, sizeof(bw_matrix)); + if (err) + return -EFAULT; + adm5120_set_bw(bw_matrix); + break; + default: + return -EOPNOTSUPP; + } + return 0; +} + +static void adm5120_dma_tx_init(struct adm5120_dma *dma, struct sk_buff **skb, + int num) +{ + memset(dma, 0, sizeof(struct adm5120_dma)*num); + dma[num-1].data |= ADM5120_DMA_RINGEND; + memset(skb, 0, sizeof(struct skb*)*num); +} + +static void adm5120_dma_rx_init(struct adm5120_dma *dma, struct sk_buff **skb, + int num) +{ + int i; + + memset(dma, 0, sizeof(struct adm5120_dma)*num); + for (i=0; idata) | ADM5120_DMA_OWN; + dma[i].cntl = 0; + dma[i].len = ADM5120_DMA_RXSIZE; + dma[i].status = 0; + } + dma[i-1].data |= ADM5120_DMA_RINGEND; +} + +static int __init adm5120_sw_init(void) +{ + int i, err; + struct net_device *dev; + + err = request_irq(ADM5120_IRQ_SWITCH, adm5120_sw_irq, 0, "ethernet switch", NULL); + if (err) + goto out; + + adm5120_nrdevs = adm5120_board.iface_num; + if (adm5120_nrdevs > 5 && !adm5120_has_gmii()) + adm5120_nrdevs = 5; + + adm5120_set_reg(ADM5120_CPUP_CONF, + ADM5120_DISCCPUPORT | ADM5120_CRC_PADDING | + ADM5120_DISUNALL | ADM5120_DISMCALL); + adm5120_set_reg(ADM5120_PORT_CONF0, ADM5120_ENMC | ADM5120_ENBP); + + adm5120_set_reg(ADM5120_PHY_CNTL2, adm5120_get_reg(ADM5120_PHY_CNTL2) | + ADM5120_AUTONEG | ADM5120_NORMAL | ADM5120_AUTOMDIX); + adm5120_set_reg(ADM5120_PHY_CNTL3, adm5120_get_reg(ADM5120_PHY_CNTL3) | + ADM5120_PHY_NTH); + + adm5120_set_reg(ADM5120_INT_MASK, ADM5120_INTMASKALL); + adm5120_set_reg(ADM5120_INT_ST, ADM5120_INTMASKALL); + + adm5120_dma_txh = (void *)KSEG1ADDR((u32)adm5120_dma_txh_v); + adm5120_dma_txl = (void *)KSEG1ADDR((u32)adm5120_dma_txl_v); + adm5120_dma_rxh = (void *)KSEG1ADDR((u32)adm5120_dma_rxh_v); + adm5120_dma_rxl = (void *)KSEG1ADDR((u32)adm5120_dma_rxl_v); + + adm5120_dma_tx_init(adm5120_dma_txh, adm5120_skb_txh, ADM5120_DMA_TXH); + adm5120_dma_tx_init(adm5120_dma_txl, adm5120_skb_txl, ADM5120_DMA_TXL); + adm5120_dma_rx_init(adm5120_dma_rxh, adm5120_skb_rxh, ADM5120_DMA_RXH); + adm5120_dma_rx_init(adm5120_dma_rxl, adm5120_skb_rxl, ADM5120_DMA_RXL); + adm5120_set_reg(ADM5120_SEND_HBADDR, KSEG1ADDR(adm5120_dma_txh)); + adm5120_set_reg(ADM5120_SEND_LBADDR, KSEG1ADDR(adm5120_dma_txl)); + adm5120_set_reg(ADM5120_RECEIVE_HBADDR, KSEG1ADDR(adm5120_dma_rxh)); + adm5120_set_reg(ADM5120_RECEIVE_LBADDR, KSEG1ADDR(adm5120_dma_rxl)); + + adm5120_set_vlan(vlan_matrix); + + for (i=0; iport = i; + dev->base_addr = SW_BASE; + dev->irq = ADM5120_IRQ_SWITCH; + dev->open = adm5120_sw_open; + dev->hard_start_xmit = adm5120_sw_tx; + dev->stop = adm5120_sw_stop; + dev->get_stats = adm5120_sw_stats; + dev->set_multicast_list = adm5120_set_multicast_list; + dev->do_ioctl = adm5120_do_ioctl; + dev->tx_timeout = adm5120_tx_timeout; + dev->watchdog_timeo = ETH_TX_TIMEOUT; + dev->set_mac_address = adm5120_sw_set_mac_address; + /* HACK alert!!! In the original admtek driver it is asumed + that you can read the MAC addressess from flash, but edimax + decided to leave that space intentionally blank... + */ + memcpy(dev->dev_addr, "\x00\x50\xfc\x11\x22\x01", 6); + dev->dev_addr[5] += i; + adm5120_write_mac(dev); + + if ((err = register_netdev(dev))) { + free_netdev(dev); + goto out_int; + } + printk(KERN_INFO "%s: ADM5120 switch port%d\n", dev->name, i); + } + adm5120_set_reg(ADM5120_CPUP_CONF, + ADM5120_CRC_PADDING | ADM5120_DISUNALL | ADM5120_DISMCALL); + + return 0; + +out_int: + /* Undo everything that did succeed */ + for (; i; i--) { + unregister_netdev(adm5120_devs[i-1]); + free_netdev(adm5120_devs[i-1]); + } + free_irq(ADM5120_IRQ_SWITCH, NULL); +out: + printk(KERN_ERR "ADM5120 Ethernet switch init failed\n"); + return err; +} + +static void __exit adm5120_sw_exit(void) +{ + int i; + + for (i = 0; i < adm5120_nrdevs; i++) { + unregister_netdev(adm5120_devs[i]); + free_netdev(adm5120_devs[i-1]); + } + + free_irq(ADM5120_IRQ_SWITCH, NULL); + + for (i = 0; i < ADM5120_DMA_RXH; i++) { + if (!adm5120_skb_rxh[i]) + break; + kfree_skb(adm5120_skb_rxh[i]); + } + for (i = 0; i < ADM5120_DMA_RXL; i++) { + if (!adm5120_skb_rxl[i]) + break; + kfree_skb(adm5120_skb_rxl[i]); + } +} + +module_init(adm5120_sw_init); +module_exit(adm5120_sw_exit); diff --git a/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.h b/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.h new file mode 100644 index 0000000000..35e7876c25 --- /dev/null +++ b/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.h @@ -0,0 +1,109 @@ +/* + * Defines for ADM5120 built in ethernet switch driver + * + * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005 + * + * Values come from ADM5120 datasheet and original ADMtek 2.4 driver, + * Copyright ADMtek Inc. + */ + +#ifndef _INCLUDE_ADM5120SW_H_ +#define _INCLUDE_ADM5120SW_H_ + +#define SW_BASE KSEG1ADDR(0x12000000) +#define SW_DEVS 6 + +#define ETH_TX_TIMEOUT HZ/4 +#define ETH_FCS 4; + +#define ADM5120_CODE 0x00 /* CPU description */ +#define ADM5120_CODE_PQFP 0x20000000 /* package type */ +#define ADM5120_CPUP_CONF 0x24 /* CPU port config */ +#define ADM5120_DISCCPUPORT 0x00000001 /* disable cpu port */ +#define ADM5120_CRC_PADDING 0x00000002 /* software crc */ +#define ADM5120_DISUNSHIFT 9 +#define ADM5120_DISUNALL 0x00007e00 /* disable unknown from all */ +#define ADM5120_DISMCSHIFT 16 +#define ADM5120_DISMCALL 0x003f0000 /* disable multicast from all */ +#define ADM5120_PORT_CONF0 0x28 +#define ADM5120_ENMC 0x00003f00 /* Enable MC routing (ex cpu) */ +#define ADM5120_ENBP 0x003f0000 /* Enable Back Pressure */ +#define ADM5120_VLAN_GI 0x40 /* VLAN settings */ +#define ADM5120_VLAN_GII 0x44 +#define ADM5120_SEND_TRIG 0x48 +#define ADM5120_SEND_TRIG_L 0x00000001 +#define ADM5120_SEND_TRIG_H 0x00000002 +#define ADM5120_MAC_WT0 0x58 +#define ADM5120_MAC_WRITE 0x00000001 +#define ADM5120_MAC_WRITE_DONE 0x00000002 +#define ADM5120_VLAN_EN 0x00000040 +#define ADM5120_MAC_WT1 0x5c +#define ADM5120_BW_CTL0 0x60 /* Bandwidth control 0 */ +#define ADM5120_BW_CTL1 0x64 /* Bandwidth control 1 */ +#define ADM5120_PHY_CNTL2 0x7c +#define ADM5120_AUTONEG 0x0000001f /* Auto negotiate */ +#define ADM5120_NORMAL 0x01f00000 /* PHY normal mode */ +#define ADM5120_AUTOMDIX 0x3e000000 /* Auto MDIX */ +#define ADM5120_PHY_CNTL3 0x80 +#define ADM5120_PHY_NTH 0x00000400 +#define ADM5120_INT_ST 0xb0 +#define ADM5120_INT_RXH 0x0000004 +#define ADM5120_INT_RXL 0x0000008 +#define ADM5120_INT_HFULL 0x0000010 +#define ADM5120_INT_LFULL 0x0000020 +#define ADM5120_INT_TXH 0x0000001 +#define ADM5120_INT_TXL 0x0000002 +#define ADM5120_INT_MASK 0xb4 +#define ADM5120_INTMASKALL 0x1FDEFFF /* All interrupts */ +#define ADM5120_INTHANDLE (ADM5120_INT_RXH | ADM5120_INT_RXL | \ + ADM5120_INT_HFULL | ADM5120_INT_LFULL | \ + ADM5120_INT_TXH | ADM5120_INT_TXL) +#define ADM5120_SEND_HBADDR 0xd0 +#define ADM5120_SEND_LBADDR 0xd4 +#define ADM5120_RECEIVE_HBADDR 0xd8 +#define ADM5120_RECEIVE_LBADDR 0xdc + +struct adm5120_dma { + u32 data; + u32 cntl; + u32 len; + u32 status; +} __attribute__ ((packed)); + +#define ADM5120_DMA_MASK 0x01ffffff +#define ADM5120_DMA_OWN 0x80000000 /* buffer owner */ +#define ADM5120_DMA_RINGEND 0x10000000 /* Last in DMA ring */ + +#define ADM5120_DMA_ADDR(ptr) ((u32)(ptr) & ADM5120_DMA_MASK) +#define ADM5120_DMA_PORTID 0x00007000 +#define ADM5120_DMA_PORTSHIFT 12 +#define ADM5120_DMA_LEN 0x07ff0000 +#define ADM5120_DMA_LENSHIFT 16 +#define ADM5120_DMA_FCSERR 0x00000008 + +#define ADM5120_DMA_TXH 16 +#define ADM5120_DMA_TXL 64 +#define ADM5120_DMA_RXH 16 +#define ADM5120_DMA_RXL 8 + +#define ADM5120_DMA_RXSIZE 1550 +#define ADM5120_DMA_EXTRA 20 + +struct adm5120_sw { + int port; + struct net_device_stats stats; +}; + +#define SIOCSMATRIX SIOCDEVPRIVATE +#define SIOCGMATRIX SIOCDEVPRIVATE+1 +#define SIOCGADMINFO SIOCDEVPRIVATE+2 +#define SIOCGETBW SIOCDEVPRIVATE+3 +#define SIOCSETBW SIOCDEVPRIVATE+4 + +struct adm5120_sw_info { + u16 magic; + u16 ports; + u16 vlan; +}; + +#endif /* _INCLUDE_ADM5120SW_H_ */ diff --git a/target/linux/adm5120-2.6/files/drivers/serial/adm5120_uart.c b/target/linux/adm5120-2.6/files/drivers/serial/adm5120_uart.c new file mode 100644 index 0000000000..8a2adaa9c4 --- /dev/null +++ b/target/linux/adm5120-2.6/files/drivers/serial/adm5120_uart.c @@ -0,0 +1,520 @@ +/* + * Serial driver for ADM5120 SoC + * + * Derived from drivers/serial/uart00.c + * Copyright 2001 Altera Corporation + * + * Some pieces are derived from the ADMtek 2.4 serial driver. + * Copyright (C) ADMtek Incorporated, 2003 + * daniell@admtek.com.tw + * Which again was derived from drivers/char/serial.c + * Copyright (C) Linus Torvalds et al. + * + * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define ADM5120_UART_REG(base, reg) \ + (*(volatile u32 *)KSEG1ADDR((base)+(reg))) + +#define ADM5120_UARTCLK_FREQ 62500000 +#define ADM5120_UART_BAUDDIV(rate) ((unsigned long)(ADM5120_UARTCLK_FREQ/(16*(rate)) - 1)) + +#define ADM5120_UART_BAUD115200 ADM5120_UART_BAUDDIV(115200) + +#define ADM5120_UART_DATA 0x00 +#define ADM5120_UART_RS 0x04 +#define ADM5120_UART_LCR_H 0x08 +#define ADM5120_UART_LCR_M 0x0c +#define ADM5120_UART_LCR_L 0x10 +#define ADM5120_UART_CR 0x14 +#define ADM5120_UART_FR 0x18 +#define ADM5120_UART_IR 0x1c + +#define ADM5120_UART_FE 0x01 +#define ADM5120_UART_PE 0x02 +#define ADM5120_UART_BE 0x04 +#define ADM5120_UART_OE 0x08 +#define ADM5120_UART_ERR 0x0f +#define ADM5120_UART_FIFO_EN 0x10 +#define ADM5120_UART_EN 0x01 +#define ADM5120_UART_TIE 0x20 +#define ADM5120_UART_RIE 0x50 +#define ADM5120_UART_IE 0x78 +#define ADM5120_UART_CTS 0x01 +#define ADM5120_UART_DSR 0x02 +#define ADM5120_UART_DCD 0x04 +#define ADM5120_UART_TXFF 0x20 +#define ADM5120_UART_TXFE 0x80 +#define ADM5120_UART_RXFE 0x10 +#define ADM5120_UART_BRK 0x01 +#define ADM5120_UART_PEN 0x02 +#define ADM5120_UART_EPS 0x04 +#define ADM5120_UART_STP2 0x08 +#define ADM5120_UART_W5 0x00 +#define ADM5120_UART_W6 0x20 +#define ADM5120_UART_W7 0x40 +#define ADM5120_UART_W8 0x60 +#define ADM5120_UART_MIS 0x01 +#define ADM5120_UART_RIS 0x02 +#define ADM5120_UART_TIS 0x04 +#define ADM5120_UART_RTIS 0x08 + +static void adm5120ser_stop_tx(struct uart_port *port) +{ + ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) &= ~ADM5120_UART_TIE; +} + +static void adm5120ser_irq_rx(struct uart_port *port) +{ + struct tty_struct *tty = port->info->tty; + unsigned int status, ch, rds, flg, ignored = 0; + + status = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR); + while (!(status & ADM5120_UART_RXFE)) { + /* + * We need to read rds before reading the + * character from the fifo + */ + rds = ADM5120_UART_REG(port->iobase, ADM5120_UART_RS); + ch = ADM5120_UART_REG(port->iobase, ADM5120_UART_DATA); + port->icount.rx++; + + if (tty->low_latency) + tty_flip_buffer_push(tty); + + flg = TTY_NORMAL; + + /* + * Note that the error handling code is + * out of the main execution path + */ + if (rds & ADM5120_UART_ERR) + goto handle_error; + if (uart_handle_sysrq_char(port, ch)) + goto ignore_char; + + error_return: + tty_insert_flip_char(tty, ch, flg); + + ignore_char: + status = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR); + } + out: + tty_flip_buffer_push(tty); + return; + + handle_error: + ADM5120_UART_REG(port->iobase, ADM5120_UART_RS) = 0xff; + if (rds & ADM5120_UART_BE) { + port->icount.brk++; + if (uart_handle_break(port)) + goto ignore_char; + } else if (rds & ADM5120_UART_PE) + port->icount.parity++; + else if (rds & ADM5120_UART_FE) + port->icount.frame++; + if (rds & ADM5120_UART_OE) + port->icount.overrun++; + + if (rds & port->ignore_status_mask) { + if (++ignored > 100) + goto out; + goto ignore_char; + } + rds &= port->read_status_mask; + + if (rds & ADM5120_UART_BE) + flg = TTY_BREAK; + else if (rds & ADM5120_UART_PE) + flg = TTY_PARITY; + else if (rds & ADM5120_UART_FE) + flg = TTY_FRAME; + + if (rds & ADM5120_UART_OE) { + /* + * CHECK: does overrun affect the current character? + * ASSUMPTION: it does not. + */ + tty_insert_flip_char(tty, ch, flg); + ch = 0; + flg = TTY_OVERRUN; + } +#ifdef CONFIG_MAGIC_SYSRQ + port->sysrq = 0; +#endif + goto error_return; +} + +static void adm5120ser_irq_tx(struct uart_port *port) +{ + struct circ_buf *xmit = &port->info->xmit; + int count; + + if (port->x_char) { + ADM5120_UART_REG(port->iobase, ADM5120_UART_DATA) = + port->x_char; + port->icount.tx++; + port->x_char = 0; + return; + } + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + adm5120ser_stop_tx(port); + return; + } + + count = port->fifosize >> 1; + do { + ADM5120_UART_REG(port->iobase, ADM5120_UART_DATA) = + xmit->buf[xmit->tail]; + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + if (uart_circ_empty(xmit)) + break; + } while (--count > 0); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (uart_circ_empty(xmit)) + adm5120ser_stop_tx(port); +} + +static void adm5120ser_irq_modem(struct uart_port *port) +{ + unsigned int status; + + status = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR); + + if (status & ADM5120_UART_DCD) + uart_handle_dcd_change(port, status & ADM5120_UART_DCD); + + if (status & ADM5120_UART_DSR) + port->icount.dsr++; + + if (status & ADM5120_UART_CTS) + uart_handle_cts_change(port, status & ADM5120_UART_CTS); + + wake_up_interruptible(&port->info->delta_msr_wait); +} + +static irqreturn_t adm5120ser_irq(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + unsigned long ir = ADM5120_UART_REG(port->iobase, ADM5120_UART_IR); + + if (ir & (ADM5120_UART_RIS | ADM5120_UART_RTIS)) + adm5120ser_irq_rx(port); + if (ir & ADM5120_UART_TIS) + adm5120ser_irq_tx(port); + if (ir & ADM5120_UART_MIS) { + adm5120ser_irq_modem(port); + ADM5120_UART_REG(port->iobase, ADM5120_UART_IR) = 0xff; + } + + return IRQ_HANDLED; +} + +static unsigned int adm5120ser_tx_empty(struct uart_port *port) +{ + unsigned int fr = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR); + return (fr & ADM5120_UART_TXFE) ? TIOCSER_TEMT : 0; +} + +static void adm5120ser_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ +} + +static unsigned int adm5120ser_get_mctrl(struct uart_port *port) +{ + unsigned int result = 0; + unsigned int fr = ADM5120_UART_REG(port->iobase, ADM5120_UART_FR); + + if (fr & ADM5120_UART_CTS) + result |= TIOCM_CTS; + if (fr & ADM5120_UART_DSR) + result |= TIOCM_DSR; + if (fr & ADM5120_UART_DCD) + result |= TIOCM_CAR; + return result; +} + +static void adm5120ser_start_tx(struct uart_port *port) +{ + ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) |= ADM5120_UART_TIE; +} + +static void adm5120ser_stop_rx(struct uart_port *port) +{ + ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) &= ~ADM5120_UART_RIE; +} + +static void adm5120ser_enable_ms(struct uart_port *port) +{ +} + +static void adm5120ser_break_ctl(struct uart_port *port, int break_state) +{ + unsigned long flags; + unsigned long lcrh; + + spin_lock_irqsave(&port->lock, flags); + lcrh = ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_H); + if (break_state == -1) + lcrh |= ADM5120_UART_BRK; + else + lcrh &= ~ADM5120_UART_BRK; + ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_H) = lcrh; + spin_unlock_irqrestore(&port->lock, flags); +} + +static int adm5120ser_startup(struct uart_port *port) +{ + int ret; + + ret = request_irq(port->irq, adm5120ser_irq, 0, "ADM5120 UART", port); + if (ret) { + printk(KERN_ERR "Couldn't get irq %d\n", port->irq); + return ret; + } + ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_H) |= + ADM5120_UART_FIFO_EN; + ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) |= + ADM5120_UART_EN | ADM5120_UART_IE; + return 0; +} + +static void adm5120ser_shutdown(struct uart_port *port) +{ + ADM5120_UART_REG(port->iobase, ADM5120_UART_CR) &= ~ADM5120_UART_IE; + free_irq(port->irq, port); +} + +static void adm5120ser_set_termios(struct uart_port *port, + struct ktermios *termios, struct ktermios *old) +{ + unsigned int baud, quot, lcrh; + unsigned long flags; + + termios->c_cflag |= CREAD; + + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); + quot = uart_get_divisor(port, baud); + + lcrh = ADM5120_UART_FIFO_EN; + switch (termios->c_cflag & CSIZE) { + case CS5: + lcrh |= ADM5120_UART_W5; + break; + case CS6: + lcrh |= ADM5120_UART_W6; + break; + case CS7: + lcrh |= ADM5120_UART_W7; + break; + default: + lcrh |= ADM5120_UART_W8; + break; + } + if (termios->c_cflag & CSTOPB) + lcrh |= ADM5120_UART_STP2; + if (termios->c_cflag & PARENB) { + lcrh |= ADM5120_UART_PEN; + if (!(termios->c_cflag & PARODD)) + lcrh |= ADM5120_UART_EPS; + } + + spin_lock_irqsave(port->lock, flags); + + ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_H) = lcrh; + + /* + * Update the per-port timeout. + */ + uart_update_timeout(port, termios->c_cflag, baud); + + port->read_status_mask = ADM5120_UART_OE; + if (termios->c_iflag & INPCK) + port->read_status_mask |= ADM5120_UART_FE | ADM5120_UART_PE; + if (termios->c_iflag & (BRKINT | PARMRK)) + port->read_status_mask |= ADM5120_UART_BE; + + /* + * Characters to ignore + */ + port->ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= ADM5120_UART_FE | ADM5120_UART_PE; + if (termios->c_iflag & IGNBRK) { + port->ignore_status_mask |= ADM5120_UART_BE; + /* + * If we're ignoring parity and break indicators, + * ignore overruns to (for real raw support). + */ + if (termios->c_iflag & IGNPAR) + port->ignore_status_mask |= ADM5120_UART_OE; + } + + quot = ADM5120_UART_BAUD115200; + ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_L) = quot & 0xff; + ADM5120_UART_REG(port->iobase, ADM5120_UART_LCR_M) = quot >> 8; + + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *adm5120ser_type(struct uart_port *port) +{ + return port->type == PORT_ADM5120 ? "ADM5120" : NULL; +} + +static void adm5120ser_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) + port->type = PORT_ADM5120; +} + +static void adm5120ser_release_port(struct uart_port *port) +{ + release_mem_region(port->iobase, ADM5120_UART_SIZE); +} + +static int adm5120ser_request_port(struct uart_port *port) +{ + return request_mem_region(port->iobase, ADM5120_UART_SIZE, + "adm5120-uart") != NULL ? 0 : -EBUSY; +} + +static struct uart_ops adm5120ser_ops = { + .tx_empty = adm5120ser_tx_empty, + .set_mctrl = adm5120ser_set_mctrl, + .get_mctrl = adm5120ser_get_mctrl, + .stop_tx = adm5120ser_stop_tx, + .start_tx = adm5120ser_start_tx, + .stop_rx = adm5120ser_stop_rx, + .enable_ms = adm5120ser_enable_ms, + .break_ctl = adm5120ser_break_ctl, + .startup = adm5120ser_startup, + .shutdown = adm5120ser_shutdown, + .set_termios = adm5120ser_set_termios, + .type = adm5120ser_type, + .config_port = adm5120ser_config_port, + .release_port = adm5120ser_release_port, + .request_port = adm5120ser_request_port, +}; + +static void adm5120console_put(const char c) +{ + while ((ADM5120_UART_REG(ADM5120_UART0_BASE, ADM5120_UART_FR) & + ADM5120_UART_TXFF) != 0); + ADM5120_UART_REG(ADM5120_UART0_BASE, ADM5120_UART_DATA) = c; +} + +static void adm5120console_write(struct console *con, const char *s, + unsigned int count) +{ + while (count--) { + if (*s == '\n') + adm5120console_put('\r'); + adm5120console_put(*s); + s++; + } +} + +static int __init adm5120console_setup(struct console *con, char *options) +{ + /* Set to 115200 baud, 8N1 and enable FIFO */ + ADM5120_UART_REG(ADM5120_UART0_BASE, ADM5120_UART_LCR_L) = + ADM5120_UART_BAUD115200 & 0xff; + ADM5120_UART_REG(ADM5120_UART0_BASE, ADM5120_UART_LCR_M) = + ADM5120_UART_BAUD115200 >> 8; + ADM5120_UART_REG(ADM5120_UART0_BASE, ADM5120_UART_LCR_H) = + ADM5120_UART_W8 | ADM5120_UART_FIFO_EN; + /* Enable port */ + ADM5120_UART_REG(ADM5120_UART0_BASE, ADM5120_UART_CR) = + ADM5120_UART_EN; + + return 0; +} + +static struct uart_driver adm5120ser_reg; + +static struct console adm5120_serconsole = { + .name = "ttyS", + .write = adm5120console_write, + .device = uart_console_device, + .setup = adm5120console_setup, + .flags = CON_PRINTBUFFER, + .cflag = B115200 | CS8 | CREAD, + .index = 0, + .data = &adm5120ser_reg, +}; + +static int __init adm5120console_init(void) +{ + register_console(&adm5120_serconsole); + return 0; +} + +console_initcall(adm5120console_init); + + +static struct uart_port adm5120ser_ports[] = { + { + .iobase = ADM5120_UART0_BASE, + .irq = ADM5120_IRQ_UART0, + .uartclk = ADM5120_UARTCLK_FREQ, + .fifosize = 16, + .ops = &adm5120ser_ops, + .line = 0, + .flags = ASYNC_BOOT_AUTOCONF, + }, +#if (CONFIG_ADM5120_NR_UARTS > 1) + { + .iobase = ADM5120_UART1_BASE, + .irq = ADM5120_IRQ_UART1, + .uartclk = ADM5120_UARTCLK_FREQ, + .fifosize = 16, + .ops = &adm5120ser_ops, + .line = 1, + .flags = ASYNC_BOOT_AUTOCONF, + }, +#endif +}; + +static struct uart_driver adm5120ser_reg = { + .owner = THIS_MODULE, + .driver_name = "ttyS", + .dev_name = "ttyS", + .major = TTY_MAJOR, + .minor = 64, + .nr = CONFIG_ADM5120_NR_UARTS, + .cons = &adm5120_serconsole, +}; + +static int __init adm5120ser_init(void) +{ + int ret, i; + + ret = uart_register_driver(&adm5120ser_reg); + if (!ret) { + for (i = 0; i < CONFIG_ADM5120_NR_UARTS; i++) + uart_add_one_port(&adm5120ser_reg, &adm5120ser_ports[i]); + } + + return ret; +} + +__initcall(adm5120ser_init); diff --git a/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c b/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c new file mode 100644 index 0000000000..87bfcc6c72 --- /dev/null +++ b/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c @@ -0,0 +1,848 @@ +/* + * HCD driver for ADM5120 SoC + * + * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org) + * + * Based on the ADMtek 2.4 driver + * (C) Copyright 2003 Junius Chen + * Which again was based on the ohci and uhci drivers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../core/hcd.h" + +MODULE_DESCRIPTION("ADM5120 USB Host Controller Driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jeroen Vreeken (pe1rxq@amsat.org)"); + +#define PFX "adm5120-hcd: " + +#define ADMHCD_REG_CONTROL 0x00 +#define ADMHCD_REG_INTSTATUS 0x04 +#define ADMHCD_REG_INTENABLE 0x08 +#define ADMHCD_REG_HOSTCONTROL 0x10 +#define ADMHCD_REG_FMINTERVAL 0x18 +#define ADMHCD_REG_FMNUMBER 0x1c +#define ADMHCD_REG_LSTHRESH 0x70 +#define ADMHCD_REG_RHDESCR 0x74 +#define ADMHCD_REG_PORTSTATUS0 0x78 +#define ADMHCD_REG_PORTSTATUS1 0x7c +#define ADMHCD_REG_HOSTHEAD 0x80 + + +#define ADMHCD_NUMPORTS 2 + +#define ADMHCD_HOST_EN 0x00000001 /* Host enable */ +#define ADMHCD_SW_INTREQ 0x00000002 /* request software int */ +#define ADMHCD_SW_RESET 0x00000008 /* Reset */ + +#define ADMHCD_INT_TD 0x00100000 /* TD completed */ +#define ADMHCD_INT_SW 0x20000000 /* software interrupt */ +#define ADMHCD_INT_FATAL 0x40000000 /* Fatal interrupt */ +#define ADMHCD_INT_ACT 0x80000000 /* Interrupt active */ + +#define ADMHCD_STATE_RST 0x00000000 /* bus state reset */ +#define ADMHCD_STATE_RES 0x00000001 /* bus state resume */ +#define ADMHCD_STATE_OP 0x00000002 /* bus state operational */ +#define ADMHCD_STATE_SUS 0x00000003 /* bus state suspended */ +#define ADMHCD_DMA_EN 0x00000004 /* enable dma engine */ + +#define ADMHCD_NPS 0x00000020 /* No Power Switch */ +#define ADMHCD_LPSC 0x04000000 /* Local power switch change */ + +#define ADMHCD_CCS 0x00000001 /* current connect status */ +#define ADMHCD_PES 0x00000002 /* port enable status */ +#define ADMHCD_PSS 0x00000004 /* port suspend status */ +#define ADMHCD_POCI 0x00000008 /* port overcurrent indicator */ +#define ADMHCD_PRS 0x00000010 /* port reset status */ +#define ADMHCD_PPS 0x00000100 /* port power status */ +#define ADMHCD_LSDA 0x00000200 /* low speed device attached */ +#define ADMHCD_CSC 0x00010000 /* connect status change */ +#define ADMHCD_PESC 0x00020000 /* enable status change */ +#define ADMHCD_PSSC 0x00040000 /* suspend status change */ +#define ADMHCD_OCIC 0x00080000 /* overcurrent change*/ +#define ADMHCD_PRSC 0x00100000 /* reset status change */ + + +struct admhcd_ed { + /* Don't change first four, they used for DMA */ + u32 control; + struct admhcd_td *tail; + struct admhcd_td *head; + struct admhcd_ed *next; + /* the rest is for the driver only: */ + struct admhcd_td *cur; + struct usb_host_endpoint *ep; + struct urb *urb; + struct admhcd_ed *real; +} __attribute__ ((packed)); + +#define ADMHCD_ED_EPSHIFT 7 /* Shift for endpoint number */ +#define ADMHCD_ED_INT 0x00000800 /* Is this an int endpoint */ +#define ADMHCD_ED_SPEED 0x00002000 /* Is it a high speed dev? */ +#define ADMHCD_ED_SKIP 0x00004000 /* Skip this ED */ +#define ADMHCD_ED_FORMAT 0x00008000 /* Is this an isoc endpoint */ +#define ADMHCD_ED_MAXSHIFT 16 /* Shift for max packet size */ + +struct admhcd_td { + /* Don't change first four, they are used for DMA */ + u32 control; + u32 buffer; + u32 buflen; + struct admhcd_td *next; + /* the rest is for the driver only: */ + struct urb *urb; + struct admhcd_td *real; +} __attribute__ ((packed)); + +#define ADMHCD_TD_OWN 0x80000000 +#define ADMHCD_TD_TOGGLE 0x00000000 +#define ADMHCD_TD_DATA0 0x01000000 +#define ADMHCD_TD_DATA1 0x01800000 +#define ADMHCD_TD_OUT 0x00200000 +#define ADMHCD_TD_IN 0x00400000 +#define ADMHCD_TD_SETUP 0x00000000 +#define ADMHCD_TD_ISO 0x00010000 +#define ADMHCD_TD_R 0x00040000 +#define ADMHCD_TD_INTEN 0x00010000 + +static int admhcd_td_err[16] = { + 0, /* No */ + -EREMOTEIO, /* CRC */ + -EREMOTEIO, /* bit stuff */ + -EREMOTEIO, /* data toggle */ + -EPIPE, /* stall */ + -ETIMEDOUT, /* timeout */ + -EPROTO, /* pid err */ + -EPROTO, /* unexpected pid */ + -EREMOTEIO, /* data overrun */ + -EREMOTEIO, /* data underrun */ + -ETIMEDOUT, /* 1010 */ + -ETIMEDOUT, /* 1011 */ + -EREMOTEIO, /* buffer overrun */ + -EREMOTEIO, /* buffer underrun */ + -ETIMEDOUT, /* 1110 */ + -ETIMEDOUT, /* 1111 */ +}; + +#define ADMHCD_TD_ERRMASK 0x38000000 +#define ADMHCD_TD_ERRSHIFT 27 + +#define TD(td) ((struct admhcd_td *)(((u32)(td)) & ~0xf)) +#define ED(ed) ((struct admhcd_ed *)(((u32)(ed)) & ~0xf)) + +struct admhcd { + spinlock_t lock; + + void __iomem *addr_reg; + void __iomem *data_reg; + /* Root hub registers */ + u32 rhdesca; + u32 rhdescb; + u32 rhstatus; + u32 rhport[2]; + + /* async schedule: control, bulk */ + struct list_head async; + u32 base; + u32 dma_en; + unsigned long flags; + +}; + +static inline struct admhcd *hcd_to_admhcd(struct usb_hcd *hcd) +{ + return (struct admhcd *)(hcd->hcd_priv); +} + +static inline struct usb_hcd *admhcd_to_hcd(struct admhcd *admhcd) +{ + return container_of((void *)admhcd, struct usb_hcd, hcd_priv); +} + +static char hcd_name[] = "adm5120-hcd"; + +static u32 admhcd_reg_get(struct admhcd *ahcd, int reg) +{ + return *(volatile u32 *)KSEG1ADDR(ahcd->base+reg); +} + +static void admhcd_reg_set(struct admhcd *ahcd, int reg, u32 val) +{ + *(volatile u32 *)KSEG1ADDR(ahcd->base+reg) = val; +} + +static void admhcd_lock(struct admhcd *ahcd) +{ + spin_lock_irqsave(&ahcd->lock, ahcd->flags); + ahcd->dma_en = admhcd_reg_get(ahcd, ADMHCD_REG_HOSTCONTROL) & + ADMHCD_DMA_EN; + admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP); +} + +static void admhcd_unlock(struct admhcd *ahcd) +{ + admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, + ADMHCD_STATE_OP | ahcd->dma_en); + spin_unlock_irqrestore(&ahcd->lock, ahcd->flags); +} + +static struct admhcd_td *admhcd_td_alloc(struct admhcd_ed *ed, struct urb *urb) +{ + struct admhcd_td *tdn, *td; + + tdn = kmalloc(sizeof(struct admhcd_td), GFP_ATOMIC); + if (!tdn) + return NULL; + tdn->real = tdn; + tdn = (struct admhcd_td *)KSEG1ADDR(tdn); + memset(tdn, 0, sizeof(struct admhcd_td)); + if (ed->cur == NULL) { + ed->cur = tdn; + ed->head = tdn; + ed->tail = tdn; + td = tdn; + } else { + /* Supply back the old tail and link in new td as tail */ + td = TD(ed->tail); + TD(ed->tail)->next = tdn; + ed->tail = tdn; + } + td->urb = urb; + + return td; +} + +static void admhcd_td_free(struct admhcd_ed *ed, struct urb *urb) +{ + struct admhcd_td *td, **tdp; + + if (urb == NULL) + ed->control |= ADMHCD_ED_SKIP; + tdp = &ed->cur; + td = ed->cur; + do { + if (td->urb == urb) + break; + tdp = &td->next; + td = TD(td->next); + } while (td); + while (td && td->urb == urb) { + *tdp = TD(td->next); + kfree(td->real); + td = *tdp; + } +} + +/* Find an endpoint's descriptor, if needed allocate a new one and link it + in the DMA chain + */ +static struct admhcd_ed *admhcd_get_ed(struct admhcd *ahcd, + struct usb_host_endpoint *ep, struct urb *urb) +{ + struct admhcd_ed *hosthead; + struct admhcd_ed *found = NULL, *ed = NULL; + unsigned int pipe = urb->pipe; + + admhcd_lock(ahcd); + hosthead = (struct admhcd_ed *)admhcd_reg_get(ahcd, ADMHCD_REG_HOSTHEAD); + if (hosthead) { + for (ed = hosthead;; ed = ED(ed->next)) { + if (ed->ep == ep) { + found = ed; + break; + } + if (ED(ed->next) == hosthead) + break; + } + } + if (!found) { + found = kmalloc(sizeof(struct admhcd_ed), GFP_ATOMIC); + if (!found) + goto out; + memset(found, 0, sizeof(struct admhcd_ed)); + found->real = found; + found->ep = ep; + found = (struct admhcd_ed *)KSEG1ADDR(found); + found->control = usb_pipedevice(pipe) | + (usb_pipeendpoint(pipe) << ADMHCD_ED_EPSHIFT) | + (usb_pipeint(pipe) ? ADMHCD_ED_INT : 0) | + (urb->dev->speed == USB_SPEED_FULL ? ADMHCD_ED_SPEED : 0) | + (usb_pipeisoc(pipe) ? ADMHCD_ED_FORMAT : 0) | + (usb_maxpacket(urb->dev, pipe, usb_pipeout(pipe)) << ADMHCD_ED_MAXSHIFT); + /* Alloc first dummy td */ + admhcd_td_alloc(found, NULL); + if (hosthead) { + found->next = hosthead; + ed->next = found; + } else { + found->next = found; + admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, (u32)found); + } + } +out: + admhcd_unlock(ahcd); + return found; +} + +static struct admhcd_td *admhcd_td_fill(u32 control, struct admhcd_td *td, + dma_addr_t data, int len) +{ + td->buffer = data; + td->buflen = len; + td->control = control; + return TD(td->next); +} + +static void admhcd_ed_start(struct admhcd *ahcd, struct admhcd_ed *ed) +{ + struct admhcd_td *td = ed->cur; + + if (ed->urb) + return; + if (td->urb) { + ed->urb = td->urb; + while (1) { + td->control |= ADMHCD_TD_OWN; + if (TD(td->next)->urb != td->urb) { + td->buflen |= ADMHCD_TD_INTEN; + break; + } + td = TD(td->next); + } + } + ed->head = TD(ed->head); + ahcd->dma_en |= ADMHCD_DMA_EN; +} + +static irqreturn_t adm5120hcd_irq(struct usb_hcd *hcd) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + u32 intstatus; + + intstatus = admhcd_reg_get(ahcd, ADMHCD_REG_INTSTATUS); + if (intstatus & ADMHCD_INT_FATAL) { + admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_FATAL); + // + } + if (intstatus & ADMHCD_INT_SW) { + admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_SW); + // + } + if (intstatus & ADMHCD_INT_TD) { + struct admhcd_ed *ed, *head; + + admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_TD); + + head = (struct admhcd_ed *)admhcd_reg_get(ahcd, ADMHCD_REG_HOSTHEAD); + ed = head; + if (ed) do { + /* Is it a finished TD? */ + if (ed->urb && !(ed->cur->control & ADMHCD_TD_OWN)) { + struct admhcd_td *td; + int error; + + td = ed->cur; + error = (td->control & ADMHCD_TD_ERRMASK) >> + ADMHCD_TD_ERRSHIFT; + ed->urb->status = admhcd_td_err[error]; + admhcd_td_free(ed, ed->urb); + // Calculate real length!!! + ed->urb->actual_length = ed->urb->transfer_buffer_length; + ed->urb->hcpriv = NULL; + usb_hcd_giveback_urb(hcd, ed->urb); + ed->urb = NULL; + } + admhcd_ed_start(ahcd, ed); + ed = ED(ed->next); + } while (ed != head); + } + + return IRQ_HANDLED; +} + +static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep, + struct urb *urb, gfp_t mem_flags) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + struct admhcd_ed *ed; + struct admhcd_td *td; + int size = 0, i, zero = 0, ret = 0; + unsigned int pipe = urb->pipe, toggle = 0; + dma_addr_t data = (dma_addr_t)urb->transfer_buffer; + int data_len = urb->transfer_buffer_length; + + ed = admhcd_get_ed(ahcd, ep, urb); + if (!ed) + return -ENOMEM; + + switch(usb_pipetype(pipe)) { + case PIPE_CONTROL: + size = 2; + case PIPE_INTERRUPT: + case PIPE_BULK: + default: + size += urb->transfer_buffer_length / 4096; + if (urb->transfer_buffer_length % 4096) + size++; + if (size == 0) + size++; + else if (urb->transfer_flags & URB_ZERO_PACKET && + !(urb->transfer_buffer_length % + usb_maxpacket(urb->dev, pipe, usb_pipeout(pipe)))) { + size++; + zero = 1; + } + break; + case PIPE_ISOCHRONOUS: + size = urb->number_of_packets; + break; + } + + admhcd_lock(ahcd); + /* Remember the first td */ + td = admhcd_td_alloc(ed, urb); + if (!td) { + ret = -ENOMEM; + goto out; + } + /* Allocate additionall tds first */ + for (i = 1; i < size; i++) { + if (admhcd_td_alloc(ed, urb) == NULL) { + admhcd_td_free(ed, urb); + ret = -ENOMEM; + goto out; + } + } + + if (usb_gettoggle(urb->dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) + toggle = ADMHCD_TD_TOGGLE; + else { + toggle = ADMHCD_TD_DATA0; + usb_settoggle(urb->dev, usb_pipeendpoint(pipe), + usb_pipeout(pipe), 1); + } + + switch(usb_pipetype(pipe)) { + case PIPE_CONTROL: + td = admhcd_td_fill(ADMHCD_TD_SETUP | ADMHCD_TD_DATA0, + td, (dma_addr_t)urb->setup_packet, 8); + while (data_len > 0) { + td = admhcd_td_fill(ADMHCD_TD_DATA1 + | ADMHCD_TD_R | + (usb_pipeout(pipe) ? + ADMHCD_TD_OUT : ADMHCD_TD_IN), td, + data, data_len % 4097); + data_len -= 4096; + } + admhcd_td_fill(ADMHCD_TD_DATA1 | (usb_pipeout(pipe) ? + ADMHCD_TD_IN : ADMHCD_TD_OUT), td, + data, 0); + break; + case PIPE_INTERRUPT: + case PIPE_BULK: + //info ok for interrupt? + i = 0; + while(data_len > 4096) { + td = admhcd_td_fill((usb_pipeout(pipe) ? + ADMHCD_TD_OUT : + ADMHCD_TD_IN | ADMHCD_TD_R) | + (i ? ADMHCD_TD_TOGGLE : toggle), td, + data, 4096); + data += 4096; + data_len -= 4096; + i++; + } + td = admhcd_td_fill((usb_pipeout(pipe) ? + ADMHCD_TD_OUT : ADMHCD_TD_IN) | + (i ? ADMHCD_TD_TOGGLE : toggle), td, data, data_len); + i++; + if (zero) + admhcd_td_fill((usb_pipeout(pipe) ? + ADMHCD_TD_OUT : ADMHCD_TD_IN) | + (i ? ADMHCD_TD_TOGGLE : toggle), td, 0, 0); + break; + case PIPE_ISOCHRONOUS: + for (i = 0; i < urb->number_of_packets; i++) { + td = admhcd_td_fill(ADMHCD_TD_ISO | + ((urb->start_frame + i) & 0xffff), td, + data + urb->iso_frame_desc[i].offset, + urb->iso_frame_desc[i].length); + } + break; + } + urb->hcpriv = ed; + admhcd_ed_start(ahcd, ed); +out: + admhcd_unlock(ahcd); + return ret; +} + +static int admhcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + struct admhcd_ed *ed; + + admhcd_lock(ahcd); + + ed = urb->hcpriv; + if (ed && ed->urb != urb) + admhcd_td_free(ed, urb); + + admhcd_unlock(ahcd); + return 0; +} + +static void admhcd_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + struct admhcd_ed *ed, *edt, *head; + + admhcd_lock(ahcd); + + head = (struct admhcd_ed *)admhcd_reg_get(ahcd, ADMHCD_REG_HOSTHEAD); + if (!head) + goto out; + for (ed = head; ED(ed->next) != head; ed = ED(ed->next)) + if (ed->ep == ep) + break; + if (ed->ep != ep) + goto out; + while (ed->cur) + admhcd_td_free(ed, ed->cur->urb); + if (head == ed) { + if (ED(ed->next) == ed) { + admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, 0); + ahcd->dma_en = 0; + goto out_free; + } + head = ED(ed->next); + for (edt = head; ED(edt->next) != head; edt = ED(edt->next)); + edt->next = ED(ed->next); + admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, (u32)ed->next); + goto out_free; + } + for (edt = head; edt->next != ed; edt = edt->next); + edt->next = ed->next; +out_free: + kfree(ed->real); +out: + admhcd_unlock(ahcd); +} + +static int admhcd_get_frame_number(struct usb_hcd *hcd) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + + return admhcd_reg_get(ahcd, ADMHCD_REG_FMNUMBER) & 0x0000ffff; +} + +static int admhcd_hub_status_data(struct usb_hcd *hcd, char *buf) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + int port; + + *buf = 0; + for (port = 0; port < ADMHCD_NUMPORTS; port++) { + if (admhcd_reg_get(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4) & + (ADMHCD_CSC | ADMHCD_PESC | ADMHCD_PSSC | ADMHCD_OCIC | + ADMHCD_PRSC)) + *buf |= (1 << (port + 1)); + } + return !!*buf; +} + +static __u8 root_hub_hub_des[] = { + 0x09, /* __u8 bLength; */ + 0x29, /* __u8 bDescriptorType; Hub-descriptor */ + 0x02, /* __u8 bNbrPorts; */ + 0x0a, 0x00, /* __u16 wHubCharacteristics; */ + 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ + 0x00, /* __u8 bHubContrCurrent; 0mA */ + 0x00, /* __u8 DeviceRemovable; */ + 0xff, /* __u8 PortPwrCtrlMask; */ +}; + +static int admhcd_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + u16 wIndex, char *buf, u16 wLength) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + int retval = 0, len; + unsigned int port = wIndex -1; + + switch (typeReq) { + + case GetHubStatus: + *(__le32 *)buf = cpu_to_le32(0); + break; + case GetPortStatus: + if (port >= ADMHCD_NUMPORTS) + goto err; + *(__le32 *)buf = cpu_to_le32( + admhcd_reg_get(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4)); + break; + case SetHubFeature: /* We don't implement these */ + case ClearHubFeature: + switch (wValue) { + case C_HUB_OVER_CURRENT: + case C_HUB_LOCAL_POWER: + break; + default: + goto err; + } + case SetPortFeature: + if (port >= ADMHCD_NUMPORTS) + goto err; + + switch (wValue) { + case USB_PORT_FEAT_SUSPEND: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_PSS); + break; + case USB_PORT_FEAT_RESET: + if (admhcd_reg_get(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4) + & ADMHCD_CCS) { + admhcd_reg_set(ahcd, + ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_PRS | ADMHCD_CSC); + mdelay(50); + admhcd_reg_set(ahcd, + ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_PES | ADMHCD_CSC); + } + break; + case USB_PORT_FEAT_POWER: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_PPS); + break; + default: + goto err; + } + break; + case ClearPortFeature: + if (port >= ADMHCD_NUMPORTS) + goto err; + + switch (wValue) { + case USB_PORT_FEAT_ENABLE: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_CCS); + break; + case USB_PORT_FEAT_C_ENABLE: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_PESC); + break; + case USB_PORT_FEAT_SUSPEND: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_POCI); + break; + case USB_PORT_FEAT_C_SUSPEND: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_PSSC); + case USB_PORT_FEAT_POWER: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_LSDA); + break; + case USB_PORT_FEAT_C_CONNECTION: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_CSC); + break; + case USB_PORT_FEAT_C_OVER_CURRENT: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_OCIC); + break; + case USB_PORT_FEAT_C_RESET: + admhcd_reg_set(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4, + ADMHCD_PRSC); + break; + default: + goto err; + } + break; + case GetHubDescriptor: + len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength); + memcpy(buf, root_hub_hub_des, len); + break; + default: +err: + retval = -EPIPE; + } + + return retval; +} + +static struct hc_driver adm5120_hc_driver = { + .description = hcd_name, + .product_desc = "ADM5120 HCD", + .hcd_priv_size = sizeof(struct admhcd), + .irq = adm5120hcd_irq, + .flags = HCD_USB11, + .urb_enqueue = admhcd_urb_enqueue, + .urb_dequeue = admhcd_urb_dequeue, + .endpoint_disable = admhcd_endpoint_disable, + .get_frame_number = admhcd_get_frame_number, + .hub_status_data = admhcd_hub_status_data, + .hub_control = admhcd_hub_control, +}; + +#define resource_len(r) (((r)->end - (r)->start) + 1) + +static int __init adm5120hcd_probe(struct platform_device *pdev) +{ + struct usb_hcd *hcd; + struct admhcd *ahcd; + struct resource *addr, *data; + void __iomem *addr_reg; + void __iomem *data_reg; + + int err = 0, irq; + + if (pdev->num_resources < 3) { + err = -ENODEV; + goto out; + } + + if (pdev->dev.dma_mask) { + printk(KERN_DEBUG "no we won't dma\n"); + return -EINVAL; + } + + irq = platform_get_irq(pdev, 0); + data = platform_get_resource(pdev, IORESOURCE_MEM, 0); + addr = platform_get_resource(pdev, IORESOURCE_MEM, 1); + + if (!addr || !data || irq < 0) { + err = -ENODEV; + goto out; + } + + if (!request_mem_region(addr->start, 2, hcd_name)) { + err = -EBUSY; + goto out; + } + + addr_reg = ioremap(addr->start, resource_len(addr)); + if (addr_reg == NULL) { + err = -ENOMEM; + goto out_mem; + } + if (!request_mem_region(data->start, 2, hcd_name)) { + err = -EBUSY; + goto out_unmap; + } + + data_reg = ioremap(data->start, resource_len(data)); + if (data_reg == NULL) { + err = -ENOMEM; + goto out_mem; + } + + hcd = usb_create_hcd(&adm5120_hc_driver, &pdev->dev, pdev->dev.bus_id); + if (!hcd) + goto out_mem; + + hcd->rsrc_start = addr->start; + ahcd = hcd_to_admhcd(hcd); + + spin_lock_init(&ahcd->lock); + INIT_LIST_HEAD(&ahcd->async); + + ahcd->data_reg = data_reg; + ahcd->addr_reg = addr_reg; + + hcd->product_desc = "ADM5120 HCD"; + + /* Initialise the HCD registers */ + admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, 0); + mdelay(10); + + admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_SW_RESET); + + while (admhcd_reg_get(ahcd, ADMHCD_REG_CONTROL) & ADMHCD_SW_RESET) + mdelay(1); + + admhcd_reg_set(ahcd, ADMHCD_REG_CONTROL, ADMHCD_HOST_EN); + admhcd_reg_set(ahcd, ADMHCD_REG_HOSTHEAD, 0x00000000); + admhcd_reg_set(ahcd, ADMHCD_REG_FMINTERVAL, 0x20002edf); + admhcd_reg_set(ahcd, ADMHCD_REG_LSTHRESH, 0x628); + admhcd_reg_set(ahcd, ADMHCD_REG_INTENABLE, + ADMHCD_INT_ACT | ADMHCD_INT_FATAL | ADMHCD_INT_SW | ADMHCD_INT_TD); + admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, + ADMHCD_INT_ACT | ADMHCD_INT_FATAL | ADMHCD_INT_SW | ADMHCD_INT_TD); + admhcd_reg_set(ahcd, ADMHCD_REG_RHDESCR, ADMHCD_NPS | ADMHCD_LPSC); + admhcd_reg_set(ahcd, ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP); + + err = usb_add_hcd(hcd, irq, IRQF_DISABLED); + if (err) + goto out_dev; + + return 0; + +out_dev: + usb_put_hcd(hcd); +out_unmap: + iounmap(addr_reg); +out_mem: + release_mem_region(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start); +out: + return err; +} + +static int __init_or_module adm5120hcd_remove(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct admhcd *ahcd; + + if (!hcd) + return 0; + ahcd = hcd_to_admhcd(hcd); + usb_remove_hcd(hcd); + + usb_put_hcd(hcd); + return 0; +} + +static struct platform_driver adm5120hcd_driver = { + .probe = adm5120hcd_probe, + .remove = adm5120hcd_remove, + .driver = { + .name = "adm5120-hcd", + .owner = THIS_MODULE, + }, +}; + +static int __init adm5120hcd_init(void) +{ + if (usb_disabled()) + return -ENODEV; + if (!adm5120_board.has_usb) { + printk(KERN_DEBUG PFX "this board does not have USB\n"); + return -ENODEV; + } + + printk(KERN_INFO PFX "registered\n"); + return platform_driver_register(&adm5120hcd_driver); +} + +static void __exit adm5120hcd_exit(void) +{ + platform_driver_unregister(&adm5120hcd_driver); +} + +module_init(adm5120hcd_init); +module_exit(adm5120hcd_exit); diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_defs.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_defs.h new file mode 100644 index 0000000000..36979c225e --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_defs.h @@ -0,0 +1,60 @@ +/* + * $Id$ + * + * ADM5120 SoC definitions + * + * This file defines some constants specific to the ADM5120 SoC + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef _ADM5120_DEFS_H +#define _ADM5120_DEFS_H + +#define ADM5120_SDRAM0_BASE 0x00000000 +#define ADM5120_SDRAM1_BASE 0x01000000 +#define ADM5120_SRAM1_BASE 0x10000000 +#define ADM5120_MPMC_BASE 0x11000000 +#define ADM5120_USBC_BASE 0x11200000 +#define ADM5120_PCIMEM_BASE 0x11400000 +#define ADM5120_PCIIO_BASE 0x11500000 +#define ADM5120_PCICFG_ADDR 0x115FFFF0 +#define ADM5120_PCICFG_DATA 0x115FFFF8 +#define ADM5120_SWITCH_BASE 0x12000000 +#define ADM5120_INTC_BASE 0x12200000 +#define ADM5120_UART0_BASE 0x12600000 +#define ADM5120_UART1_BASE 0x12800000 +#define ADM5120_SRAM0_BASE 0x1FC00000 + +#define ADM5120_MPMC_SIZE 0x1000 +#define ADM5120_USBC_SIZE 0x84 +#define ADM5120_PCIMEM_SIZE (ADM5120_PCIIO_BASE - ADM5120_PCIMEM_BASE) +#define ADM5120_PCIIO_SIZE (ADM5120_PCICFG_ADDR - ADM5120_PCIIO_BASE) +#define ADM5120_PCICFG_SIZE 0x10 +#define ADM5120_SWITCH_SIZE 0x114 +#define ADM5120_INTC_SIZE 0x28 +#define ADM5120_UART_SIZE 0x20 + +#define ADM5120_CLK_175 175000000 +#define ADM5120_CLK_200 200000000 +#define ADM5120_CLK_225 225000000 +#define ADM5120_CLK_250 250000000 + +#define ADM5120_UART_CLOCK 62500000 + +#endif /* _ADM5120_DEFS_H */ diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h new file mode 100644 index 0000000000..5c6424418a --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h @@ -0,0 +1,88 @@ +/* + * $Id$ + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) Gabor Juhos + * + * 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. + */ + +#ifndef _ADM5120_INFO_H +#define _ADM5120_INFO_H + +#include + +#define ADM5120_BOARD_NAMELEN 64 + +struct adm5120_board { + char name[ADM5120_BOARD_NAMELEN]; + unsigned long mach_type; + unsigned int iface_num; /* Number of Ethernet interfaces */ + unsigned int has_usb; /* USB controller presence flag */ + u32 mem_size; /* onboard memory size */ + u32 flash0_size; /* Flash 0 size */ +}; + +extern struct adm5120_board adm5120_board; + +extern unsigned int adm5120_boot_loader; +#define BOOT_LOADER_UNKNOWN 0 +#define BOOT_LOADER_CFE 1 +#define BOOT_LOADER_UBOOT 2 +#define BOOT_LOADER_MYLOADER 3 +#define BOOT_LOADER_ROUTERBOOT 4 +#define BOOT_LOADER_BOOTBASE 5 +#define BOOT_LOADER_LAST 5 + +extern unsigned int adm5120_product_code; +extern unsigned int adm5120_revision; +extern unsigned int adm5120_nand_boot; + +extern unsigned long adm5120_speed; +#define ADM5120_SPEED_175 175000000 +#define ADM5120_SPEED_200 200000000 +#define ADM5120_SPEED_225 225000000 +#define ADM5120_SPEED_250 250000000 + +extern unsigned int adm5120_package; +#define ADM5120_PACKAGE_PQFP 0 +#define ADM5120_PACKAGE_BGA 1 + +extern unsigned long adm5120_memsize; + +extern void adm5120_info_init(void); + +static inline int adm5120_package_pqfp(void) +{ + return (adm5120_package == ADM5120_PACKAGE_PQFP); +} + +static inline int adm5120_package_bga(void) +{ + return (adm5120_package == ADM5120_PACKAGE_BGA); +} + +static inline int adm5120_has_pci(void) +{ + return (adm5120_package == ADM5120_PACKAGE_BGA); +} + +static inline int adm5120_has_gmii(void) +{ + return (adm5120_package == ADM5120_PACKAGE_BGA); +} + +static inline char *adm5120_board_name(void) +{ + return adm5120_board.name; +} + +static inline u32 adm5120_board_memsize(void) +{ + return adm5120_board.mem_size; +} + +#endif /* _ADM5120_INFO_H */ diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_intc.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_intc.h new file mode 100644 index 0000000000..1d16fdcda9 --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_intc.h @@ -0,0 +1,73 @@ +/* + * ADM5120 interrupt controller definitions + * + * This header file defines the hardware registers of the ADM5120 SoC + * built-in interrupt controller. + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef _ADM5120_INTC_H_ +#define _ADM5120_INTC_H_ + +/* + * INTC register offsets + */ +#define INTC_REG_IRQ_STATUS 0x00 /* Interrupt status after masking */ +#define INTC_REG_IRQ_RAW_STATUS 0x04 /* Interrupt status before masking */ +#define INTC_REG_IRQ_ENABLE 0x08 /* Used to enable the interrupt sources */ +#define INTC_REG_IRQ_ENABLE_CLEAR 0x0C /* Used to disable the interrupt sources */ +#define INTC_REG_IRQ_DISABLE INTC_REG_IRQ_ENABLE_CLEAR +#define INTC_REG_INT_MODE 0x14 /* The interrupt mode of the sources */ +#define INTC_REG_FIQ_STATUS 0x18 /* FIQ status */ +#define INTC_REG_IRQ_TEST_SOURCE 0x1C +#define INTC_REG_IRQ_SOURCE_SELECT 0x20 +#define INTC_REG_INT_LEVEL 0x24 + +/* + * INTC IRQ numbers + */ +#define INTC_IRQ_TIMER 0 /* built in timer */ +#define INTC_IRQ_UART0 1 /* built-in UART0 */ +#define INTC_IRQ_UART1 2 /* built-in UART1 */ +#define INTC_IRQ_USBC 3 /* USB Host Controller */ +#define INTC_IRQ_GPIO2 4 /* GPIO line 2 */ +#define INTC_IRQ_GPIO4 5 /* GPIO line 4 */ +#define INTC_IRQ_PCI0 6 /* PCI slot 2 */ +#define INTC_IRQ_PCI1 7 /* PCI slot 3 */ +#define INTC_IRQ_PCI2 8 /* PCI slot 4 */ +#define INTC_IRQ_SWITCH 9 /* built-in ethernet switch */ +#define INTC_IRQ_LAST INTC_IRQ_SWITCH +#define INTC_IRQ_COUNT 10 + +/* + * INTC register bits + */ +#define INTC_INT_TIMER ( 1 << INTC_IRQ_TIMER ) +#define INTC_INT_UART0 ( 1 << INTC_IRQ_UART0 ) +#define INTC_INT_UART1 ( 1 << INTC_IRQ_UART1 ) +#define INTC_INT_USBC ( 1 << INTC_IRQ_USBC ) +#define INTC_INT_INTX0 ( 1 << INTC_IRQ_INTX0 ) +#define INTC_INT_INTX1 ( 1 << INTC_IRQ_INTX1 ) +#define INTC_INT_PCI0 ( 1 << INTC_IRQ_PCI0 ) +#define INTC_INT_PCI1 ( 1 << INTC_IRQ_PCI1 ) +#define INTC_INT_PCI2 ( 1 << INTC_IRQ_PCI2 ) +#define INTC_INT_SWITCH ( 1 << INTC_IRQ_SWITCH ) +#define INTC_INT_ALL (( 1 << INTC_IRQ_COUNT)-1) + +#endif /* _ADM5120_INTC_H_ */ diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_irq.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_irq.h new file mode 100644 index 0000000000..655df32bf7 --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_irq.h @@ -0,0 +1,55 @@ +/* + * $Id$ + * + * ADM5120 specific IRQ numbers + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#ifndef _ADM5120_IRQ_H_ +#define _ADM5120_IRQ_H_ + +#include + +#define MIPS_IRQ_HW0 2 +#define MIPS_IRQ_COUNTER 7 +#define MIPS_IRQ_COUNT 8 + +#define ADM5120_CPU_IRQ_BASE 0 +#define ADM5120_INTC_IRQ_BASE (ADM5120_CPU_IRQ_BASE+MIPS_IRQ_COUNT) +#define ADM5120_SWITCH_IRQ_BASE (ADM5120_INTC_IRQ_BASE+INTC_IRQ_COUNT) + +#define ADM5120_CPU_IRQ(x) (ADM5120_CPU_IRQ_BASE + (x)) +#define ADM5120_INTC_IRQ(x) (ADM5120_INTC_IRQ_BASE + (x)) + +#define ADM5120_IRQ_INTC ADM5120_CPU_IRQ(MIPS_IRQ_HW0) +#define ADM5120_IRQ_COUNTER ADM5120_CPU_IRQ(MIPS_IRQ_COUNTER) + +#define ADM5120_IRQ_TIMER ADM5120_INTC_IRQ(INTC_IRQ_TIMER) +#define ADM5120_IRQ_UART0 ADM5120_INTC_IRQ(INTC_IRQ_UART0) +#define ADM5120_IRQ_UART1 ADM5120_INTC_IRQ(INTC_IRQ_UART1) +#define ADM5120_IRQ_USBC ADM5120_INTC_IRQ(INTC_IRQ_USBC) +#define ADM5120_IRQ_GPIO2 ADM5120_INTC_IRQ(INTC_IRQ_GPIO2) +#define ADM5120_IRQ_GPIO4 ADM5120_INTC_IRQ(INTC_IRQ_GPIO4) +#define ADM5120_IRQ_PCI0 ADM5120_INTC_IRQ(INTC_IRQ_PCI0) +#define ADM5120_IRQ_PCI1 ADM5120_INTC_IRQ(INTC_IRQ_PCI1) +#define ADM5120_IRQ_PCI2 ADM5120_INTC_IRQ(INTC_IRQ_PCI2) +#define ADM5120_IRQ_SWITCH ADM5120_INTC_IRQ(INTC_IRQ_SWITCH) + +#endif diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_mpmc.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_mpmc.h new file mode 100644 index 0000000000..df536520cc --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_mpmc.h @@ -0,0 +1,87 @@ +/* + * $Id$ + * + * ADM5120 MPMC (Multiport Memory Controller) register definitions + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef _ADM5120_MPMC_H_ +#define _ADM5120_MPMC_H_ + +#define MPMC_REG_CTRL 0x0000 +#define MPMC_REG_STATUS 0x0004 +#define MPMC_REG_CONF 0x0008 +#define MPMC_REG_DC 0x0020 +#define MPMC_REG_DR 0x0024 +#define MPMC_REG_DRP 0x0030 + +#define MPMC_REG_DC0 0x0100 +#define MPMC_REG_DRC0 0x0104 +#define MPMC_REG_DC1 0x0120 +#define MPMC_REG_DRC1 0x0124 +#define MPMC_REG_DC2 0x0140 +#define MPMC_REG_DRC2 0x0144 +#define MPMC_REG_DC3 0x0160 +#define MPMC_REG_DRC3 0x0164 +#define MPMC_REG_SC0 0x0200 /* for F_CS1_N */ +#define MPMC_REG_SC1 0x0220 /* for F_CS0_N */ +#define MPMC_REG_SC2 0x0240 +#define MPMC_REG_SC3 0x0260 + +#define MPMC_CTRL_AM ( 1 << 1 ) + +/* Dynamic Control register bits */ +#define MPMC_DC_CE ( 1 << 0 ) +#define MPMC_DC_DMC ( 1 << 1 ) +#define MPMC_DC_SRR ( 1 << 2 ) +#define MPMC_DC_SI_SHIFT 7 +#define MPMC_DC_SI_MASK ( 3 << 7 ) +#define MPMC_DC_SI_NORMAL ( 0 << 7 ) +#define MPMC_DC_SI_MODE ( 1 << 7 ) +#define MPMC_DC_SI_PALL ( 2 << 7 ) +#define MPMC_DC_SI_NOP ( 3 << 7 ) + +#define SRAM_REG_CONF 0x00 +#define SRAM_REG_WWE 0x04 +#define SRAM_REG_WOE 0x08 +#define SRAM_REG_WRD 0x0C +#define SRAM_REG_WPG 0x10 +#define SRAM_REG_WWR 0x14 +#define SRAM_REG_WTR 0x18 + +/* Dynamic Configuration register bits */ +#define DC_BE (1 << 19) /* buffer enable */ +#define DC_RW_SHIFT 28 /* shift for number of rows */ +#define DC_RW_MASK 0x03 +#define DC_NB_SHIFT 26 /* shift for number of banks */ +#define DC_NB_MASK 0x01 +#define DC_CW_SHIFT 22 /* shift for number of columns */ +#define DC_CW_MASK 0x07 +#define DC_DW_SHIFT 7 /* shift for device width */ +#define DC_DW_MASK 0x03 + +/* Static Configuration register bits */ +#define SC_MW_MASK 0x03 /* memory width mask */ +#define SC_MW_8 0x00 /* 8 bit memory width */ +#define SC_MW_16 0x01 /* 16 bit memory width */ +#define SC_MW_32 0x02 /* 32 bit memory width */ + +#endif /* _ADM5120_MPMC_H_ */ diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_switch.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_switch.h new file mode 100644 index 0000000000..c796475c4c --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_switch.h @@ -0,0 +1,148 @@ +/* + * ADM5120 ethernet switch definitions + * + * This header file defines the hardware registers of the ADM5120 SoC + * built-in Ethernet switch. + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _ADM5120_SWITCH_H +#define _ADM5120_SWITCH_H + +#define BITMASK(len) ((1 << (len))-1) +#define ONEBIT(at) (1 << (at)) + +/* Switch register offsets */ +#define SWITCH_REG_CODE 0x0000 +#define SWITCH_REG_SOFT_RESET 0x0004 +#define SWITCH_REG_MEMCTRL 0x001C +#define SWITCH_REG_CPUP_CONF 0x0024 +#define SWITCH_REG_PORT_CONF0 0x0028 +#define SWITCH_REG_PORT_CONF1 0x002C +#define SWITCH_REG_PORT_CONF2 0x0030 +#define SWITCH_REG_VLAN_G1 0x0040 +#define SWITCH_REG_VLAN_G2 0x0044 +#define SWITCH_REG_SEND_TRIG 0x0048 +#define SWITCH_REG_MAC_WT0 0x0058 +#define SWITCH_REG_MAC_WT1 0x005C +#define SWITCH_REG_PHY_CNTL0 0x0068 +#define SWITCH_REG_PHY_CNTL1 0x006C +#define SWITCH_REG_PHY_CNTL2 0x007C +#define SWITCH_REG_PHY_CNTL3 0x0080 +#define SWITCH_REG_PRI_CNTL 0x0084 +#define SWITCH_REG_INT_STATUS 0x00B0 +#define SWITCH_REG_INT_MASK 0x00B4 +#define SWITCH_REG_GPIO_CONF0 0x00B8 +#define SWITCH_REG_GPIO_CONF2 0x00BC +#define SWITCH_REG_WDOG0 0x00C0 +#define SWITCH_REG_WDOG1 0x00C4 +#define SWITCH_REG_PHY_CNTL4 0x00A0 + +#define SWITCH_REG_SEND_HBADDR 0x00D0 +#define SWITCH_REG_SEND_LBADDR 0x00D4 +#define SWITCH_REG_RECV_HBADDR 0x00D8 +#define SWITCH_REG_RECV_LBADDR 0x00DC + +#define SWITCH_REG_TIMER_INT 0x00F0 +#define SWITCH_REG_TIMER 0x00F4 + +#define SWITCH_REG_PORT0_LED 0x0100 +#define SWITCH_REG_PORT1_LED 0x0104 +#define SWITCH_REG_PORT2_LED 0x0108 +#define SWITCH_REG_PORT3_LED 0x010C +#define SWITCH_REG_PORT4_LED 0x0110 + +/* CODE register bits */ +#define CODE_PC_MASK BITMASK(16) /* Product Code */ +#define CODE_REV_SHIFT 16 +#define CODE_REV_MASK BITMASK(4) /* Product Revision */ +#define CODE_CLKS_SHIFT 20 +#define CODE_CLKS_MASK BITMASK(2) /* Clock Speed */ +#define CODE_CLKS_175 0 /* 175 MHz */ +#define CODE_CLKS_200 1 /* 200 MHz */ +#define CODE_CLKS_225 2 /* 225 MHz */ +#define CODE_CLKS_250 3 /* 250 MHz */ +#define CODE_NAB ONEBIT(24) /* NAND boot */ +#define CODE_PK_MASK BITMASK(1) /* Package type */ +#define CODE_PK_SHIFT 29 +#define CODE_PK_BGA 0 /* BGA package */ +#define CODE_PK_PQFP 1 /* PQFP package */ + +/* MEMCTRL register bits */ +#define MEMCTRL_SDRS_MASK BITMASK(3) /* SDRAM bank size */ +#define MEMCTRL_SDRS_4M 0x01 +#define MEMCTRL_SDRS_8M 0x02 +#define MEMCTRL_SDRS_16M 0x03 +#define MEMCTRL_SDRS_64M 0x04 +#define MEMCTRL_SDRS_128M 0x05 +#define MEMCTRL_SDR1_ENABLE ONEBIT(5) /* enable SDRAM bank 1 */ + +#define MEMCTRL_SRS0_SHIFT 8 /* shift for SRAM0 size */ +#define MEMCTRL_SRS1_SHIFT 16 /* shift for SRAM1 size */ +#define MEMCTRL_SRS_MASK BITMASK(3) /* SRAM size mask */ +#define MEMCTRL_SRS_DISABLED 0x00 /* Disabled */ +#define MEMCTRL_SRS_512K 0x01 /* 512KB*/ +#define MEMCTRL_SRS_1M 0x02 /* 1MB */ +#define MEMCTRL_SRS_2M 0x03 /* 2MB */ +#define MEMCTRL_SRS_4M 0x04 /* 4MB */ + +/* GPIO_CONF0 register bits */ +#define GPIO_CONF0_MASK BITMASK(8) +#define GPIO_CONF0_IM_SHIFT 0 +#define GPIO_CONF0_IV_SHIFT 8 +#define GPIO_CONF0_OE_SHIFT 16 +#define GPIO_CONF0_OV_SHIFT 24 +#define GPIO_CONF0_IM_MASK (0xFF << GPIO_CONF0_IM_SHIFT) +#define GPIO_CONF0_IV_MASK (0xFF << GPIO_CONF0_IV_SHIFT) +#define GPIO_CONF0_OE_MASK (0xFF << GPIO_CONF0_OE_SHIFT) +#define GPIO_CONF0_OV_MASK (0xFF << GPIO_CONF0_OV_SHIFT) + +/* TIMER_INT register bits */ +#define TIMER_INT_TOS ONEBIT(1) /* time-out status */ +#define TIMER_INT_TOM ONEBIT(16) /* mask time-out interrupt */ + +/* TIMER register bits */ +#define TIMER_PERIOD_MASK BITMASK(16) /* mask for timer period */ +#define TIMER_PERIOD_DEFAULT 0xFFFF /* default timer period */ +#define TIMER_TE ONEBIT(16) /* timer enable bit */ + +/* PORTx_LED register bits */ +#define LED_MODE_MASK BITMASK(4) +#define LED_MODE_INPUT 0 +#define LED_MODE_FLASH 1 +#define LED_MODE_OUT_HIGH 2 +#define LED_MODE_OUT_LOW 3 +#define LED_MODE_LINK 4 +#define LED_MODE_SPEED 5 +#define LED_MODE_DUPLEX 6 +#define LED_MODE_ACT 7 +#define LED_MODE_COLL 8 +#define LED_MODE_LINK_ACT 9 +#define LED_MODE_DUPLEX_COLL 10 +#define LED_MODE_10M_ACT 11 +#define LED_MODE_100M_ACT 12 +#define LED0_MODE_SHIFT 0 /* LED0 mode shift */ +#define LED1_MODE_SHIFT 4 /* LED1 mode shift */ +#define LED2_MODE_SHIFT 8 /* LED2 mode shift */ +#define LED0_IV_SHIFT 12 /* LED0 input value shift */ +#define LED1_IV_SHIFT 13 /* LED1 input value shift */ +#define LED2_IV_SHIFT 14 /* LED2 input value shift */ + +#endif /* _ADM5120_SWITCH_H */ diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/gpio.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/gpio.h new file mode 100644 index 0000000000..97e187ea0c --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/gpio.h @@ -0,0 +1,109 @@ +/* + * $Id$ + * + * ADM5120 GPIO wrappers for arch-neutral GPIO calls + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef _ADM5120_GPIO_H_ +#define _ADM5120_GPIO_H_ + +#define ADM5120_GPIO_PIN0 0 +#define ADM5120_GPIO_PIN1 1 +#define ADM5120_GPIO_PIN2 2 +#define ADM5120_GPIO_PIN3 3 +#define ADM5120_GPIO_PIN4 4 +#define ADM5120_GPIO_PIN5 5 +#define ADM5120_GPIO_PIN6 6 +#define ADM5120_GPIO_PIN7 7 +#define ADM5120_GPIO_P0L0 8 +#define ADM5120_GPIO_P0L1 9 +#define ADM5120_GPIO_P0L2 10 +#define ADM5120_GPIO_P1L0 11 +#define ADM5120_GPIO_P1L1 12 +#define ADM5120_GPIO_P1L2 13 +#define ADM5120_GPIO_P2L0 14 +#define ADM5120_GPIO_P2L1 15 +#define ADM5120_GPIO_P2L2 16 +#define ADM5120_GPIO_P3L0 17 +#define ADM5120_GPIO_P3L1 18 +#define ADM5120_GPIO_P3L2 19 +#define ADM5120_GPIO_P4L0 20 +#define ADM5120_GPIO_P4L1 21 +#define ADM5120_GPIO_P4L2 22 +#define ADM5120_GPIO_MAX 22 +#define ADM5120_GPIO_COUNT ADM5120_GPIO_MAX+1 + +extern int adm5120_gpio_direction_input(unsigned gpio); +extern int adm5120_gpio_direction_output(unsigned gpio, int value); +extern int adm5120_gpio_get_value(unsigned gpio); +extern void adm5120_gpio_set_value(unsigned gpio, int value); +extern int adm5120_gpio_request(unsigned gpio, const char *label); +extern void adm5120_gpio_free(unsigned gpio); +extern int adm5120_gpio_to_irq(unsigned gpio); +extern int adm5120_irq_to_gpio(unsigned irq); + +/* + * Wrappers for the generic GPIO layer + */ +static inline int gpio_direction_input(unsigned gpio) +{ + return adm5120_gpio_direction_input(gpio); +} + +static inline int gpio_direction_output(unsigned gpio, int value) +{ + return adm5120_gpio_direction_output(gpio,value); +} + +static inline int gpio_get_value(unsigned gpio) +{ + return adm5120_gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + adm5120_gpio_set_value(gpio, value); +} + +static inline int gpio_request(unsigned gpio, const char *label) +{ + return adm5120_gpio_request(gpio, label); +} + +static inline void gpio_free(unsigned gpio) +{ + adm5120_gpio_free(gpio); +} + +static inline int gpio_to_irq(unsigned gpio) +{ + return adm5120_gpio_to_irq(gpio); +} + +static inline int irq_to_gpio(unsigned irq) +{ + return adm5120_irq_to_gpio(irq); +} + +#include /* cansleep wrappers */ + +#endif diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/myloader.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/myloader.h new file mode 100644 index 0000000000..3c0c6021b1 --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/myloader.h @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2006,2007 Gabor Juhos + * + * 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. + * + */ + +#ifndef _MYLOADER_H_ +#define _MYLOADER_H_ + +/* + * Firmware file format: + * + *
+ * [] + * ... + * [] + * + * [] + * ... + * [] + * + * + */ + +/* Myloader specific magic numbers */ +#define MYLO_MAGIC_FIRMWARE 0x4C594D00 +#define MYLO_MAGIC_20021103 0x20021103 +#define MYLO_MAGIC_20021107 0x20021107 + +#define MYLO_MAGIC_SYS_PARAMS MYLO_MAGIC_20021107 +#define MYLO_MAGIC_PARTITIONS MYLO_MAGIC_20021103 +#define MYLO_MAGIC_BOARD_PARAMS MYLO_MAGIC_20021103 + +/* + * Addresses of the data structures provided by MyLoader + */ +#define MYLO_MIPS_SYS_PARAMS 0x80000800 /* System Parameters */ +#define MYLO_MIPS_BOARD_PARAMS 0x80000A00 /* Board Parameters */ +#define MYLO_MIPS_PARTITIONS 0x80000C00 /* Partition Table */ +#define MYLO_MIPS_BOOT_PARAMS 0x80000E00 /* Boot Parameters */ + +/* Vendor ID's (seems to be same as the PCI vendor ID's) */ +#define VENID_COMPEX 0x11F6 + +/* Devices based on the ADM5120 */ +#define DEVID_COMPEX_NP27G 0x0078 +#define DEVID_COMPEX_NP28G 0x044C +#define DEVID_COMPEX_NP28GHS 0x044E +#define DEVID_COMPEX_WP54Gv1C 0x0514 +#define DEVID_COMPEX_WP54G 0x0515 +#define DEVID_COMPEX_WP54AG 0x0546 +#define DEVID_COMPEX_WPP54AG 0x0550 +#define DEVID_COMPEX_WPP54G 0x0555 + +/* Devices based on the IXP422 */ +#define DEVID_COMPEX_WP18 0x047E +#define DEVID_COMPEX_NP18A 0x0489 + +/* Other devices */ +#define DEVID_COMPEX_NP26G8M 0x03E8 +#define DEVID_COMPEX_NP26G16M 0x03E9 + +struct mylo_fw_header { + uint32_t magic; /* must be MYLO_MAGIC_FIRMWARE */ + uint32_t crc; /* CRC of the whole firmware */ + uint32_t res0; /* unknown/unused */ + uint32_t res1; /* unknown/unused */ + uint16_t vid; /* vendor ID */ + uint16_t did; /* device ID */ + uint16_t svid; /* sub vendor ID */ + uint16_t sdid; /* sub device ID */ + uint32_t rev; /* device revision */ + uint32_t fwhi; /* FIXME: firmware version high? */ + uint32_t fwlo; /* FIXME: firmware version low? */ + uint32_t flags; /* firmware flags */ +}; + +#define FW_FLAG_BOARD_PARAMS_WP 0x01 /* board parameters are write protected */ +#define FW_FLAG_BOOT_SECTOR_WE 0x02 /* enable of write boot sectors (below 64K) */ + +struct mylo_fw_blockdesc { + uint32_t type; /* block type */ + uint32_t addr; /* relative address to flash start */ + uint32_t dlen; /* size of block data in bytes */ + uint32_t blen; /* total size of block in bytes */ +}; + +#define FW_DESC_TYPE_UNUSED 0 +#define FW_DESC_TYPE_USED 1 + +struct mylo_partition { + uint16_t flags; /* partition flags */ + uint16_t type; /* type of the partition */ + uint32_t addr; /* relative address of the partition from the + flash start */ + uint32_t size; /* size of the partition in bytes */ + uint32_t param; /* if this is the active partition, the + MyLoader load code to this address */ +}; + +#define PARTITION_FLAG_ACTIVE 0x8000 /* this is the active partition, + * MyLoader loads firmware from here */ +#define PARTITION_FLAG_ISRAM 0x2000 /* FIXME: this is a RAM partition? */ +#define PARTIIION_FLAG_RAMLOAD 0x1000 /* FIXME: load this partition into the RAM? */ +#define PARTITION_FLAG_PRELOAD 0x0800 /* the partition data preloaded to RAM + * before decompression */ +#define PARTITION_FLAG_HAVEHDR 0x0002 /* the partition data have a header */ + +#define PARTITION_TYPE_FREE 0 +#define PARTITION_TYPE_USED 1 + +#define MYLO_MAX_PARTITIONS 8 /* maximum number of partitions in the + partition table */ + +struct mylo_partition_table { + uint32_t magic; /* must be MYLO_MAGIC_PARTITIONS */ + uint32_t res0; /* unknown/unused */ + uint32_t res1; /* unknown/unused */ + uint32_t res2; /* unknown/unused */ + struct mylo_partition partitions[MYLO_MAX_PARTITIONS]; +}; + +struct mylo_partition_header { + uint32_t len; /* length of the partition data */ + uint32_t crc; /* CRC value of the partition data */ +}; + +struct mylo_system_params { + uint32_t magic; /* must be MYLO_MAGIC_SYS_PARAMS */ + uint32_t res0; + uint32_t res1; + uint32_t mylo_ver; + uint16_t vid; /* Vendor ID */ + uint16_t did; /* Device ID */ + uint16_t svid; /* Sub Vendor ID */ + uint16_t sdid; /* Sub Device ID */ + uint32_t rev; /* device revision */ + uint32_t fwhi; + uint32_t fwlo; + uint32_t tftp_addr; + uint32_t prog_start; + uint32_t flash_size; /* Size of boot FLASH in bytes */ + uint32_t dram_size; /* Size of onboard RAM in bytes */ +}; + + +struct mylo_eth_addr { + uint8_t mac[6]; + uint8_t csum[2]; +}; + +#define MYLO_ETHADDR_COUNT 8 /* maximum number of ethernet address + in the board parameters */ + +struct mylo_board_params { + uint32_t magic; /* must be MYLO_MAGIC_BOARD_PARAMS */ + uint32_t res0; + uint32_t res1; + uint32_t res2; + struct mylo_eth_addr addr[MYLO_ETHADDR_COUNT]; +}; + +#endif /* _MYLOADER_H_*/ diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/routerboot.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/routerboot.h new file mode 100644 index 0000000000..2a593e9336 --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/routerboot.h @@ -0,0 +1,123 @@ +/* + * $Id$ + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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. + * + */ + +#ifndef _ROUTERBOOT_H +#define _ROUTERBOOT_H + +#define RB_MAC_SIZE 6 +#define RB_MAX_MAC_COUNT 6 + +struct rb_bios_settings { + u32 hs_offs; /* hard settings offset */ + u32 hs_size; /* hard settings size */ + u32 fw_offs; /* firmware offset */ + u32 ss_offs; /* soft settings offset */ + u32 ss_size; /* soft settings size */ +}; + +struct rb_hard_settings { + char *name; /* board name */ + char *bios_ver; /* BIOS version */ + u32 mem_size; /* memory size in bytes */ + u32 mac_count; /* number of mac addresses */ + u8 macs[RB_MAC_SIZE][RB_MAX_MAC_COUNT]; /* mac addresses */ +}; + +/* + * Magic numbers + */ +#define RB_MAGIC_HARD 0x64726148 /* "Hard" */ +#define RB_MAGIC_SOFT 0x74666F53 /* "Soft" */ +#define RB_MAGIC_DAWN 0x6E776144 /* "Dawn" */ + +#define RB_ID_TERMINATOR 0 + +/* + * ID values for Hardware settings + */ +#define RB_ID_HARD_01 1 +#define RB_ID_HARD_02 2 +#define RB_ID_FLASH_INFO 3 +#define RB_ID_MAC_ADDRESS_PACK 4 +#define RB_ID_BOARD_NAME 5 +#define RB_ID_BIOS_VERSION 6 +#define RB_ID_HARD_07 7 +#define RB_ID_SDRAM_TIMINGS 8 +#define RB_ID_DEVICE_TIMINGS 9 +#define RB_ID_SOFTWARE_ID 10 +#define RB_ID_SERIAL_NUMBER 11 +#define RB_ID_HARD_12 12 +#define RB_ID_MEMORY_SIZE 13 +#define RB_ID_MAC_ADDRESS_COUNT 14 + +/* + * ID values for Software settings + */ +#define RB_ID_UART_SPEED 1 +#define RB_ID_BOOT_DELAY 2 +#define RB_ID_BOOT_DEVICE 3 +#define RB_ID_BOOT_KEY 4 +#define RB_ID_CPU_MODE 5 +#define RB_ID_FW_VERSION 6 +#define RB_ID_SOFT_07 7 +#define RB_ID_SOFT_08 8 +#define RB_ID_BOOT_PROTOCOL 9 +#define RB_ID_SOFT_10 10 +#define RB_ID_SOFT_11 11 + +/* + * UART_SPEED values + */ +#define RB_UART_SPEED_115200 0 +#define RB_UART_SPEED_57600 1 +#define RB_UART_SPEED_38400 2 +#define RB_UART_SPEED_19200 3 +#define RB_UART_SPEED_9600 4 +#define RB_UART_SPEED_4800 5 +#define RB_UART_SPEED_2400 6 +#define RB_UART_SPEED_1200 7 + +/* + * BOOT_DELAY values + */ +#define RB_BOOT_DELAY_0SEC 0 +#define RB_BOOT_DELAY_1SEC 1 +#define RB_BOOT_DELAY_2SEC 2 + +/* + * BOOT_DEVICE values + */ +#define RB_BOOT_DEVICE_ETHER 0 +#define RB_BOOT_DEVICE_NANDETH 1 +#define RB_BOOT_DEVICE_ETHONCE 2 +#define RB_BOOT_DEVICE_NANDONLY 3 + +/* + * BOOT_KEY values + */ +#define RB_BOOT_KEY_ANY 0 +#define RB_BOOT_KEY_DEL 1 + +/* + * CPU_MODE values + */ +#define RB_CPU_MODE_POWERSAVE 0 +#define RB_CPU_MODE_REGULAR 1 + +/* + * BOOT_PROTOCOL values + */ +#define RB_BOOT_PROTOCOL_BOOTP 0 +#define RB_BOOT_PROTOCOL_DHCP 1 + +#endif /* _ROUTERBOOT_H */ diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/zynos.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/zynos.h new file mode 100644 index 0000000000..ba372d3d3e --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/zynos.h @@ -0,0 +1,78 @@ +/* + * $Id$ + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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. + * + */ + +#ifndef _ZYNOS_H +#define _ZYNOS_H + +#define ZYNOS_NAME_LEN 32 +#define ZYNOS_FEAT_BYTES 22 +#define ZYNOS_MAC_LEN 6 + +struct zynos_board_info { + unsigned char vendor[ZYNOS_NAME_LEN]; + unsigned char product[ZYNOS_NAME_LEN]; + u32 bootext_addr; + u32 res0; + u16 board_id; + u8 res1[6]; + u8 feat_other[ZYNOS_FEAT_BYTES]; + u8 feat_main; + u8 res2; + u8 mac[ZYNOS_MAC_LEN]; + u8 country; + u8 dbgflag; +} __attribute__ ((packed)); + +/* + * Vendor IDs + */ +#define ZYNOS_VENDOR_ID_ZYXEL 0 +#define ZYNOS_VENDOR_ID_NETGEAR 1 +#define ZYNOS_VENDOR_ID_DLINK 2 +#define ZYNOS_VENDOR_ID_OTHER 3 +#define ZYNOS_VENDOR_ID_LUCENT 4 + +/* + * Vendor names + */ +#define ZYNOS_VENDOR_DLINK "D-Link" +#define ZYNOS_VENDOR_LUCENT "LUCENT" +#define ZYNOS_VENDOR_NETGEAR "NetGear" +#define ZYNOS_VENDOR_ZYXEL "ZyXEL" + +/* + * Board IDs (big-endian) + */ +#define ZYNOS_BOARD_ES2108 0x00F2 /* Ethernet Switch 2108 */ +#define ZYNOS_BOARD_ES2108F 0x01AF /* Ethernet Switch 2108-F */ +#define ZYNOS_BOARD_ES2108G 0x00F3 /* Ethernet Switch 2108-G */ +#define ZYNOS_BOARD_ES2108LC 0x00FC /* Ethernet Switch 2108-LC */ +#define ZYNOS_BOARD_ES2108PWR 0x00F4 /* Ethernet Switch 2108PWR */ +#define ZYNOS_BOARD_HS100 0x9FF1 /* HomeSafe 100/100W */ +#define ZYNOS_BOARD_P334 0x9FF5 /* Prestige 334 */ +#define ZYNOS_BOARD_P334U 0x9FDD /* Prestige 334U */ +#define ZYNOS_BOARD_P334W 0x9FF3 /* Prestige 334W */ +#define ZYNOS_BOARD_P334WH 0x00E0 /* Prestige 334WH */ +#define ZYNOS_BOARD_P334WHD 0x00E1 /* Prestige 334WHD */ +#define ZYNOS_BOARD_P334WT 0x9FEF /* Prestige 334WT */ +#define ZYNOS_BOARD_P335 0x9FED /* Prestige 335/335WT */ +#define ZYNOS_BOARD_P335PLUS 0x0025 /* Prestige 335Plus */ +#define ZYNOS_BOARD_P335U 0x9FDC /* Prestige 335U */ + +/* + * Some magic numbers (big-endian) + */ +#define ZYNOS_MAGIC_DBGAREA1 0x48646267 /* "Hdbg" */ +#define ZYNOS_MAGIC_DBGAREA2 0x61726561 /* "area" */ + +#endif /* _ZYNOS_H */ diff --git a/target/linux/adm5120-2.6/files/include/linux/gpio_leds.h b/target/linux/adm5120-2.6/files/include/linux/gpio_leds.h new file mode 100644 index 0000000000..95a09e51ee --- /dev/null +++ b/target/linux/adm5120-2.6/files/include/linux/gpio_leds.h @@ -0,0 +1,37 @@ +/* + * $Id$ + * + * GPIO LEDs platform data structure + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef _GPIO_LEDS_H_ +#define _GPIO_LEDS_H_ + +struct gpio_led_platform_data { + char *name; + char *trigger; + unsigned gpio; /* GPIO line number */ + int value_off; /* value to turn LED OFF */ + int value_on; /* value to turn LED ON */ +}; + +#endif /* _GPIO_LEDS_H__ */ diff --git a/target/linux/adm5120-2.6/image/Makefile b/target/linux/adm5120-2.6/image/Makefile new file mode 100644 index 0000000000..ae869f6055 --- /dev/null +++ b/target/linux/adm5120-2.6/image/Makefile @@ -0,0 +1,163 @@ +# +# Copyright (C) 2006,2007 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 + +IMGNAME = $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL) +LOADER_MAKE = $(MAKE) -C lzma-loader KDIR=$(KDIR) + +define Image/Build/Loader + $(LOADER_MAKE) LOADER=loader-$(1).$(2) LOADER_DATA="" \ + LZMA_TEXT_START=$(3) LZMA_STARTUP_ORG=$(4) \ + CONFIG_PASS_KARGS=$(5) CONFIG_BOARD=$(6) \ + compile loader.$(2) +endef + +define Build/Clean + $(LOADER_MAKE) clean +endef + +define Image/Prepare + cat $(KDIR)/vmlinux | $(STAGING_DIR)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma +endef + +define trxalign/jffs2-128k +-a 0x20000 +endef +define trxalign/jffs2-64k +-a 0x10000 +endef +define trxalign/squashfs +-a 1024 +endef + +define Image/Build/TRX + $(STAGING_DIR)/bin/trx -o $(1) -f $(3) -f $(KDIR)/vmlinux.lzma \ + $(call trxalign/$(2)) -f $(KDIR)/root.$(2) +endef + +define Image/Build/TRXNoloader + $(STAGING_DIR)/bin/trx -o $(1) -f $(KDIR)/vmlinux.lzma \ + $(call trxalign/$(2)) -f $(KDIR)/root.$(2) +endef + +define Image/Build/Compex + $(call Image/Build/Loader,$(2),gz,0x80500000,0,y,$(2)) + $(call Image/Build/TRX,$(IMGNAME)-$(3)-$(2).trx,$(1),$(KDIR)/loader-$(2).gz) +endef + +define Image/Build/Edimax + $(call Image/Build/Loader,$(2),gz,0x80500000,0x6D8,y,$(2)) + $(call Image/Build/TRXNoloader,$(IMGNAME)-$(3)-$(2).trx,$(1)) + $(STAGING_DIR)/bin/mkcsysimg -B $(4) -d -w \ + -r $(KDIR)/loader-$(2).gz \ + -x $(IMGNAME)-$(3)-$(2).trx \ + $(IMGNAME)-$(3)-$(2).bin +endef + +define Image/Build/Infineon + $(call Image/Build/Loader,$(2),gz,0x80500000,0x6D8,y,$(2)) + $(call Image/Build/TRXNoloader,$(IMGNAME)-$(3)-$(2).trx,$(1)) + dd if=$(KDIR)/loader-$(2).gz of=$(IMGNAME)-$(3)-$(2).img bs=64k conv=sync + cat $(IMGNAME)-$(3)-$(2).trx >>$(IMGNAME)-$(3)-$(2).img +endef + +define Image/Build/MyLoader + $(call Image/Build/Loader,$(2),gz,0x80500000,0) + $(call Image/Build/TRXNoloader,$(IMGNAME)-$(3)-$(2).trx,$(1)) + $(STAGING_DIR)/bin/mkmylofw -B $(4) \ + -p0x20000:0x10000:ahp:0x80001000 \ + -p0x30000:0 \ + -b0x20000:0x10000:h:$(KDIR)/loader-$(2).gz \ + -b0x30000:0::$(IMGNAME)-$(3)-$(2).trx \ + $(IMGNAME)-$(3)-$(2).bin +endef + +define Image/cmdline/yaffs2 +root=/dev/mtdblock1 rootfstype=yaffs2 init=/etc/preinit +endef + +define Image/Build/RouterBoard + $(CP) $(KDIR)/vmlinux.elf $(IMGNAME)-vmlinux + $(STAGING_DIR)/bin/patch-cmdline $(KDIR)/vmlinux.elf '$(strip $(call Image/cmdline/yaffs2)) ' +endef + +define Image/Build +# this line is here intentionally +ifneq ($(1),jffs2-256k) +ifneq ($(1),jffs2-128k) + $(call Image/Build/Compex,$(1),wp54g-wrt,$(patsubst jffs2-%,jffs2,$(1)),WP54G-WRT) + $(call Image/Build/Edimax,$(1),br-6104k,$(patsubst jffs2-%,jffs2,$(1)),BR-6104K) + $(call Image/Build/Edimax,$(1),br-6104kp,$(patsubst jffs2-%,jffs2,$(1)),BR-6104KP) + $(call Image/Build/Edimax,$(1),br-6114wg,$(patsubst jffs2-%,jffs2,$(1)),BR-6114WG) + $(call Image/Build/Edimax,$(1),br-6524k,$(patsubst jffs2-%,jffs2,$(1)),BR-6524K) + $(call Image/Build/Edimax,$(1),br-6524kp,$(patsubst jffs2-%,jffs2,$(1)),BR-6524KP) + $(call Image/Build/Edimax,$(1),br-6541k,$(patsubst jffs2-%,jffs2,$(1)),BR-6541K) + $(call Image/Build/Edimax,$(1),br-6541kp,$(patsubst jffs2-%,jffs2,$(1)),BR-6541KP) + $(call Image/Build/Edimax,$(1),ew-7207apg,$(patsubst jffs2-%,jffs2,$(1)),EW-7207APg) + $(call Image/Build/Edimax,$(1),ps-1205uwg,$(patsubst jffs2-%,jffs2,$(1)),PS-1205UWg) + $(call Image/Build/Edimax,$(1),ps-3205u,$(patsubst jffs2-%,jffs2,$(1)),PS-3205U) + $(call Image/Build/Edimax,$(1),ps-3205uwg,$(patsubst jffs2-%,jffs2,$(1)),PS-3205UWg) + $(call Image/Build/Edimax,$(1),br-6524wg,$(patsubst jffs2-%,jffs2,$(1)),BR-6524WG) + $(call Image/Build/Edimax,$(1),br-6524wp,$(patsubst jffs2-%,jffs2,$(1)),BR-6524WP) + $(call Image/Build/Infineon,$(1),easy-5120,$(patsubst jffs2-%,jffs2,$(1))) + $(call Image/Build/Infineon,$(1),easy-5120-rt,$(patsubst jffs2-%,jffs2,$(1))) + $(call Image/Build/Infineon,$(1),easy-5120p-ata,$(patsubst jffs2-%,jffs2,$(1))) + $(call Image/Build/Infineon,$(1),easy-83000,$(patsubst jffs2-%,jffs2,$(1))) + $(call Image/Build/MyLoader,$(1),np27g,$(patsubst jffs2-%,jffs2,$(1)),NP27G) + $(call Image/Build/MyLoader,$(1),np28g,$(patsubst jffs2-%,jffs2,$(1)),NP28G) + $(call Image/Build/MyLoader,$(1),np28ghs,$(patsubst jffs2-%,jffs2,$(1)),NP28GHS) + $(call Image/Build/MyLoader,$(1),wp54g,$(patsubst jffs2-%,jffs2,$(1)),WP54G) + $(call Image/Build/MyLoader,$(1),wp54ag,$(patsubst jffs2-%,jffs2,$(1)),WP54AG) + $(call Image/Build/MyLoader,$(1),wpp54g,$(patsubst jffs2-%,jffs2,$(1)),WPP54G) + $(call Image/Build/MyLoader,$(1),wpp54ag,$(patsubst jffs2-%,jffs2,$(1)),WPP54AG) +endif +endif +ifeq ($(1),tgz) + $(call Image/Build/RouterBoard) +endif +endef + +define Image/Build/LZMAKernel + $(LOADER_MAKE) TARGET_DIR=$(BIN_DIR) \ + LOADER=openwrt-$(BOARD)-$(KERNEL)-ramfs-lzma-$(1).$(2) \ + LOADER_DATA=$(KDIR)/vmlinux.lzma \ + LZMA_TEXT_START=$(3) LZMA_STARTUP_ORG=$(4) \ + CONFIG_PASS_KARGS=$(5) CONFIG_BOARD=$(6) \ + compile loader.$(2) +endef + +define Image/Build/LZMAKernel/Compex + $(call Image/Build/LZMAKernel,$(1),$(2),0x80500000,0,y,$(1)) +endef + +define Image/Build/LZMAKernel/Generic + $(call Image/Build/LZMAKernel,$(1),$(2),0x80500000,0) +endef + +define Image/Build/LZMAKernel/Admboot + $(call Image/Build/LZMAKernel,$(1),$(2),0x80500000,0x6D8,y,$(1)) +endef + +define Image/Build/Initramfs + $(call Image/Build/LZMAKernel/Generic,generic,bin) + $(call Image/Build/LZMAKernel/Generic,rb-100,elf) + $(call Image/Build/LZMAKernel/Generic,np27g,bin) + $(call Image/Build/LZMAKernel/Generic,wp54g,bin) + $(call Image/Build/LZMAKernel/Compex,wp54g-wrt,bin) + $(call Image/Build/LZMAKernel/Admboot,br-6104k,gz) + $(call Image/Build/LZMAKernel/Admboot,easy-5120,gz) + $(call Image/Build/LZMAKernel/Admboot,easy-83000,gz) + $(call Image/Build/LZMAKernel/Admboot,cas-630,gz) + $(call Image/Build/LZMAKernel/Admboot,cas-670,gz) + $(call Image/Build/LZMAKernel/Admboot,cas-700,gz) + $(call Image/Build/LZMAKernel/Admboot,cas-771,gz) + $(call Image/Build/LZMAKernel/Admboot,cas-790,gz) + $(call Image/Build/LZMAKernel/Admboot,cas-861,gz) +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/adm5120-2.6/image/lzma-loader/Makefile b/target/linux/adm5120-2.6/image/lzma-loader/Makefile new file mode 100644 index 0000000000..74866e765e --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/Makefile @@ -0,0 +1,63 @@ +# +# 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 + +LOADER := loader.bin +LOADER_NAME := $(basename $(notdir $(LOADER))) +LOADER_DATA := +TARGET_DIR := + +ifeq ($(TARGET_DIR),) +TARGET_DIR := $(KDIR) +endif + +LOADER_BIN := $(TARGET_DIR)/$(LOADER_NAME).bin +LOADER_GZ := $(TARGET_DIR)/$(LOADER_NAME).gz +LOADER_ELF := $(TARGET_DIR)/$(LOADER_NAME).elf + +LZMA_STARTUP_ORG:= 0 +LZMA_TEXT_START := 0x80300000 + +PKG_NAME := lzma-loader +PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME) + +.PHONY : loader-compile loader.bin loader.elf loader.gz + +$(PKG_BUILD_DIR)/.prepared: + mkdir $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ + touch $@ + +loader-compile: $(PKG_BUILD_DIR)/.prepared + $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \ + LZMA_STARTUP_ORG=$(LZMA_STARTUP_ORG) \ + LZMA_TEXT_START=$(LZMA_TEXT_START) \ + LOADER_DATA=$(LOADER_DATA) \ + CONFIG_BOARD=$(CONFIG_BOARD) \ + CONFIG_PASS_KARGS=$(CONFIG_PASS_KARGS) \ + clean all + +loader.gz: $(PKG_BUILD_DIR)/loader.bin + gzip -nc9 $< > $(LOADER_GZ) + +loader.elf: $(PKG_BUILD_DIR)/loader.elf + $(CP) $< $(LOADER_ELF) + +loader.bin: $(PKG_BUILD_DIR)/loader.bin + $(CP) $< $(LOADER_BIN) + +download: +prepare: $(PKG_BUILD_DIR)/.prepared +compile: loader-compile + +install: + +clean: + rm -rf $(PKG_BUILD_DIR) + diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/LzmaDecode.c b/target/linux/adm5120-2.6/image/lzma-loader/src/LzmaDecode.c new file mode 100644 index 0000000000..951700bddf --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/LzmaDecode.c @@ -0,0 +1,663 @@ +/* + LzmaDecode.c + LZMA Decoder + + LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) + 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. +*/ + +#include "LzmaDecode.h" + +#ifndef Byte +#define Byte unsigned char +#endif + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +typedef struct _CRangeDecoder +{ + Byte *Buffer; + Byte *BufferLim; + UInt32 Range; + UInt32 Code; + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback; + int Result; + #endif + int ExtraBytes; +} CRangeDecoder; + +Byte RangeDecoderReadByte(CRangeDecoder *rd) +{ + if (rd->Buffer == rd->BufferLim) + { + #ifdef _LZMA_IN_CB + UInt32 size; + rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); + rd->BufferLim = rd->Buffer + size; + if (size == 0) + #endif + { + rd->ExtraBytes = 1; + return 0xFF; + } + } + return (*rd->Buffer++); +} + +/* #define ReadByte (*rd->Buffer++) */ +#define ReadByte (RangeDecoderReadByte(rd)) + +void RangeDecoderInit(CRangeDecoder *rd, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback + #else + Byte *stream, UInt32 bufferSize + #endif + ) +{ + int i; + #ifdef _LZMA_IN_CB + rd->InCallback = inCallback; + rd->Buffer = rd->BufferLim = 0; + #else + rd->Buffer = stream; + rd->BufferLim = stream + bufferSize; + #endif + rd->ExtraBytes = 0; + rd->Code = 0; + rd->Range = (0xFFFFFFFF); + for(i = 0; i < 5; i++) + rd->Code = (rd->Code << 8) | ReadByte; +} + +#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code; +#define RC_FLUSH_VAR rd->Range = range; rd->Code = code; +#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; } + +UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits) +{ + RC_INIT_VAR + UInt32 result = 0; + int i; + for (i = numTotalBits; i > 0; i--) + { + /* UInt32 t; */ + range >>= 1; + + result <<= 1; + if (code >= range) + { + code -= range; + result |= 1; + } + /* + t = (code - range) >> 31; + t &= 1; + code -= range & (t - 1); + result = (result + result) | (1 - t); + */ + RC_NORMALIZE + } + RC_FLUSH_VAR + return result; +} + +int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd) +{ + UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob; + if (rd->Code < bound) + { + rd->Range = bound; + *prob += (kBitModelTotal - *prob) >> kNumMoveBits; + if (rd->Range < kTopValue) + { + rd->Code = (rd->Code << 8) | ReadByte; + rd->Range <<= 8; + } + return 0; + } + else + { + rd->Range -= bound; + rd->Code -= bound; + *prob -= (*prob) >> kNumMoveBits; + if (rd->Range < kTopValue) + { + rd->Code = (rd->Code << 8) | ReadByte; + rd->Range <<= 8; + } + return 1; + } +} + +#define RC_GET_BIT2(prob, mi, A0, A1) \ + UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \ + if (code < bound) \ + { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \ + else \ + { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \ + RC_NORMALIZE + +#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;) + +int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ + int mi = 1; + int i; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + for(i = numLevels; i > 0; i--) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + mi; + RC_GET_BIT(prob, mi) + #else + mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd); + #endif + } + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return mi - (1 << numLevels); +} + +int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ + int mi = 1; + int i; + int symbol = 0; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + for(i = 0; i < numLevels; i++) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + mi; + RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i)) + #else + int bit = RangeDecoderBitDecode(probs + mi, rd); + mi = mi + mi + bit; + symbol |= (bit << i); + #endif + } + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) +{ + int symbol = 1; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + do + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + symbol; + RC_GET_BIT(prob, symbol) + #else + symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); + #endif + } + while (symbol < 0x100); + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte) +{ + int symbol = 1; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + do + { + int bit; + int matchBit = (matchByte >> 7) & 1; + matchByte <<= 1; + #ifdef _LZMA_LOC_OPT + { + CProb *prob = probs + ((1 + matchBit) << 8) + symbol; + RC_GET_BIT2(prob, symbol, bit = 0, bit = 1) + } + #else + bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd); + symbol = (symbol << 1) | bit; + #endif + if (matchBit != bit) + { + while (symbol < 0x100) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + symbol; + RC_GET_BIT(prob, symbol) + #else + symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); + #endif + } + break; + } + } + while (symbol < 0x100); + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +#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) + +int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState) +{ + if(RangeDecoderBitDecode(p + LenChoice, rd) == 0) + return RangeDecoderBitTreeDecode(p + LenLow + + (posState << kLenNumLowBits), kLenNumLowBits, rd); + if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0) + return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid + + (posState << kLenNumMidBits), kLenNumMidBits, rd); + return kLenNumLowSymbols + kLenNumMidSymbols + + RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd); +} + +#define kNumStates 12 + +#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 + +#ifdef _LZMA_OUT_READ + +typedef struct _LzmaVarState +{ + CRangeDecoder RangeDecoder; + Byte *Dictionary; + UInt32 DictionarySize; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 Reps[4]; + int lc; + int lp; + int pb; + int State; + int PreviousIsMatch; + int RemainLen; +} LzmaVarState; + +int LzmaDecoderInit( + unsigned char *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + unsigned char *dictionary, UInt32 dictionarySize, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback + #else + unsigned char *inStream, UInt32 inSize + #endif + ) +{ + LzmaVarState *vs = (LzmaVarState *)buffer; + CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); + UInt32 i; + if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState)) + return LZMA_RESULT_NOT_ENOUGH_MEM; + vs->Dictionary = dictionary; + vs->DictionarySize = dictionarySize; + vs->DictionaryPos = 0; + vs->GlobalPos = 0; + vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1; + vs->lc = lc; + vs->lp = lp; + vs->pb = pb; + vs->State = 0; + vs->PreviousIsMatch = 0; + vs->RemainLen = 0; + dictionary[dictionarySize - 1] = 0; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + RangeDecoderInit(&vs->RangeDecoder, + #ifdef _LZMA_IN_CB + inCallback + #else + inStream, inSize + #endif + ); + return LZMA_RESULT_OK; +} + +int LzmaDecode(unsigned char *buffer, + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed) +{ + LzmaVarState *vs = (LzmaVarState *)buffer; + CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); + CRangeDecoder rd = vs->RangeDecoder; + int state = vs->State; + int previousIsMatch = vs->PreviousIsMatch; + Byte previousByte; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + UInt32 nowPos = 0; + UInt32 posStateMask = (1 << (vs->pb)) - 1; + UInt32 literalPosMask = (1 << (vs->lp)) - 1; + int lc = vs->lc; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + if (len == -1) + { + *outSizeProcessed = 0; + return LZMA_RESULT_OK; + } + + 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 + +int LzmaDecode( + Byte *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + unsigned char *inStream, UInt32 inSize, + #endif + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed) +{ + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); + CProb *p = (CProb *)buffer; + CRangeDecoder rd; + UInt32 i; + int state = 0; + int previousIsMatch = 0; + Byte previousByte = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + UInt32 nowPos = 0; + UInt32 posStateMask = (1 << pb) - 1; + UInt32 literalPosMask = (1 << lp) - 1; + int len = 0; + if (bufferSize < numProbs * sizeof(CProb)) + return LZMA_RESULT_NOT_ENOUGH_MEM; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + RangeDecoderInit(&rd, + #ifdef _LZMA_IN_CB + inCallback + #else + inStream, inSize + #endif + ); +#endif + + *outSizeProcessed = 0; + while(nowPos < outSize) + { + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + #ifdef _LZMA_IN_CB + if (rd.Result != LZMA_RESULT_OK) + return rd.Result; + #endif + if (rd.ExtraBytes != 0) + return LZMA_RESULT_DATA_ERROR; + if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) + { + CProb *probs = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + if (previousIsMatch) + { + Byte matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); + previousIsMatch = 0; + } + else + previousByte = LzmaLiteralDecode(probs, &rd); + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + } + else + { + previousIsMatch = 1; + if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) + { + if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) + { + if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + if ( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + == 0) + return LZMA_RESULT_DATA_ERROR; + state = state < 7 ? 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; + continue; + } + } + else + { + UInt32 distance; + if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) + distance = rep1; + else + { + if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) + distance = rep2; + else + { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + len = LzmaLenDecode(p + RepLenCoder, &rd, posState); + state = state < 7 ? 8 : 11; + } + else + { + int posSlot; + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < 7 ? 7 : 10; + len = LzmaLenDecode(p + LenCoder, &rd, posState); + posSlot = RangeDecoderBitTreeDecode(p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits), kNumPosSlotBits, &rd); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); + if (posSlot < kEndPosModelIndex) + { + rep0 += RangeDecoderReverseBitTreeDecode( + p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); + } + else + { + rep0 += RangeDecoderDecodeDirectBits(&rd, + numDirectBits - kNumAlignBits) << kNumAlignBits; + rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); + } + } + else + rep0 = posSlot; + rep0++; + } + if (rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = -1; + break; + } + if (rep0 > nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + { + return LZMA_RESULT_DATA_ERROR; + } + len += kMatchMinLen; + 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 + outStream[nowPos++] = previousByte; + len--; + } + while(len > 0 && nowPos < outSize); + } + } + + #ifdef _LZMA_OUT_READ + vs->RangeDecoder = rd; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + nowPos; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->PreviousIsMatch = previousIsMatch; + vs->RemainLen = len; + #endif + + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/LzmaDecode.h b/target/linux/adm5120-2.6/image/lzma-loader/src/LzmaDecode.h new file mode 100644 index 0000000000..f58944e3c3 --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/LzmaDecode.h @@ -0,0 +1,100 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) + 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 + +/* #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 */ + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb unsigned short +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 +#define LZMA_RESULT_NOT_ENOUGH_MEM 2 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback +{ + int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize); +} ILzmaInCallback; +#endif + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +/* +bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb) +bufferSize += 100 in case of _LZMA_OUT_READ +by default CProb is unsigned short, +but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int) +*/ + +#ifdef _LZMA_OUT_READ +int LzmaDecoderInit( + unsigned char *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + unsigned char *dictionary, UInt32 dictionarySize, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback + #else + unsigned char *inStream, UInt32 inSize + #endif +); +#endif + +int LzmaDecode( + unsigned char *buffer, + #ifndef _LZMA_OUT_READ + UInt32 bufferSize, + int lc, int lp, int pb, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + unsigned char *inStream, UInt32 inSize, + #endif + #endif + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed); + +#endif diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/Makefile b/target/linux/adm5120-2.6/image/lzma-loader/src/Makefile new file mode 100644 index 0000000000..a3749f2ee9 --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/Makefile @@ -0,0 +1,98 @@ +# +# Makefile for Broadcom BCM947XX boards +# +# Copyright 2001-2003, Broadcom Corporation +# All Rights Reserved. +# +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. +# +# Copyright 2004 Manuel Novoa III +# Modified to support bzip'd kernels. +# Of course, it would be better to integrate bunzip capability into CFE. +# +# Copyright 2005 Oleg I. Vdovikin +# Cleaned up, modified for lzma support, removed from kernel +# +# Copyright 2007 Gabor Juhos +# Modified to support user defined entry point address. +# Added support for make targets with different names +# + +LOADADDR := 0x80001000 +LZMA_TEXT_START := 0x80500000 +LZMA_STARTUP_ORG:= 0 +LOADER_DATA := +CONFIG_PASS_KARGS := +CONFIG_BOARD := + +CC := $(CROSS_COMPILE)gcc +LD := $(CROSS_COMPILE)ld +OBJCOPY := $(CROSS_COMPILE)objcopy +OBJDUMP := $(CROSS_COMPILE)objdump + +BIN_FLAGS := -O binary -R .reginfo -R .note -R .comment -R .mdebug -S + +CFLAGS = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ + -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \ + -ffunction-sections -pipe -mlong-calls -fno-common \ + -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap +CFLAGS += -DLOADADDR=$(LOADADDR) + +ASFLAGS = $(CFLAGS) -D__ASSEMBLY__ -DLZMA_STARTUP_ORG=$(LZMA_STARTUP_ORG) + +LDFLAGS = -static --gc-sections -no-warn-mismatch +LDFLAGS += -e startup -T loader.lds -Ttext $(LZMA_TEXT_START) + +O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32) + +OBJECTS := head.o decompress.o board.o LzmaDecode.o + +ifneq ($(strip $(LOADER_DATA)),) +OBJECTS += data.o +CFLAGS += -DLZMA_WRAPPER=1 +else +CFLAGS += -D_LZMA_IN_CB +endif + +ifneq ($(strip $(CONFIG_PASS_KARGS)),) +CFLAGS += -DCONFIG_PASS_KARGS +endif + +BOARD_DEF := $(strip $(CONFIG_BOARD)) +BOARD_DEF := $(shell echo $(BOARD_DEF) | tr a-z A-Z | tr -d -) +ifneq ($(BOARD_DEF),) +CFLAGS += -DCONFIG_BOARD_$(BOARD_DEF) +endif + +all: loader.bin + +# Don't build dependencies, this may die if $(CC) isn't gcc +dep: + +install: + +%.o : %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.o : %.S + $(CC) $(ASFLAGS) -c -o $@ $< + +data.o: $(LOADER_DATA) + $(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $< + +loader.bin: loader.elf + $(OBJCOPY) $(BIN_FLAGS) $< $@ + +loader.elf: $(OBJECTS) + $(LD) $(LDFLAGS) -o $@ $(OBJECTS) + +mrproper: clean + +clean: + rm -f *.elf *.bin *.o + + + diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/README b/target/linux/adm5120-2.6/image/lzma-loader/src/README new file mode 100644 index 0000000000..16649e9500 --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/README @@ -0,0 +1,55 @@ +/* + * LZMA compressed kernel decompressor for bcm947xx boards + * + * Copyright (C) 2005 by Oleg I. Vdovikin + * + * 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 + * + */ + +The code is intended to decompress kernel, being compressed using lzma utility +build using 7zip LZMA SDK. This utility is located in the LZMA_Alone directory + +decompressor code expects that your .trx file consist of three partitions: + +1) decompressor itself (this is gziped code which pmon/cfe will extract and run +on boot-up instead of real kernel) +2) LZMA compressed kernel (both streamed and regular modes are supported now) +3) Root filesystem + +Please be sure to apply the following patch for use this new trx layout (it will +allow using both new and old trx files for root filesystem lookup code) + +--- linuz/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:24:27.503322896 +0300 ++++ linux/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:29:05.237100944 +0300 +@@ -221,7 +221,9 @@ + /* Try looking at TRX header for rootfs offset */ + if (le32_to_cpu(trx->magic) == TRX_MAGIC) { + bcm947xx_parts[1].offset = off; +- if (le32_to_cpu(trx->offsets[1]) > off) ++ if (le32_to_cpu(trx->offsets[2]) > off) ++ off = le32_to_cpu(trx->offsets[2]); ++ else if (le32_to_cpu(trx->offsets[1]) > off) + off = le32_to_cpu(trx->offsets[1]); + continue; + } + + +Revision history: + 0.02 Initial release + 0.03 Added Mineharu Takahara patch to pass actual + output size to decoder (stream mode compressed input is not + a requirement anymore) + 0.04 Reordered functions using lds script diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/board.c b/target/linux/adm5120-2.6/image/lzma-loader/src/board.c new file mode 100644 index 0000000000..616e7562a8 --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/board.c @@ -0,0 +1,184 @@ +/* + * ADM5120 specific board support for LZMA decompressor + * + * Copyright (C) 2007 OpenWrt.org + * Copyright (C) 2007 Gabor Juhos + * + * 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 + +#define READREG(r) *(volatile unsigned int *)(r) +#define WRITEREG(r,v) *(volatile unsigned int *)(r) = v + +/* + * INTC definitions + */ +#define INTC_BASE 0xB2200000 + +/* INTC registers */ +#define INTC_REG_IRQ_DISABLE 0x0C + +/* + * UART definitions + */ +#define UART_BASE 0xB2600000 +/* UART registers */ +#define UART_REG_DATA 0x00 /* Data register */ +#define UART_REG_ECR 0x04 /* Error Clear register */ +#define UART_REG_LCRH 0x08 /* Line Control High register */ +#define UART_REG_LCRM 0x0C /* Line Control Middle register */ +#define UART_REG_LCRL 0x10 /* Line Control Low register */ +#define UART_REG_CTRL 0x14 /* Control register */ +#define UART_REG_FLAG 0x18 /* Flag register */ + +/* Control register bits */ +#define UART_CTRL_EN ( 1 << 0 ) /* UART enable */ + +/* Line Control High register bits */ +#define UART_LCRH_FEN ( 1 << 4 ) /* FIFO enable */ + +/* Flag register bits */ +#define UART_FLAG_CTS ( 1 << 0 ) +#define UART_FLAG_DSR ( 1 << 1 ) +#define UART_FLAG_DCD ( 1 << 2 ) +#define UART_FLAG_BUSY ( 1 << 3 ) +#define UART_FLAG_RXFE ( 1 << 4 ) /* RX FIFO empty */ +#define UART_FLAG_TXFF ( 1 << 5 ) /* TX FIFO full */ +#define UART_FLAG_RXFF ( 1 << 6 ) /* RX FIFO full */ +#define UART_FLAG_TXFE ( 1 << 7 ) /* TX FIFO empty */ + +/* + * SWITCH definitions + */ +#define SWITCH_BASE 0xB2000000 + +#define SWITCH_REG_CPUP_CONF 0x0024 +#define SWITCH_REG_PORT_CONF0 0x0028 + +#define SWITCH_REG_GPIO_CONF0 0x00B8 +#define SWITCH_REG_GPIO_CONF2 0x00BC + +#define SWITCH_REG_PORT0_LED 0x0100 +#define SWITCH_REG_PORT1_LED 0x0104 +#define SWITCH_REG_PORT2_LED 0x0108 +#define SWITCH_REG_PORT3_LED 0x010C +#define SWITCH_REG_PORT4_LED 0x0110 + +#define SWITCH_PORTS_HW 0x3F /* Hardware Ports */ + +/* CPUP_CONF register bits */ +#define CPUP_CONF_DCPUP ( 1 << 0 ) /* Disable CPU port */ + +/* PORT_CONF0 register bits */ +#define PORT_CONF0_DP_SHIFT 0 /* disable port shift*/ + + +/* + * UART routines + */ + +#define UART_READ(r) READREG(UART_BASE+(r)) +#define UART_WRITE(r,v) WRITEREG(UART_BASE+(r),(v)) + +static void uart_init(void) +{ + unsigned int t; + + /* disable uart */ + UART_WRITE(UART_REG_CTRL, 0); + + /* keep current baud rate */ + t = UART_READ(UART_REG_LCRM); + UART_WRITE(UART_REG_LCRM, t); + t = UART_READ(UART_REG_LCRL); + UART_WRITE(UART_REG_LCRL, t); + + /* keep data, stop, and parity bits, but disable FIFO */ + t = UART_READ(UART_REG_LCRH); + t &= ~(UART_LCRH_FEN); + UART_WRITE(UART_REG_LCRH, t ); + + /* clear error bits */ + UART_WRITE(UART_REG_ECR, 0xFF); + + /* enable uart, and disable interrupts */ + UART_WRITE(UART_REG_CTRL, UART_CTRL_EN); +} + +static void uart_putc(int ch) +{ + while ((UART_READ(UART_REG_FLAG) & UART_FLAG_TXFE) == 0); + + UART_WRITE(UART_REG_DATA, ch); + + while ((UART_READ(UART_REG_FLAG) & UART_FLAG_TXFF) != 0); +} + +/* + * INTC routines + */ + +#define INTC_READ(r) READREG(INTC_BASE+(r)) +#define INTC_WRITE(r,v) WRITEREG(INTC_BASE+(r),v) + +static void intc_init(void) +{ + INTC_WRITE(INTC_REG_IRQ_DISABLE, 0xFFFFFFFF); +} + +/* + * SWITCH routines + */ + +#define SWITCH_READ(r) READREG(SWITCH_BASE+(r)) +#define SWITCH_WRITE(r,v) WRITEREG(SWITCH_BASE+(r),v) + +static void switch_init(void) +{ + /* disable PHYS ports */ + SWITCH_WRITE(SWITCH_REG_PORT_CONF0, + (SWITCH_PORTS_HW << PORT_CONF0_DP_SHIFT)); + + /* disable CPU port */ + SWITCH_WRITE(SWITCH_REG_CPUP_CONF, CPUP_CONF_DCPUP); + + /* disable GPIO lines */ + SWITCH_WRITE(SWITCH_REG_GPIO_CONF0, 0); + SWITCH_WRITE(SWITCH_REG_GPIO_CONF2, 0); + + /* disable LED lines */ + SWITCH_WRITE(SWITCH_REG_PORT0_LED, 0); + SWITCH_WRITE(SWITCH_REG_PORT1_LED, 0); + SWITCH_WRITE(SWITCH_REG_PORT2_LED, 0); + SWITCH_WRITE(SWITCH_REG_PORT3_LED, 0); + SWITCH_WRITE(SWITCH_REG_PORT4_LED, 0); +} + +/* + * routines needed by decompress.c + */ +void board_putc(int ch) +{ + uart_putc(ch); +} + +void board_init(void) +{ + intc_init(); + switch_init(); + uart_init(); +} diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/config.h b/target/linux/adm5120-2.6/image/lzma-loader/src/config.h new file mode 100644 index 0000000000..5002b18192 --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/config.h @@ -0,0 +1,83 @@ +/* + * Cellvision/SparkLAN boards + */ + +#if defined(CONFIG_BOARD_CAS630) +# define CONFIG_BOARD_NAME "CAS-630" +#endif + +#if defined(CONFIG_BOARD_CAS670) +# define CONFIG_BOARD_NAME "CAS-670" +#endif + +#if defined(CONFIG_BOARD_CAS700) +# define CONFIG_BOARD_NAME "CAS-700" +#endif + +#if defined(CONFIG_BOARD_CAS790) +# define CONFIG_BOARD_NAME "CAS-790" +#endif + +#if defined(CONFIG_BOARD_CAS771) +# define CONFIG_BOARD_NAME "CAS-771" +#endif + +#if defined(CONFIG_BOARD_CAS861) +# define CONFIG_BOARD_NAME "CAS-861" +#endif + +#if defined(CONFIG_BOARD_NFS101U) +# define CONFIG_BOARD_NAME "NFS-101U" +#endif + +#if defined(CONFIG_BOARD_NFS202U) +# define CONFIG_BOARD_NAME "NFS-202U" +#endif + +/* + * Edimax boards + */ +#if defined(CONFIG_BOARD_BR6104K) +# define CONFIG_BOARD_NAME "BR-6104K" +#endif + +#if defined(CONFIG_BOARD_BR6104KP) +# define CONFIG_BOARD_NAME "BR-6104KP" +#endif + +/* + * Infineon boards + */ +#if defined(CONFIG_BOARD_EASY5120) +# define CONFIG_BOARD_NAME "EASY 5120" +#endif + +#if defined(CONFIG_BOARD_EASY5120RT) +# define CONFIG_BOARD_NAME "EASY 5120-RT" +#endif + +#if defined(CONFIG_BOARD_EASY5120PATA) +# define CONFIG_BOARD_NAME "EASY 5120P-ATA" +#endif + +#if defined(CONFIG_BOARD_EASY83000) +# define CONFIG_BOARD_NAME "EASY 83000" +#endif + +/* + * ZyXEL boards + */ +#if defined(CONFIG_BOARD_P334WT) +# define CONFIG_BOARD_NAME "P-334WT" +#endif + +#if defined(CONFIG_BOARD_P335) +# define CONFIG_BOARD_NAME "P-335" +#endif + +/* + * Default values + */ +#ifndef CONFIG_BOARD_NAME +# define CONFIG_BOARD_NAME "ADM5120" +#endif diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/decompress.c b/target/linux/adm5120-2.6/image/lzma-loader/src/decompress.c new file mode 100644 index 0000000000..e2f9bee234 --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/decompress.c @@ -0,0 +1,329 @@ +/* + * LZMA compressed kernel decompressor for ADM5120 boards + * + * Copyright (C) 2005 by Oleg I. Vdovikin + * Copyright (C) 2007 OpenWrt.org + * + * 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 + * + * + * Please note, this was code based on the bunzip2 decompressor code + * by Manuel Novoa III (mjn3@codepoet.org), although the only thing left + * is an idea and part of original vendor code + * + * + * 12-Mar-2005 Mineharu Takahara + * pass actual output size to decoder (stream mode + * compressed input is not a requirement anymore) + * + * 24-Apr-2005 Oleg I. Vdovikin + * reordered functions using lds script, removed forward decl + * + * 24-Mar-2007 Gabor Juhos + * pass original values of the a0,a1,a2,a3 registers to the kernel + * + * 19-May-2007 Gabor Juhos + * endiannes related cleanups + * add support for decompressing an embedded kernel + * + */ + +#include + +#include "config.h" +#include "LzmaDecode.h" + +#define ADM5120_FLASH_START 0x1fc00000 /* Flash start */ +#define ADM5120_FLASH_END 0x1fe00000 /* Flash end */ + +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 + +#define KSEG1ADDR(a) ((((unsigned)(a)) & 0x1fffffffU) | KSEG1) + +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 + +#define cache_unroll(base,op) \ + __asm__ __volatile__( \ + ".set noreorder;\n" \ + ".set mips3;\n" \ + "cache %1, (%0);\n" \ + ".set mips0;\n" \ + ".set reorder\n" \ + : \ + : "r" (base), \ + "i" (op)); + +static __inline__ void blast_icache(unsigned long size, unsigned long lsize) +{ + unsigned long start = KSEG0; + unsigned long end = (start + size); + + while(start < end) { + cache_unroll(start,Index_Invalidate_I); + start += lsize; + } +} + +static __inline__ void blast_dcache(unsigned long size, unsigned long lsize) +{ + unsigned long start = KSEG0; + unsigned long end = (start + size); + + while(start < end) { + cache_unroll(start,Index_Writeback_Inv_D); + start += lsize; + } +} + +#define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_ALIGN 0x1000 + +struct trx_header { + unsigned int magic; /* "HDR0" */ + unsigned int len; /* Length of file including header */ + unsigned int crc32; /* 32-bit CRC from flag_version to end of file */ + unsigned int flag_version; /* 0:15 flags, 16:31 version */ + unsigned int offsets[3]; /* Offsets of partitions from start of header */ +}; + +/* beyound the image end, size not known in advance */ +extern unsigned char workspace[]; +#if LZMA_WRAPPER +extern unsigned char _lzma_data_start[]; +extern unsigned char _lzma_data_end[]; +#endif + +extern void board_init(void); +extern void board_putc(int ch); + +struct env_var { + char *name; + char *value; +}; + +#ifdef CONFIG_PASS_KARGS +#define ENVV(n,v) {.name = (n), .value = (v)} +struct env_var env_vars[] = { + ENVV("board_name", CONFIG_BOARD_NAME), + ENVV(NULL, NULL) +}; +#endif + +unsigned char *data; +unsigned long datalen; + +typedef void (*kernel_entry)(unsigned long reg_a0, unsigned long reg_a1, + unsigned long reg_a2, unsigned long reg_a3); + +static int read_byte(void *object, unsigned char **buffer, UInt32 *bufferSize) +{ + *bufferSize = 1; + *buffer = data++; + + return LZMA_RESULT_OK; +} + +static __inline__ unsigned char get_byte(void) +{ + unsigned char *buffer; + UInt32 fake; + + read_byte(0, &buffer, &fake); + return *buffer; +} + +static __inline__ unsigned int read_le32(void *buf) +{ + unsigned char *p; + + p = buf; + return ((unsigned int)p[0] + ((unsigned int)p[1] << 8) + + ((unsigned int)p[2] << 16) +((unsigned int)p[3] << 24)); +} + +static void print_char(char ch) +{ + if (ch == '\n') + board_putc('\r'); + board_putc(ch); +} + +static void print_str(char * str) +{ + while ( *str != 0 ) + print_char(*str++); +} + +static void print_hex(int val) +{ + int i; + int tmp; + + print_str("0x"); + for ( i=0 ; i<8 ; i++ ) { + tmp = (val >> ((7-i) * 4 )) & 0xf; + tmp = tmp < 10 ? (tmp + '0') : (tmp + 'A' - 10); + board_putc(tmp); + } +} + +#if !(LZMA_WRAPPER) +static unsigned char *find_kernel(void) +{ + struct trx_header *hdr; + unsigned char *ret; + + print_str("Looking for TRX header... "); + /* look for trx header, 32-bit data access */ + hdr = NULL; + for (ret = ((unsigned char *) KSEG1ADDR(ADM5120_FLASH_START)); + ret < ((unsigned char *)KSEG1ADDR(ADM5120_FLASH_END)); + ret += TRX_ALIGN) { + + if (read_le32(ret) == TRX_MAGIC) { + hdr = (struct trx_header *)ret; + break; + } + } + + if (hdr == NULL) { + print_str("not found!\n"); + return NULL; + } + + print_str("found at "); + print_hex((unsigned int)ret); + print_str(", kernel in partition "); + + /* compressed kernel is in the partition 0 or 1 */ + if ((read_le32(&hdr->offsets[1]) == 0) || + (read_le32(&hdr->offsets[1]) > 65536)) { + ret += read_le32(&hdr->offsets[0]); + print_str("0\n"); + } else { + ret += read_le32(&hdr->offsets[1]); + print_str("1\n"); + } + + return ret; +} +#endif /* !(LZMA_WRAPPER) */ + +static void halt(void) +{ + print_str("\nSystem halted!\n"); + for(;;); +} + +/* should be the first function */ +void decompress_entry(unsigned long reg_a0, unsigned long reg_a1, + unsigned long reg_a2, unsigned long reg_a3, + unsigned long icache_size, unsigned long icache_lsize, + unsigned long dcache_size, unsigned long dcache_lsize) +{ + unsigned int i; /* temp value */ + unsigned int lc; /* literal context bits */ + unsigned int lp; /* literal pos state bits */ + unsigned int pb; /* pos state bits */ + unsigned int osize; /* uncompressed size */ + int res; +#if !(LZMA_WRAPPER) + ILzmaInCallback callback; +#endif + + board_init(); + + print_str("\n\nLZMA loader for " CONFIG_BOARD_NAME + ", Copyright (C) 2007 OpenWrt.org\n\n"); + +#if LZMA_WRAPPER + data = _lzma_data_start; + datalen = _lzma_data_end - _lzma_data_start; +#else + data = find_kernel(); + if (data == NULL) { + /* no compressed kernel found, halting */ + halt(); + } + + datalen = ((unsigned char *) KSEG1ADDR(ADM5120_FLASH_END))-data; +#endif + + /* lzma args */ + i = get_byte(); + lc = i % 9, i = i / 9; + lp = i % 5, pb = i / 5; + + /* skip rest of the LZMA coder property */ + for (i = 0; i < 4; i++) + get_byte(); + + /* read the lower half of uncompressed size in the header */ + osize = ((unsigned int)get_byte()) + + ((unsigned int)get_byte() << 8) + + ((unsigned int)get_byte() << 16) + + ((unsigned int)get_byte() << 24); + + /* skip rest of the header (upper half of uncompressed size) */ + for (i = 0; i < 4; i++) + get_byte(); + + print_str("decompressing kernel... "); + + /* decompress kernel */ +#if LZMA_WRAPPER + res = LzmaDecode(workspace, ~0, lc, lp, pb, data, datalen, + (unsigned char*)LOADADDR, osize, &i); +#else + callback.Read = read_byte; + res = LzmaDecode(workspace, ~0, lc, lp, pb, &callback, + (unsigned char*)LOADADDR, osize, &i); +#endif + if (res != LZMA_RESULT_OK) { + print_str("failed!\n"); + print_str("LzmaDecode: "); + switch (res) { + case LZMA_RESULT_DATA_ERROR: + print_str("data error\n"); + break; + case LZMA_RESULT_NOT_ENOUGH_MEM: + print_str("not enough memory\n"); + break; + default: + print_str("unknown error, err=0x"); + print_hex(res); + print_str("\n"); + } + halt(); + } + + print_str("done!\n"); + + blast_dcache(dcache_size, dcache_lsize); + blast_icache(icache_size, icache_lsize); + + print_str("launching kernel...\n\n"); + +#ifdef CONFIG_PASS_KARGS + reg_a0 = 0; + reg_a1 = 0; + reg_a2 = (unsigned long)env_vars; + reg_a3 = 0; +#endif + /* Jump to load address */ + ((kernel_entry) LOADADDR)(reg_a0, reg_a1, reg_a2, reg_a3); +} diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/head.S b/target/linux/adm5120-2.6/image/lzma-loader/src/head.S new file mode 100644 index 0000000000..ee8b3200cf --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/head.S @@ -0,0 +1,209 @@ +/* Copyright 2007 Gabor Juhos */ +/* keep original values of the a0,a1,a2,a3 registers */ +/* modifed to support user defined entry point address */ +/* Copyright 2005 Oleg I. Vdovikin (oleg@cs.msu.su) */ +/* cache manipulation adapted from Broadcom code */ +/* idea taken from original bunzip2 decompressor code */ +/* Copyright 2004 Manuel Novoa III (mjn3@codepoet.org) */ +/* Licensed under the linux kernel's version of the GPL.*/ + +#include +#include + +#define KSEG0 0x80000000 + +#define C0_STATUS $12 +#define C0_CAUSE $13 +#define C0_CONFIG $16 +#define C0_WATCHLO $18 +#define C0_WATCHHI $19 +#define C0_TAGLO $28 +#define C0_TAGHI $29 + +#define CONF1_DA_SHIFT 7 /* D$ associativity */ +#define CONF1_DA_MASK 0x00000380 +#define CONF1_DA_BASE 1 +#define CONF1_DL_SHIFT 10 /* D$ line size */ +#define CONF1_DL_MASK 0x00001c00 +#define CONF1_DL_BASE 2 +#define CONF1_DS_SHIFT 13 /* D$ sets/way */ +#define CONF1_DS_MASK 0x0000e000 +#define CONF1_DS_BASE 64 +#define CONF1_IA_SHIFT 16 /* I$ associativity */ +#define CONF1_IA_MASK 0x00070000 +#define CONF1_IA_BASE 1 +#define CONF1_IL_SHIFT 19 /* I$ line size */ +#define CONF1_IL_MASK 0x00380000 +#define CONF1_IL_BASE 2 +#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ +#define CONF1_IS_MASK 0x01c00000 +#define CONF1_IS_BASE 64 + +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 + + .text + +#if (LZMA_STARTUP_ORG) + .set noreorder + + b startup + nop + + .org LZMA_STARTUP_ORG +#endif + +LEAF(startup) + .set noreorder + .set mips32 + + mtc0 zero, C0_WATCHLO # clear watch registers + mtc0 zero, C0_WATCHHI + + mtc0 zero, C0_CAUSE # clear before writing status register + + mfc0 t0, C0_STATUS # get status register + li t1, ~(0xFF01) + and t0, t1 # mask interrupts + mtc0 t0, C0_STATUS # set up status register + + move t1, ra # save return address + la t0, __reloc_label # get linked address of label + bal __reloc_label # branch and link to label to + nop # get actual address +__reloc_label: + subu t0, ra, t0 # get reloc_delta + move ra, t1 # restore return address + + beqz t0, __reloc_end # if delta is 0 we are in the right place + nop + + /* Copy our code to the right place */ + la t1, _code_start # get linked address of _code_start + la t2, _code_end # get linked address of _code_end + addu t0, t0, t1 # calculate actual address of _code_start + +__reloc_copy: + lw t3, 0(t0) + sw t3, 0(t1) + add t1, 4 + blt t1, t2, __reloc_copy + add t0, 4 + +__reloc_end: + + /* At this point we need to invalidate dcache and */ + /* icache before jumping to new code */ + +1: /* Get cache sizes */ + .set mips32 + mfc0 s0,C0_CONFIG,1 + .set mips0 + + li s1,CONF1_DL_MASK + and s1,s0 + beq s1,zero,nodc + nop + + srl s1,CONF1_DL_SHIFT + li t0,CONF1_DL_BASE + sll s1,t0,s1 /* s1 has D$ cache line size */ + + li s2,CONF1_DA_MASK + and s2,s0 + srl s2,CONF1_DA_SHIFT + addiu s2,CONF1_DA_BASE /* s2 now has D$ associativity */ + + li t0,CONF1_DS_MASK + and t0,s0 + srl t0,CONF1_DS_SHIFT + li s3,CONF1_DS_BASE + sll s3,s3,t0 /* s3 has D$ sets per way */ + + multu s2,s3 /* sets/way * associativity */ + mflo t0 /* total cache lines */ + + multu s1,t0 /* D$ linesize * lines */ + mflo s2 /* s2 is now D$ size in bytes */ + + /* Initilize the D$: */ + mtc0 zero,C0_TAGLO + mtc0 zero,C0_TAGHI + + li t0,KSEG0 /* Just an address for the first $ line */ + addu t1,t0,s2 /* + size of cache == end */ + + .set mips3 +1: cache Index_Writeback_Inv_D,0(t0) + .set mips0 + bne t0,t1,1b + addu t0,s1 + +nodc: + /* Now we get to do it all again for the I$ */ + + move s3,zero /* just in case there is no icache */ + move s4,zero + + li t0,CONF1_IL_MASK + and t0,s0 + beq t0,zero,noic + nop + + srl t0,CONF1_IL_SHIFT + li s3,CONF1_IL_BASE + sll s3,t0 /* s3 has I$ cache line size */ + + li t0,CONF1_IA_MASK + and t0,s0 + srl t0,CONF1_IA_SHIFT + addiu s4,t0,CONF1_IA_BASE /* s4 now has I$ associativity */ + + li t0,CONF1_IS_MASK + and t0,s0 + srl t0,CONF1_IS_SHIFT + li s5,CONF1_IS_BASE + sll s5,t0 /* s5 has I$ sets per way */ + + multu s4,s5 /* sets/way * associativity */ + mflo t0 /* s4 is now total cache lines */ + + multu s3,t0 /* I$ linesize * lines */ + mflo s4 /* s4 is cache size in bytes */ + + /* Initilize the I$: */ + mtc0 zero,C0_TAGLO + mtc0 zero,C0_TAGHI + + li t0,KSEG0 /* Just an address for the first $ line */ + addu t1,t0,s4 /* + size of cache == end */ + + .set mips3 +1: cache Index_Invalidate_I,0(t0) + .set mips0 + bne t0,t1,1b + addu t0,s3 + +noic: + /* Setup new "C" stack */ + la sp, _stack + + addiu sp, -32 /* reserve stack for parameters */ +#if 0 + sw a0, 0(sp) + sw a1, 4(sp) + sw a2, 8(sp) + sw a3, 12(sp) +#endif + sw s3, 16(sp) /* icache line size */ + sw s4, 20(sp) /* icache size */ + sw s1, 24(sp) /* dcache line size */ + sw s2, 28(sp) /* dcache size */ + + /* jump to the decompressor routine */ + la t0, decompress_entry + jr t0 + nop + + .set reorder +END(startup) diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/loader.lds b/target/linux/adm5120-2.6/image/lzma-loader/src/loader.lds new file mode 100644 index 0000000000..bae70fb6ea --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/loader.lds @@ -0,0 +1,29 @@ +OUTPUT_ARCH(mips) +SECTIONS { + .text : { + _code_start = .; + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(16); + *(.data.lzma) + } + + .data : { + *(.data) + *(.data.*) + } + _code_end = .; + + .bss : { + *(.bss) + *(.bss.*) + } + + . = ALIGN(16); + . = . + 8192; + _stack = .; + + workspace = .; +} diff --git a/target/linux/adm5120-2.6/image/lzma-loader/src/lzma-data.lds b/target/linux/adm5120-2.6/image/lzma-loader/src/lzma-data.lds new file mode 100644 index 0000000000..abf756ba13 --- /dev/null +++ b/target/linux/adm5120-2.6/image/lzma-loader/src/lzma-data.lds @@ -0,0 +1,8 @@ +OUTPUT_ARCH(mips) +SECTIONS { + .data.lzma : { + _lzma_data_start = .; + *(.data) + _lzma_data_end = .; + } +} diff --git a/target/linux/adm5120-2.6/patches-2.6.22/001-adm5120.patch b/target/linux/adm5120-2.6/patches-2.6.22/001-adm5120.patch new file mode 100644 index 0000000000..da601b919d --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/001-adm5120.patch @@ -0,0 +1,111 @@ +Index: linux-2.6.22-rc6/arch/mips/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/arch/mips/Kconfig ++++ linux-2.6.22-rc6/arch/mips/Kconfig +@@ -15,6 +15,17 @@ choice + prompt "System type" + default SGI_IP22 + ++config MIPS_ADM5120 ++ bool "Support for ADM5120 SoC" ++ select SYS_HAS_CPU_MIPS32_R1 ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select GENERIC_GPIO ++ + config MACH_ALCHEMY + bool "Alchemy processor based machines" + +@@ -658,6 +669,7 @@ config TOSHIBA_RBTX4938 + + endchoice + ++source "arch/mips/adm5120/Kconfig" + source "arch/mips/au1000/Kconfig" + source "arch/mips/ddb5xxx/Kconfig" + source "arch/mips/gt64120/ev64120/Kconfig" +Index: linux-2.6.22-rc6/arch/mips/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/arch/mips/Makefile ++++ linux-2.6.22-rc6/arch/mips/Makefile +@@ -165,6 +165,14 @@ cflags-$(CONFIG_MACH_JAZZ) += -Iinclude/ + load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000 + + # ++# ADMtek 5120 ++# ++ ++core-$(CONFIG_MIPS_ADM5120) += arch/mips/adm5120/ ++cflags-$(CONFIG_MIPS_ADM5120) += -Iinclude/asm-mips/mach-adm5120 ++load-$(CONFIG_MIPS_ADM5120) += 0xffffffff80001000 ++ ++# + # Common Alchemy Au1x00 stuff + # + core-$(CONFIG_SOC_AU1X00) += arch/mips/au1000/common/ +Index: linux-2.6.22-rc6/include/asm-mips/bootinfo.h +=================================================================== +--- linux-2.6.22-rc6.orig/include/asm-mips/bootinfo.h ++++ linux-2.6.22-rc6/include/asm-mips/bootinfo.h +@@ -213,6 +213,57 @@ + #define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */ + #define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */ + ++/* ++ * Valid machtype for group ADMtek ADM5120 ++ */ ++#define MACH_GROUP_ADM5120 26 ++#define MACH_ADM5120_UNKNOWN 0 /* Unknown board */ ++#define MACH_ADM5120_WP54G_WRT 1 /* Compex WP54G-WRT */ ++#define MACH_ADM5120_WP54G 2 /* Compex WP54G */ ++#define MACH_ADM5120_WP54AG 3 /* Compex WP54AG */ ++#define MACH_ADM5120_WPP54G 4 /* Compex WPP54G */ ++#define MACH_ADM5120_WPP54AG 5 /* Compex WPP54AG */ ++#define MACH_ADM5120_NP28G 6 /* Compex NP28G */ ++#define MACH_ADM5120_NP28GHS 7 /* Compex NP28G HotSpot */ ++#define MACH_ADM5120_NP27G 8 /* Compex NP27G */ ++#define MACH_ADM5120_WP54Gv1C 9 /* Compex WP54G version 1C */ ++#define MACH_ADM5120_RB_111 10 /* Mikrotik RouterBOARD 111 */ ++#define MACH_ADM5120_RB_112 11 /* Mikrotik RouterBOARD 112 */ ++#define MACH_ADM5120_RB_133 12 /* Mikrotik RouterBOARD 133 */ ++#define MACH_ADM5120_RB_133C 13 /* Mikrotik RouterBOARD 133c */ ++#define MACH_ADM5120_RB_150 14 /* Mikrotik RouterBOARD 150 */ ++#define MACH_ADM5120_RB_153 15 /* Mikrotik RouterBOARD 153 */ ++#define MACH_ADM5120_HS100 16 /* ZyXEL HomeSafe 100/100W */ ++#define MACH_ADM5120_P334 17 /* ZyXEL Prestige 334 */ ++#define MACH_ADM5120_P334U 18 /* ZyXEL Prestige 334U */ ++#define MACH_ADM5120_P334W 19 /* ZyXEL Prestige 334W */ ++#define MACH_ADM5120_P334WH 20 /* ZyXEL Prestige 334WH */ ++#define MACH_ADM5120_P334WHD 21 /* ZyXEL Prestige 334WHD */ ++#define MACH_ADM5120_P334WT 22 /* ZyXEL Prestige 334WT */ ++#define MACH_ADM5120_P335 23 /* ZyXEL Prestige 335/335WT */ ++#define MACH_ADM5120_P335PLUS 24 /* ZyXEL Prestige 335Plus */ ++#define MACH_ADM5120_P335U 25 /* ZyXEL Prestige 335U */ ++#define MACH_ADM5120_ES2108 26 /* ZyXEL Ethernet Switch 2108 */ ++#define MACH_ADM5120_ES2108F 27 /* ZyXEL Ethernet Switch 2108-F */ ++#define MACH_ADM5120_ES2108G 28 /* ZyXEL Ethernet Switch 2108-G */ ++#define MACH_ADM5120_ES2108LC 29 /* ZyXEL Ethernet Switch 2108-LC */ ++#define MACH_ADM5120_ES2108PWR 30 /* ZyXEL Ethernet Switch 2108-PWR */ ++#define MACH_ADM5120_ES2024A 31 /* ZyXEL Ethernet Switch 2024A */ ++#define MACH_ADM5120_ES2024PWR 32 /* ZyXEL Ethernet Switch 2024PWR */ ++#define MACH_ADM5120_CAS630 33 /* Cellvision CAS-630/630W */ ++#define MACH_ADM5120_CAS670 34 /* Cellvision CAS-670/670W */ ++#define MACH_ADM5120_CAS700 36 /* Cellvision CAS-700/700W */ ++#define MACH_ADM5120_CAS771 37 /* Cellvision CAS-771/771W */ ++#define MACH_ADM5120_CAS790 38 /* Cellvision CAS-790 */ ++#define MACH_ADM5120_CAS861 39 /* Cellvision CAS-861/861W */ ++#define MACH_ADM5120_NFS101U 40 /* Cellvision NFS-101U/101WU */ ++#define MACH_ADM5120_NFS202U 41 /* Cellvision NFS-202U/202WU */ ++#define MACH_ADM5120_EASY5120 43 /* Infineon EASY 5120 */ ++#define MACH_ADM5120_EASY5120RT 44 /* Infineon EASY 5120-RT */ ++#define MACH_ADM5120_EASY5120PATA 45 /* Infineon EASY 5120P-ATA */ ++#define MACH_ADM5120_EASY83000 46 /* Infineon EASY-83000 */ ++#define MACH_ADM5120_BR6104K 47 /* Edimax BR-6104K */ ++ + #define CL_SIZE COMMAND_LINE_SIZE + + const char *get_system_type(void); diff --git a/target/linux/adm5120-2.6/patches-2.6.22/002-adm5120_flash.patch b/target/linux/adm5120-2.6/patches-2.6.22/002-adm5120_flash.patch new file mode 100644 index 0000000000..355c126c92 --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/002-adm5120_flash.patch @@ -0,0 +1,27 @@ +Index: linux-2.6.22-rc6/drivers/mtd/maps/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/mtd/maps/Kconfig ++++ linux-2.6.22-rc6/drivers/mtd/maps/Kconfig +@@ -620,5 +620,10 @@ config MTD_PLATRAM + + This selection automatically selects the map_ram driver. + ++config MTD_ADM5120 ++ tristate "Map driver for ADMtek ADM5120 boards" ++ depends on MIPS_ADM5120 ++ select MTD_CFI_AMDSTD ++ + endmenu + +Index: linux-2.6.22-rc6/drivers/mtd/maps/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/mtd/maps/Makefile ++++ linux-2.6.22-rc6/drivers/mtd/maps/Makefile +@@ -47,6 +47,7 @@ obj-$(CONFIG_MTD_OCELOT) += ocelot.o + obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o + obj-$(CONFIG_MTD_PCI) += pci.o + obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o ++obj-$(CONFIG_MTD_ADM5120) += adm5120_mtd.o + obj-$(CONFIG_MTD_LASAT) += lasat.o + obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o + obj-$(CONFIG_MTD_EDB7312) += edb7312.o diff --git a/target/linux/adm5120-2.6/patches-2.6.22/003-adm5120_switch.patch b/target/linux/adm5120-2.6/patches-2.6.22/003-adm5120_switch.patch new file mode 100644 index 0000000000..9dde782501 --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/003-adm5120_switch.patch @@ -0,0 +1,27 @@ +Index: linux-2.6.22-rc6/drivers/net/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/net/Kconfig ++++ linux-2.6.22-rc6/drivers/net/Kconfig +@@ -574,6 +574,10 @@ config MIPS_AU1X00_ENET + If you have an Alchemy Semi AU1X00 based system + say Y. Otherwise, say N. + ++config MIPS_ADM5120_ENET ++ tristate "MIPS ADM5120 Ethernet switch support" ++ depends on NET_ETHERNET && MIPS_ADM5120 ++ + config NET_SB1250_MAC + tristate "SB1250 Ethernet support" + depends on NET_ETHERNET && SIBYTE_SB1xxx_SOC +Index: linux-2.6.22-rc6/drivers/net/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/net/Makefile ++++ linux-2.6.22-rc6/drivers/net/Makefile +@@ -165,6 +165,7 @@ obj-$(CONFIG_SC92031) += sc92031.o + # This is also a 82596 and should probably be merged + obj-$(CONFIG_LP486E) += lp486e.o + ++obj-$(CONFIG_MIPS_ADM5120_ENET) += adm5120sw.o + obj-$(CONFIG_ETH16I) += eth16i.o + obj-$(CONFIG_ZORRO8390) += zorro8390.o + obj-$(CONFIG_HPLANCE) += hplance.o 7990.o diff --git a/target/linux/adm5120-2.6/patches-2.6.22/004-adm5120_uart.patch b/target/linux/adm5120-2.6/patches-2.6.22/004-adm5120_uart.patch new file mode 100644 index 0000000000..eb78e03574 --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/004-adm5120_uart.patch @@ -0,0 +1,53 @@ +Index: linux-2.6.22-rc6/drivers/serial/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/serial/Makefile ++++ linux-2.6.22-rc6/drivers/serial/Makefile +@@ -21,6 +21,7 @@ obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) + obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o + obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o + obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o ++obj-$(CONFIG_SERIAL_ADM5120) += adm5120_uart.o + obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o + obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o + obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o +Index: linux-2.6.22-rc6/include/linux/serial_core.h +=================================================================== +--- linux-2.6.22-rc6.orig/include/linux/serial_core.h ++++ linux-2.6.22-rc6/include/linux/serial_core.h +@@ -143,6 +143,9 @@ + #define PORT_KS8695 76 + + ++/* ADMtek ADM5120 SoC */ ++#define PORT_ADM5120 77 ++ + #ifdef __KERNEL__ + + #include +Index: linux-2.6.22-rc6/drivers/serial/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/serial/Kconfig ++++ linux-2.6.22-rc6/drivers/serial/Kconfig +@@ -270,6 +270,22 @@ config SERIAL_8250_RM9K + + comment "Non-8250 serial port support" + ++config SERIAL_ADM5120 ++ bool "ADM5120 serial port support" ++ depends on MIPS_ADM5120 ++ select SERIAL_CORE ++ select SERIAL_CORE_CONSOLE ++ help ++ Driver for the on chip UARTs on the ADM5120 SoC ++ ++config ADM5120_NR_UARTS ++ int "Maximum number of ADM5120 serial ports" ++ depends on SERIAL_ADM5120 ++ default "2" ++ ---help--- ++ Set this to the number of serial ports you want the driver to ++ support. ++ + config SERIAL_AMBA_PL010 + tristate "ARM AMBA PL010 serial port support" + depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE) diff --git a/target/linux/adm5120-2.6/patches-2.6.22/005-adm5120_usb.patch b/target/linux/adm5120-2.6/patches-2.6.22/005-adm5120_usb.patch new file mode 100644 index 0000000000..c862f906e3 --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/005-adm5120_usb.patch @@ -0,0 +1,232 @@ +Index: linux-2.6.22-rc6/drivers/usb/core/hub.c +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/usb/core/hub.c ++++ linux-2.6.22-rc6/drivers/usb/core/hub.c +@@ -464,7 +464,7 @@ void usb_hub_tt_clear_buffer (struct usb + : (USB_ENDPOINT_XFER_BULK << 11); + if (usb_pipein (pipe)) + clear->devinfo |= 1 << 15; +- ++ + /* tell keventd to clear state for this TT */ + spin_lock_irqsave (&tt->lock, flags); + list_add_tail (&clear->clear_list, &tt->clear_list); +@@ -540,7 +540,7 @@ static int hub_hub_status(struct usb_hub + "%s failed (err = %d)\n", __FUNCTION__, ret); + else { + *status = le16_to_cpu(hub->status->hub.wHubStatus); +- *change = le16_to_cpu(hub->status->hub.wHubChange); ++ *change = le16_to_cpu(hub->status->hub.wHubChange); + ret = 0; + } + mutex_unlock(&hub->status_mutex); +@@ -1424,7 +1424,7 @@ static int hub_port_status(struct usb_hu + ret = -EIO; + } else { + *status = le16_to_cpu(hub->status->port.wPortStatus); +- *change = le16_to_cpu(hub->status->port.wPortChange); ++ *change = le16_to_cpu(hub->status->port.wPortChange); + ret = 0; + } + mutex_unlock(&hub->status_mutex); +@@ -2007,7 +2007,7 @@ static inline int remote_wakeup(struct u + * Between connect detection and reset signaling there must be a delay + * of 100ms at least for debounce and power-settling. The corresponding + * timer shall restart whenever the downstream port detects a disconnect. +- * ++ * + * Apparently there are some bluetooth and irda-dongles and a number of + * low-speed devices for which this debounce period may last over a second. + * Not covered by the spec - but easy to deal with. +@@ -2142,7 +2142,7 @@ hub_port_init (struct usb_hub *hub, stru + goto fail; + } + oldspeed = udev->speed; +- ++ + /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... + * it's fixed size except for full speed devices. + * For Wireless USB devices, ep0 max packet is always 512 (tho +@@ -2168,7 +2168,7 @@ hub_port_init (struct usb_hub *hub, stru + default: + goto fail; + } +- ++ + type = ""; + switch (udev->speed) { + case USB_SPEED_LOW: speed = "low"; break; +@@ -2194,7 +2194,7 @@ hub_port_init (struct usb_hub *hub, stru + udev->tt = &hub->tt; + udev->ttport = port1; + } +- ++ + /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way? + * Because device hardware and firmware is sometimes buggy in + * this area, and this is how Linux has done it for ages. +@@ -2230,6 +2230,8 @@ hub_port_init (struct usb_hub *hub, stru + USB_DT_DEVICE << 8, 0, + buf, GET_DESCRIPTOR_BUFSIZE, + USB_CTRL_GET_TIMEOUT); ++printk(KERN_CRIT "usb_control_msg: %d %d %d (%d)\n", r, buf->bMaxPacketSize0, ++buf->bDescriptorType, USB_DT_DEVICE); + switch (buf->bMaxPacketSize0) { + case 8: case 16: case 32: case 64: case 255: + if (buf->bDescriptorType == +@@ -2281,7 +2283,7 @@ hub_port_init (struct usb_hub *hub, stru + udev->devnum, retval); + goto fail; + } +- ++ + /* cope with hardware quirkiness: + * - let SET_ADDRESS settle, some device hardware wants it + * - read ep0 maxpacket even for high and low speed, +@@ -2318,7 +2320,7 @@ hub_port_init (struct usb_hub *hub, stru + udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i); + ep0_reinit(udev); + } +- ++ + retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE); + if (retval < (signed)sizeof(udev->descriptor)) { + dev_err(&udev->dev, "device descriptor read/%s, error %d\n", +@@ -2416,7 +2418,7 @@ static void hub_port_connect_change(stru + struct device *hub_dev = hub->intfdev; + u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); + int status, i; +- ++ + dev_dbg (hub_dev, + "port %d, status %04x, change %04x, %s\n", + port1, portstatus, portchange, portspeed (portstatus)); +@@ -2425,7 +2427,7 @@ static void hub_port_connect_change(stru + set_port_led(hub, port1, HUB_LED_AUTO); + hub->indicator[port1-1] = INDICATOR_AUTO; + } +- ++ + /* Disconnect any existing devices under this port */ + if (hdev->children[port1-1]) + usb_disconnect(&hdev->children[port1-1]); +@@ -2455,7 +2457,7 @@ static void hub_port_connect_change(stru + if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 + && !(portstatus & (1 << USB_PORT_FEAT_POWER))) + set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); +- ++ + if (portstatus & USB_PORT_STAT_ENABLE) + goto done; + return; +@@ -2535,7 +2537,7 @@ static void hub_port_connect_change(stru + goto loop_disable; + } + } +- ++ + /* check for devices running slower than they could */ + if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200 + && udev->speed == USB_SPEED_FULL +@@ -2587,7 +2589,7 @@ loop: + if (status == -ENOTCONN) + break; + } +- ++ + done: + hub_port_disable(hub, port1, 1); + } +@@ -2720,7 +2722,7 @@ static void hub_events(void) + * EM interference sometimes causes badly + * shielded USB devices to be shutdown by + * the hub, this hack enables them again. +- * Works at least with mouse driver. ++ * Works at least with mouse driver. + */ + if (!(portstatus & USB_PORT_STAT_ENABLE) + && !connect_change +@@ -2750,7 +2752,7 @@ static void hub_events(void) + "resume on port %d, status %d\n", + i, ret); + } +- ++ + if (portchange & USB_PORT_STAT_C_OVERCURRENT) { + dev_err (hub_dev, + "over-current change on port %d\n", +@@ -2985,7 +2987,7 @@ int usb_reset_device(struct usb_device * + + if (ret < 0) + goto re_enumerate; +- ++ + /* Device might have changed firmware (DFU or similar) */ + if (memcmp(&udev->descriptor, &descriptor, sizeof descriptor) + || config_descriptors_changed (udev)) { +@@ -2993,7 +2995,7 @@ int usb_reset_device(struct usb_device * + udev->descriptor = descriptor; /* for disconnect() calls */ + goto re_enumerate; + } +- ++ + if (!udev->actconfig) + goto done; + +@@ -3031,7 +3033,7 @@ int usb_reset_device(struct usb_device * + + done: + return 0; +- ++ + re_enumerate: + hub_port_logical_disconnect(parent_hub, port1); + return -ENODEV; +Index: linux-2.6.22-rc6/drivers/usb/host/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/usb/host/Kconfig ++++ linux-2.6.22-rc6/drivers/usb/host/Kconfig +@@ -224,3 +224,6 @@ config USB_SL811_CS + To compile this driver as a module, choose M here: the + module will be called "sl811_cs". + ++config USB_ADM5120_HCD ++ tristate "ADM5120 HCD support" ++ depends on USB && MIPS_ADM5120 +Index: linux-2.6.22-rc6/drivers/usb/host/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/usb/host/Makefile ++++ linux-2.6.22-rc6/drivers/usb/host/Makefile +@@ -8,6 +8,7 @@ endif + + obj-$(CONFIG_PCI) += pci-quirks.o + ++obj-$(CONFIG_USB_ADM5120_HCD) += adm5120-hcd.o + obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o + obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o + obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o +Index: linux-2.6.22-rc6/drivers/usb/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/usb/Kconfig ++++ linux-2.6.22-rc6/drivers/usb/Kconfig +@@ -88,8 +88,6 @@ source "drivers/usb/storage/Kconfig" + + source "drivers/usb/image/Kconfig" + +-source "drivers/usb/mon/Kconfig" +- + comment "USB port drivers" + depends on USB + +Index: linux-2.6.22-rc6/drivers/usb/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/usb/Makefile ++++ linux-2.6.22-rc6/drivers/usb/Makefile +@@ -16,6 +16,7 @@ obj-$(CONFIG_USB_UHCI_HCD) += host/ + obj-$(CONFIG_USB_SL811_HCD) += host/ + obj-$(CONFIG_USB_U132_HCD) += host/ + obj-$(CONFIG_USB_OHCI_AT91) += host/ ++obj-$(CONFIG_USB_ADM5120_HCD) += host/ + + obj-$(CONFIG_USB_ACM) += class/ + obj-$(CONFIG_USB_PRINTER) += class/ diff --git a/target/linux/adm5120-2.6/patches-2.6.22/006-adm5120_leds.patch b/target/linux/adm5120-2.6/patches-2.6.22/006-adm5120_leds.patch new file mode 100644 index 0000000000..91ca638ded --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/006-adm5120_leds.patch @@ -0,0 +1,45 @@ +Index: linux-2.6.22-rc6/drivers/leds/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/leds/Kconfig ++++ linux-2.6.22-rc6/drivers/leds/Kconfig +@@ -20,6 +20,27 @@ config LEDS_CLASS + + comment "LED drivers" + ++config LEDS_GPIO ++ tristate "LED support for LEDS on GPIO lines" ++ depends on LEDS_CLASS && GENERIC_GPIO ++ help ++ This option enables support for LEDs connected to GPIO lines ++ ++config LEDS_ADM5120 ++ tristate "LED Support for ADM5120 GPIO LEDs" ++ depends on LEDS_GPIO && MIPS_ADM5120 ++ help ++ This option enables support for LEDs connected to GPIO lines ++ on ADM5120 SoC based platforms. ++ ++config LEDS_ADM5120_EXPERIMENTAL ++ bool "Enable ADM5120 LEDs experimental code" ++ depends on LEDS_ADM5120 ++ ++config LEDS_ADM5120_DIAG ++ bool "Enable ADM5120 LEDs diagnostic mode" ++ depends on LEDS_ADM5120 ++ + config LEDS_CORGI + tristate "LED Support for the Sharp SL-C7x0 series" + depends on LEDS_CLASS && PXA_SHARP_C7xx +Index: linux-2.6.22-rc6/drivers/leds/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/leds/Makefile ++++ linux-2.6.22-rc6/drivers/leds/Makefile +@@ -5,6 +5,8 @@ obj-$(CONFIG_LEDS_CLASS) += led-class.o + obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o + + # LED Platform Drivers ++obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o ++obj-$(CONFIG_LEDS_ADM5120) += leds-adm5120.o + obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o + obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o + obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o diff --git a/target/linux/adm5120-2.6/patches-2.6.22/007-adm5120_pci.patch b/target/linux/adm5120-2.6/patches-2.6.22/007-adm5120_pci.patch new file mode 100644 index 0000000000..18839cf362 --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/007-adm5120_pci.patch @@ -0,0 +1,23 @@ +Index: linux-2.6.22-rc6/arch/mips/pci/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/arch/mips/pci/Makefile ++++ linux-2.6.22-rc6/arch/mips/pci/Makefile +@@ -50,3 +50,4 @@ obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup- + obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o + obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o + obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o ++obj-$(CONFIG_PCI_ADM5120) += fixup-adm5120.o ops-adm5120.o pci-adm5120.o +Index: linux-2.6.22-rc6/include/linux/pci_ids.h +=================================================================== +--- linux-2.6.22-rc6.orig/include/linux/pci_ids.h ++++ linux-2.6.22-rc6/include/linux/pci_ids.h +@@ -1712,6 +1712,9 @@ + #define PCI_VENDOR_ID_ESDGMBH 0x12fe + #define PCI_DEVICE_ID_ESDGMBH_CPCIASIO4 0x0111 + ++#define PCI_VENDOR_ID_ADMTEK 0x1317 ++#define PCI_DEVICE_ID_ADMTEK_ADM5120 0x5120 ++ + #define PCI_VENDOR_ID_SIIG 0x131f + #define PCI_SUBVENDOR_ID_SIIG 0x131f + #define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000 diff --git a/target/linux/adm5120-2.6/patches-2.6.22/008-adm5120_hardware_swab.patch b/target/linux/adm5120-2.6/patches-2.6.22/008-adm5120_hardware_swab.patch new file mode 100644 index 0000000000..c0fd645b5d --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/008-adm5120_hardware_swab.patch @@ -0,0 +1,40 @@ +Index: linux-2.6.22-rc6/include/asm-mips/byteorder.h +=================================================================== +--- linux-2.6.22-rc6.orig/include/asm-mips/byteorder.h ++++ linux-2.6.22-rc6/include/asm-mips/byteorder.h +@@ -58,6 +58,35 @@ static __inline__ __attribute_const__ __ + + #endif /* CONFIG_CPU_MIPSR2 */ + ++#ifdef CONFIG_ADM5120_HARDWARE_SWAB ++ ++static __inline__ __attribute_const__ __u16 ___adm5120__swab16(__u16 x) ++{ ++ __asm__ ( ++ " sh %2, 0xCA(%1) \n" ++ " lhu %0, 0xCC(%1) \n" ++ : "=r" (x) ++ : "r" (0xB2000000), "r" (x)); ++ ++ return x; ++} ++ ++static __inline__ __attribute_const__ __u32 ___adm5120__swab32(__u32 x) ++{ ++ __asm__ ( ++ " sw %2, 0xC8(%1) \n" ++ " lw %0, 0xCC(%1) \n" ++ : "=r" (x) ++ : "r" (0xB2000000), "r" (x)); ++ ++ return x; ++} ++ ++#define __arch__swab16(x) ___adm5120__swab16(x) ++#define __arch__swab32(x) ___adm5120__swab32(x) ++ ++#endif /* CONFIG_ADM5120_HARDWARE_SWAB */ ++ + #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) + # define __BYTEORDER_HAS_U64__ + # define __SWAB_64_THRU_32__ diff --git a/target/linux/adm5120-2.6/patches-2.6.22/100-mtd-myloder-partition-parser.patch b/target/linux/adm5120-2.6/patches-2.6.22/100-mtd-myloder-partition-parser.patch new file mode 100644 index 0000000000..2b4381cd98 --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/100-mtd-myloder-partition-parser.patch @@ -0,0 +1,39 @@ +Index: linux-2.6.22-rc6/drivers/mtd/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/mtd/Kconfig ++++ linux-2.6.22-rc6/drivers/mtd/Kconfig +@@ -155,6 +155,22 @@ config MTD_AFS_PARTS + for your particular device. It won't happen automatically. The + 'armflash' map driver (CONFIG_MTD_ARMFLASH) does this, for example. + ++config MTD_MYLOADER_PARTS ++ tristate "MyLoader partition parsing" ++ depends on MIPS_ADM5120 && MTD_PARTITIONS ++ ---help--- ++ MyLoader is a bootloader which allows the user to define partitions ++ in flash devices, by putting a table in the second erase block ++ on the device, similar to a partition table. This table gives the ++ offsets and lengths of the user defined partitions. ++ ++ If you need code which can detect and parse these tables, and ++ register MTD 'partitions' corresponding to each image detected, ++ enable this option. ++ ++ You will still need the parsing functions to be called by the driver ++ for your particular device. It won't happen automatically. ++ + comment "User Modules And Translation Layers" + + config MTD_CHAR +Index: linux-2.6.22-rc6/drivers/mtd/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/mtd/Makefile ++++ linux-2.6.22-rc6/drivers/mtd/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o + obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o + obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o ++obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o + + # 'Users' - code which presents functionality to userspace. + obj-$(CONFIG_MTD_CHAR) += mtdchar.o diff --git a/target/linux/adm5120-2.6/patches-2.6.22/101-cfi-fixup-macronix-bootloc.patch b/target/linux/adm5120-2.6/patches-2.6.22/101-cfi-fixup-macronix-bootloc.patch new file mode 100644 index 0000000000..543cb940a4 --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/101-cfi-fixup-macronix-bootloc.patch @@ -0,0 +1,87 @@ +Index: linux-2.6.22-rc6/drivers/mtd/chips/cfi_cmdset_0002.c +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/mtd/chips/cfi_cmdset_0002.c ++++ linux-2.6.22-rc6/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -47,12 +47,17 @@ + #define MANUFACTURER_AMD 0x0001 + #define MANUFACTURER_ATMEL 0x001F + #define MANUFACTURER_SST 0x00BF ++#define MANUFACTURER_MACRONIX 0x00C2 + #define SST49LF004B 0x0060 + #define SST49LF040B 0x0050 + #define SST49LF008A 0x005a + #define AT49BV6416 0x00d6 + #define MANUFACTURER_SAMSUNG 0x00ec + ++/* Macronix */ ++#define MX29LV160B 0x2249 /* MX29LV160 Bottom-boot chip */ ++#define MX29LV320B 0x22A8 /* MX29LV320 Bottom-boot chip */ ++ + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); + static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); + static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); +@@ -217,6 +222,35 @@ static void fixup_use_atmel_lock(struct + mtd->flags |= MTD_STUPID_LOCK; + } + ++#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC ++/* ++ * Some Macronix chips has bad bootblock information in the CFI table ++ */ ++static void fixup_macronix_bootloc(struct mtd_info *mtd, void* param) ++{ ++ struct map_info *map = mtd->priv; ++ struct cfi_private *cfi = map->fldrv_priv; ++ struct cfi_pri_amdstd *extp = cfi->cmdset_priv; ++ __u8 major = extp->MajorVersion; ++ __u8 minor = extp->MinorVersion; ++ ++ switch (cfi->id) { ++ /* TODO: put affected chip ids here */ ++ case MX29LV160B: ++ case MX29LV320B: ++ if (((major << 8) | minor) != 0x3131) ++ break; ++ ++ if (extp->TopBottom == 2) ++ break; ++ ++ extp->TopBottom = 2; /* Bottom boot */ ++ printk("%s: weird Macronix chip detected, id:0x%04X, boot location " ++ "forced to bottom\n", map->name, cfi->id); ++ } ++} ++#endif /* CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC */ ++ + static struct cfi_fixup cfi_fixup_table[] = { + #ifdef AMD_BOOTLOC_BUG + { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, +@@ -231,6 +265,9 @@ static struct cfi_fixup cfi_fixup_table[ + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, + #endif + { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, ++#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC ++ { MANUFACTURER_MACRONIX, CFI_ID_ANY, fixup_macronix_bootloc, NULL, }, ++#endif + { 0, 0, NULL, NULL } + }; + static struct cfi_fixup jedec_fixup_table[] = { +Index: linux-2.6.22-rc6/drivers/mtd/chips/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/mtd/chips/Kconfig ++++ linux-2.6.22-rc6/drivers/mtd/chips/Kconfig +@@ -196,6 +196,14 @@ config MTD_CFI_AMDSTD + provides support for one of those command sets, used on chips + including the AMD Am29LV320. + ++config MTD_CFI_FIXUP_MACRONIX_BOOTLOC ++ bool "Force bottom boot for Macronix flash chips" ++ depends on MTD_CFI_AMDSTD ++ help ++ Some Macronix flash chips have wrong boot-block location in the ++ CFI table, and the driver may detect the type incorrectly. Select ++ this if your board has such chip. ++ + config MTD_CFI_STAA + tristate "Support for ST (Advanced Architecture) flash chips" + depends on MTD_GEN_PROBE diff --git a/target/linux/adm5120-2.6/patches-2.6.22/140-cmdline_hack.patch b/target/linux/adm5120-2.6/patches-2.6.22/140-cmdline_hack.patch new file mode 100644 index 0000000000..47378e5a90 --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/140-cmdline_hack.patch @@ -0,0 +1,26 @@ +Index: linux-2.6.22-rc6/arch/mips/kernel/head.S +=================================================================== +--- linux-2.6.22-rc6.orig/arch/mips/kernel/head.S ++++ linux-2.6.22-rc6/arch/mips/kernel/head.S +@@ -129,14 +129,19 @@ + #endif + .endm + +- + j kernel_entry + nop +- ++ nop ++ + /* + * Reserved space for exception handlers. + * Necessary for machines which link their kernels at KSEG0. ++ * Use as temporary storage for the kernel command line, so that it ++ * can be updated easily without having to relink the kernel. + */ ++ ++EXPORT(_image_cmdline) ++ .ascii "CMDLINE:" + .align 10 + + EXPORT(stext) # used for profiling diff --git a/target/linux/adm5120-2.6/patches-2.6.22/500-Nand.patch b/target/linux/adm5120-2.6/patches-2.6.22/500-Nand.patch new file mode 100644 index 0000000000..fb503c5dcf --- /dev/null +++ b/target/linux/adm5120-2.6/patches-2.6.22/500-Nand.patch @@ -0,0 +1,29 @@ +Index: linux-2.6.22-rc6/drivers/mtd/nand/Kconfig +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/mtd/nand/Kconfig ++++ linux-2.6.22-rc6/drivers/mtd/nand/Kconfig +@@ -81,6 +81,12 @@ config MTD_NAND_TS7250 + help + Support for NAND flash on Technologic Systems TS-7250 platform. + ++config MTD_NAND_RB100 ++ tristate "NAND Flash device on RB100 board" ++ depends on MTD_NAND ++ help ++ Support for NAND flash on RB100 platform. ++ + config MTD_NAND_IDS + tristate + +Index: linux-2.6.22-rc6/drivers/mtd/nand/Makefile +=================================================================== +--- linux-2.6.22-rc6.orig/drivers/mtd/nand/Makefile ++++ linux-2.6.22-rc6/drivers/mtd/nand/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nan + obj-$(CONFIG_MTD_NAND_SPIA) += spia.o + obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o + obj-$(CONFIG_MTD_NAND_TOTO) += toto.o ++obj-$(CONFIG_MTD_NAND_RB100) += rbmipsnand.o + obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o + obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o + obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o diff --git a/target/linux/adm5120-2.6/patches/001-adm5120.patch b/target/linux/adm5120-2.6/patches/001-adm5120.patch new file mode 100644 index 0000000000..c1b2688d5a --- /dev/null +++ b/target/linux/adm5120-2.6/patches/001-adm5120.patch @@ -0,0 +1,111 @@ +Index: linux-2.6.21.1/arch/mips/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/arch/mips/Kconfig ++++ linux-2.6.21.1/arch/mips/Kconfig +@@ -16,6 +16,17 @@ choice + prompt "System type" + default SGI_IP22 + ++config MIPS_ADM5120 ++ bool "Support for ADM5120 SoC" ++ select SYS_HAS_CPU_MIPS32_R1 ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select GENERIC_GPIO ++ + config MIPS_MTX1 + bool "4G Systems MTX-1 board" + select DMA_NONCOHERENT +@@ -766,6 +775,7 @@ + + endchoice + ++source "arch/mips/adm5120/Kconfig" + source "arch/mips/ddb5xxx/Kconfig" + source "arch/mips/gt64120/ev64120/Kconfig" + source "arch/mips/jazz/Kconfig" +Index: linux-2.6.21.1/arch/mips/Makefile +=================================================================== +--- linux-2.6.21.1.orig/arch/mips/Makefile ++++ linux-2.6.21.1/arch/mips/Makefile +@@ -165,6 +165,14 @@ cflags-$(CONFIG_MACH_JAZZ) += -Iinclude/ + load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000 + + # ++# ADMtek 5120 ++# ++ ++core-$(CONFIG_MIPS_ADM5120) += arch/mips/adm5120/ ++cflags-$(CONFIG_MIPS_ADM5120) += -Iinclude/asm-mips/mach-adm5120 ++load-$(CONFIG_MIPS_ADM5120) += 0xffffffff80001000 ++ ++# + # Common Alchemy Au1x00 stuff + # + core-$(CONFIG_SOC_AU1X00) += arch/mips/au1000/common/ +Index: linux-2.6.21.1/include/asm-mips/bootinfo.h +=================================================================== +--- linux-2.6.21.1.orig/include/asm-mips/bootinfo.h ++++ linux-2.6.21.1/include/asm-mips/bootinfo.h +@@ -213,6 +213,57 @@ + #define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */ + #define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */ + ++/* ++ * Valid machtype for group ADMtek ADM5120 ++ */ ++#define MACH_GROUP_ADM5120 23 ++#define MACH_ADM5120_UNKNOWN 0 /* Unknown board */ ++#define MACH_ADM5120_WP54G_WRT 1 /* Compex WP54G-WRT */ ++#define MACH_ADM5120_WP54G 2 /* Compex WP54G */ ++#define MACH_ADM5120_WP54AG 3 /* Compex WP54AG */ ++#define MACH_ADM5120_WPP54G 4 /* Compex WPP54G */ ++#define MACH_ADM5120_WPP54AG 5 /* Compex WPP54AG */ ++#define MACH_ADM5120_NP28G 6 /* Compex NP28G */ ++#define MACH_ADM5120_NP28GHS 7 /* Compex NP28G HotSpot */ ++#define MACH_ADM5120_NP27G 8 /* Compex NP27G */ ++#define MACH_ADM5120_WP54Gv1C 9 /* Compex WP54G version 1C */ ++#define MACH_ADM5120_RB_111 10 /* Mikrotik RouterBOARD 111 */ ++#define MACH_ADM5120_RB_112 11 /* Mikrotik RouterBOARD 112 */ ++#define MACH_ADM5120_RB_133 12 /* Mikrotik RouterBOARD 133 */ ++#define MACH_ADM5120_RB_133C 13 /* Mikrotik RouterBOARD 133c */ ++#define MACH_ADM5120_RB_150 14 /* Mikrotik RouterBOARD 150 */ ++#define MACH_ADM5120_RB_153 15 /* Mikrotik RouterBOARD 153 */ ++#define MACH_ADM5120_HS100 16 /* ZyXEL HomeSafe 100/100W */ ++#define MACH_ADM5120_P334 17 /* ZyXEL Prestige 334 */ ++#define MACH_ADM5120_P334U 18 /* ZyXEL Prestige 334U */ ++#define MACH_ADM5120_P334W 19 /* ZyXEL Prestige 334W */ ++#define MACH_ADM5120_P334WH 20 /* ZyXEL Prestige 334WH */ ++#define MACH_ADM5120_P334WHD 21 /* ZyXEL Prestige 334WHD */ ++#define MACH_ADM5120_P334WT 22 /* ZyXEL Prestige 334WT */ ++#define MACH_ADM5120_P335 23 /* ZyXEL Prestige 335/335WT */ ++#define MACH_ADM5120_P335PLUS 24 /* ZyXEL Prestige 335Plus */ ++#define MACH_ADM5120_P335U 25 /* ZyXEL Prestige 335U */ ++#define MACH_ADM5120_ES2108 26 /* ZyXEL Ethernet Switch 2108 */ ++#define MACH_ADM5120_ES2108F 27 /* ZyXEL Ethernet Switch 2108-F */ ++#define MACH_ADM5120_ES2108G 28 /* ZyXEL Ethernet Switch 2108-G */ ++#define MACH_ADM5120_ES2108LC 29 /* ZyXEL Ethernet Switch 2108-LC */ ++#define MACH_ADM5120_ES2108PWR 30 /* ZyXEL Ethernet Switch 2108-PWR */ ++#define MACH_ADM5120_ES2024A 31 /* ZyXEL Ethernet Switch 2024A */ ++#define MACH_ADM5120_ES2024PWR 32 /* ZyXEL Ethernet Switch 2024PWR */ ++#define MACH_ADM5120_CAS630 33 /* Cellvision CAS-630/630W */ ++#define MACH_ADM5120_CAS670 34 /* Cellvision CAS-670/670W */ ++#define MACH_ADM5120_CAS700 36 /* Cellvision CAS-700/700W */ ++#define MACH_ADM5120_CAS771 37 /* Cellvision CAS-771/771W */ ++#define MACH_ADM5120_CAS790 38 /* Cellvision CAS-790 */ ++#define MACH_ADM5120_CAS861 39 /* Cellvision CAS-861/861W */ ++#define MACH_ADM5120_NFS101U 40 /* Cellvision NFS-101U/101WU */ ++#define MACH_ADM5120_NFS202U 41 /* Cellvision NFS-202U/202WU */ ++#define MACH_ADM5120_EASY5120 43 /* Infineon EASY 5120 */ ++#define MACH_ADM5120_EASY5120RT 44 /* Infineon EASY 5120-RT */ ++#define MACH_ADM5120_EASY5120PATA 45 /* Infineon EASY 5120P-ATA */ ++#define MACH_ADM5120_EASY83000 46 /* Infineon EASY-83000 */ ++#define MACH_ADM5120_BR6104K 47 /* Edimax BR-6104K */ ++ + #define CL_SIZE COMMAND_LINE_SIZE + + const char *get_system_type(void); diff --git a/target/linux/adm5120-2.6/patches/002-adm5120_flash.patch b/target/linux/adm5120-2.6/patches/002-adm5120_flash.patch new file mode 100644 index 0000000000..c6237c6dd0 --- /dev/null +++ b/target/linux/adm5120-2.6/patches/002-adm5120_flash.patch @@ -0,0 +1,27 @@ +Index: linux-2.6.21.1/drivers/mtd/maps/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/drivers/mtd/maps/Kconfig ++++ linux-2.6.21.1/drivers/mtd/maps/Kconfig +@@ -605,5 +605,10 @@ config MTD_PLATRAM + + This selection automatically selects the map_ram driver. + ++config MTD_ADM5120 ++ tristate "Map driver for ADMtek ADM5120 boards" ++ depends on MIPS_ADM5120 ++ select MTD_CFI_AMDSTD ++ + endmenu + +Index: linux-2.6.21.1/drivers/mtd/maps/Makefile +=================================================================== +--- linux-2.6.21.1.orig/drivers/mtd/maps/Makefile ++++ linux-2.6.21.1/drivers/mtd/maps/Makefile +@@ -45,6 +45,7 @@ obj-$(CONFIG_MTD_OCELOT) += ocelot.o + obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o + obj-$(CONFIG_MTD_PCI) += pci.o + obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o ++obj-$(CONFIG_MTD_ADM5120) += adm5120_mtd.o + obj-$(CONFIG_MTD_LASAT) += lasat.o + obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o + obj-$(CONFIG_MTD_EDB7312) += edb7312.o diff --git a/target/linux/adm5120-2.6/patches/003-adm5120_switch.patch b/target/linux/adm5120-2.6/patches/003-adm5120_switch.patch new file mode 100644 index 0000000000..cbd28b1aa8 --- /dev/null +++ b/target/linux/adm5120-2.6/patches/003-adm5120_switch.patch @@ -0,0 +1,27 @@ +Index: linux-2.6.21.1/drivers/net/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/drivers/net/Kconfig ++++ linux-2.6.21.1/drivers/net/Kconfig +@@ -574,6 +574,10 @@ config MIPS_AU1X00_ENET + If you have an Alchemy Semi AU1X00 based system + say Y. Otherwise, say N. + ++config MIPS_ADM5120_ENET ++ tristate "MIPS ADM5120 Ethernet switch support" ++ depends on NET_ETHERNET && MIPS_ADM5120 ++ + config NET_SB1250_MAC + tristate "SB1250 Ethernet support" + depends on NET_ETHERNET && SIBYTE_SB1xxx_SOC +Index: linux-2.6.21.1/drivers/net/Makefile +=================================================================== +--- linux-2.6.21.1.orig/drivers/net/Makefile ++++ linux-2.6.21.1/drivers/net/Makefile +@@ -165,6 +165,7 @@ obj-$(CONFIG_SC92031) += sc92031.o + # This is also a 82596 and should probably be merged + obj-$(CONFIG_LP486E) += lp486e.o + ++obj-$(CONFIG_MIPS_ADM5120_ENET) += adm5120sw.o + obj-$(CONFIG_ETH16I) += eth16i.o + obj-$(CONFIG_ZORRO8390) += zorro8390.o + obj-$(CONFIG_HPLANCE) += hplance.o 7990.o diff --git a/target/linux/adm5120-2.6/patches/004-adm5120_uart.patch b/target/linux/adm5120-2.6/patches/004-adm5120_uart.patch new file mode 100644 index 0000000000..8a6d0205e2 --- /dev/null +++ b/target/linux/adm5120-2.6/patches/004-adm5120_uart.patch @@ -0,0 +1,53 @@ +Index: linux-2.6.21.1/drivers/serial/Makefile +=================================================================== +--- linux-2.6.21.1.orig/drivers/serial/Makefile ++++ linux-2.6.21.1/drivers/serial/Makefile +@@ -21,6 +21,7 @@ obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) + obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o + obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o + obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o ++obj-$(CONFIG_SERIAL_ADM5120) += adm5120_uart.o + obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o + obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o + obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o +Index: linux-2.6.21.1/include/linux/serial_core.h +=================================================================== +--- linux-2.6.21.1.orig/include/linux/serial_core.h ++++ linux-2.6.21.1/include/linux/serial_core.h +@@ -135,6 +135,9 @@ + /* Xilinx uartlite */ + #define PORT_UARTLITE 74 + ++/* ADMtek ADM5120 SoC */ ++#define PORT_ADM5120 68 ++ + #ifdef __KERNEL__ + + #include +Index: linux-2.6.21.1/drivers/serial/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/drivers/serial/Kconfig ++++ linux-2.6.21.1/drivers/serial/Kconfig +@@ -256,6 +256,22 @@ config SERIAL_8250_AU1X00 + + comment "Non-8250 serial port support" + ++config SERIAL_ADM5120 ++ bool "ADM5120 serial port support" ++ depends on MIPS_ADM5120 ++ select SERIAL_CORE ++ select SERIAL_CORE_CONSOLE ++ help ++ Driver for the on chip UARTs on the ADM5120 SoC ++ ++config ADM5120_NR_UARTS ++ int "Maximum number of ADM5120 serial ports" ++ depends on SERIAL_ADM5120 ++ default "2" ++ ---help--- ++ Set this to the number of serial ports you want the driver to ++ support. ++ + config SERIAL_AMBA_PL010 + tristate "ARM AMBA PL010 serial port support" + depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE) diff --git a/target/linux/adm5120-2.6/patches/005-adm5120_usb.patch b/target/linux/adm5120-2.6/patches/005-adm5120_usb.patch new file mode 100644 index 0000000000..f48b0f96c3 --- /dev/null +++ b/target/linux/adm5120-2.6/patches/005-adm5120_usb.patch @@ -0,0 +1,58 @@ +Index: linux-2.6.21.1/drivers/usb/core/hub.c +=================================================================== +--- linux-2.6.21.1.orig/drivers/usb/core/hub.c ++++ linux-2.6.21.1/drivers/usb/core/hub.c +@@ -2227,6 +2227,8 @@ hub_port_init (struct usb_hub *hub, stru + USB_DT_DEVICE << 8, 0, + buf, GET_DESCRIPTOR_BUFSIZE, + (i ? USB_CTRL_GET_TIMEOUT : 1000)); ++printk(KERN_CRIT "usb_control_msg: %d %d %d (%d)\n", r, buf->bMaxPacketSize0, ++buf->bDescriptorType, USB_DT_DEVICE); + switch (buf->bMaxPacketSize0) { + case 8: case 16: case 32: case 64: case 255: + if (buf->bDescriptorType == +Index: linux-2.6.21.1/drivers/usb/host/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/drivers/usb/host/Kconfig ++++ linux-2.6.21.1/drivers/usb/host/Kconfig +@@ -224,3 +224,6 @@ config USB_SL811_CS + To compile this driver as a module, choose M here: the + module will be called "sl811_cs". + ++config USB_ADM5120_HCD ++ tristate "ADM5120 HCD support" ++ depends on USB && MIPS_ADM5120 +Index: linux-2.6.21.1/drivers/usb/host/Makefile +=================================================================== +--- linux-2.6.21.1.orig/drivers/usb/host/Makefile ++++ linux-2.6.21.1/drivers/usb/host/Makefile +@@ -16,3 +16,4 @@ obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd + obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o + obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o + obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o ++obj-$(CONFIG_USB_ADM5120_HCD) += adm5120-hcd.o +Index: linux-2.6.21.1/drivers/usb/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/drivers/usb/Kconfig ++++ linux-2.6.21.1/drivers/usb/Kconfig +@@ -91,8 +91,6 @@ source "drivers/usb/image/Kconfig" + + source "drivers/usb/net/Kconfig" + +-source "drivers/usb/mon/Kconfig" +- + comment "USB port drivers" + depends on USB + +Index: linux-2.6.21.1/drivers/usb/Makefile +=================================================================== +--- linux-2.6.21.1.orig/drivers/usb/Makefile ++++ linux-2.6.21.1/drivers/usb/Makefile +@@ -17,6 +17,7 @@ obj-$(CONFIG_USB_SL811_HCD) += host/ + obj-$(CONFIG_USB_U132_HCD) += host/ + obj-$(CONFIG_ETRAX_USB_HOST) += host/ + obj-$(CONFIG_USB_OHCI_AT91) += host/ ++obj-$(CONFIG_USB_ADM5120_HCD) += host/ + + obj-$(CONFIG_USB_ACM) += class/ + obj-$(CONFIG_USB_PRINTER) += class/ diff --git a/target/linux/adm5120-2.6/patches/006-adm5120_leds.patch b/target/linux/adm5120-2.6/patches/006-adm5120_leds.patch new file mode 100644 index 0000000000..ac654a017e --- /dev/null +++ b/target/linux/adm5120-2.6/patches/006-adm5120_leds.patch @@ -0,0 +1,45 @@ +Index: linux-2.6.21.1/drivers/leds/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/drivers/leds/Kconfig ++++ linux-2.6.21.1/drivers/leds/Kconfig +@@ -19,6 +19,27 @@ config LEDS_CLASS + + comment "LED drivers" + ++config LEDS_GPIO ++ tristate "LED support for LEDS on GPIO lines" ++ depends on LEDS_CLASS && GENERIC_GPIO ++ help ++ This option enables support for LEDs connected to GPIO lines ++ ++config LEDS_ADM5120 ++ tristate "LED Support for ADM5120 GPIO LEDs" ++ depends on LEDS_GPIO && MIPS_ADM5120 ++ help ++ This option enables support for LEDs connected to GPIO lines ++ on ADM5120 SoC based platforms. ++ ++config LEDS_ADM5120_EXPERIMENTAL ++ bool "Enable ADM5120 LEDs experimental code" ++ depends on LEDS_ADM5120 ++ ++config LEDS_ADM5120_DIAG ++ bool "Enable ADM5120 LEDs diagnostic mode" ++ depends on LEDS_ADM5120 ++ + config LEDS_CORGI + tristate "LED Support for the Sharp SL-C7x0 series" + depends on LEDS_CLASS && PXA_SHARP_C7xx +Index: linux-2.6.21.1/drivers/leds/Makefile +=================================================================== +--- linux-2.6.21.1.orig/drivers/leds/Makefile ++++ linux-2.6.21.1/drivers/leds/Makefile +@@ -5,6 +5,8 @@ obj-$(CONFIG_LEDS_CLASS) += led-class.o + obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o + + # LED Platform Drivers ++obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o ++obj-$(CONFIG_LEDS_ADM5120) += leds-adm5120.o + obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o + obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o + obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o diff --git a/target/linux/adm5120-2.6/patches/007-adm5120_pci.patch b/target/linux/adm5120-2.6/patches/007-adm5120_pci.patch new file mode 100644 index 0000000000..1098a24ba8 --- /dev/null +++ b/target/linux/adm5120-2.6/patches/007-adm5120_pci.patch @@ -0,0 +1,23 @@ +Index: linux-2.6.21.1/arch/mips/pci/Makefile +=================================================================== +--- linux-2.6.21.1.orig/arch/mips/pci/Makefile ++++ linux-2.6.21.1/arch/mips/pci/Makefile +@@ -53,3 +53,4 @@ obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup- + obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o + obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o + obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o ++obj-$(CONFIG_PCI_ADM5120) += fixup-adm5120.o ops-adm5120.o pci-adm5120.o +Index: linux-2.6.21.1/include/linux/pci_ids.h +=================================================================== +--- linux-2.6.21.1.orig/include/linux/pci_ids.h ++++ linux-2.6.21.1/include/linux/pci_ids.h +@@ -1701,6 +1701,9 @@ + #define PCI_VENDOR_ID_ESDGMBH 0x12fe + #define PCI_DEVICE_ID_ESDGMBH_CPCIASIO4 0x0111 + ++#define PCI_VENDOR_ID_ADMTEK 0x1317 ++#define PCI_DEVICE_ID_ADMTEK_ADM5120 0x5120 ++ + #define PCI_VENDOR_ID_SIIG 0x131f + #define PCI_SUBVENDOR_ID_SIIG 0x131f + #define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000 diff --git a/target/linux/adm5120-2.6/patches/008-adm5120_hardware_swab.patch b/target/linux/adm5120-2.6/patches/008-adm5120_hardware_swab.patch new file mode 100644 index 0000000000..6b0fe55edf --- /dev/null +++ b/target/linux/adm5120-2.6/patches/008-adm5120_hardware_swab.patch @@ -0,0 +1,38 @@ +--- linux-2.6.19.2/include/asm-mips/byteorder.h 2007-01-10 20:10:37.000000000 +0100 ++++ linux-2.6.19.2.new/include/asm-mips/byteorder.h 2007-05-16 21:14:47.000000000 +0200 +@@ -58,6 +58,35 @@ + + #endif /* CONFIG_CPU_MIPSR2 */ + ++#ifdef CONFIG_ADM5120_HARDWARE_SWAB ++ ++static __inline__ __attribute_const__ __u16 ___adm5120__swab16(__u16 x) ++{ ++ __asm__ ( ++ " sh %2, 0xCA(%1) \n" ++ " lhu %0, 0xCC(%1) \n" ++ : "=r" (x) ++ : "r" (0xB2000000), "r" (x)); ++ ++ return x; ++} ++ ++static __inline__ __attribute_const__ __u32 ___adm5120__swab32(__u32 x) ++{ ++ __asm__ ( ++ " sw %2, 0xC8(%1) \n" ++ " lw %0, 0xCC(%1) \n" ++ : "=r" (x) ++ : "r" (0xB2000000), "r" (x)); ++ ++ return x; ++} ++ ++#define __arch__swab16(x) ___adm5120__swab16(x) ++#define __arch__swab32(x) ___adm5120__swab32(x) ++ ++#endif /* CONFIG_ADM5120_HARDWARE_SWAB */ ++ + #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) + # define __BYTEORDER_HAS_U64__ + # define __SWAB_64_THRU_32__ diff --git a/target/linux/adm5120-2.6/patches/100-mtd-myloder-partition-parser.patch b/target/linux/adm5120-2.6/patches/100-mtd-myloder-partition-parser.patch new file mode 100644 index 0000000000..88b90454a8 --- /dev/null +++ b/target/linux/adm5120-2.6/patches/100-mtd-myloder-partition-parser.patch @@ -0,0 +1,39 @@ +Index: linux-2.6.21.1/drivers/mtd/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/drivers/mtd/Kconfig ++++ linux-2.6.21.1/drivers/mtd/Kconfig +@@ -157,6 +157,22 @@ config MTD_AFS_PARTS + for your particular device. It won't happen automatically. The + 'armflash' map driver (CONFIG_MTD_ARMFLASH) does this, for example. + ++config MTD_MYLOADER_PARTS ++ tristate "MyLoader partition parsing" ++ depends on MIPS_ADM5120 && MTD_PARTITIONS ++ ---help--- ++ MyLoader is a bootloader which allows the user to define partitions ++ in flash devices, by putting a table in the second erase block ++ on the device, similar to a partition table. This table gives the ++ offsets and lengths of the user defined partitions. ++ ++ If you need code which can detect and parse these tables, and ++ register MTD 'partitions' corresponding to each image detected, ++ enable this option. ++ ++ You will still need the parsing functions to be called by the driver ++ for your particular device. It won't happen automatically. ++ + comment "User Modules And Translation Layers" + depends on MTD + +Index: linux-2.6.21.1/drivers/mtd/Makefile +=================================================================== +--- linux-2.6.21.1.orig/drivers/mtd/Makefile ++++ linux-2.6.21.1/drivers/mtd/Makefile +@@ -12,6 +12,7 @@ obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o + obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o + obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o ++obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o + + # 'Users' - code which presents functionality to userspace. + obj-$(CONFIG_MTD_CHAR) += mtdchar.o diff --git a/target/linux/adm5120-2.6/patches/101-cfi-fixup-macronix-bootloc.patch b/target/linux/adm5120-2.6/patches/101-cfi-fixup-macronix-bootloc.patch new file mode 100644 index 0000000000..58b6dff1f2 --- /dev/null +++ b/target/linux/adm5120-2.6/patches/101-cfi-fixup-macronix-bootloc.patch @@ -0,0 +1,87 @@ +Index: linux-2.6.21.1/drivers/mtd/chips/cfi_cmdset_0002.c +=================================================================== +--- linux-2.6.21.1.orig/drivers/mtd/chips/cfi_cmdset_0002.c ++++ linux-2.6.21.1/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -47,12 +47,17 @@ + #define MANUFACTURER_AMD 0x0001 + #define MANUFACTURER_ATMEL 0x001F + #define MANUFACTURER_SST 0x00BF ++#define MANUFACTURER_MACRONIX 0x00C2 + #define SST49LF004B 0x0060 + #define SST49LF040B 0x0050 + #define SST49LF008A 0x005a + #define AT49BV6416 0x00d6 + #define MANUFACTURER_SAMSUNG 0x00ec + ++/* Macronix */ ++#define MX29LV160B 0x2249 /* MX29LV160 Bottom-boot chip */ ++#define MX29LV320B 0x22A8 /* MX29LV320 Bottom-boot chip */ ++ + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); + static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); + static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); +@@ -217,6 +222,35 @@ static void fixup_use_atmel_lock(struct + mtd->flags |= MTD_STUPID_LOCK; + } + ++#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC ++/* ++ * Some Macronix chips has bad bootblock information in the CFI table ++ */ ++static void fixup_macronix_bootloc(struct mtd_info *mtd, void* param) ++{ ++ struct map_info *map = mtd->priv; ++ struct cfi_private *cfi = map->fldrv_priv; ++ struct cfi_pri_amdstd *extp = cfi->cmdset_priv; ++ __u8 major = extp->MajorVersion; ++ __u8 minor = extp->MinorVersion; ++ ++ switch (cfi->id) { ++ /* TODO: put affected chip ids here */ ++ case MX29LV160B: ++ case MX29LV320B: ++ if (((major << 8) | minor) != 0x3131) ++ break; ++ ++ if (extp->TopBottom == 2) ++ break; ++ ++ extp->TopBottom = 2; /* Bottom boot */ ++ printk("%s: weird Macronix chip detected, id:0x%04X, boot location " ++ "forced to bottom\n", map->name, cfi->id); ++ } ++} ++#endif /* CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC */ ++ + static struct cfi_fixup cfi_fixup_table[] = { + #ifdef AMD_BOOTLOC_BUG + { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, +@@ -231,6 +265,9 @@ static struct cfi_fixup cfi_fixup_table[ + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, + #endif + { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, ++#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC ++ { MANUFACTURER_MACRONIX, CFI_ID_ANY, fixup_macronix_bootloc, NULL, }, ++#endif + { 0, 0, NULL, NULL } + }; + static struct cfi_fixup jedec_fixup_table[] = { +Index: linux-2.6.21.1/drivers/mtd/chips/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/drivers/mtd/chips/Kconfig ++++ linux-2.6.21.1/drivers/mtd/chips/Kconfig +@@ -199,6 +199,14 @@ config MTD_CFI_AMDSTD + provides support for one of those command sets, used on chips + including the AMD Am29LV320. + ++config MTD_CFI_FIXUP_MACRONIX_BOOTLOC ++ bool "Force bottom boot for Macronix flash chips" ++ depends on MTD_CFI_AMDSTD ++ help ++ Some Macronix flash chips have wrong boot-block location in the ++ CFI table, and the driver may detect the type incorrectly. Select ++ this if your board has such chip. ++ + config MTD_CFI_STAA + tristate "Support for ST (Advanced Architecture) flash chips" + depends on MTD_GEN_PROBE diff --git a/target/linux/adm5120-2.6/patches/140-cmdline_hack.patch b/target/linux/adm5120-2.6/patches/140-cmdline_hack.patch new file mode 100644 index 0000000000..d5edc23dce --- /dev/null +++ b/target/linux/adm5120-2.6/patches/140-cmdline_hack.patch @@ -0,0 +1,26 @@ +Index: linux-2.6.21.1/arch/mips/kernel/head.S +=================================================================== +--- linux-2.6.21.1.orig/arch/mips/kernel/head.S ++++ linux-2.6.21.1/arch/mips/kernel/head.S +@@ -129,14 +129,19 @@ + #endif + .endm + +- + j kernel_entry + nop +- ++ nop ++ + /* + * Reserved space for exception handlers. + * Necessary for machines which link their kernels at KSEG0. ++ * Use as temporary storage for the kernel command line, so that it ++ * can be updated easily without having to relink the kernel. + */ ++ ++EXPORT(_image_cmdline) ++ .ascii "CMDLINE:" + .align 10 + + EXPORT(stext) # used for profiling diff --git a/target/linux/adm5120-2.6/patches/500-Nand.patch b/target/linux/adm5120-2.6/patches/500-Nand.patch new file mode 100644 index 0000000000..8929a73fbb --- /dev/null +++ b/target/linux/adm5120-2.6/patches/500-Nand.patch @@ -0,0 +1,29 @@ +Index: linux-2.6.21.1/drivers/mtd/nand/Kconfig +=================================================================== +--- linux-2.6.21.1.orig/drivers/mtd/nand/Kconfig ++++ linux-2.6.21.1/drivers/mtd/nand/Kconfig +@@ -75,6 +75,12 @@ config MTD_NAND_TS7250 + help + Support for NAND flash on Technologic Systems TS-7250 platform. + ++config MTD_NAND_RB100 ++ tristate "NAND Flash device on RB100 board" ++ depends on MTD_NAND ++ help ++ Support for NAND flash on RB100 platform. ++ + config MTD_NAND_IDS + tristate + +Index: linux-2.6.21.1/drivers/mtd/nand/Makefile +=================================================================== +--- linux-2.6.21.1.orig/drivers/mtd/nand/Makefile ++++ linux-2.6.21.1/drivers/mtd/nand/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nan + obj-$(CONFIG_MTD_NAND_SPIA) += spia.o + obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o + obj-$(CONFIG_MTD_NAND_TOTO) += toto.o ++obj-$(CONFIG_MTD_NAND_RB100) += rbmipsnand.o + obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o + obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o + obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o diff --git a/target/linux/adm5120-2.6/profiles/100-Atheros.mk b/target/linux/adm5120-2.6/profiles/100-Atheros.mk new file mode 100644 index 0000000000..029586848f --- /dev/null +++ b/target/linux/adm5120-2.6/profiles/100-Atheros.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006 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/adm5120-2.6/profiles/105-Texas.mk b/target/linux/adm5120-2.6/profiles/105-Texas.mk new file mode 100644 index 0000000000..727a0c0648 --- /dev/null +++ b/target/linux/adm5120-2.6/profiles/105-Texas.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Texas + NAME:=Texas Instruments WiFi + PACKAGES:=kmod-acx +endef + +define Profile/Texas/Description + Package set compatible with hardware using Texas Instruments WiFi cards +endef +$(eval $(call Profile,Texas)) + diff --git a/target/linux/adm5120-2.6/profiles/110-Ralink.mk b/target/linux/adm5120-2.6/profiles/110-Ralink.mk new file mode 100644 index 0000000000..d30ee73944 --- /dev/null +++ b/target/linux/adm5120-2.6/profiles/110-Ralink.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Ralink + NAME:=Ralink WiFi + PACKAGES:=kmod-rt2500 +endef + +define Profile/Ralink/Description + Package set compatible with hardware using Ralink WiFi cards +endef +$(eval $(call Profile,Ralink)) diff --git a/target/linux/adm5120-2.6/profiles/200-None.mk b/target/linux/adm5120-2.6/profiles/200-None.mk new file mode 100644 index 0000000000..2fcfacde9f --- /dev/null +++ b/target/linux/adm5120-2.6/profiles/200-None.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/None + NAME:=No WiFi + PACKAGES:= +endef + +define Profile/None/Description + Package set without WiFi support +endef +$(eval $(call Profile,None)) + diff --git a/target/linux/adm5120-2.6/profiles/Cellvision.mk b/target/linux/adm5120-2.6/profiles/Cellvision.mk new file mode 100644 index 0000000000..6912f13e3e --- /dev/null +++ b/target/linux/adm5120-2.6/profiles/Cellvision.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Cellvision + NAME:=Cellvision CAS-63x/77x cameras + PACKAGES:=kmod-rt2500 kmod-cpia2 kmod-usb-ohci kmod-usb2 kmod-usb-audio +endef + +define Profile/Cellvision/Description + Package set compatible with the Cellvision CAS devices, including Wireless variants. +endef +$(eval $(call Profile,Cellvision)) diff --git a/target/linux/adm5120-2.6/profiles/RB1xx.mk b/target/linux/adm5120-2.6/profiles/RB1xx.mk new file mode 100644 index 0000000000..9dd3de0973 --- /dev/null +++ b/target/linux/adm5120-2.6/profiles/RB1xx.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/RouterBoard + NAME:=RouterBoard RB1xx + PACKAGES:=kmod-madwifi +endef + +define Profile/RouterBoard/Description + Package set compatible with the RouterBoard RB1xx devices. Contains RouterOS to OpenWrt\\\ + installation scripts. +endef +$(eval $(call Profile,RouterBoard)) diff --git a/target/linux/amcc-2.6/Makefile b/target/linux/amcc-2.6/Makefile new file mode 100644 index 0000000000..4dd366caa9 --- /dev/null +++ b/target/linux/amcc-2.6/Makefile @@ -0,0 +1,25 @@ +# +# 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:=powerpc +BOARD:=amcc +BOARDNAME:=AMCC Taishan +FEATURES:=jffs2 + +LINUX_VERSION:=2.6.21.5 + +define Target/Description + Build firmware images for the AMCC Taishan evaluation board +endef + +include $(INCLUDE_DIR)/kernel-build.mk + +# include the profiles +-include profiles/*.mk + +$(eval $(call BuildKernel)) diff --git a/target/linux/amcc-2.6/base-files/default/etc/inittab b/target/linux/amcc-2.6/base-files/default/etc/inittab new file mode 100644 index 0000000000..859dc530ce --- /dev/null +++ b/target/linux/amcc-2.6/base-files/default/etc/inittab @@ -0,0 +1,5 @@ +::sysinit:/etc/init.d/rcS S boot +::shutdown:/etc/init.d/rcS K stop +tts/0::askfirst:/bin/ash --login +ttyS1::askfirst:/bin/ash --login +tty1::askfirst:/bin/ash --login diff --git a/target/linux/amcc-2.6/config/default b/target/linux/amcc-2.6/config/default new file mode 100644 index 0000000000..4edff5b9d5 --- /dev/null +++ b/target/linux/amcc-2.6/config/default @@ -0,0 +1,173 @@ +# CONFIG_40x is not set +CONFIG_44x=y +CONFIG_4xx=y +# CONFIG_6xx is not set +# CONFIG_8139TOO is not set +# CONFIG_8xx is not set +# CONFIG_ATM_DRIVERS is not set +# CONFIG_BAMBOO is not set +# CONFIG_E200 is not set +# CONFIG_E500 is not set +# CONFIG_EBONY is not set +# CONFIG_LUAN is not set +# CONFIG_YUCCA is not set +# CONFIG_OCOTEA is not set +CONFIG_TAISHAN=y +CONFIG_440GX=y +CONFIG_440A=y +CONFIG_PTE_64BIT=y +CONFIG_PHYS_64BIT=y +# CONFIG_ADVANCED_OPTIONS is not set +# CONFIG_AGP is not set +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_B44 is not set +CONFIG_BASE_SMALL=0 +CONFIG_BIOS_FIXUP=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BOOKE_WDT is not set +CONFIG_BOOT_LOAD=0x01000000 +# CONFIG_BT is not set +# CONFIG_BUBINGA is not set +CONFIG_CMDLINE="console=ttyS1,115200 init=/etc/preinit" +CONFIG_CMDLINE_BOOL=y +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_CONSISTENT_START=0xff100000 +# CONFIG_CPCI405 is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_E200 is not set +# CONFIG_E500 is not set +# CONFIG_EP405 is not set +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_NVRAM=y +# CONFIG_GEN_RTC is not set +# CONFIG_HIGHMEM is not set +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_HW_RANDOM=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_I2C is not set +CONFIG_IBM_EMAC=y +# CONFIG_IBM_EMAC_DEBUG is not set +CONFIG_IBM_EMAC_PHY_RX_CLK_FIX=y +CONFIG_IBM_EMAC_POLL_WEIGHT=32 +CONFIG_IBM_EMAC_RXB=128 +CONFIG_IBM_EMAC_RX_COPY_THRESHOLD=256 +CONFIG_IBM_EMAC_RX_SKB_HEADROOM=0 +CONFIG_IBM_EMAC_TXB=128 +CONFIG_IBM_OCP=y +# CONFIG_IDE is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_ISA_DMA_API=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_KERNEL_START=0xc0000000 +# CONFIG_KEXEC is not set +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_MATH_EMULATION=y +CONFIG_MINI_FO=y +CONFIG_MTD=y +# CONFIG_MTD_ABSENT is not set +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 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_JEDECPROBE is not set +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 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_OBSOLETE_CHIPS 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_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# 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_MTD_SPLIT_ROOTFS=y +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NETDEV_1000=y +CONFIG_NOT_COHERENT_CACHE=y +# CONFIG_NVRAM is not set +# CONFIG_PCIPCWATCHDOG is not set +CONFIG_PCI_DOMAINS=y +# CONFIG_PCMCIA_ATMEL is not set +# CONFIG_PC_KEYBOARD is not set +# CONFIG_PM is not set +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_PPC4xx_DMA=y +CONFIG_PPC4xx_EDMA=y +CONFIG_PPC_GEN550=y +# CONFIG_PPC_I8259 is not set +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PPC_OCP=y +# CONFIG_REDWOOD_5 is not set +# CONFIG_REDWOOD_6 is not set +CONFIG_RESOURCES_64BIT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SECCOMP is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_SOUND is not set +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SYCAMORE is not set +CONFIG_TASK_SIZE=0x80000000 +CONFIG_UART0_TTYS0=y +# CONFIG_UART0_TTYS1 is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_USB is not set +# CONFIG_VIA_RHINE is not set +CONFIG_WANT_EARLY_SERIAL=y +# CONFIG_WINDFARM is not set +# CONFIG_XILINX_ML300 is not set +# CONFIG_XILINX_ML403 is not set diff --git a/target/linux/amcc-2.6/image/Makefile b/target/linux/amcc-2.6/image/Makefile new file mode 100644 index 0000000000..bd391f02f2 --- /dev/null +++ b/target/linux/amcc-2.6/image/Makefile @@ -0,0 +1,37 @@ +# +# 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 +include $(INCLUDE_DIR)/image.mk + +define Image/Prepare + cp $(LINUX_DIR)/arch/ppc/boot/images/uImage $(KDIR)/uImage +endef + +define Image/BuildKernel + cp $(KDIR)/uImage $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-uImage +endef + +define Image/Build + $(call Image/Build/$(1),$(1)) +endef + +define Image/Build/jffs2-256k + ( \ + dd if=$(LINUX_DIR)/arch/ppc/boot/images/uImage bs=4096k conv=sync; \ + dd if=$(KDIR)/root.$(1) bs=256k conv=sync; \ + ) > $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-jffs2.img +endef + +define Image/Build/squashfs + $(call prepare_generic_squashfs,$(KDIR)/root.squashfs) + ( \ + dd if=$(LINUX_DIR)/arch/ppc/boot/images/uImage bs=4096k conv=sync; \ + dd if=$(KDIR)/root.$(1) bs=256k conv=sync; \ + ) > $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).img +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/amcc-2.6/patches/100-taishan_emac.patch b/target/linux/amcc-2.6/patches/100-taishan_emac.patch new file mode 100644 index 0000000000..fde73b77b6 --- /dev/null +++ b/target/linux/amcc-2.6/patches/100-taishan_emac.patch @@ -0,0 +1,71 @@ +diff -Nur linux-2.6.21/drivers/net/ibm_emac/ibm_emac_phy.c linux-2.6.21-owrt/drivers/net/ibm_emac/ibm_emac_phy.c +--- linux-2.6.21/drivers/net/ibm_emac/ibm_emac_phy.c 2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21-owrt/drivers/net/ibm_emac/ibm_emac_phy.c 2007-05-28 16:27:15.000000000 +0200 +@@ -299,11 +299,50 @@ + .ops = &cis8201_phy_ops + }; + ++#if defined(CONFIG_TAISHAN) ++static int et1011c_init(struct mii_phy *phy) ++{ ++ u16 reg_short; ++ ++ reg_short = (u16)(phy_read(phy,0x16)); ++ reg_short &= ~(0x7); ++ reg_short |= 0x6; /* RGMII Trace Delay*/ ++ phy_write(phy, 0x16, reg_short); ++ ++ reg_short = (u16)(phy_read(phy, 0x17)); ++ reg_short &= ~(0x40); ++ phy_write(phy, 0x17, reg_short); ++ ++ phy_write(phy,0x1c,0x74f0); ++ return 0; ++} ++ ++static struct mii_phy_ops et1011c_phy_ops = { ++ .init = et1011c_init, ++ .setup_aneg = genmii_setup_aneg, ++ .setup_forced = genmii_setup_forced, ++ .poll_link = genmii_poll_link, ++ .read_link = genmii_read_link ++}; ++ ++static struct mii_phy_def et1011c_phy_def = { ++ .phy_id = 0x0282f000, ++ .phy_id_mask = 0x0fffff00, ++ .name = "ET1011C Gigabit Ethernet", ++ .ops = &et1011c_phy_ops ++}; ++ ++static struct mii_phy_def *mii_phy_table[] = { ++ &et1011c_phy_def, ++ NULL ++}; ++#else + static struct mii_phy_def *mii_phy_table[] = { + &cis8201_phy_def, + &genmii_phy_def, + NULL + }; ++#endif + + int mii_phy_probe(struct mii_phy *phy, int address) + { +diff -Nur linux-2.6.21/drivers/net/ibm_emac/ibm_emac_zmii.c linux-2.6.21-owrt/drivers/net/ibm_emac/ibm_emac_zmii.c +--- linux-2.6.21/drivers/net/ibm_emac/ibm_emac_zmii.c 2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21-owrt/drivers/net/ibm_emac/ibm_emac_zmii.c 2007-05-28 16:26:48.000000000 +0200 +@@ -170,6 +170,13 @@ + struct ocp_func_emac_data *emacdata = dev->def->additions; + + if (emacdata->zmii_idx >= 0) { ++#if defined(CONFIG_TAISHAN) ++ /* don't attach emac0 and emac1 */ ++ if( dev->def->index < 2 ) ++ { ++ return -ENODEV; ++ } ++#endif + dev->zmii_input = emacdata->zmii_mux; + dev->zmii_dev = + ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_ZMII, diff --git a/target/linux/amcc-2.6/patches/110-openwrt_mtd_mapping.patch b/target/linux/amcc-2.6/patches/110-openwrt_mtd_mapping.patch new file mode 100644 index 0000000000..7d07fa9256 --- /dev/null +++ b/target/linux/amcc-2.6/patches/110-openwrt_mtd_mapping.patch @@ -0,0 +1,29 @@ +diff -Nur linux-2.6.21/arch/ppc/platforms/4xx/taishan.c linux-2.6.21-owrt/arch/ppc/platforms/4xx/taishan.c +--- linux-2.6.21/arch/ppc/platforms/4xx/taishan.c 2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21-owrt/arch/ppc/platforms/4xx/taishan.c 2007-05-28 17:21:46.000000000 +0200 +@@ -60,8 +60,8 @@ + }; + + #define RW_PART0_OF 0 +-#define RW_PART0_SZ 0x180000 +-#define RW_PART1_SZ 0x200000 ++#define RW_PART0_SZ 0x400000 ++#define RW_PART1_SZ 0x3a00000 + /* Partition 2 will be autosized dynamically... */ + #define RW_PART3_SZ 0x80000 + #define RW_PART4_SZ 0x40000 +@@ -73,12 +73,12 @@ + .size = RW_PART0_SZ + }, + { +- .name = "root", ++ .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = RW_PART1_SZ, + }, + { +- .name = "user", ++ .name = "diagnostics", + .offset = MTDPART_OFS_APPEND, + /* .size = RW_PART2_SZ */ /* will be adjusted dynamically */ + }, diff --git a/target/linux/amcc-2.6/patches/120-uncompressed_uImage.patch b/target/linux/amcc-2.6/patches/120-uncompressed_uImage.patch new file mode 100644 index 0000000000..b1f2707834 --- /dev/null +++ b/target/linux/amcc-2.6/patches/120-uncompressed_uImage.patch @@ -0,0 +1,17 @@ +diff -Nur linux-2.6.21/arch/ppc/boot/images/Makefile linux-2.6.21-owrt/arch/ppc/boot/images/Makefile +--- linux-2.6.21/arch/ppc/boot/images/Makefile 2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21-owrt/arch/ppc/boot/images/Makefile 2007-05-28 17:44:11.000000000 +0200 +@@ -20,11 +20,11 @@ + + quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \ +- -C gzip -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \ ++ -C none -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \ + -d $< $@ + + targets += uImage +-$(obj)/uImage: $(obj)/vmlinux.gz ++$(obj)/uImage: $(obj)/vmlinux.bin + $(Q)rm -f $@ + $(call cmd,uimage) + @echo -n ' Image: $@ ' diff --git a/target/linux/avr32-2.6/Makefile b/target/linux/avr32-2.6/Makefile new file mode 100644 index 0000000000..465d96c93d --- /dev/null +++ b/target/linux/avr32-2.6/Makefile @@ -0,0 +1,27 @@ +# +# 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:=avr32 +BOARD:=avr32 +BOARDNAME:=Atmel AVR32 +FEATURES:=squashfs + +LINUX_VERSION:=2.6.21.5 + +define Target/Description + Build firmware images for ATNGW100 board +endef + +KERNEL:=2.6 + +include $(INCLUDE_DIR)/kernel-build.mk + +#include the profiles +-include profiles/*.mk + +$(eval $(call BuildKernel)) diff --git a/target/linux/avr32-2.6/config/default b/target/linux/avr32-2.6/config/default new file mode 100644 index 0000000000..5bd7078c94 --- /dev/null +++ b/target/linux/avr32-2.6/config/default @@ -0,0 +1,89 @@ +CONFIG_AP7000_16_BIT_SMC=y +# CONFIG_AP7000_32_BIT_SMC is not set +# CONFIG_AP7000_8_BIT_SMC is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +# CONFIG_ATM_DRIVERS is not set +CONFIG_AVR32=y +CONFIG_BOARD_ATNGW100=y +# CONFIG_BOARD_ATSTK1000 is not set +# CONFIG_BT is not set +CONFIG_CPU_AT32AP7000=y +CONFIG_DW_DMAC=y +CONFIG_ENTRY_ADDRESS=0x90000000 +# CONFIG_GEN_RTC is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ=250 +CONFIG_HZ_250=y +# CONFIG_HW_RANDOM is not set +# CONFIG_I2C is not set +# CONFIG_IDE is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_MACB=y +# CONFIG_MTD_ABSENT is not set +CONFIG_MTD_BLKDEVS=y +# CONFIG_MTD_BLOCK2MTD is not set +CONFIG_MTD_BLOCK=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=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_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_DATAFLASH=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 is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +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 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_ONENAND is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_PHRAM is not set +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_START=0x80000000 +CONFIG_MTD_PHYSMAP=y +# 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_MTD_SPLIT_ROOTFS=y +CONFIG_MTD=y +# CONFIG_OWNERSHIP_TRACE is not set +CONFIG_PHYS_OFFSET=0x10000000 +CONFIG_PLATFORM_AT32AP=y +# CONFIG_RTC is not set +# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_ATMEL_CONSOLE=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +CONFIG_SERIAL_ATMEL=y +# CONFIG_SPI_AT25 is not set +CONFIG_SPI_ATMEL=y +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +# CONFIG_SPI_SPIDEV is not set +CONFIG_SPI=y +CONFIG_SUBARCH_AVR32B=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_WATCHDOG is not set diff --git a/target/linux/avr32-2.6/image/Makefile b/target/linux/avr32-2.6/image/Makefile new file mode 100644 index 0000000000..a001097c58 --- /dev/null +++ b/target/linux/avr32-2.6/image/Makefile @@ -0,0 +1,37 @@ +# +# 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 +include $(INCLUDE_DIR)/image.mk + +define Image/Prepare + cp $(LINUX_DIR)/arch/avr32/boot/images/uImage $(KDIR)/uImage +endef + +define Image/BuildKernel + cp $(KDIR)/uImage $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-uImage +endef + +define Image/Build + $(call Image/Build/$(1),$(1)) +endef + +define Image/Build/squashfs + $(call prepare_generic_squashfs,$(KDIR)/root.squashfs) + ( \ + dd if=$(KDIR)/uImage bs=1024k conv=sync; \ + dd if=$(KDIR)/root.$(1) bs=64k conv=sync; \ + ) > $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).img +endef + +define Image/Build/jffs2-64k + ( \ + dd if=$(KDIR)/uImage bs=1024k conv=sync; \ + dd if=$(KDIR)/root.$(1) bs=64k conv=sync; \ + ) > $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).img +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/avr32-2.6/patches/100-git_sync.patch b/target/linux/avr32-2.6/patches/100-git_sync.patch new file mode 100644 index 0000000000..5c5cc8e7fb --- /dev/null +++ b/target/linux/avr32-2.6/patches/100-git_sync.patch @@ -0,0 +1,11252 @@ +diff -Nur -x .gitignore -x .git linux-2.6.21.3/arch/avr32/boards/atngw100/flash.c avr32-git/arch/avr32/boards/atngw100/flash.c +--- linux-2.6.21.3/arch/avr32/boards/atngw100/flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ avr32-git/arch/avr32/boards/atngw100/flash.c 2007-06-06 11:33:46.000000000 +0200 +@@ -0,0 +1,95 @@ ++/* ++ * ATNGW100 board-specific flash initialization ++ * ++ * Copyright (C) 2005-2006 Atmel Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++static struct smc_config flash_config __initdata = { ++ .ncs_read_setup = 0, ++ .nrd_setup = 40, ++ .ncs_write_setup = 0, ++ .nwe_setup = 10, ++ ++ .ncs_read_pulse = 80, ++ .nrd_pulse = 40, ++ .ncs_write_pulse = 65, ++ .nwe_pulse = 55, ++ ++ .read_cycle = 120, ++ .write_cycle = 120, ++ ++ .bus_width = 2, ++ .nrd_controlled = 1, ++ .nwe_controlled = 1, ++ .byte_write = 1, ++}; ++ ++static struct mtd_partition flash_parts[] = { ++ { ++ .name = "u-boot", ++ .offset = 0x00000000, ++ .size = 0x00020000, /* 128 KiB */ ++ .mask_flags = MTD_WRITEABLE, ++ }, ++ { ++ .name = "root", ++ .offset = 0x00020000, ++ .size = 0x007d0000, ++ }, ++ { ++ .name = "env", ++ .offset = 0x007f0000, ++ .size = 0x00010000, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++}; ++ ++static struct physmap_flash_data flash_data = { ++ .width = 2, ++ .nr_parts = ARRAY_SIZE(flash_parts), ++ .parts = flash_parts, ++}; ++ ++static struct resource flash_resource = { ++ .start = 0x00000000, ++ .end = 0x007fffff, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct platform_device flash_device = { ++ .name = "physmap-flash", ++ .id = 0, ++ .resource = &flash_resource, ++ .num_resources = 1, ++ .dev = { ++ .platform_data = &flash_data, ++ }, ++}; ++ ++/* This needs to be called after the SMC has been initialized */ ++static int __init atngw100_flash_init(void) ++{ ++ int ret; ++ ++ ret = smc_set_configuration(0, &flash_config); ++ if (ret < 0) { ++ printk(KERN_ERR "atngw100: failed to set NOR flash timing\n"); ++ return ret; ++ } ++ ++ platform_device_register(&flash_device); ++ ++ return 0; ++} ++device_initcall(atngw100_flash_init); +diff -Nur -x .gitignore -x .git linux-2.6.21.3/arch/avr32/boards/atngw100/Makefile avr32-git/arch/avr32/boards/atngw100/Makefile +--- linux-2.6.21.3/arch/avr32/boards/atngw100/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ avr32-git/arch/avr32/boards/atngw100/Makefile 2007-06-06 11:33:46.000000000 +0200 +@@ -0,0 +1 @@ ++obj-y += setup.o flash.o +diff -Nur -x .gitignore -x .git linux-2.6.21.3/arch/avr32/boards/atngw100/setup.c avr32-git/arch/avr32/boards/atngw100/setup.c +--- linux-2.6.21.3/arch/avr32/boards/atngw100/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ avr32-git/arch/avr32/boards/atngw100/setup.c 2007-06-06 11:33:46.000000000 +0200 +@@ -0,0 +1,131 @@ ++/* ++ * Board-specific setup code for the ATNGW100 Network Gateway ++ * ++ * Copyright (C) 2005-2006 Atmel Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* Initialized by bootloader-specific startup code. */ ++struct tag *bootloader_tags __initdata; ++ ++struct eth_addr { ++ u8 addr[6]; ++}; ++static struct eth_addr __initdata hw_addr[2]; ++static struct eth_platform_data __initdata eth_data[2]; ++ ++static struct spi_board_info spi0_board_info[] __initdata = { ++ { ++ .modalias = "mtd_dataflash", ++ .max_speed_hz = 10000000, ++ .chip_select = 0, ++ }, ++}; ++ ++static struct mci_platform_data __initdata mci0_data = { ++ .detect_pin = GPIO_PIN_PC(25), ++ .wp_pin = GPIO_PIN_PE(0), ++}; ++ ++/* ++ * The next two functions should go away as the boot loader is ++ * supposed to initialize the macb address registers with a valid ++ * ethernet address. But we need to keep it around for a while until ++ * we can be reasonably sure the boot loader does this. ++ * ++ * The phy_id is ignored as the driver will probe for it. ++ */ ++static int __init parse_tag_ethernet(struct tag *tag) ++{ ++ int i; ++ ++ i = tag->u.ethernet.mac_index; ++ if (i < ARRAY_SIZE(hw_addr)) ++ memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, ++ sizeof(hw_addr[i].addr)); ++ ++ return 0; ++} ++__tagtable(ATAG_ETHERNET, parse_tag_ethernet); ++ ++static void __init set_hw_addr(struct platform_device *pdev) ++{ ++ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ const u8 *addr; ++ void __iomem *regs; ++ struct clk *pclk; ++ ++ if (!res) ++ return; ++ if (pdev->id >= ARRAY_SIZE(hw_addr)) ++ return; ++ ++ addr = hw_addr[pdev->id].addr; ++ if (!is_valid_ether_addr(addr)) ++ return; ++ ++ /* ++ * Since this is board-specific code, we'll cheat and use the ++ * physical address directly as we happen to know that it's ++ * the same as the virtual address. ++ */ ++ regs = (void __iomem __force *)res->start; ++ pclk = clk_get(&pdev->dev, "pclk"); ++ if (!pclk) ++ return; ++ ++ clk_enable(pclk); ++ __raw_writel((addr[3] << 24) | (addr[2] << 16) ++ | (addr[1] << 8) | addr[0], regs + 0x98); ++ __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); ++ clk_disable(pclk); ++ clk_put(pclk); ++} ++ ++struct platform_device *at32_usart_map[1]; ++unsigned int at32_nr_usarts = 1; ++ ++void __init setup_board(void) ++{ ++ at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */ ++ at32_setup_serial_console(0); ++} ++ ++static int __init atngw100_init(void) ++{ ++ /* ++ * ATNGW100 uses 16-bit SDRAM interface, so we don't need to ++ * reserve any pins for it. ++ */ ++ ++ at32_add_system_devices(); ++ ++ at32_add_device_usart(0); ++ ++ set_hw_addr(at32_add_device_eth(0, ð_data[0])); ++ set_hw_addr(at32_add_device_eth(1, ð_data[1])); ++ ++ at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); ++ at32_add_device_mci(0, &mci0_data); ++ at32_add_device_usba(0); ++ ++ return 0; ++} ++postcore_initcall(atngw100_init); +diff -Nur -x .gitignore -x .git linux-2.6.21.3/arch/avr32/boards/atstk1000/atstk1000.h avr32-git/arch/avr32/boards/atstk1000/atstk1000.h +--- linux-2.6.21.3/arch/avr32/boards/atstk1000/atstk1000.h 1970-01-01 01:00:00.000000000 +0100 ++++ avr32-git/arch/avr32/boards/atstk1000/atstk1000.h 2007-06-06 11:33:46.000000000 +0200 +@@ -0,0 +1,15 @@ ++/* ++ * ATSTK1000 setup code: Daughterboard interface ++ * ++ * Copyright (C) 2007 Atmel Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H ++#define __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H ++ ++extern struct atmel_lcdfb_info atstk1000_lcdc_data; ++ ++#endif /* __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H */ +diff -Nur -x .gitignore -x .git linux-2.6.21.3/arch/avr32/boards/atstk1000/atstk1002.c avr32-git/arch/avr32/boards/atstk1000/atstk1002.c +--- linux-2.6.21.3/arch/avr32/boards/atstk1000/atstk1002.c 2007-05-24 23:22:47.000000000 +0200 ++++ avr32-git/arch/avr32/boards/atstk1000/atstk1002.c 2007-06-06 11:33:46.000000000 +0200 +@@ -16,6 +16,8 @@ + #include + #include + ++#include