aboutsummaryrefslogtreecommitdiffstats
path: root/package/boot
diff options
context:
space:
mode:
authorJames <>2013-03-17 12:16:37 +0000
committerJames <>2013-03-17 12:16:37 +0000
commit27b76ab0671089c47506615a796a261e993896a7 (patch)
tree61213d67e7fa87b20356b23798558e2c4212c42f /package/boot
downloadtrunk-36060-27b76ab0671089c47506615a796a261e993896a7.tar.gz
trunk-36060-27b76ab0671089c47506615a796a261e993896a7.tar.bz2
trunk-36060-27b76ab0671089c47506615a796a261e993896a7.zip
Diffstat (limited to 'package/boot')
-rw-r--r--package/boot/.svn/entries67
-rw-r--r--package/boot/fconfig/.svn/entries62
-rw-r--r--package/boot/fconfig/.svn/prop-base/Makefile.svn-base9
-rw-r--r--package/boot/fconfig/.svn/text-base/Makefile.svn-base45
-rw-r--r--package/boot/fconfig/Makefile45
-rw-r--r--package/boot/grub2/.svn/entries65
-rw-r--r--package/boot/grub2/.svn/text-base/Makefile.svn-base51
-rw-r--r--package/boot/grub2/Makefile51
-rw-r--r--package/boot/grub2/patches/.svn/entries130
-rw-r--r--package/boot/grub2/patches/.svn/text-base/100-grub_setup_root.patch.svn-base77
-rw-r--r--package/boot/grub2/patches/.svn/text-base/200-fix-gets-removal.patch.svn-base15
-rw-r--r--package/boot/grub2/patches/.svn/text-base/200-grub_musl.patch.svn-base22
-rw-r--r--package/boot/grub2/patches/100-grub_setup_root.patch77
-rw-r--r--package/boot/grub2/patches/200-fix-gets-removal.patch15
-rw-r--r--package/boot/grub2/patches/200-grub_musl.patch22
-rw-r--r--package/boot/kexec-tools/.svn/entries99
-rw-r--r--package/boot/kexec-tools/.svn/prop-base/Config.in.svn-base5
-rw-r--r--package/boot/kexec-tools/.svn/prop-base/Makefile.svn-base9
-rw-r--r--package/boot/kexec-tools/.svn/text-base/Config.in.svn-base21
-rw-r--r--package/boot/kexec-tools/.svn/text-base/Makefile.svn-base80
-rw-r--r--package/boot/kexec-tools/Config.in21
-rw-r--r--package/boot/kexec-tools/Makefile80
-rw-r--r--package/boot/kexec-tools/patches/.svn/entries62
-rw-r--r--package/boot/kexec-tools/patches/.svn/text-base/0004-mips_regdefs.patch.svn-base103
-rw-r--r--package/boot/kexec-tools/patches/0004-mips_regdefs.patch103
-rw-r--r--package/boot/rbcfg/.svn/entries65
-rw-r--r--package/boot/rbcfg/.svn/prop-base/Makefile.svn-base5
-rw-r--r--package/boot/rbcfg/.svn/text-base/Makefile.svn-base49
-rw-r--r--package/boot/rbcfg/Makefile49
-rw-r--r--package/boot/rbcfg/src/.svn/entries198
-rw-r--r--package/boot/rbcfg/src/.svn/prop-base/Makefile.svn-base5
-rw-r--r--package/boot/rbcfg/src/.svn/prop-base/cyg_crc.h.svn-base5
-rw-r--r--package/boot/rbcfg/src/.svn/prop-base/cyg_crc32.c.svn-base5
-rw-r--r--package/boot/rbcfg/src/.svn/prop-base/main.c.svn-base5
-rw-r--r--package/boot/rbcfg/src/.svn/prop-base/rbcfg.h.svn-base5
-rw-r--r--package/boot/rbcfg/src/.svn/text-base/Makefile.svn-base14
-rw-r--r--package/boot/rbcfg/src/.svn/text-base/cyg_crc.h.svn-base109
-rw-r--r--package/boot/rbcfg/src/.svn/text-base/cyg_crc32.c.svn-base172
-rw-r--r--package/boot/rbcfg/src/.svn/text-base/main.c.svn-base791
-rw-r--r--package/boot/rbcfg/src/.svn/text-base/rbcfg.h.svn-base75
-rw-r--r--package/boot/rbcfg/src/Makefile14
-rw-r--r--package/boot/rbcfg/src/cyg_crc.h109
-rw-r--r--package/boot/rbcfg/src/cyg_crc32.c172
-rw-r--r--package/boot/rbcfg/src/main.c791
-rw-r--r--package/boot/rbcfg/src/rbcfg.h75
-rw-r--r--package/boot/uboot-ar71xx/.svn/entries68
-rw-r--r--package/boot/uboot-ar71xx/.svn/prop-base/Makefile.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/.svn/text-base/Makefile.svn-base90
-rw-r--r--package/boot/uboot-ar71xx/Makefile90
-rw-r--r--package/boot/uboot-ar71xx/files/.svn/entries40
-rw-r--r--package/boot/uboot-ar71xx/files/board/.svn/entries31
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/.svn/entries31
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/entries198
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/Makefile.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/config.mk.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/nbg460n.c.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/Makefile.svn-base46
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/config.mk.svn-base1
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/lowlevel_init.S.svn-base39
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/nbg460n.c.svn-base96
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/u-boot.lds.svn-base42
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile46
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk1
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S39
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c96
-rw-r--r--package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds42
-rw-r--r--package/boot/uboot-ar71xx/files/cpu/.svn/entries31
-rw-r--r--package/boot/uboot-ar71xx/files/cpu/mips/.svn/entries62
-rw-r--r--package/boot/uboot-ar71xx/files/cpu/mips/.svn/prop-base/ar71xx_serial.c.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/cpu/mips/.svn/text-base/ar71xx_serial.c.svn-base177
-rw-r--r--package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c177
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/.svn/entries34
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/.svn/entries99
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.c.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.h.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.c.svn-base809
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.h.svn-base374
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c809
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h374
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/entries96
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366.h.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366_mii.c.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366.h.svn-base188
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366_mii.c.svn-base786
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h188
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366_mii.c786
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/spi/.svn/entries62
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/spi/.svn/prop-base/ar71xx_spi.c.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/spi/.svn/text-base/ar71xx_spi.c.svn-base191
-rw-r--r--package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c191
-rw-r--r--package/boot/uboot-ar71xx/files/include/.svn/entries34
-rw-r--r--package/boot/uboot-ar71xx/files/include/asm-mips/.svn/entries96
-rw-r--r--package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx.h.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx_gpio.h.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx.h.svn-base515
-rw-r--r--package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx_gpio.h.svn-base65
-rw-r--r--package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h515
-rw-r--r--package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h65
-rw-r--r--package/boot/uboot-ar71xx/files/include/configs/.svn/entries62
-rw-r--r--package/boot/uboot-ar71xx/files/include/configs/.svn/prop-base/nbg460n.h.svn-base5
-rw-r--r--package/boot/uboot-ar71xx/files/include/configs/.svn/text-base/nbg460n.h.svn-base136
-rw-r--r--package/boot/uboot-ar71xx/files/include/configs/nbg460n.h136
-rw-r--r--package/boot/uboot-ar71xx/patches/.svn/entries266
-rw-r--r--package/boot/uboot-ar71xx/patches/.svn/text-base/001-ar71xx.patch.svn-base28
-rw-r--r--package/boot/uboot-ar71xx/patches/.svn/text-base/002-ar71xx-spi.patch.svn-base11
-rw-r--r--package/boot/uboot-ar71xx/patches/.svn/text-base/010-enet-ag71xx.patch.svn-base22
-rw-r--r--package/boot/uboot-ar71xx/patches/.svn/text-base/011-switch-rtl8366sr.patch.svn-base28
-rw-r--r--package/boot/uboot-ar71xx/patches/.svn/text-base/020-freebsd-compat.patch.svn-base11
-rw-r--r--package/boot/uboot-ar71xx/patches/.svn/text-base/021-darwin_compat.patch.svn-base23
-rw-r--r--package/boot/uboot-ar71xx/patches/.svn/text-base/022-getline_backport.patch.svn-base21
-rw-r--r--package/boot/uboot-ar71xx/patches/001-ar71xx.patch28
-rw-r--r--package/boot/uboot-ar71xx/patches/002-ar71xx-spi.patch11
-rw-r--r--package/boot/uboot-ar71xx/patches/010-enet-ag71xx.patch22
-rw-r--r--package/boot/uboot-ar71xx/patches/011-switch-rtl8366sr.patch28
-rw-r--r--package/boot/uboot-ar71xx/patches/020-freebsd-compat.patch11
-rw-r--r--package/boot/uboot-ar71xx/patches/021-darwin_compat.patch23
-rw-r--r--package/boot/uboot-ar71xx/patches/022-getline_backport.patch21
-rw-r--r--package/boot/uboot-envtools/.svn/entries68
-rw-r--r--package/boot/uboot-envtools/.svn/text-base/Makefile.svn-base74
-rw-r--r--package/boot/uboot-envtools/Makefile74
-rw-r--r--package/boot/uboot-envtools/files/.svn/entries198
-rw-r--r--package/boot/uboot-envtools/files/.svn/text-base/ar71xx.svn-base38
-rw-r--r--package/boot/uboot-envtools/files/.svn/text-base/kirkwood.svn-base25
-rw-r--r--package/boot/uboot-envtools/files/.svn/text-base/lantiq.svn-base25
-rw-r--r--package/boot/uboot-envtools/files/.svn/text-base/ramips.svn-base32
-rw-r--r--package/boot/uboot-envtools/files/.svn/text-base/uboot-envtools.sh.svn-base36
-rw-r--r--package/boot/uboot-envtools/files/ar71xx38
-rw-r--r--package/boot/uboot-envtools/files/kirkwood25
-rw-r--r--package/boot/uboot-envtools/files/lantiq25
-rw-r--r--package/boot/uboot-envtools/files/ramips32
-rw-r--r--package/boot/uboot-envtools/files/uboot-envtools.sh36
-rw-r--r--package/boot/uboot-envtools/patches/.svn/entries28
-rw-r--r--package/boot/uboot-kirkwood/.svn/entries68
-rw-r--r--package/boot/uboot-kirkwood/.svn/text-base/Makefile.svn-base104
-rw-r--r--package/boot/uboot-kirkwood/Makefile104
-rw-r--r--package/boot/uboot-kirkwood/files/.svn/entries34
-rw-r--r--package/boot/uboot-kirkwood/files/board/.svn/entries31
-rw-r--r--package/boot/uboot-kirkwood/files/board/iomega/.svn/entries31
-rw-r--r--package/boot/uboot-kirkwood/files/board/iomega/iconnect/.svn/entries28
-rw-r--r--package/boot/uboot-kirkwood/files/include/.svn/entries31
-rw-r--r--package/boot/uboot-kirkwood/files/include/configs/.svn/entries28
-rw-r--r--package/boot/uboot-kirkwood/patches/.svn/entries62
-rw-r--r--package/boot/uboot-kirkwood/patches/.svn/text-base/110-dockstar.patch.svn-base35
-rw-r--r--package/boot/uboot-kirkwood/patches/110-dockstar.patch35
-rw-r--r--package/boot/uboot-lantiq/.svn/entries65
-rw-r--r--package/boot/uboot-lantiq/.svn/text-base/Makefile.svn-base123
-rw-r--r--package/boot/uboot-lantiq/Makefile123
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/entries980
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0002-sf-handle-CONFIG_MANUAL_RELOC.patch.svn-base46
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch.svn-base719
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch.svn-base131
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0005-sf-factor-out-the-flash-address-calculation.patch.svn-base107
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0006-sf-add-generic-support-for-4-byte-address-mode.patch.svn-base161
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0007-sf-eon-use-16-bit-ID-for-comparison.patch.svn-base45
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0008-sf-eon-add-support-for-4-byte-address-mode.patch.svn-base43
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0009-sf-eon-add-support-for-EN25QH256.patch.svn-base21
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch.svn-base30
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0011-sf-spansion-add-support-for-4-byte-address-mode.patch.svn-base55
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0012-sf-spansion-add-support-for-S25FL512S.patch.svn-base23
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0013-sf-macronix-add-support-for-4-byte-address-mode.patch.svn-base44
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0014-sf-macronix-add-support-for-MX25L25635E.patch.svn-base21
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0015-sf-macronix-add-support-for-MX66L51235L.patch.svn-base21
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch.svn-base133
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0017-sf-add-init-function.patch.svn-base57
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0018-MIPS-add-SPI-flash-init-hook.patch.svn-base47
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch.svn-base239
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch.svn-base162
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch.svn-base158
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch.svn-base158
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch.svn-base9496
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch.svn-base33
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch.svn-base355
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch.svn-base264
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch.svn-base248
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch.svn-base248
-rw-r--r--package/boot/uboot-lantiq/patches/.svn/text-base/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch.svn-base361
-rw-r--r--package/boot/uboot-lantiq/patches/0002-sf-handle-CONFIG_MANUAL_RELOC.patch46
-rw-r--r--package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch719
-rw-r--r--package/boot/uboot-lantiq/patches/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch131
-rw-r--r--package/boot/uboot-lantiq/patches/0005-sf-factor-out-the-flash-address-calculation.patch107
-rw-r--r--package/boot/uboot-lantiq/patches/0006-sf-add-generic-support-for-4-byte-address-mode.patch161
-rw-r--r--package/boot/uboot-lantiq/patches/0007-sf-eon-use-16-bit-ID-for-comparison.patch45
-rw-r--r--package/boot/uboot-lantiq/patches/0008-sf-eon-add-support-for-4-byte-address-mode.patch43
-rw-r--r--package/boot/uboot-lantiq/patches/0009-sf-eon-add-support-for-EN25QH256.patch21
-rw-r--r--package/boot/uboot-lantiq/patches/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch30
-rw-r--r--package/boot/uboot-lantiq/patches/0011-sf-spansion-add-support-for-4-byte-address-mode.patch55
-rw-r--r--package/boot/uboot-lantiq/patches/0012-sf-spansion-add-support-for-S25FL512S.patch23
-rw-r--r--package/boot/uboot-lantiq/patches/0013-sf-macronix-add-support-for-4-byte-address-mode.patch44
-rw-r--r--package/boot/uboot-lantiq/patches/0014-sf-macronix-add-support-for-MX25L25635E.patch21
-rw-r--r--package/boot/uboot-lantiq/patches/0015-sf-macronix-add-support-for-MX66L51235L.patch21
-rw-r--r--package/boot/uboot-lantiq/patches/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch133
-rw-r--r--package/boot/uboot-lantiq/patches/0017-sf-add-init-function.patch57
-rw-r--r--package/boot/uboot-lantiq/patches/0018-MIPS-add-SPI-flash-init-hook.patch47
-rw-r--r--package/boot/uboot-lantiq/patches/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch239
-rw-r--r--package/boot/uboot-lantiq/patches/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch162
-rw-r--r--package/boot/uboot-lantiq/patches/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch158
-rw-r--r--package/boot/uboot-lantiq/patches/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch158
-rw-r--r--package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch9496
-rw-r--r--package/boot/uboot-lantiq/patches/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch33
-rw-r--r--package/boot/uboot-lantiq/patches/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch355
-rw-r--r--package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch264
-rw-r--r--package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch248
-rw-r--r--package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch248
-rw-r--r--package/boot/uboot-lantiq/patches/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch361
-rw-r--r--package/boot/uboot-omap35xx/.svn/entries65
-rw-r--r--package/boot/uboot-omap35xx/.svn/text-base/Makefile.svn-base89
-rw-r--r--package/boot/uboot-omap35xx/Makefile89
-rw-r--r--package/boot/uboot-omap35xx/files/.svn/entries31
-rw-r--r--package/boot/uboot-omap35xx/files/include/.svn/entries31
-rw-r--r--package/boot/uboot-omap35xx/files/include/configs/.svn/entries62
-rw-r--r--package/boot/uboot-omap35xx/files/include/configs/.svn/text-base/omap3_overo.h.svn-base316
-rw-r--r--package/boot/uboot-omap35xx/files/include/configs/omap3_overo.h316
-rw-r--r--package/boot/uboot-omap4/.svn/entries62
-rw-r--r--package/boot/uboot-omap4/.svn/text-base/Makefile.svn-base90
-rw-r--r--package/boot/uboot-omap4/Makefile90
-rw-r--r--package/boot/uboot-pxa/.svn/entries65
-rw-r--r--package/boot/uboot-pxa/.svn/text-base/Makefile.svn-base89
-rw-r--r--package/boot/uboot-pxa/Makefile89
-rw-r--r--package/boot/uboot-pxa/patches/.svn/entries62
-rw-r--r--package/boot/uboot-pxa/patches/.svn/text-base/001-squashfs_rootfstype_cmdline.patch.svn-base13
-rw-r--r--package/boot/uboot-pxa/patches/001-squashfs_rootfstype_cmdline.patch13
-rw-r--r--package/boot/uboot-xburst/.svn/entries68
-rw-r--r--package/boot/uboot-xburst/.svn/text-base/Makefile.svn-base83
-rw-r--r--package/boot/uboot-xburst/Makefile83
-rw-r--r--package/boot/uboot-xburst/files/.svn/entries40
-rw-r--r--package/boot/uboot-xburst/files/board/.svn/entries37
-rw-r--r--package/boot/uboot-xburst/files/board/n516/.svn/entries28
-rw-r--r--package/boot/uboot-xburst/files/board/nanonote/.svn/entries28
-rw-r--r--package/boot/uboot-xburst/files/board/sakc/.svn/entries28
-rw-r--r--package/boot/uboot-xburst/files/cpu/.svn/entries31
-rw-r--r--package/boot/uboot-xburst/files/cpu/mips/.svn/entries28
-rw-r--r--package/boot/uboot-xburst/files/include/.svn/entries34
-rw-r--r--package/boot/uboot-xburst/files/include/asm-mips/.svn/entries28
-rw-r--r--package/boot/uboot-xburst/files/include/configs/.svn/entries28
-rw-r--r--package/boot/uboot-xburst/files/nand_spl/.svn/entries31
-rw-r--r--package/boot/uboot-xburst/files/nand_spl/board/.svn/entries37
-rw-r--r--package/boot/uboot-xburst/files/nand_spl/board/n516/.svn/entries28
-rw-r--r--package/boot/uboot-xburst/files/nand_spl/board/nanonote/.svn/entries28
-rw-r--r--package/boot/uboot-xburst/files/nand_spl/board/sakc/.svn/entries28
-rw-r--r--package/boot/uboot-xburst/patches/.svn/entries232
-rw-r--r--package/boot/uboot-xburst/patches/.svn/text-base/0001-qi_lb60-add-nand-spl-support.patch.svn-base894
-rw-r--r--package/boot/uboot-xburst/patches/.svn/text-base/0002-qi_lb60-add-software-usbboot-support.patch.svn-base916
-rw-r--r--package/boot/uboot-xburst/patches/.svn/text-base/0003-add-mmc-support.patch.svn-base1664
-rw-r--r--package/boot/uboot-xburst/patches/.svn/text-base/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch.svn-base200
-rw-r--r--package/boot/uboot-xburst/patches/.svn/text-base/0005-add-nanonote-lcd-support.patch.svn-base847
-rw-r--r--package/boot/uboot-xburst/patches/.svn/text-base/0006-enable-silent-console.patch.svn-base60
-rw-r--r--package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch894
-rw-r--r--package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch916
-rw-r--r--package/boot/uboot-xburst/patches/0003-add-mmc-support.patch1664
-rw-r--r--package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch200
-rw-r--r--package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch847
-rw-r--r--package/boot/uboot-xburst/patches/0006-enable-silent-console.patch60
-rw-r--r--package/boot/yamonenv/.svn/entries65
-rw-r--r--package/boot/yamonenv/.svn/prop-base/Makefile.svn-base9
-rw-r--r--package/boot/yamonenv/.svn/text-base/Makefile.svn-base39
-rw-r--r--package/boot/yamonenv/Makefile39
-rw-r--r--package/boot/yamonenv/patches/.svn/entries62
-rw-r--r--package/boot/yamonenv/patches/.svn/text-base/001-yamonenv_mtd_partition.patch.svn-base11
-rw-r--r--package/boot/yamonenv/patches/001-yamonenv_mtd_partition.patch11
259 files changed, 54108 insertions, 0 deletions
diff --git a/package/boot/.svn/entries b/package/boot/.svn/entries
new file mode 100644
index 0000000..4d0cef9
--- /dev/null
+++ b/package/boot/.svn/entries
@@ -0,0 +1,67 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-03-15T01:36:53.833391Z
+36033
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+uboot-envtools
+dir
+
+uboot-kirkwood
+dir
+
+uboot-ar71xx
+dir
+
+grub2
+dir
+
+rbcfg
+dir
+
+uboot-omap4
+dir
+
+uboot-omap35xx
+dir
+
+fconfig
+dir
+
+yamonenv
+dir
+
+kexec-tools
+dir
+
+uboot-xburst
+dir
+
+uboot-lantiq
+dir
+
+uboot-pxa
+dir
+
diff --git a/package/boot/fconfig/.svn/entries b/package/boot/fconfig/.svn/entries
new file mode 100644
index 0000000..43502aa
--- /dev/null
+++ b/package/boot/fconfig/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/fconfig
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+ce975dc74a1a3684527983fd088edae2
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+990
+
diff --git a/package/boot/fconfig/.svn/prop-base/Makefile.svn-base b/package/boot/fconfig/.svn/prop-base/Makefile.svn-base
new file mode 100644
index 0000000..4179626
--- /dev/null
+++ b/package/boot/fconfig/.svn/prop-base/Makefile.svn-base
@@ -0,0 +1,9 @@
+K 9
+copyright
+V 30
+Copyright (C) 2006 OpenWrt.org
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/fconfig/.svn/text-base/Makefile.svn-base b/package/boot/fconfig/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..14bbec5
--- /dev/null
+++ b/package/boot/fconfig/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2006-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=fconfig
+PKG_VERSION:=20080329
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://andrzejekiert.ovh.org/software/fconfig/
+PKG_MD5SUM:=dac355e9f2a0f48c414c52e2034b6346
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/fconfig
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=RedBoot configuration editor
+ URL:=http://andrzejekiert.ovh.org/software.html.en
+endef
+
+define Package/fconfig/description
+ displays and (if writable) also edits the RedBoot configuration.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(call Build/Compile/Default)
+endef
+
+define Package/fconfig/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/fconfig $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,fconfig))
diff --git a/package/boot/fconfig/Makefile b/package/boot/fconfig/Makefile
new file mode 100644
index 0000000..14bbec5
--- /dev/null
+++ b/package/boot/fconfig/Makefile
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2006-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=fconfig
+PKG_VERSION:=20080329
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://andrzejekiert.ovh.org/software/fconfig/
+PKG_MD5SUM:=dac355e9f2a0f48c414c52e2034b6346
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/fconfig
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=RedBoot configuration editor
+ URL:=http://andrzejekiert.ovh.org/software.html.en
+endef
+
+define Package/fconfig/description
+ displays and (if writable) also edits the RedBoot configuration.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(call Build/Compile/Default)
+endef
+
+define Package/fconfig/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/fconfig $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,fconfig))
diff --git a/package/boot/grub2/.svn/entries b/package/boot/grub2/.svn/entries
new file mode 100644
index 0000000..1fbbf4b
--- /dev/null
+++ b/package/boot/grub2/.svn/entries
@@ -0,0 +1,65 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/grub2
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-26T16:03:40.540832Z
+34389
+jow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+patches
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+0b28cdcaf03ae3f53f28ce7026102dcb
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1147
+
diff --git a/package/boot/grub2/.svn/text-base/Makefile.svn-base b/package/boot/grub2/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..b606f54
--- /dev/null
+++ b/package/boot/grub2/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=grub
+PKG_VERSION:=2.00
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/grub
+PKG_MD5SUM:=e927540b6eda8b024fb0391eeaa4091c
+
+PKG_HOST_ONLY:=1
+HOST_BUILD_PARALLEL:=1
+PKG_BUILD_DEPENDS:=grub2/host
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/grub2
+ SUBMENU:=Boot Loaders
+ CATEGORY:=Utilities
+ SECTION:=utils
+ TITLE:=GRand Unified Bootloader
+ URL:=http://www.gnu.org/software/grub/
+ DEPENDS:=@TARGET_x86
+endef
+
+HOST_CONFIGURE_ARGS += \
+ --target=$(REAL_GNU_TARGET_NAME) \
+ --sbindir="$(STAGING_DIR_HOST)/bin" \
+ --disable-werror \
+ --disable-nls
+
+HOST_MAKE_FLAGS += \
+ TARGET_RANLIB=$(TARGET_RANLIB) \
+ LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a
+
+define Host/Configure
+ $(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in
+ $(Host/Configure/Default)
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,grub2))
diff --git a/package/boot/grub2/Makefile b/package/boot/grub2/Makefile
new file mode 100644
index 0000000..b606f54
--- /dev/null
+++ b/package/boot/grub2/Makefile
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=grub
+PKG_VERSION:=2.00
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/grub
+PKG_MD5SUM:=e927540b6eda8b024fb0391eeaa4091c
+
+PKG_HOST_ONLY:=1
+HOST_BUILD_PARALLEL:=1
+PKG_BUILD_DEPENDS:=grub2/host
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/grub2
+ SUBMENU:=Boot Loaders
+ CATEGORY:=Utilities
+ SECTION:=utils
+ TITLE:=GRand Unified Bootloader
+ URL:=http://www.gnu.org/software/grub/
+ DEPENDS:=@TARGET_x86
+endef
+
+HOST_CONFIGURE_ARGS += \
+ --target=$(REAL_GNU_TARGET_NAME) \
+ --sbindir="$(STAGING_DIR_HOST)/bin" \
+ --disable-werror \
+ --disable-nls
+
+HOST_MAKE_FLAGS += \
+ TARGET_RANLIB=$(TARGET_RANLIB) \
+ LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a
+
+define Host/Configure
+ $(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in
+ $(Host/Configure/Default)
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,grub2))
diff --git a/package/boot/grub2/patches/.svn/entries b/package/boot/grub2/patches/.svn/entries
new file mode 100644
index 0000000..aa580af
--- /dev/null
+++ b/package/boot/grub2/patches/.svn/entries
@@ -0,0 +1,130 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/grub2/patches
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-26T16:03:40.540832Z
+34389
+jow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+200-fix-gets-removal.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+4347c13528381c1ebf68d183a9cc0165
+2012-11-26T16:03:40.540832Z
+34389
+jow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+560
+
+200-grub_musl.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+eae2474dbd84e1bcbe72e4b91f9f79be
+2012-11-23T20:01:53.954168Z
+34306
+florian
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1059
+
+100-grub_setup_root.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+aec4834762dc8e05bb7c862cc82aab40
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2328
+
diff --git a/package/boot/grub2/patches/.svn/text-base/100-grub_setup_root.patch.svn-base b/package/boot/grub2/patches/.svn/text-base/100-grub_setup_root.patch.svn-base
new file mode 100644
index 0000000..7775b2a
--- /dev/null
+++ b/package/boot/grub2/patches/.svn/text-base/100-grub_setup_root.patch.svn-base
@@ -0,0 +1,77 @@
+--- a/util/grub-setup.c
++++ b/util/grub-setup.c
+@@ -141,12 +141,11 @@ write_rootdev (char *core_img, grub_devi
+ static void
+ setup (const char *dir,
+ const char *boot_file, const char *core_file,
+- const char *dest, int force,
++ const char *root, const char *dest, int force,
+ int fs_probe, int allow_floppy)
+ {
+ char *boot_path, *core_path, *core_path_dev, *core_path_dev_full;
+ char *boot_img, *core_img;
+- char *root = 0;
+ size_t boot_size, core_size;
+ grub_uint16_t core_sectors;
+ grub_device_t root_dev = 0, dest_dev, core_dev;
+@@ -253,7 +252,10 @@ setup (const char *dir,
+
+ core_dev = dest_dev;
+
+- {
++ if (root)
++ root_dev = grub_device_open(root);
++
++ if (!root_dev) {
+ char **root_devices = grub_guess_root_devices (dir);
+ char **cur;
+ int found = 0;
+@@ -263,6 +265,8 @@ setup (const char *dir,
+ char *drive;
+ grub_device_t try_dev;
+
++ if (root_dev)
++ break;
+ drive = grub_util_get_grub_dev (*cur);
+ if (!drive)
+ continue;
+@@ -956,6 +960,8 @@ static struct argp_option options[] = {
+ N_("install even if problems are detected"), 0},
+ {"skip-fs-probe",'s',0, 0,
+ N_("do not probe for filesystems in DEVICE"), 0},
++ {"root-device", 'r', N_("DEVICE"), 0,
++ N_("use DEVICE as the root device"), 0},
+ {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
+ {"allow-floppy", 'a', 0, 0,
+ /* TRANSLATORS: The potential breakage isn't limited to floppies but it's
+@@ -993,6 +999,7 @@ struct arguments
+ char *core_file;
+ char *dir;
+ char *dev_map;
++ char *root_dev;
+ int force;
+ int fs_probe;
+ int allow_floppy;
+@@ -1040,6 +1047,13 @@ argp_parser (int key, char *arg, struct
+ arguments->dev_map = xstrdup (arg);
+ break;
+
++ case 'r':
++ if (arguments->root_dev)
++ free (arguments->root_dev);
++
++ arguments->root_dev = xstrdup (arg);
++ break;
++
+ case 'f':
+ arguments->force = 1;
+ break;
+@@ -1172,7 +1186,7 @@ main (int argc, char *argv[])
+ setup (arguments.dir ? : DEFAULT_DIRECTORY,
+ arguments.boot_file ? : DEFAULT_BOOT_FILE,
+ arguments.core_file ? : DEFAULT_CORE_FILE,
+- dest_dev, arguments.force,
++ arguments.root_dev, dest_dev, arguments.force,
+ arguments.fs_probe, arguments.allow_floppy);
+
+ /* Free resources. */
diff --git a/package/boot/grub2/patches/.svn/text-base/200-fix-gets-removal.patch.svn-base b/package/boot/grub2/patches/.svn/text-base/200-fix-gets-removal.patch.svn-base
new file mode 100644
index 0000000..4370fb5
--- /dev/null
+++ b/package/boot/grub2/patches/.svn/text-base/200-fix-gets-removal.patch.svn-base
@@ -0,0 +1,15 @@
+--- a/grub-core/gnulib/stdio.in.h
++++ b/grub-core/gnulib/stdio.in.h
+@@ -137,12 +137,6 @@
+ "use gnulib module fflush for portable POSIX compliance");
+ #endif
+
+-/* It is very rare that the developer ever has full control of stdin,
+- so any use of gets warrants an unconditional warning. Assume it is
+- always declared, since it is required by C89. */
+-#undef gets
+-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
+-
+ #if @GNULIB_FOPEN@
+ # if @REPLACE_FOPEN@
+ # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/package/boot/grub2/patches/.svn/text-base/200-grub_musl.patch.svn-base b/package/boot/grub2/patches/.svn/text-base/200-grub_musl.patch.svn-base
new file mode 100644
index 0000000..b1ff63a
--- /dev/null
+++ b/package/boot/grub2/patches/.svn/text-base/200-grub_musl.patch.svn-base
@@ -0,0 +1,22 @@
+diff -urN grub-2.00/build-aux/config.sub grub-2.00.new/build-aux/config.sub
+--- grub-2.00/build-aux/config.sub 2012-06-18 23:08:46.000000000 +0200
++++ grub-2.00.new/build-aux/config.sub 2012-11-22 14:12:12.190748353 +0100
+@@ -126,7 +126,8 @@
+ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+- storm-chaos* | os2-emx* | rtmk-nova*)
++ storm-chaos* | os2-emx* | rtmk-nova* | \
++ linux-musl*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+@@ -1360,7 +1361,7 @@
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-android* \
+- | -linux-newlib* | -linux-uclibc* \
++ | -linux-newlib* | -linux-uclibc* | -linux-musl* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
diff --git a/package/boot/grub2/patches/100-grub_setup_root.patch b/package/boot/grub2/patches/100-grub_setup_root.patch
new file mode 100644
index 0000000..7775b2a
--- /dev/null
+++ b/package/boot/grub2/patches/100-grub_setup_root.patch
@@ -0,0 +1,77 @@
+--- a/util/grub-setup.c
++++ b/util/grub-setup.c
+@@ -141,12 +141,11 @@ write_rootdev (char *core_img, grub_devi
+ static void
+ setup (const char *dir,
+ const char *boot_file, const char *core_file,
+- const char *dest, int force,
++ const char *root, const char *dest, int force,
+ int fs_probe, int allow_floppy)
+ {
+ char *boot_path, *core_path, *core_path_dev, *core_path_dev_full;
+ char *boot_img, *core_img;
+- char *root = 0;
+ size_t boot_size, core_size;
+ grub_uint16_t core_sectors;
+ grub_device_t root_dev = 0, dest_dev, core_dev;
+@@ -253,7 +252,10 @@ setup (const char *dir,
+
+ core_dev = dest_dev;
+
+- {
++ if (root)
++ root_dev = grub_device_open(root);
++
++ if (!root_dev) {
+ char **root_devices = grub_guess_root_devices (dir);
+ char **cur;
+ int found = 0;
+@@ -263,6 +265,8 @@ setup (const char *dir,
+ char *drive;
+ grub_device_t try_dev;
+
++ if (root_dev)
++ break;
+ drive = grub_util_get_grub_dev (*cur);
+ if (!drive)
+ continue;
+@@ -956,6 +960,8 @@ static struct argp_option options[] = {
+ N_("install even if problems are detected"), 0},
+ {"skip-fs-probe",'s',0, 0,
+ N_("do not probe for filesystems in DEVICE"), 0},
++ {"root-device", 'r', N_("DEVICE"), 0,
++ N_("use DEVICE as the root device"), 0},
+ {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
+ {"allow-floppy", 'a', 0, 0,
+ /* TRANSLATORS: The potential breakage isn't limited to floppies but it's
+@@ -993,6 +999,7 @@ struct arguments
+ char *core_file;
+ char *dir;
+ char *dev_map;
++ char *root_dev;
+ int force;
+ int fs_probe;
+ int allow_floppy;
+@@ -1040,6 +1047,13 @@ argp_parser (int key, char *arg, struct
+ arguments->dev_map = xstrdup (arg);
+ break;
+
++ case 'r':
++ if (arguments->root_dev)
++ free (arguments->root_dev);
++
++ arguments->root_dev = xstrdup (arg);
++ break;
++
+ case 'f':
+ arguments->force = 1;
+ break;
+@@ -1172,7 +1186,7 @@ main (int argc, char *argv[])
+ setup (arguments.dir ? : DEFAULT_DIRECTORY,
+ arguments.boot_file ? : DEFAULT_BOOT_FILE,
+ arguments.core_file ? : DEFAULT_CORE_FILE,
+- dest_dev, arguments.force,
++ arguments.root_dev, dest_dev, arguments.force,
+ arguments.fs_probe, arguments.allow_floppy);
+
+ /* Free resources. */
diff --git a/package/boot/grub2/patches/200-fix-gets-removal.patch b/package/boot/grub2/patches/200-fix-gets-removal.patch
new file mode 100644
index 0000000..4370fb5
--- /dev/null
+++ b/package/boot/grub2/patches/200-fix-gets-removal.patch
@@ -0,0 +1,15 @@
+--- a/grub-core/gnulib/stdio.in.h
++++ b/grub-core/gnulib/stdio.in.h
+@@ -137,12 +137,6 @@
+ "use gnulib module fflush for portable POSIX compliance");
+ #endif
+
+-/* It is very rare that the developer ever has full control of stdin,
+- so any use of gets warrants an unconditional warning. Assume it is
+- always declared, since it is required by C89. */
+-#undef gets
+-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
+-
+ #if @GNULIB_FOPEN@
+ # if @REPLACE_FOPEN@
+ # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/package/boot/grub2/patches/200-grub_musl.patch b/package/boot/grub2/patches/200-grub_musl.patch
new file mode 100644
index 0000000..b1ff63a
--- /dev/null
+++ b/package/boot/grub2/patches/200-grub_musl.patch
@@ -0,0 +1,22 @@
+diff -urN grub-2.00/build-aux/config.sub grub-2.00.new/build-aux/config.sub
+--- grub-2.00/build-aux/config.sub 2012-06-18 23:08:46.000000000 +0200
++++ grub-2.00.new/build-aux/config.sub 2012-11-22 14:12:12.190748353 +0100
+@@ -126,7 +126,8 @@
+ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+- storm-chaos* | os2-emx* | rtmk-nova*)
++ storm-chaos* | os2-emx* | rtmk-nova* | \
++ linux-musl*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+@@ -1360,7 +1361,7 @@
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-android* \
+- | -linux-newlib* | -linux-uclibc* \
++ | -linux-newlib* | -linux-uclibc* | -linux-musl* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
diff --git a/package/boot/kexec-tools/.svn/entries b/package/boot/kexec-tools/.svn/entries
new file mode 100644
index 0000000..491df3a
--- /dev/null
+++ b/package/boot/kexec-tools/.svn/entries
@@ -0,0 +1,99 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/kexec-tools
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+patches
+dir
+
+Config.in
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+feb1f5431985cc3122a22da7a6949801
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+450
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+9cf805153359d6a9fd758b0ba696c92c
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1988
+
diff --git a/package/boot/kexec-tools/.svn/prop-base/Config.in.svn-base b/package/boot/kexec-tools/.svn/prop-base/Config.in.svn-base
new file mode 100644
index 0000000..3160658
--- /dev/null
+++ b/package/boot/kexec-tools/.svn/prop-base/Config.in.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/package/boot/kexec-tools/.svn/prop-base/Makefile.svn-base b/package/boot/kexec-tools/.svn/prop-base/Makefile.svn-base
new file mode 100644
index 0000000..8e522ae
--- /dev/null
+++ b/package/boot/kexec-tools/.svn/prop-base/Makefile.svn-base
@@ -0,0 +1,9 @@
+K 13
+svn:copyright
+V 30
+Copyright (C) 2006 OpenWrt.org
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/kexec-tools/.svn/text-base/Config.in.svn-base b/package/boot/kexec-tools/.svn/text-base/Config.in.svn-base
new file mode 100644
index 0000000..60c819d
--- /dev/null
+++ b/package/boot/kexec-tools/.svn/text-base/Config.in.svn-base
@@ -0,0 +1,21 @@
+menu "Configuration"
+ depends on PACKAGE_kexec-tools
+
+config KEXEC_TOOLS_TARGET_NAME
+ string
+ prompt "Target name for kexec kernel"
+ default EXTRA_TARGET_ARCH_NAME if powerpc64
+ default ARCH
+ help
+ Defines the target type of the kernels that kexec deals
+ with. This should be the target specification of
+ the kernel you're booting.
+
+config KEXEC_TOOLS_kdump
+ bool
+ prompt "kdump support"
+ default n
+ help
+ Include the kdump utility.
+
+endmenu
diff --git a/package/boot/kexec-tools/.svn/text-base/Makefile.svn-base b/package/boot/kexec-tools/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..fa4f4d8
--- /dev/null
+++ b/package/boot/kexec-tools/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,80 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=kexec-tools
+PKG_VERSION:=2.0.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@KERNEL/linux/utils/kernel/kexec
+PKG_MD5SUM:=b3ced2097ce3981abba38ceedc84f939
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/kexec-tools
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=@armeb||@arm||@i386||@powerpc64||@mipsel||@mips +zlib
+ TITLE:=Kernel boots kernel
+ URL:=http://kernel.org/pub/linux/kernel/people/horms/kexec-tools/
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+ MENU:=1
+endef
+
+define Package/kexec-tools/description
+ kexec is a set of systems call that allows you to load
+ another kernel from the currently executing Linux kernel.
+endef
+
+define Package/kexec-tools/config
+ source "$(SOURCE)/Config.in"
+endef
+
+KEXEC_TARGET_NAME:=$(call qstrip,$(CONFIG_KEXEC_TOOLS_TARGET_NAME))-linux-$(TARGET_SUFFIX)
+
+CONFIGURE_ARGS = \
+ --target=$(KEXEC_TARGET_NAME) \
+ --host=$(REAL_GNU_TARGET_NAME) \
+ --build=$(GNU_HOST_NAME) \
+ --program-prefix="" \
+ --program-suffix="" \
+ --prefix=/usr \
+ --exec-prefix=/usr \
+ --bindir=/usr/bin \
+ --sbindir=/usr/sbin \
+ --libexecdir=/usr/lib \
+ --sysconfdir=/etc
+
+CONFIGURE_VARS += \
+ BUILD_CC="$(HOSTCC)" \
+ TARGET_CC="$(TARGET_CC)"
+
+kexec-extra-sbin-$(CONFIG_KEXEC_TOOLS_kdump) += kdump
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) DESTDIR="$(PKG_INSTALL_DIR)" all install
+endef
+
+define Package/kexec-tools/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) \
+ $(addprefix $(PKG_INSTALL_DIR)/usr/sbin/, \
+ $(kexec-extra-sbin-y)) \
+ $(kexec-extra-bin-y) \
+ $(PKG_INSTALL_DIR)/usr/sbin/kexec \
+ $(1)/usr/sbin
+
+# make a link for compatability with other distros
+ $(INSTALL_DIR) $(1)/sbin
+ ln -s /usr/sbin/kexec $(1)/sbin/kexec
+endef
+
+$(eval $(call BuildPackage,kexec-tools))
diff --git a/package/boot/kexec-tools/Config.in b/package/boot/kexec-tools/Config.in
new file mode 100644
index 0000000..60c819d
--- /dev/null
+++ b/package/boot/kexec-tools/Config.in
@@ -0,0 +1,21 @@
+menu "Configuration"
+ depends on PACKAGE_kexec-tools
+
+config KEXEC_TOOLS_TARGET_NAME
+ string
+ prompt "Target name for kexec kernel"
+ default EXTRA_TARGET_ARCH_NAME if powerpc64
+ default ARCH
+ help
+ Defines the target type of the kernels that kexec deals
+ with. This should be the target specification of
+ the kernel you're booting.
+
+config KEXEC_TOOLS_kdump
+ bool
+ prompt "kdump support"
+ default n
+ help
+ Include the kdump utility.
+
+endmenu
diff --git a/package/boot/kexec-tools/Makefile b/package/boot/kexec-tools/Makefile
new file mode 100644
index 0000000..fa4f4d8
--- /dev/null
+++ b/package/boot/kexec-tools/Makefile
@@ -0,0 +1,80 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=kexec-tools
+PKG_VERSION:=2.0.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@KERNEL/linux/utils/kernel/kexec
+PKG_MD5SUM:=b3ced2097ce3981abba38ceedc84f939
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/kexec-tools
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=@armeb||@arm||@i386||@powerpc64||@mipsel||@mips +zlib
+ TITLE:=Kernel boots kernel
+ URL:=http://kernel.org/pub/linux/kernel/people/horms/kexec-tools/
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+ MENU:=1
+endef
+
+define Package/kexec-tools/description
+ kexec is a set of systems call that allows you to load
+ another kernel from the currently executing Linux kernel.
+endef
+
+define Package/kexec-tools/config
+ source "$(SOURCE)/Config.in"
+endef
+
+KEXEC_TARGET_NAME:=$(call qstrip,$(CONFIG_KEXEC_TOOLS_TARGET_NAME))-linux-$(TARGET_SUFFIX)
+
+CONFIGURE_ARGS = \
+ --target=$(KEXEC_TARGET_NAME) \
+ --host=$(REAL_GNU_TARGET_NAME) \
+ --build=$(GNU_HOST_NAME) \
+ --program-prefix="" \
+ --program-suffix="" \
+ --prefix=/usr \
+ --exec-prefix=/usr \
+ --bindir=/usr/bin \
+ --sbindir=/usr/sbin \
+ --libexecdir=/usr/lib \
+ --sysconfdir=/etc
+
+CONFIGURE_VARS += \
+ BUILD_CC="$(HOSTCC)" \
+ TARGET_CC="$(TARGET_CC)"
+
+kexec-extra-sbin-$(CONFIG_KEXEC_TOOLS_kdump) += kdump
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) DESTDIR="$(PKG_INSTALL_DIR)" all install
+endef
+
+define Package/kexec-tools/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) \
+ $(addprefix $(PKG_INSTALL_DIR)/usr/sbin/, \
+ $(kexec-extra-sbin-y)) \
+ $(kexec-extra-bin-y) \
+ $(PKG_INSTALL_DIR)/usr/sbin/kexec \
+ $(1)/usr/sbin
+
+# make a link for compatability with other distros
+ $(INSTALL_DIR) $(1)/sbin
+ ln -s /usr/sbin/kexec $(1)/sbin/kexec
+endef
+
+$(eval $(call BuildPackage,kexec-tools))
diff --git a/package/boot/kexec-tools/patches/.svn/entries b/package/boot/kexec-tools/patches/.svn/entries
new file mode 100644
index 0000000..a6d2354
--- /dev/null
+++ b/package/boot/kexec-tools/patches/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/kexec-tools/patches
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+0004-mips_regdefs.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+33113e08f846ec68e08370825d881eab
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2919
+
diff --git a/package/boot/kexec-tools/patches/.svn/text-base/0004-mips_regdefs.patch.svn-base b/package/boot/kexec-tools/patches/.svn/text-base/0004-mips_regdefs.patch.svn-base
new file mode 100644
index 0000000..7e21349
--- /dev/null
+++ b/package/boot/kexec-tools/patches/.svn/text-base/0004-mips_regdefs.patch.svn-base
@@ -0,0 +1,103 @@
+--- /dev/null
++++ b/kexec/arch/mips/regdef.h
+@@ -0,0 +1,100 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 1985 MIPS Computer Systems, Inc.
++ * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle
++ * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc.
++ */
++#ifndef _ASM_REGDEF_H
++#define _ASM_REGDEF_H
++
++#include <asm/sgidefs.h>
++
++#if _MIPS_SIM == _MIPS_SIM_ABI32
++
++/*
++ * Symbolic register names for 32 bit ABI
++ */
++#define zero $0 /* wired zero */
++#define AT $1 /* assembler temp - uppercase because of ".set at" */
++#define v0 $2 /* return value */
++#define v1 $3
++#define a0 $4 /* argument registers */
++#define a1 $5
++#define a2 $6
++#define a3 $7
++#define t0 $8 /* caller saved */
++#define t1 $9
++#define t2 $10
++#define t3 $11
++#define t4 $12
++#define t5 $13
++#define t6 $14
++#define t7 $15
++#define s0 $16 /* callee saved */
++#define s1 $17
++#define s2 $18
++#define s3 $19
++#define s4 $20
++#define s5 $21
++#define s6 $22
++#define s7 $23
++#define t8 $24 /* caller saved */
++#define t9 $25
++#define jp $25 /* PIC jump register */
++#define k0 $26 /* kernel scratch */
++#define k1 $27
++#define gp $28 /* global pointer */
++#define sp $29 /* stack pointer */
++#define fp $30 /* frame pointer */
++#define s8 $30 /* same like fp! */
++#define ra $31 /* return address */
++
++#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
++
++#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
++
++#define zero $0 /* wired zero */
++#define AT $at /* assembler temp - uppercase because of ".set at" */
++#define v0 $2 /* return value - caller saved */
++#define v1 $3
++#define a0 $4 /* argument registers */
++#define a1 $5
++#define a2 $6
++#define a3 $7
++#define a4 $8 /* arg reg 64 bit; caller saved in 32 bit */
++#define ta0 $8
++#define a5 $9
++#define ta1 $9
++#define a6 $10
++#define ta2 $10
++#define a7 $11
++#define ta3 $11
++#define t0 $12 /* caller saved */
++#define t1 $13
++#define t2 $14
++#define t3 $15
++#define s0 $16 /* callee saved */
++#define s1 $17
++#define s2 $18
++#define s3 $19
++#define s4 $20
++#define s5 $21
++#define s6 $22
++#define s7 $23
++#define t8 $24 /* caller saved */
++#define t9 $25 /* callee address for PIC/temp */
++#define jp $25 /* PIC jump register */
++#define k0 $26 /* kernel temporary */
++#define k1 $27
++#define gp $28 /* global pointer - caller saved for PIC */
++#define sp $29 /* stack pointer */
++#define fp $30 /* frame pointer */
++#define s8 $30 /* callee saved */
++#define ra $31 /* return address */
++
++#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
++
++#endif /* _ASM_REGDEF_H */
diff --git a/package/boot/kexec-tools/patches/0004-mips_regdefs.patch b/package/boot/kexec-tools/patches/0004-mips_regdefs.patch
new file mode 100644
index 0000000..7e21349
--- /dev/null
+++ b/package/boot/kexec-tools/patches/0004-mips_regdefs.patch
@@ -0,0 +1,103 @@
+--- /dev/null
++++ b/kexec/arch/mips/regdef.h
+@@ -0,0 +1,100 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 1985 MIPS Computer Systems, Inc.
++ * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle
++ * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc.
++ */
++#ifndef _ASM_REGDEF_H
++#define _ASM_REGDEF_H
++
++#include <asm/sgidefs.h>
++
++#if _MIPS_SIM == _MIPS_SIM_ABI32
++
++/*
++ * Symbolic register names for 32 bit ABI
++ */
++#define zero $0 /* wired zero */
++#define AT $1 /* assembler temp - uppercase because of ".set at" */
++#define v0 $2 /* return value */
++#define v1 $3
++#define a0 $4 /* argument registers */
++#define a1 $5
++#define a2 $6
++#define a3 $7
++#define t0 $8 /* caller saved */
++#define t1 $9
++#define t2 $10
++#define t3 $11
++#define t4 $12
++#define t5 $13
++#define t6 $14
++#define t7 $15
++#define s0 $16 /* callee saved */
++#define s1 $17
++#define s2 $18
++#define s3 $19
++#define s4 $20
++#define s5 $21
++#define s6 $22
++#define s7 $23
++#define t8 $24 /* caller saved */
++#define t9 $25
++#define jp $25 /* PIC jump register */
++#define k0 $26 /* kernel scratch */
++#define k1 $27
++#define gp $28 /* global pointer */
++#define sp $29 /* stack pointer */
++#define fp $30 /* frame pointer */
++#define s8 $30 /* same like fp! */
++#define ra $31 /* return address */
++
++#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
++
++#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
++
++#define zero $0 /* wired zero */
++#define AT $at /* assembler temp - uppercase because of ".set at" */
++#define v0 $2 /* return value - caller saved */
++#define v1 $3
++#define a0 $4 /* argument registers */
++#define a1 $5
++#define a2 $6
++#define a3 $7
++#define a4 $8 /* arg reg 64 bit; caller saved in 32 bit */
++#define ta0 $8
++#define a5 $9
++#define ta1 $9
++#define a6 $10
++#define ta2 $10
++#define a7 $11
++#define ta3 $11
++#define t0 $12 /* caller saved */
++#define t1 $13
++#define t2 $14
++#define t3 $15
++#define s0 $16 /* callee saved */
++#define s1 $17
++#define s2 $18
++#define s3 $19
++#define s4 $20
++#define s5 $21
++#define s6 $22
++#define s7 $23
++#define t8 $24 /* caller saved */
++#define t9 $25 /* callee address for PIC/temp */
++#define jp $25 /* PIC jump register */
++#define k0 $26 /* kernel temporary */
++#define k1 $27
++#define gp $28 /* global pointer - caller saved for PIC */
++#define sp $29 /* stack pointer */
++#define fp $30 /* frame pointer */
++#define s8 $30 /* callee saved */
++#define ra $31 /* return address */
++
++#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
++
++#endif /* _ASM_REGDEF_H */
diff --git a/package/boot/rbcfg/.svn/entries b/package/boot/rbcfg/.svn/entries
new file mode 100644
index 0000000..a16907b
--- /dev/null
+++ b/package/boot/rbcfg/.svn/entries
@@ -0,0 +1,65 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/rbcfg
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-17T21:53:23.143554Z
+33824
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+src
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+54ebd1734c602f5d5c63ed6b37cd830c
+2012-10-17T21:53:23.143554Z
+33824
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1009
+
diff --git a/package/boot/rbcfg/.svn/prop-base/Makefile.svn-base b/package/boot/rbcfg/.svn/prop-base/Makefile.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/rbcfg/.svn/prop-base/Makefile.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/rbcfg/.svn/text-base/Makefile.svn-base b/package/boot/rbcfg/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..51fefd5
--- /dev/null
+++ b/package/boot/rbcfg/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=rbcfg
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/rbcfg
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=RouterBOOT configuration tool
+ DEPENDS:=@TARGET_ar71xx
+endef
+
+define Package/rbcfg/description
+ This package contains an utility to manipulate RouterBOOT configuration on the
+ MikroTIK RB-4XX devices.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -Wall" \
+ LDFLAGS="$(TARGET_LDFLAGS)"
+endef
+
+define Package/rbcfg/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/rbcfg $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,rbcfg))
diff --git a/package/boot/rbcfg/Makefile b/package/boot/rbcfg/Makefile
new file mode 100644
index 0000000..51fefd5
--- /dev/null
+++ b/package/boot/rbcfg/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=rbcfg
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/rbcfg
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=RouterBOOT configuration tool
+ DEPENDS:=@TARGET_ar71xx
+endef
+
+define Package/rbcfg/description
+ This package contains an utility to manipulate RouterBOOT configuration on the
+ MikroTIK RB-4XX devices.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -Wall" \
+ LDFLAGS="$(TARGET_LDFLAGS)"
+endef
+
+define Package/rbcfg/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/rbcfg $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,rbcfg))
diff --git a/package/boot/rbcfg/src/.svn/entries b/package/boot/rbcfg/src/.svn/entries
new file mode 100644
index 0000000..2f111cd
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/entries
@@ -0,0 +1,198 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/rbcfg/src
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-17T21:53:23.143554Z
+33824
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+cyg_crc.h
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+ba9d1cf06e7d26d19e67fff283506d18
+2012-10-17T21:53:23.143554Z
+33824
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3372
+
+cyg_crc32.c
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+2005e143bb82ddc198ca4e919a800aee
+2012-10-17T21:53:23.143554Z
+33824
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7963
+
+main.c
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+7acc0c5073dc83633e151d35618baa2f
+2012-10-17T21:53:23.143554Z
+33824
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+15073
+
+rbcfg.h
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+c2945a0eae01cc2749251ab0e3c959b2
+2012-10-17T21:53:23.143554Z
+33824
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1759
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+0496a56c341577ddcd18f510c963447f
+2012-10-17T21:53:23.143554Z
+33824
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+163
+
diff --git a/package/boot/rbcfg/src/.svn/prop-base/Makefile.svn-base b/package/boot/rbcfg/src/.svn/prop-base/Makefile.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/prop-base/Makefile.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/rbcfg/src/.svn/prop-base/cyg_crc.h.svn-base b/package/boot/rbcfg/src/.svn/prop-base/cyg_crc.h.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/prop-base/cyg_crc.h.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/rbcfg/src/.svn/prop-base/cyg_crc32.c.svn-base b/package/boot/rbcfg/src/.svn/prop-base/cyg_crc32.c.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/prop-base/cyg_crc32.c.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/rbcfg/src/.svn/prop-base/main.c.svn-base b/package/boot/rbcfg/src/.svn/prop-base/main.c.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/prop-base/main.c.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/rbcfg/src/.svn/prop-base/rbcfg.h.svn-base b/package/boot/rbcfg/src/.svn/prop-base/rbcfg.h.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/prop-base/rbcfg.h.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/rbcfg/src/.svn/text-base/Makefile.svn-base b/package/boot/rbcfg/src/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..62c74b2
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,14 @@
+CC = gcc
+CFLAGS = -Wall
+OBJS = main.o cyg_crc32.o
+
+all: rbcfg
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+rbcfg: $(OBJS)
+ $(CC) -o $@ $(OBJS)
+
+clean:
+ rm -f rbcfg *.o
diff --git a/package/boot/rbcfg/src/.svn/text-base/cyg_crc.h.svn-base b/package/boot/rbcfg/src/.svn/text-base/cyg_crc.h.svn-base
new file mode 100644
index 0000000..7b59803
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/text-base/cyg_crc.h.svn-base
@@ -0,0 +1,109 @@
+//==========================================================================
+//
+// crc.h
+//
+// Interface for the CRC algorithms.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2002 Andrew Lunn
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Andrew Lunn
+// Contributors: Andrew Lunn
+// Date: 2002-08-06
+// Purpose:
+// Description:
+//
+// This code is part of eCos (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef _SERVICES_CRC_CRC_H_
+#define _SERVICES_CRC_CRC_H_
+
+#if 0
+#include <cyg/infra/cyg_type.h>
+#else
+#include <stdint.h>
+typedef uint32_t cyg_uint32;
+typedef uint16_t cyg_uint16;
+#endif
+
+#ifndef __externC
+# ifdef __cplusplus
+# define __externC extern "C"
+# else
+# define __externC extern
+# endif
+#endif
+
+// Compute a CRC, using the POSIX 1003 definition
+
+__externC cyg_uint32
+cyg_posix_crc32(unsigned char *s, int len);
+
+// Gary S. Brown's 32 bit CRC
+
+__externC cyg_uint32
+cyg_crc32(unsigned char *s, int len);
+
+// Gary S. Brown's 32 bit CRC, but accumulate the result from a
+// previous CRC calculation
+
+__externC cyg_uint32
+cyg_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len);
+
+// Ethernet FCS Algorithm
+
+__externC cyg_uint32
+cyg_ether_crc32(unsigned char *s, int len);
+
+// Ethernet FCS algorithm, but accumulate the result from a previous
+// CRC calculation.
+
+__externC cyg_uint32
+cyg_ether_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len);
+
+// 16 bit CRC with polynomial x^16+x^12+x^5+1
+
+__externC cyg_uint16
+cyg_crc16(unsigned char *s, int len);
+
+#endif // _SERVICES_CRC_CRC_H_
+
+
+
diff --git a/package/boot/rbcfg/src/.svn/text-base/cyg_crc32.c.svn-base b/package/boot/rbcfg/src/.svn/text-base/cyg_crc32.c.svn-base
new file mode 100644
index 0000000..9462598
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/text-base/cyg_crc32.c.svn-base
@@ -0,0 +1,172 @@
+//==========================================================================
+//
+// crc32.c
+//
+// Gary S. Brown's 32 bit CRC
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas,asl
+// Date: 2001-01-31
+// Purpose:
+// Description:
+//
+// This code is part of eCos (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#if 0
+#include <cyg/crc/crc.h>
+#else
+#include "cyg_crc.h"
+#endif
+
+ /* ====================================================================== */
+ /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */
+ /* code or tables extracted from it, as desired without restriction. */
+ /* */
+ /* First, the polynomial itself and its table of feedback terms. The */
+ /* polynomial is */
+ /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+ /* */
+ /* ====================================================================== */
+
+static const cyg_uint32 crc32_tab[] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+ };
+
+/* This is the standard Gary S. Brown's 32 bit CRC algorithm, but
+ accumulate the CRC into the result of a previous CRC. */
+cyg_uint32
+cyg_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
+ }
+ return crc32val;
+}
+
+/* This is the standard Gary S. Brown's 32 bit CRC algorithm */
+cyg_uint32
+cyg_crc32(unsigned char *s, int len)
+{
+ return (cyg_crc32_accumulate(0,s,len));
+}
+
+/* Return a 32-bit CRC of the contents of the buffer accumulating the
+ result from a previous CRC calculation. This uses the Ethernet FCS
+ algorithm.*/
+cyg_uint32
+cyg_ether_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len)
+{
+ int i;
+
+ if (s == 0) return 0L;
+
+ crc32val = crc32val ^ 0xffffffff;
+ for (i = 0; i < len; i++) {
+ crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
+ }
+ return crc32val ^ 0xffffffff;
+}
+
+/* Return a 32-bit CRC of the contents of the buffer, using the
+ Ethernet FCS algorithm. */
+cyg_uint32
+cyg_ether_crc32(unsigned char *s, int len)
+{
+ return cyg_ether_crc32_accumulate(0,s,len);
+}
+
+
diff --git a/package/boot/rbcfg/src/.svn/text-base/main.c.svn-base b/package/boot/rbcfg/src/.svn/text-base/main.c.svn-base
new file mode 100644
index 0000000..5614a6c
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/text-base/main.c.svn-base
@@ -0,0 +1,791 @@
+/*
+ * RouterBOOT configuration utility
+ *
+ * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <linux/limits.h>
+
+#include "rbcfg.h"
+#include "cyg_crc.h"
+
+#define RBCFG_TMP_FILE "/tmp/.rbcfg"
+#define RBCFG_MTD_NAME "soft_config"
+
+#define RB_ERR_NOTFOUND 1
+#define RB_ERR_INVALID 2
+#define RB_ERR_NOMEM 3
+#define RB_ERR_IO 4
+
+#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0]))
+
+struct rbcfg_ctx {
+ char *mtd_device;
+ char *tmp_file;
+ char *buf;
+ unsigned buflen;
+};
+
+struct rbcfg_value {
+ const char *name;
+ const char *desc;
+ union {
+ uint32_t u32;
+ const char *raw;
+ } val;
+};
+
+#define RBCFG_ENV_TYPE_U32 0
+
+struct rbcfg_env {
+ const char *name;
+ int type;
+ uint16_t id;
+ const struct rbcfg_value *values;
+ int num_values;
+};
+
+#define CMD_FLAG_USES_CFG 0x01
+
+struct rbcfg_command {
+ const char *command;
+ const char *usage;
+ int flags;
+ int (*exec)(int argc, const char *argv[]);
+};
+
+static void usage(void);
+
+/* Globals */
+
+static struct rbcfg_ctx *rbcfg_ctx;
+static char *rbcfg_name;
+
+#define CFG_U32(_name, _desc, _val) { \
+ .name = (_name), \
+ .desc = (_desc), \
+ .val.u32 = (_val), \
+}
+
+static const struct rbcfg_value rbcfg_boot_delay[] = {
+ CFG_U32("1", "1 second", RB_BOOT_DELAY_1SEC),
+ CFG_U32("2", "2 seconds", RB_BOOT_DELAY_2SEC),
+ CFG_U32("3", "3 seconds", RB_BOOT_DELAY_3SEC),
+ CFG_U32("4", "4 seconds", RB_BOOT_DELAY_4SEC),
+ CFG_U32("5", "5 seconds", RB_BOOT_DELAY_5SEC),
+ CFG_U32("6", "6 seconds", RB_BOOT_DELAY_6SEC),
+ CFG_U32("7", "7 seconds", RB_BOOT_DELAY_7SEC),
+ CFG_U32("8", "8 seconds", RB_BOOT_DELAY_8SEC),
+ CFG_U32("9", "9 seconds", RB_BOOT_DELAY_9SEC),
+};
+
+static const struct rbcfg_value rbcfg_boot_device[] = {
+ CFG_U32("eth", "boot over Ethernet",
+ RB_BOOT_DEVICE_ETHER),
+ CFG_U32("nandeth", "boot from NAND, if fail then Ethernet",
+ RB_BOOT_DEVICE_NANDETH),
+ CFG_U32("ethnand", "boot Ethernet once, then NAND",
+ RB_BOOT_DEVICE_ETHONCE),
+ CFG_U32("nand", "boot from NAND only",
+ RB_BOOT_DEVICE_NANDONLY),
+};
+
+static const struct rbcfg_value rbcfg_boot_key[] = {
+ CFG_U32("any", "any key", RB_BOOT_KEY_ANY),
+ CFG_U32("del", "<Delete> key only", RB_BOOT_KEY_DEL),
+};
+
+static const struct rbcfg_value rbcfg_boot_protocol[] = {
+ CFG_U32("bootp", "BOOTP protocol", RB_BOOT_PROTOCOL_BOOTP),
+ CFG_U32("dhcp", "DHCP protocol", RB_BOOT_PROTOCOL_DHCP),
+};
+
+static const struct rbcfg_value rbcfg_uart_speed[] = {
+ CFG_U32("115200", "", RB_UART_SPEED_115200),
+ CFG_U32("57600", "", RB_UART_SPEED_57600),
+ CFG_U32("38400", "", RB_UART_SPEED_38400),
+ CFG_U32("19200", "", RB_UART_SPEED_19200),
+ CFG_U32("9600", "", RB_UART_SPEED_9600),
+ CFG_U32("4800", "", RB_UART_SPEED_4800),
+ CFG_U32("2400", "", RB_UART_SPEED_2400),
+ CFG_U32("1200", "", RB_UART_SPEED_1200),
+ CFG_U32("off", "disable console output", RB_UART_SPEED_OFF),
+};
+
+static const struct rbcfg_value rbcfg_cpu_mode[] = {
+ CFG_U32("powersave", "power save", RB_CPU_MODE_POWERSAVE),
+ CFG_U32("regular", "regular (better for -0c environment)",
+ RB_CPU_MODE_REGULAR),
+};
+
+static const struct rbcfg_value rbcfg_booter[] = {
+ CFG_U32("regular", "load regular booter", RB_BOOTER_REGULAR),
+ CFG_U32("backup", "force backup-booter loading", RB_BOOTER_BACKUP),
+};
+
+static const struct rbcfg_env rbcfg_envs[] = {
+ {
+ .name = "boot_delay",
+ .id = RB_ID_BOOT_DELAY,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_boot_delay,
+ .num_values = ARRAY_SIZE(rbcfg_boot_delay),
+ }, {
+ .name = "boot_device",
+ .id = RB_ID_BOOT_DEVICE,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_boot_device,
+ .num_values = ARRAY_SIZE(rbcfg_boot_device),
+ }, {
+ .name = "boot_key",
+ .id = RB_ID_BOOT_KEY,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_boot_key,
+ .num_values = ARRAY_SIZE(rbcfg_boot_key),
+ }, {
+ .name = "boot_protocol",
+ .id = RB_ID_BOOT_PROTOCOL,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_boot_protocol,
+ .num_values = ARRAY_SIZE(rbcfg_boot_protocol),
+ }, {
+ .name = "booter",
+ .id = RB_ID_BOOTER,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_booter,
+ .num_values = ARRAY_SIZE(rbcfg_booter),
+ }, {
+ .name = "cpu_mode",
+ .id = RB_ID_CPU_MODE,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_cpu_mode,
+ .num_values = ARRAY_SIZE(rbcfg_cpu_mode),
+ }, {
+ .name = "uart_speed",
+ .id = RB_ID_UART_SPEED,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_uart_speed,
+ .num_values = ARRAY_SIZE(rbcfg_uart_speed),
+ }
+};
+
+static inline uint16_t
+get_u16(const void *buf)
+{
+ const uint8_t *p = buf;
+
+ return ((uint16_t) p[1] + ((uint16_t) p[0] << 8));
+}
+
+static inline uint32_t
+get_u32(const void *buf)
+{
+ const uint8_t *p = buf;
+
+ return ((uint32_t) p[3] + ((uint32_t) p[2] << 8) +
+ ((uint32_t) p[1] << 16) + ((uint32_t) p[0] << 24));
+}
+
+static inline void
+put_u32(void *buf, uint32_t val)
+{
+ uint8_t *p = buf;
+
+ p[3] = val & 0xff;
+ p[2] = (val >> 8) & 0xff;
+ p[1] = (val >> 16) & 0xff;
+ p[0] = (val >> 24) & 0xff;
+}
+
+static int
+rbcfg_find_tag(struct rbcfg_ctx *ctx, uint16_t tag_id, uint16_t *tag_len,
+ void **tag_data)
+{
+ uint16_t id;
+ uint16_t len;
+ char *buf = ctx->buf;
+ unsigned int buflen = ctx->buflen;
+ int ret = RB_ERR_NOTFOUND;
+
+ /* skip magic and CRC value */
+ buf += 8;
+ buflen -= 8;
+
+ while (buflen > 2) {
+ len = get_u16(buf);
+ buf += 2;
+ buflen -= 2;
+
+ if (buflen < 2)
+ break;
+
+ id = get_u16(buf);
+ buf += 2;
+ buflen -= 2;
+
+ if (id == RB_ID_TERMINATOR)
+ break;
+
+ if (buflen < len)
+ break;
+
+ if (id == tag_id) {
+ *tag_len = len;
+ *tag_data = buf;
+ ret = 0;
+ break;
+ }
+
+ buf += len;
+ buflen -= len;
+ }
+
+ if (ret)
+ fprintf(stderr, "no tag found with id=%u\n", tag_id);
+
+ return ret;
+}
+
+static int
+rbcfg_get_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t *val)
+{
+ void *tag_data;
+ uint16_t tag_len;
+ int err;
+
+ err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data);
+ if (err)
+ return err;
+
+ *val = get_u32(tag_data);
+ return 0;
+}
+
+static int
+rbcfg_set_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t val)
+{
+ void *tag_data;
+ uint16_t tag_len;
+ int err;
+
+ err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data);
+ if (err)
+ return err;
+
+ put_u32(tag_data, val);
+ return 0;
+}
+
+char *rbcfg_find_mtd(const char *name, int *erase_size)
+{
+ FILE *f;
+ int mtd_num;
+ char dev[PATH_MAX];
+ char *ret = NULL;
+ struct stat s;
+ int err;
+
+ f = fopen("/proc/mtd", "r");
+ if (!f)
+ return NULL;
+
+ while (1) {
+ char *p;
+ p = fgets(dev, sizeof(dev), f);
+ if (!p)
+ break;
+
+ if (!strstr(dev, name))
+ continue;
+
+ err = sscanf(dev, "mtd%d: %08x", &mtd_num, erase_size);
+ if (err != 2)
+ break;
+
+ sprintf(dev, "/dev/mtdblock%d", mtd_num);
+ err = stat(dev, &s);
+ if (err < 0)
+ break;
+
+ if ((s.st_mode & S_IFBLK) == 0)
+ break;
+
+ ret = malloc(strlen(dev) + 1);
+ if (ret == NULL)
+ break;
+
+ strncpy(ret, dev, strlen(dev) + 1);
+ break;
+ }
+
+ fclose(f);
+ return ret;
+}
+
+static int
+rbcfg_check_tmp(struct rbcfg_ctx *ctx)
+{
+ struct stat s;
+ int err;
+
+ err = stat(ctx->tmp_file, &s);
+ if (err < 0)
+ return 0;
+
+ if ((s.st_mode & S_IFREG) == 0)
+ return 0;
+
+ if (s.st_size != ctx->buflen)
+ return 0;
+
+ return 1;
+}
+
+static int
+rbcfg_load(struct rbcfg_ctx *ctx)
+{
+ uint32_t magic;
+ uint32_t crc_orig, crc;
+ char *name;
+ int tmp;
+ int fd;
+ int err;
+
+ tmp = rbcfg_check_tmp(ctx);
+ name = (tmp) ? ctx->tmp_file : ctx->mtd_device;
+
+ fd = open(name, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "unable to open %s\n", name);
+ err = RB_ERR_IO;
+ goto err;
+ }
+
+ err = read(fd, ctx->buf, ctx->buflen);
+ if (err != ctx->buflen) {
+ fprintf(stderr, "unable to read from %s\n", name);
+ err = RB_ERR_IO;
+ goto err_close;
+ }
+
+ magic = get_u32(ctx->buf);
+ if (magic != RB_MAGIC_SOFT) {
+ fprintf(stderr, "invalid configuration\n");
+ err = RB_ERR_INVALID;
+ goto err_close;
+ }
+
+ crc_orig = get_u32(ctx->buf + 4);
+ put_u32(ctx->buf + 4, 0);
+ crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen);
+ if (crc != crc_orig) {
+ fprintf(stderr, "configuration has CRC error\n");
+ err = RB_ERR_INVALID;
+ goto err_close;
+ }
+
+ err = 0;
+
+ err_close:
+ close(fd);
+ err:
+ return err;
+}
+
+static int
+rbcfg_open()
+{
+ char *mtd_device;
+ struct rbcfg_ctx *ctx;
+ int buflen;
+ int err;
+
+ mtd_device = rbcfg_find_mtd(RBCFG_MTD_NAME, &buflen);
+ if (!mtd_device) {
+ fprintf(stderr, "unable to find configuration\n");
+ return RB_ERR_NOTFOUND;
+ }
+
+ ctx = malloc(sizeof(struct rbcfg_ctx) + buflen);
+ if (ctx == NULL) {
+ err = RB_ERR_NOMEM;
+ goto err_free_mtd;
+ }
+
+ ctx->mtd_device = mtd_device;
+ ctx->tmp_file = RBCFG_TMP_FILE;
+ ctx->buflen = buflen;
+ ctx->buf = (char *) &ctx[1];
+
+ err = rbcfg_load(ctx);
+ if (err)
+ goto err_free_ctx;
+
+ rbcfg_ctx = ctx;
+ return 0;
+
+ err_free_ctx:
+ free(ctx);
+ err_free_mtd:
+ free(mtd_device);
+ return err;
+}
+
+static int
+rbcfg_update(int tmp)
+{
+ struct rbcfg_ctx *ctx = rbcfg_ctx;
+ char *name;
+ uint32_t crc;
+ int fd;
+ int err;
+
+ put_u32(ctx->buf, RB_MAGIC_SOFT);
+ put_u32(ctx->buf + 4, 0);
+ crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen);
+ put_u32(ctx->buf + 4, crc);
+
+ name = (tmp) ? ctx->tmp_file : ctx->mtd_device;
+ fd = open(name, O_WRONLY | O_CREAT);
+ if (fd < 0) {
+ fprintf(stderr, "unable to open %s for writing\n", name);
+ err = RB_ERR_IO;
+ goto out;
+ }
+
+ err = write(fd, ctx->buf, ctx->buflen);
+ if (err != ctx->buflen) {
+ err = RB_ERR_IO;
+ goto out_close;
+ }
+
+ fsync(fd);
+ err = 0;
+
+ out_close:
+ close(fd);
+ out:
+ return err;
+}
+
+static void
+rbcfg_close(void)
+{
+ struct rbcfg_ctx *ctx;
+
+ ctx = rbcfg_ctx;
+ free(ctx->mtd_device);
+ free(ctx);
+}
+
+static const struct rbcfg_value *
+rbcfg_env_find(const struct rbcfg_env *env, const char *name)
+{
+ unsigned i;
+
+ for (i = 0; i < env->num_values; i++) {
+ const struct rbcfg_value *v = &env->values[i];
+
+ if (strcmp(v->name, name) == 0)
+ return v;
+ }
+
+ return NULL;
+}
+
+static const struct rbcfg_value *
+rbcfg_env_find_u32(const struct rbcfg_env *env, uint32_t val)
+{
+ unsigned i;
+
+ for (i = 0; i < env->num_values; i++) {
+ const struct rbcfg_value *v = &env->values[i];
+
+ if (v->val.u32 == val)
+ return v;
+ }
+
+ return NULL;
+}
+
+static const char *
+rbcfg_env_get_u32(const struct rbcfg_env *env)
+{
+ const struct rbcfg_value *v;
+ uint32_t val;
+ int err;
+
+ err = rbcfg_get_u32(rbcfg_ctx, env->id, &val);
+ if (err)
+ return NULL;
+
+ v = rbcfg_env_find_u32(env, val);
+ if (v == NULL) {
+ fprintf(stderr, "unknown value %08x found for %s\n",
+ val, env->name);
+ return NULL;
+ }
+
+ return v->name;
+}
+
+static int
+rbcfg_env_set_u32(const struct rbcfg_env *env, const char *data)
+{
+ const struct rbcfg_value *v;
+ int err;
+
+ v = rbcfg_env_find(env, data);
+ if (v == NULL) {
+ fprintf(stderr, "invalid value '%s'\n", data);
+ return RB_ERR_INVALID;
+ }
+
+ err = rbcfg_set_u32(rbcfg_ctx, env->id, v->val.u32);
+ return err;
+}
+
+static const char *
+rbcfg_env_get(const struct rbcfg_env *env)
+{
+ const char *ret = NULL;
+
+ switch (env->type) {
+ case RBCFG_ENV_TYPE_U32:
+ ret = rbcfg_env_get_u32(env);
+ break;
+ }
+
+ return ret;
+}
+
+static int
+rbcfg_env_set(const struct rbcfg_env *env, const char *data)
+{
+ int ret = 0;
+
+ switch (env->type) {
+ case RBCFG_ENV_TYPE_U32:
+ ret = rbcfg_env_set_u32(env, data);
+ break;
+ }
+
+ return ret;
+}
+
+static int
+rbcfg_cmd_apply(int argc, const char *argv[])
+{
+ return rbcfg_update(0);
+}
+
+static int
+rbcfg_cmd_help(int argc, const char *argv[])
+{
+ usage();
+ return 0;
+}
+
+static int
+rbcfg_cmd_get(int argc, const char *argv[])
+{
+ int err = RB_ERR_NOTFOUND;
+ int i;
+
+ if (argc != 1) {
+ usage();
+ return RB_ERR_INVALID;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
+ const struct rbcfg_env *env = &rbcfg_envs[i];
+ const char *value;
+
+ if (strcmp(env->name, argv[0]))
+ continue;
+
+ value = rbcfg_env_get(env);
+ if (value) {
+ fprintf(stdout, "%s\n", value);
+ err = 0;
+ }
+ break;
+ }
+
+ return err;
+}
+
+static int
+rbcfg_cmd_set(int argc, const char *argv[])
+{
+ int err = RB_ERR_INVALID;
+ int i;
+
+ if (argc != 2) {
+ /* not enough parameters */
+ usage();
+ return RB_ERR_INVALID;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
+ const struct rbcfg_env *env = &rbcfg_envs[i];
+
+ if (strcmp(env->name, argv[0]))
+ continue;
+
+ err = rbcfg_env_set(env, argv[1]);
+ if (err == 0)
+ err = rbcfg_update(1);
+ break;
+ }
+
+ return err;
+}
+
+static int
+rbcfg_cmd_show(int argc, const char *argv[])
+{
+ int i;
+
+ if (argc != 0) {
+ usage();
+ return RB_ERR_INVALID;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
+ const struct rbcfg_env *env = &rbcfg_envs[i];
+ const char *value;
+
+ value = rbcfg_env_get(env);
+ if (value)
+ fprintf(stdout, "%s=%s\n", env->name, value);
+ }
+
+ return 0;
+}
+
+static const struct rbcfg_command rbcfg_commands[] = {
+ {
+ .command = "apply",
+ .usage = "apply\n"
+ "\t- write configuration to the mtd device",
+ .flags = CMD_FLAG_USES_CFG,
+ .exec = rbcfg_cmd_apply,
+ }, {
+ .command = "help",
+ .usage = "help\n"
+ "\t- show this screen",
+ .exec = rbcfg_cmd_help,
+ }, {
+ .command = "get",
+ .usage = "get <name>\n"
+ "\t- get value of the configuration option <name>",
+ .flags = CMD_FLAG_USES_CFG,
+ .exec = rbcfg_cmd_get,
+ }, {
+ .command = "set",
+ .usage = "set <name> <value>\n"
+ "\t- set value of the configuration option <name> to <value>",
+ .flags = CMD_FLAG_USES_CFG,
+ .exec = rbcfg_cmd_set,
+ }, {
+ .command = "show",
+ .usage = "show\n"
+ "\t- show value of all configuration options",
+ .flags = CMD_FLAG_USES_CFG,
+ .exec = rbcfg_cmd_show,
+ }
+};
+
+static void
+usage(void)
+{
+ char buf[255];
+ int len;
+ int i;
+
+ fprintf(stderr, "Usage: %s <command>\n", rbcfg_name);
+
+ fprintf(stderr, "\nCommands:\n");
+ for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) {
+ const struct rbcfg_command *cmd;
+ cmd = &rbcfg_commands[i];
+
+ len = snprintf(buf, sizeof(buf), cmd->usage);
+ buf[len] = '\0';
+ fprintf(stderr, "%s\n", buf);
+ }
+
+ fprintf(stderr, "\nConfiguration options:\n");
+ for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
+ const struct rbcfg_env *env;
+ int j;
+
+ env = &rbcfg_envs[i];
+ fprintf(stderr, "\n%s:\n", env->name);
+ for (j = 0; j < env->num_values; j++) {
+ const struct rbcfg_value *v = &env->values[j];
+ fprintf(stderr, "\t%-12s %s\n", v->name, v->desc);
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+int main(int argc, const char *argv[])
+{
+ const struct rbcfg_command *cmd = NULL;
+ int ret;
+ int i;
+
+ rbcfg_name = (char *) argv[0];
+
+ if (argc < 2) {
+ usage();
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) {
+ if (strcmp(rbcfg_commands[i].command, argv[1]) == 0) {
+ cmd = &rbcfg_commands[i];
+ break;
+ }
+ }
+
+ if (cmd == NULL) {
+ fprintf(stderr, "unknown command '%s'\n", argv[1]);
+ usage();
+ return EXIT_FAILURE;
+ }
+
+ argc -= 2;
+ argv += 2;
+
+ if (cmd->flags & CMD_FLAG_USES_CFG) {
+ ret = rbcfg_open();
+ if (ret)
+ return EXIT_FAILURE;
+ }
+
+ ret = cmd->exec(argc, argv);
+
+ if (cmd->flags & CMD_FLAG_USES_CFG)
+ rbcfg_close();
+
+ if (ret)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
diff --git a/package/boot/rbcfg/src/.svn/text-base/rbcfg.h.svn-base b/package/boot/rbcfg/src/.svn/text-base/rbcfg.h.svn-base
new file mode 100644
index 0000000..899161a
--- /dev/null
+++ b/package/boot/rbcfg/src/.svn/text-base/rbcfg.h.svn-base
@@ -0,0 +1,75 @@
+/*
+ * Mikrotik's RouterBOOT configuration defines
+ *
+ * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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 _RBCFG_H
+#define _RBCFG_H
+
+/*
+ * Magic numbers
+ */
+#define RB_MAGIC_SOFT 0x74666f53 /* 'Soft' */
+
+/*
+ * ID values for Software settings
+ */
+#define RB_ID_TERMINATOR 0
+#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
+#define RB_ID_BOOTER 13
+
+#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
+#define RB_UART_SPEED_OFF 8
+
+#define RB_BOOT_DELAY_1SEC 1
+#define RB_BOOT_DELAY_2SEC 2
+#define RB_BOOT_DELAY_3SEC 3
+#define RB_BOOT_DELAY_4SEC 4
+#define RB_BOOT_DELAY_5SEC 5
+#define RB_BOOT_DELAY_6SEC 6
+#define RB_BOOT_DELAY_7SEC 7
+#define RB_BOOT_DELAY_8SEC 8
+#define RB_BOOT_DELAY_9SEC 9
+
+#define RB_BOOT_DEVICE_ETHER 0
+#define RB_BOOT_DEVICE_NANDETH 1
+#define RB_BOOT_DEVICE_CFCARD 2
+#define RB_BOOT_DEVICE_ETHONCE 3
+#define RB_BOOT_DEVICE_NANDONLY 5
+
+#define RB_BOOT_KEY_ANY 0
+#define RB_BOOT_KEY_DEL 1
+
+#define RB_CPU_MODE_POWERSAVE 0
+#define RB_CPU_MODE_REGULAR 1
+
+#define RB_BOOT_PROTOCOL_BOOTP 0
+#define RB_BOOT_PROTOCOL_DHCP 1
+
+#define RB_BOOTER_REGULAR 0
+#define RB_BOOTER_BACKUP 1
+
+#endif /* _RBCFG_H */
diff --git a/package/boot/rbcfg/src/Makefile b/package/boot/rbcfg/src/Makefile
new file mode 100644
index 0000000..62c74b2
--- /dev/null
+++ b/package/boot/rbcfg/src/Makefile
@@ -0,0 +1,14 @@
+CC = gcc
+CFLAGS = -Wall
+OBJS = main.o cyg_crc32.o
+
+all: rbcfg
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+rbcfg: $(OBJS)
+ $(CC) -o $@ $(OBJS)
+
+clean:
+ rm -f rbcfg *.o
diff --git a/package/boot/rbcfg/src/cyg_crc.h b/package/boot/rbcfg/src/cyg_crc.h
new file mode 100644
index 0000000..7b59803
--- /dev/null
+++ b/package/boot/rbcfg/src/cyg_crc.h
@@ -0,0 +1,109 @@
+//==========================================================================
+//
+// crc.h
+//
+// Interface for the CRC algorithms.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2002 Andrew Lunn
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Andrew Lunn
+// Contributors: Andrew Lunn
+// Date: 2002-08-06
+// Purpose:
+// Description:
+//
+// This code is part of eCos (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef _SERVICES_CRC_CRC_H_
+#define _SERVICES_CRC_CRC_H_
+
+#if 0
+#include <cyg/infra/cyg_type.h>
+#else
+#include <stdint.h>
+typedef uint32_t cyg_uint32;
+typedef uint16_t cyg_uint16;
+#endif
+
+#ifndef __externC
+# ifdef __cplusplus
+# define __externC extern "C"
+# else
+# define __externC extern
+# endif
+#endif
+
+// Compute a CRC, using the POSIX 1003 definition
+
+__externC cyg_uint32
+cyg_posix_crc32(unsigned char *s, int len);
+
+// Gary S. Brown's 32 bit CRC
+
+__externC cyg_uint32
+cyg_crc32(unsigned char *s, int len);
+
+// Gary S. Brown's 32 bit CRC, but accumulate the result from a
+// previous CRC calculation
+
+__externC cyg_uint32
+cyg_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len);
+
+// Ethernet FCS Algorithm
+
+__externC cyg_uint32
+cyg_ether_crc32(unsigned char *s, int len);
+
+// Ethernet FCS algorithm, but accumulate the result from a previous
+// CRC calculation.
+
+__externC cyg_uint32
+cyg_ether_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len);
+
+// 16 bit CRC with polynomial x^16+x^12+x^5+1
+
+__externC cyg_uint16
+cyg_crc16(unsigned char *s, int len);
+
+#endif // _SERVICES_CRC_CRC_H_
+
+
+
diff --git a/package/boot/rbcfg/src/cyg_crc32.c b/package/boot/rbcfg/src/cyg_crc32.c
new file mode 100644
index 0000000..9462598
--- /dev/null
+++ b/package/boot/rbcfg/src/cyg_crc32.c
@@ -0,0 +1,172 @@
+//==========================================================================
+//
+// crc32.c
+//
+// Gary S. Brown's 32 bit CRC
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+//
+// eCos 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 or (at your option) any later version.
+//
+// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas,asl
+// Date: 2001-01-31
+// Purpose:
+// Description:
+//
+// This code is part of eCos (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#if 0
+#include <cyg/crc/crc.h>
+#else
+#include "cyg_crc.h"
+#endif
+
+ /* ====================================================================== */
+ /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */
+ /* code or tables extracted from it, as desired without restriction. */
+ /* */
+ /* First, the polynomial itself and its table of feedback terms. The */
+ /* polynomial is */
+ /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+ /* */
+ /* ====================================================================== */
+
+static const cyg_uint32 crc32_tab[] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+ };
+
+/* This is the standard Gary S. Brown's 32 bit CRC algorithm, but
+ accumulate the CRC into the result of a previous CRC. */
+cyg_uint32
+cyg_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
+ }
+ return crc32val;
+}
+
+/* This is the standard Gary S. Brown's 32 bit CRC algorithm */
+cyg_uint32
+cyg_crc32(unsigned char *s, int len)
+{
+ return (cyg_crc32_accumulate(0,s,len));
+}
+
+/* Return a 32-bit CRC of the contents of the buffer accumulating the
+ result from a previous CRC calculation. This uses the Ethernet FCS
+ algorithm.*/
+cyg_uint32
+cyg_ether_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len)
+{
+ int i;
+
+ if (s == 0) return 0L;
+
+ crc32val = crc32val ^ 0xffffffff;
+ for (i = 0; i < len; i++) {
+ crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
+ }
+ return crc32val ^ 0xffffffff;
+}
+
+/* Return a 32-bit CRC of the contents of the buffer, using the
+ Ethernet FCS algorithm. */
+cyg_uint32
+cyg_ether_crc32(unsigned char *s, int len)
+{
+ return cyg_ether_crc32_accumulate(0,s,len);
+}
+
+
diff --git a/package/boot/rbcfg/src/main.c b/package/boot/rbcfg/src/main.c
new file mode 100644
index 0000000..5614a6c
--- /dev/null
+++ b/package/boot/rbcfg/src/main.c
@@ -0,0 +1,791 @@
+/*
+ * RouterBOOT configuration utility
+ *
+ * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <linux/limits.h>
+
+#include "rbcfg.h"
+#include "cyg_crc.h"
+
+#define RBCFG_TMP_FILE "/tmp/.rbcfg"
+#define RBCFG_MTD_NAME "soft_config"
+
+#define RB_ERR_NOTFOUND 1
+#define RB_ERR_INVALID 2
+#define RB_ERR_NOMEM 3
+#define RB_ERR_IO 4
+
+#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0]))
+
+struct rbcfg_ctx {
+ char *mtd_device;
+ char *tmp_file;
+ char *buf;
+ unsigned buflen;
+};
+
+struct rbcfg_value {
+ const char *name;
+ const char *desc;
+ union {
+ uint32_t u32;
+ const char *raw;
+ } val;
+};
+
+#define RBCFG_ENV_TYPE_U32 0
+
+struct rbcfg_env {
+ const char *name;
+ int type;
+ uint16_t id;
+ const struct rbcfg_value *values;
+ int num_values;
+};
+
+#define CMD_FLAG_USES_CFG 0x01
+
+struct rbcfg_command {
+ const char *command;
+ const char *usage;
+ int flags;
+ int (*exec)(int argc, const char *argv[]);
+};
+
+static void usage(void);
+
+/* Globals */
+
+static struct rbcfg_ctx *rbcfg_ctx;
+static char *rbcfg_name;
+
+#define CFG_U32(_name, _desc, _val) { \
+ .name = (_name), \
+ .desc = (_desc), \
+ .val.u32 = (_val), \
+}
+
+static const struct rbcfg_value rbcfg_boot_delay[] = {
+ CFG_U32("1", "1 second", RB_BOOT_DELAY_1SEC),
+ CFG_U32("2", "2 seconds", RB_BOOT_DELAY_2SEC),
+ CFG_U32("3", "3 seconds", RB_BOOT_DELAY_3SEC),
+ CFG_U32("4", "4 seconds", RB_BOOT_DELAY_4SEC),
+ CFG_U32("5", "5 seconds", RB_BOOT_DELAY_5SEC),
+ CFG_U32("6", "6 seconds", RB_BOOT_DELAY_6SEC),
+ CFG_U32("7", "7 seconds", RB_BOOT_DELAY_7SEC),
+ CFG_U32("8", "8 seconds", RB_BOOT_DELAY_8SEC),
+ CFG_U32("9", "9 seconds", RB_BOOT_DELAY_9SEC),
+};
+
+static const struct rbcfg_value rbcfg_boot_device[] = {
+ CFG_U32("eth", "boot over Ethernet",
+ RB_BOOT_DEVICE_ETHER),
+ CFG_U32("nandeth", "boot from NAND, if fail then Ethernet",
+ RB_BOOT_DEVICE_NANDETH),
+ CFG_U32("ethnand", "boot Ethernet once, then NAND",
+ RB_BOOT_DEVICE_ETHONCE),
+ CFG_U32("nand", "boot from NAND only",
+ RB_BOOT_DEVICE_NANDONLY),
+};
+
+static const struct rbcfg_value rbcfg_boot_key[] = {
+ CFG_U32("any", "any key", RB_BOOT_KEY_ANY),
+ CFG_U32("del", "<Delete> key only", RB_BOOT_KEY_DEL),
+};
+
+static const struct rbcfg_value rbcfg_boot_protocol[] = {
+ CFG_U32("bootp", "BOOTP protocol", RB_BOOT_PROTOCOL_BOOTP),
+ CFG_U32("dhcp", "DHCP protocol", RB_BOOT_PROTOCOL_DHCP),
+};
+
+static const struct rbcfg_value rbcfg_uart_speed[] = {
+ CFG_U32("115200", "", RB_UART_SPEED_115200),
+ CFG_U32("57600", "", RB_UART_SPEED_57600),
+ CFG_U32("38400", "", RB_UART_SPEED_38400),
+ CFG_U32("19200", "", RB_UART_SPEED_19200),
+ CFG_U32("9600", "", RB_UART_SPEED_9600),
+ CFG_U32("4800", "", RB_UART_SPEED_4800),
+ CFG_U32("2400", "", RB_UART_SPEED_2400),
+ CFG_U32("1200", "", RB_UART_SPEED_1200),
+ CFG_U32("off", "disable console output", RB_UART_SPEED_OFF),
+};
+
+static const struct rbcfg_value rbcfg_cpu_mode[] = {
+ CFG_U32("powersave", "power save", RB_CPU_MODE_POWERSAVE),
+ CFG_U32("regular", "regular (better for -0c environment)",
+ RB_CPU_MODE_REGULAR),
+};
+
+static const struct rbcfg_value rbcfg_booter[] = {
+ CFG_U32("regular", "load regular booter", RB_BOOTER_REGULAR),
+ CFG_U32("backup", "force backup-booter loading", RB_BOOTER_BACKUP),
+};
+
+static const struct rbcfg_env rbcfg_envs[] = {
+ {
+ .name = "boot_delay",
+ .id = RB_ID_BOOT_DELAY,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_boot_delay,
+ .num_values = ARRAY_SIZE(rbcfg_boot_delay),
+ }, {
+ .name = "boot_device",
+ .id = RB_ID_BOOT_DEVICE,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_boot_device,
+ .num_values = ARRAY_SIZE(rbcfg_boot_device),
+ }, {
+ .name = "boot_key",
+ .id = RB_ID_BOOT_KEY,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_boot_key,
+ .num_values = ARRAY_SIZE(rbcfg_boot_key),
+ }, {
+ .name = "boot_protocol",
+ .id = RB_ID_BOOT_PROTOCOL,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_boot_protocol,
+ .num_values = ARRAY_SIZE(rbcfg_boot_protocol),
+ }, {
+ .name = "booter",
+ .id = RB_ID_BOOTER,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_booter,
+ .num_values = ARRAY_SIZE(rbcfg_booter),
+ }, {
+ .name = "cpu_mode",
+ .id = RB_ID_CPU_MODE,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_cpu_mode,
+ .num_values = ARRAY_SIZE(rbcfg_cpu_mode),
+ }, {
+ .name = "uart_speed",
+ .id = RB_ID_UART_SPEED,
+ .type = RBCFG_ENV_TYPE_U32,
+ .values = rbcfg_uart_speed,
+ .num_values = ARRAY_SIZE(rbcfg_uart_speed),
+ }
+};
+
+static inline uint16_t
+get_u16(const void *buf)
+{
+ const uint8_t *p = buf;
+
+ return ((uint16_t) p[1] + ((uint16_t) p[0] << 8));
+}
+
+static inline uint32_t
+get_u32(const void *buf)
+{
+ const uint8_t *p = buf;
+
+ return ((uint32_t) p[3] + ((uint32_t) p[2] << 8) +
+ ((uint32_t) p[1] << 16) + ((uint32_t) p[0] << 24));
+}
+
+static inline void
+put_u32(void *buf, uint32_t val)
+{
+ uint8_t *p = buf;
+
+ p[3] = val & 0xff;
+ p[2] = (val >> 8) & 0xff;
+ p[1] = (val >> 16) & 0xff;
+ p[0] = (val >> 24) & 0xff;
+}
+
+static int
+rbcfg_find_tag(struct rbcfg_ctx *ctx, uint16_t tag_id, uint16_t *tag_len,
+ void **tag_data)
+{
+ uint16_t id;
+ uint16_t len;
+ char *buf = ctx->buf;
+ unsigned int buflen = ctx->buflen;
+ int ret = RB_ERR_NOTFOUND;
+
+ /* skip magic and CRC value */
+ buf += 8;
+ buflen -= 8;
+
+ while (buflen > 2) {
+ len = get_u16(buf);
+ buf += 2;
+ buflen -= 2;
+
+ if (buflen < 2)
+ break;
+
+ id = get_u16(buf);
+ buf += 2;
+ buflen -= 2;
+
+ if (id == RB_ID_TERMINATOR)
+ break;
+
+ if (buflen < len)
+ break;
+
+ if (id == tag_id) {
+ *tag_len = len;
+ *tag_data = buf;
+ ret = 0;
+ break;
+ }
+
+ buf += len;
+ buflen -= len;
+ }
+
+ if (ret)
+ fprintf(stderr, "no tag found with id=%u\n", tag_id);
+
+ return ret;
+}
+
+static int
+rbcfg_get_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t *val)
+{
+ void *tag_data;
+ uint16_t tag_len;
+ int err;
+
+ err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data);
+ if (err)
+ return err;
+
+ *val = get_u32(tag_data);
+ return 0;
+}
+
+static int
+rbcfg_set_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t val)
+{
+ void *tag_data;
+ uint16_t tag_len;
+ int err;
+
+ err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data);
+ if (err)
+ return err;
+
+ put_u32(tag_data, val);
+ return 0;
+}
+
+char *rbcfg_find_mtd(const char *name, int *erase_size)
+{
+ FILE *f;
+ int mtd_num;
+ char dev[PATH_MAX];
+ char *ret = NULL;
+ struct stat s;
+ int err;
+
+ f = fopen("/proc/mtd", "r");
+ if (!f)
+ return NULL;
+
+ while (1) {
+ char *p;
+ p = fgets(dev, sizeof(dev), f);
+ if (!p)
+ break;
+
+ if (!strstr(dev, name))
+ continue;
+
+ err = sscanf(dev, "mtd%d: %08x", &mtd_num, erase_size);
+ if (err != 2)
+ break;
+
+ sprintf(dev, "/dev/mtdblock%d", mtd_num);
+ err = stat(dev, &s);
+ if (err < 0)
+ break;
+
+ if ((s.st_mode & S_IFBLK) == 0)
+ break;
+
+ ret = malloc(strlen(dev) + 1);
+ if (ret == NULL)
+ break;
+
+ strncpy(ret, dev, strlen(dev) + 1);
+ break;
+ }
+
+ fclose(f);
+ return ret;
+}
+
+static int
+rbcfg_check_tmp(struct rbcfg_ctx *ctx)
+{
+ struct stat s;
+ int err;
+
+ err = stat(ctx->tmp_file, &s);
+ if (err < 0)
+ return 0;
+
+ if ((s.st_mode & S_IFREG) == 0)
+ return 0;
+
+ if (s.st_size != ctx->buflen)
+ return 0;
+
+ return 1;
+}
+
+static int
+rbcfg_load(struct rbcfg_ctx *ctx)
+{
+ uint32_t magic;
+ uint32_t crc_orig, crc;
+ char *name;
+ int tmp;
+ int fd;
+ int err;
+
+ tmp = rbcfg_check_tmp(ctx);
+ name = (tmp) ? ctx->tmp_file : ctx->mtd_device;
+
+ fd = open(name, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "unable to open %s\n", name);
+ err = RB_ERR_IO;
+ goto err;
+ }
+
+ err = read(fd, ctx->buf, ctx->buflen);
+ if (err != ctx->buflen) {
+ fprintf(stderr, "unable to read from %s\n", name);
+ err = RB_ERR_IO;
+ goto err_close;
+ }
+
+ magic = get_u32(ctx->buf);
+ if (magic != RB_MAGIC_SOFT) {
+ fprintf(stderr, "invalid configuration\n");
+ err = RB_ERR_INVALID;
+ goto err_close;
+ }
+
+ crc_orig = get_u32(ctx->buf + 4);
+ put_u32(ctx->buf + 4, 0);
+ crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen);
+ if (crc != crc_orig) {
+ fprintf(stderr, "configuration has CRC error\n");
+ err = RB_ERR_INVALID;
+ goto err_close;
+ }
+
+ err = 0;
+
+ err_close:
+ close(fd);
+ err:
+ return err;
+}
+
+static int
+rbcfg_open()
+{
+ char *mtd_device;
+ struct rbcfg_ctx *ctx;
+ int buflen;
+ int err;
+
+ mtd_device = rbcfg_find_mtd(RBCFG_MTD_NAME, &buflen);
+ if (!mtd_device) {
+ fprintf(stderr, "unable to find configuration\n");
+ return RB_ERR_NOTFOUND;
+ }
+
+ ctx = malloc(sizeof(struct rbcfg_ctx) + buflen);
+ if (ctx == NULL) {
+ err = RB_ERR_NOMEM;
+ goto err_free_mtd;
+ }
+
+ ctx->mtd_device = mtd_device;
+ ctx->tmp_file = RBCFG_TMP_FILE;
+ ctx->buflen = buflen;
+ ctx->buf = (char *) &ctx[1];
+
+ err = rbcfg_load(ctx);
+ if (err)
+ goto err_free_ctx;
+
+ rbcfg_ctx = ctx;
+ return 0;
+
+ err_free_ctx:
+ free(ctx);
+ err_free_mtd:
+ free(mtd_device);
+ return err;
+}
+
+static int
+rbcfg_update(int tmp)
+{
+ struct rbcfg_ctx *ctx = rbcfg_ctx;
+ char *name;
+ uint32_t crc;
+ int fd;
+ int err;
+
+ put_u32(ctx->buf, RB_MAGIC_SOFT);
+ put_u32(ctx->buf + 4, 0);
+ crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen);
+ put_u32(ctx->buf + 4, crc);
+
+ name = (tmp) ? ctx->tmp_file : ctx->mtd_device;
+ fd = open(name, O_WRONLY | O_CREAT);
+ if (fd < 0) {
+ fprintf(stderr, "unable to open %s for writing\n", name);
+ err = RB_ERR_IO;
+ goto out;
+ }
+
+ err = write(fd, ctx->buf, ctx->buflen);
+ if (err != ctx->buflen) {
+ err = RB_ERR_IO;
+ goto out_close;
+ }
+
+ fsync(fd);
+ err = 0;
+
+ out_close:
+ close(fd);
+ out:
+ return err;
+}
+
+static void
+rbcfg_close(void)
+{
+ struct rbcfg_ctx *ctx;
+
+ ctx = rbcfg_ctx;
+ free(ctx->mtd_device);
+ free(ctx);
+}
+
+static const struct rbcfg_value *
+rbcfg_env_find(const struct rbcfg_env *env, const char *name)
+{
+ unsigned i;
+
+ for (i = 0; i < env->num_values; i++) {
+ const struct rbcfg_value *v = &env->values[i];
+
+ if (strcmp(v->name, name) == 0)
+ return v;
+ }
+
+ return NULL;
+}
+
+static const struct rbcfg_value *
+rbcfg_env_find_u32(const struct rbcfg_env *env, uint32_t val)
+{
+ unsigned i;
+
+ for (i = 0; i < env->num_values; i++) {
+ const struct rbcfg_value *v = &env->values[i];
+
+ if (v->val.u32 == val)
+ return v;
+ }
+
+ return NULL;
+}
+
+static const char *
+rbcfg_env_get_u32(const struct rbcfg_env *env)
+{
+ const struct rbcfg_value *v;
+ uint32_t val;
+ int err;
+
+ err = rbcfg_get_u32(rbcfg_ctx, env->id, &val);
+ if (err)
+ return NULL;
+
+ v = rbcfg_env_find_u32(env, val);
+ if (v == NULL) {
+ fprintf(stderr, "unknown value %08x found for %s\n",
+ val, env->name);
+ return NULL;
+ }
+
+ return v->name;
+}
+
+static int
+rbcfg_env_set_u32(const struct rbcfg_env *env, const char *data)
+{
+ const struct rbcfg_value *v;
+ int err;
+
+ v = rbcfg_env_find(env, data);
+ if (v == NULL) {
+ fprintf(stderr, "invalid value '%s'\n", data);
+ return RB_ERR_INVALID;
+ }
+
+ err = rbcfg_set_u32(rbcfg_ctx, env->id, v->val.u32);
+ return err;
+}
+
+static const char *
+rbcfg_env_get(const struct rbcfg_env *env)
+{
+ const char *ret = NULL;
+
+ switch (env->type) {
+ case RBCFG_ENV_TYPE_U32:
+ ret = rbcfg_env_get_u32(env);
+ break;
+ }
+
+ return ret;
+}
+
+static int
+rbcfg_env_set(const struct rbcfg_env *env, const char *data)
+{
+ int ret = 0;
+
+ switch (env->type) {
+ case RBCFG_ENV_TYPE_U32:
+ ret = rbcfg_env_set_u32(env, data);
+ break;
+ }
+
+ return ret;
+}
+
+static int
+rbcfg_cmd_apply(int argc, const char *argv[])
+{
+ return rbcfg_update(0);
+}
+
+static int
+rbcfg_cmd_help(int argc, const char *argv[])
+{
+ usage();
+ return 0;
+}
+
+static int
+rbcfg_cmd_get(int argc, const char *argv[])
+{
+ int err = RB_ERR_NOTFOUND;
+ int i;
+
+ if (argc != 1) {
+ usage();
+ return RB_ERR_INVALID;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
+ const struct rbcfg_env *env = &rbcfg_envs[i];
+ const char *value;
+
+ if (strcmp(env->name, argv[0]))
+ continue;
+
+ value = rbcfg_env_get(env);
+ if (value) {
+ fprintf(stdout, "%s\n", value);
+ err = 0;
+ }
+ break;
+ }
+
+ return err;
+}
+
+static int
+rbcfg_cmd_set(int argc, const char *argv[])
+{
+ int err = RB_ERR_INVALID;
+ int i;
+
+ if (argc != 2) {
+ /* not enough parameters */
+ usage();
+ return RB_ERR_INVALID;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
+ const struct rbcfg_env *env = &rbcfg_envs[i];
+
+ if (strcmp(env->name, argv[0]))
+ continue;
+
+ err = rbcfg_env_set(env, argv[1]);
+ if (err == 0)
+ err = rbcfg_update(1);
+ break;
+ }
+
+ return err;
+}
+
+static int
+rbcfg_cmd_show(int argc, const char *argv[])
+{
+ int i;
+
+ if (argc != 0) {
+ usage();
+ return RB_ERR_INVALID;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
+ const struct rbcfg_env *env = &rbcfg_envs[i];
+ const char *value;
+
+ value = rbcfg_env_get(env);
+ if (value)
+ fprintf(stdout, "%s=%s\n", env->name, value);
+ }
+
+ return 0;
+}
+
+static const struct rbcfg_command rbcfg_commands[] = {
+ {
+ .command = "apply",
+ .usage = "apply\n"
+ "\t- write configuration to the mtd device",
+ .flags = CMD_FLAG_USES_CFG,
+ .exec = rbcfg_cmd_apply,
+ }, {
+ .command = "help",
+ .usage = "help\n"
+ "\t- show this screen",
+ .exec = rbcfg_cmd_help,
+ }, {
+ .command = "get",
+ .usage = "get <name>\n"
+ "\t- get value of the configuration option <name>",
+ .flags = CMD_FLAG_USES_CFG,
+ .exec = rbcfg_cmd_get,
+ }, {
+ .command = "set",
+ .usage = "set <name> <value>\n"
+ "\t- set value of the configuration option <name> to <value>",
+ .flags = CMD_FLAG_USES_CFG,
+ .exec = rbcfg_cmd_set,
+ }, {
+ .command = "show",
+ .usage = "show\n"
+ "\t- show value of all configuration options",
+ .flags = CMD_FLAG_USES_CFG,
+ .exec = rbcfg_cmd_show,
+ }
+};
+
+static void
+usage(void)
+{
+ char buf[255];
+ int len;
+ int i;
+
+ fprintf(stderr, "Usage: %s <command>\n", rbcfg_name);
+
+ fprintf(stderr, "\nCommands:\n");
+ for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) {
+ const struct rbcfg_command *cmd;
+ cmd = &rbcfg_commands[i];
+
+ len = snprintf(buf, sizeof(buf), cmd->usage);
+ buf[len] = '\0';
+ fprintf(stderr, "%s\n", buf);
+ }
+
+ fprintf(stderr, "\nConfiguration options:\n");
+ for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
+ const struct rbcfg_env *env;
+ int j;
+
+ env = &rbcfg_envs[i];
+ fprintf(stderr, "\n%s:\n", env->name);
+ for (j = 0; j < env->num_values; j++) {
+ const struct rbcfg_value *v = &env->values[j];
+ fprintf(stderr, "\t%-12s %s\n", v->name, v->desc);
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+int main(int argc, const char *argv[])
+{
+ const struct rbcfg_command *cmd = NULL;
+ int ret;
+ int i;
+
+ rbcfg_name = (char *) argv[0];
+
+ if (argc < 2) {
+ usage();
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) {
+ if (strcmp(rbcfg_commands[i].command, argv[1]) == 0) {
+ cmd = &rbcfg_commands[i];
+ break;
+ }
+ }
+
+ if (cmd == NULL) {
+ fprintf(stderr, "unknown command '%s'\n", argv[1]);
+ usage();
+ return EXIT_FAILURE;
+ }
+
+ argc -= 2;
+ argv += 2;
+
+ if (cmd->flags & CMD_FLAG_USES_CFG) {
+ ret = rbcfg_open();
+ if (ret)
+ return EXIT_FAILURE;
+ }
+
+ ret = cmd->exec(argc, argv);
+
+ if (cmd->flags & CMD_FLAG_USES_CFG)
+ rbcfg_close();
+
+ if (ret)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
diff --git a/package/boot/rbcfg/src/rbcfg.h b/package/boot/rbcfg/src/rbcfg.h
new file mode 100644
index 0000000..899161a
--- /dev/null
+++ b/package/boot/rbcfg/src/rbcfg.h
@@ -0,0 +1,75 @@
+/*
+ * Mikrotik's RouterBOOT configuration defines
+ *
+ * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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 _RBCFG_H
+#define _RBCFG_H
+
+/*
+ * Magic numbers
+ */
+#define RB_MAGIC_SOFT 0x74666f53 /* 'Soft' */
+
+/*
+ * ID values for Software settings
+ */
+#define RB_ID_TERMINATOR 0
+#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
+#define RB_ID_BOOTER 13
+
+#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
+#define RB_UART_SPEED_OFF 8
+
+#define RB_BOOT_DELAY_1SEC 1
+#define RB_BOOT_DELAY_2SEC 2
+#define RB_BOOT_DELAY_3SEC 3
+#define RB_BOOT_DELAY_4SEC 4
+#define RB_BOOT_DELAY_5SEC 5
+#define RB_BOOT_DELAY_6SEC 6
+#define RB_BOOT_DELAY_7SEC 7
+#define RB_BOOT_DELAY_8SEC 8
+#define RB_BOOT_DELAY_9SEC 9
+
+#define RB_BOOT_DEVICE_ETHER 0
+#define RB_BOOT_DEVICE_NANDETH 1
+#define RB_BOOT_DEVICE_CFCARD 2
+#define RB_BOOT_DEVICE_ETHONCE 3
+#define RB_BOOT_DEVICE_NANDONLY 5
+
+#define RB_BOOT_KEY_ANY 0
+#define RB_BOOT_KEY_DEL 1
+
+#define RB_CPU_MODE_POWERSAVE 0
+#define RB_CPU_MODE_REGULAR 1
+
+#define RB_BOOT_PROTOCOL_BOOTP 0
+#define RB_BOOT_PROTOCOL_DHCP 1
+
+#define RB_BOOTER_REGULAR 0
+#define RB_BOOTER_BACKUP 1
+
+#endif /* _RBCFG_H */
diff --git a/package/boot/uboot-ar71xx/.svn/entries b/package/boot/uboot-ar71xx/.svn/entries
new file mode 100644
index 0000000..c22743c
--- /dev/null
+++ b/package/boot/uboot-ar71xx/.svn/entries
@@ -0,0 +1,68 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+files
+dir
+
+patches
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+0bd109b1804aa08c7b5d06154eec7560
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2105
+
diff --git a/package/boot/uboot-ar71xx/.svn/prop-base/Makefile.svn-base b/package/boot/uboot-ar71xx/.svn/prop-base/Makefile.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/.svn/prop-base/Makefile.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/.svn/text-base/Makefile.svn-base b/package/boot/uboot-ar71xx/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..ab692d5
--- /dev/null
+++ b/package/boot/uboot-ar71xx/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2010.03
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/nbg460n_550n_550nh
+ TITLE:=U-boot for the NBG460N/550N/550NH routers
+endef
+
+UBOOTS:=nbg460n_550n_550nh
+
+define Package/uboot/template
+define Package/uboot-ar71xx-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ TITLE:=$(2)
+ DEPENDS:=@TARGET_ar71xx
+ URL:=http://www.denx.de/wiki/U-Boot
+ DEFAULT:=y if (TARGET_ar71xx_generic_NBG_460N_550N_550NH || TARGET_ar71xx_generic_Default || CONFIG_TARGET_ar71xx_generic_Minimal)
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUbootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Prepare
+ $(call Build/Prepare/Default)
+ $(CP) ./files/* $(PKG_BUILD_DIR)
+ find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf
+endef
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/template
+define Package/uboot-ar71xx-$(1)/install
+ $(INSTALL_DIR) $$(1)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.bin $(BIN_DIR)/$(2)
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(SUBTARGET)-$(u)-u-boot.bin)) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUbootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-ar71xx-$(u))) \
+)
diff --git a/package/boot/uboot-ar71xx/Makefile b/package/boot/uboot-ar71xx/Makefile
new file mode 100644
index 0000000..ab692d5
--- /dev/null
+++ b/package/boot/uboot-ar71xx/Makefile
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2010.03
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/nbg460n_550n_550nh
+ TITLE:=U-boot for the NBG460N/550N/550NH routers
+endef
+
+UBOOTS:=nbg460n_550n_550nh
+
+define Package/uboot/template
+define Package/uboot-ar71xx-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ TITLE:=$(2)
+ DEPENDS:=@TARGET_ar71xx
+ URL:=http://www.denx.de/wiki/U-Boot
+ DEFAULT:=y if (TARGET_ar71xx_generic_NBG_460N_550N_550NH || TARGET_ar71xx_generic_Default || CONFIG_TARGET_ar71xx_generic_Minimal)
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUbootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Prepare
+ $(call Build/Prepare/Default)
+ $(CP) ./files/* $(PKG_BUILD_DIR)
+ find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf
+endef
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/template
+define Package/uboot-ar71xx-$(1)/install
+ $(INSTALL_DIR) $$(1)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.bin $(BIN_DIR)/$(2)
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(SUBTARGET)-$(u)-u-boot.bin)) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUbootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-ar71xx-$(u))) \
+)
diff --git a/package/boot/uboot-ar71xx/files/.svn/entries b/package/boot/uboot-ar71xx/files/.svn/entries
new file mode 100644
index 0000000..11e092f
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/.svn/entries
@@ -0,0 +1,40 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+include
+dir
+
+board
+dir
+
+cpu
+dir
+
+drivers
+dir
+
diff --git a/package/boot/uboot-ar71xx/files/board/.svn/entries b/package/boot/uboot-ar71xx/files/board/.svn/entries
new file mode 100644
index 0000000..fe48131
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/board
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+zyxel
+dir
+
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/.svn/entries b/package/boot/uboot-ar71xx/files/board/zyxel/.svn/entries
new file mode 100644
index 0000000..2067997
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/board/zyxel
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+nbg460n
+dir
+
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/entries b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/entries
new file mode 100644
index 0000000..2cd7eba
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/entries
@@ -0,0 +1,198 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+nbg460n.c
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+4ca6c195407e477c7ce5e894b0047bd7
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2519
+
+u-boot.lds
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+189327e68f6732474873394c31ecb392
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+644
+
+config.mk
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+e0a9c9382bb06ca19e6e6277bd6cb25e
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+23
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+adb668f790f345afd4d82777c8bd28e0
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1403
+
+lowlevel_init.S
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+6bcc57bddec47e9957d0b00bd2755913
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1089
+
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/Makefile.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/Makefile.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/Makefile.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/config.mk.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/config.mk.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/config.mk.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/nbg460n.c.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/nbg460n.c.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/nbg460n.c.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/Makefile.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..b0a385b
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2003-2008
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS-y += $(BOARD).o
+SOBJS-y += lowlevel_init.o
+
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS-y))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/config.mk.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/config.mk.svn-base
new file mode 100644
index 0000000..e042e78
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/config.mk.svn-base
@@ -0,0 +1 @@
+TEXT_BASE = 0x81E00000
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/lowlevel_init.S.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/lowlevel_init.S.svn-base
new file mode 100644
index 0000000..83084c8
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/lowlevel_init.S.svn-base
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+
+
+
+.globl lowlevel_init
+/*
+ All done by Bootbase, nothing to do
+*/
+lowlevel_init:
+ jr ra
+ nop
+
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/nbg460n.c.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/nbg460n.c.svn-base
new file mode 100644
index 0000000..03a479d
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/nbg460n.c.svn-base
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/reboot.h>
+#include <asm/ar71xx.h>
+#include <asm/ar71xx_gpio.h>
+
+#define NBG460N_WAN_LED 19
+
+phys_size_t initdram(int board_type)
+{
+ return (32*1024*1024);
+}
+
+int checkboard(void)
+{
+ // Set pin 19 to 1, to stop WAN LED blinking
+ ar71xx_setpindir(NBG460N_WAN_LED, 1);
+ ar71xx_setpin(NBG460N_WAN_LED, 1);
+
+ printf("U-boot on Zyxel NBG460N\n");
+ return 0;
+}
+
+void _machine_restart(void)
+{
+ for (;;) {
+ writel((RESET_MODULE_FULL_CHIP | RESET_MODULE_DDR),
+ KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE));
+ readl(KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE));
+ }
+}
+
+int board_eth_init(bd_t *bis)
+{
+ char *phynames[] = {RTL8366_DEVNAME, RTL8366_DEVNAME};
+ u16 phyids[] = {RTL8366_LANPHY_ID, RTL8366_WANPHY_ID};
+ u16 phyfixed[] = {1, 0};
+
+ if (ag71xx_register(bis, phynames, phyids, phyfixed) <= 0)
+ return -1;
+
+ if (rtl8366s_initialize())
+ return -1;
+
+ if (rtl8366_mii_register(bis))
+ return -1;
+
+ return 0;
+}
+
+int misc_init_r(void) {
+ uint8_t macaddr[6];
+ uint8_t enetaddr[6];
+
+ debug("Testing mac addresses\n");
+
+ memcpy(macaddr, (uint8_t *) CONFIG_ETHADDR_ADDR, 6);
+
+ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
+ debug("Setting eth0 mac addr to %pM\n", macaddr);
+ eth_setenv_enetaddr("ethaddr", macaddr);
+ }
+
+ if (!eth_getenv_enetaddr("eth1addr", enetaddr)) {
+ macaddr[5] += 1;
+ debug("Setting eth1 mac addr to %pM\n", macaddr);
+ eth_setenv_enetaddr("eth1addr", macaddr);
+ }
+
+ return 0;
+}
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/u-boot.lds.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/u-boot.lds.svn-base
new file mode 100644
index 0000000..8dc2b76
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/u-boot.lds.svn-base
@@ -0,0 +1,42 @@
+OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips")
+OUTPUT_ARCH(mips)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .sdata : { *(.sdata) }
+
+ _gp = ALIGN(16);
+
+ __got_start = .;
+ .got : { *(.got) }
+ __got_end = .;
+
+ .sdata : { *(.sdata) }
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ uboot_end_data = .;
+ num_got_entries = (__got_end - __got_start) >> 2;
+
+ . = ALIGN(4);
+ .sbss : { *(.sbss) }
+ .bss : { *(.bss) }
+ uboot_end = .;
+}
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile
new file mode 100644
index 0000000..b0a385b
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2003-2008
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS-y += $(BOARD).o
+SOBJS-y += lowlevel_init.o
+
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS-y))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk
new file mode 100644
index 0000000..e042e78
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk
@@ -0,0 +1 @@
+TEXT_BASE = 0x81E00000
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S
new file mode 100644
index 0000000..83084c8
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <version.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+
+
+
+.globl lowlevel_init
+/*
+ All done by Bootbase, nothing to do
+*/
+lowlevel_init:
+ jr ra
+ nop
+
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c
new file mode 100644
index 0000000..03a479d
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/reboot.h>
+#include <asm/ar71xx.h>
+#include <asm/ar71xx_gpio.h>
+
+#define NBG460N_WAN_LED 19
+
+phys_size_t initdram(int board_type)
+{
+ return (32*1024*1024);
+}
+
+int checkboard(void)
+{
+ // Set pin 19 to 1, to stop WAN LED blinking
+ ar71xx_setpindir(NBG460N_WAN_LED, 1);
+ ar71xx_setpin(NBG460N_WAN_LED, 1);
+
+ printf("U-boot on Zyxel NBG460N\n");
+ return 0;
+}
+
+void _machine_restart(void)
+{
+ for (;;) {
+ writel((RESET_MODULE_FULL_CHIP | RESET_MODULE_DDR),
+ KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE));
+ readl(KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE));
+ }
+}
+
+int board_eth_init(bd_t *bis)
+{
+ char *phynames[] = {RTL8366_DEVNAME, RTL8366_DEVNAME};
+ u16 phyids[] = {RTL8366_LANPHY_ID, RTL8366_WANPHY_ID};
+ u16 phyfixed[] = {1, 0};
+
+ if (ag71xx_register(bis, phynames, phyids, phyfixed) <= 0)
+ return -1;
+
+ if (rtl8366s_initialize())
+ return -1;
+
+ if (rtl8366_mii_register(bis))
+ return -1;
+
+ return 0;
+}
+
+int misc_init_r(void) {
+ uint8_t macaddr[6];
+ uint8_t enetaddr[6];
+
+ debug("Testing mac addresses\n");
+
+ memcpy(macaddr, (uint8_t *) CONFIG_ETHADDR_ADDR, 6);
+
+ if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
+ debug("Setting eth0 mac addr to %pM\n", macaddr);
+ eth_setenv_enetaddr("ethaddr", macaddr);
+ }
+
+ if (!eth_getenv_enetaddr("eth1addr", enetaddr)) {
+ macaddr[5] += 1;
+ debug("Setting eth1 mac addr to %pM\n", macaddr);
+ eth_setenv_enetaddr("eth1addr", macaddr);
+ }
+
+ return 0;
+}
diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds
new file mode 100644
index 0000000..8dc2b76
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds
@@ -0,0 +1,42 @@
+OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips")
+OUTPUT_ARCH(mips)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .sdata : { *(.sdata) }
+
+ _gp = ALIGN(16);
+
+ __got_start = .;
+ .got : { *(.got) }
+ __got_end = .;
+
+ .sdata : { *(.sdata) }
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ uboot_end_data = .;
+ num_got_entries = (__got_end - __got_start) >> 2;
+
+ . = ALIGN(4);
+ .sbss : { *(.sbss) }
+ .bss : { *(.bss) }
+ uboot_end = .;
+}
diff --git a/package/boot/uboot-ar71xx/files/cpu/.svn/entries b/package/boot/uboot-ar71xx/files/cpu/.svn/entries
new file mode 100644
index 0000000..b2aff8b
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/cpu/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/cpu
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+mips
+dir
+
diff --git a/package/boot/uboot-ar71xx/files/cpu/mips/.svn/entries b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/entries
new file mode 100644
index 0000000..d93fd35
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/cpu/mips
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+ar71xx_serial.c
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+f5711b1fa72d76b55261c16e7d73d225
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4579
+
diff --git a/package/boot/uboot-ar71xx/files/cpu/mips/.svn/prop-base/ar71xx_serial.c.svn-base b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/prop-base/ar71xx_serial.c.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/prop-base/ar71xx_serial.c.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/cpu/mips/.svn/text-base/ar71xx_serial.c.svn-base b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/text-base/ar71xx_serial.c.svn-base
new file mode 100644
index 0000000..f093318
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/text-base/ar71xx_serial.c.svn-base
@@ -0,0 +1,177 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <config.h>
+#include <asm/ar71xx.h>
+
+#define REG_SIZE 4
+
+/* === END OF CONFIG === */
+
+/* register offset */
+#define OFS_RCV_BUFFER (0*REG_SIZE)
+#define OFS_TRANS_HOLD (0*REG_SIZE)
+#define OFS_SEND_BUFFER (0*REG_SIZE)
+#define OFS_INTR_ENABLE (1*REG_SIZE)
+#define OFS_INTR_ID (2*REG_SIZE)
+#define OFS_DATA_FORMAT (3*REG_SIZE)
+#define OFS_LINE_CONTROL (3*REG_SIZE)
+#define OFS_MODEM_CONTROL (4*REG_SIZE)
+#define OFS_RS232_OUTPUT (4*REG_SIZE)
+#define OFS_LINE_STATUS (5*REG_SIZE)
+#define OFS_MODEM_STATUS (6*REG_SIZE)
+#define OFS_RS232_INPUT (6*REG_SIZE)
+#define OFS_SCRATCH_PAD (7*REG_SIZE)
+
+#define OFS_DIVISOR_LSB (0*REG_SIZE)
+#define OFS_DIVISOR_MSB (1*REG_SIZE)
+
+#define UART16550_READ(y) readl(KSEG1ADDR(AR71XX_UART_BASE+y))
+#define UART16550_WRITE(x, z) writel(z, KSEG1ADDR((AR71XX_UART_BASE+x)))
+
+void
+ar71xx_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq)
+{
+#ifndef CONFIG_AR91XX
+ u32 pll, pll_div, cpu_div, ahb_div, ddr_div, freq;
+
+ pll = readl(KSEG1ADDR(AR71XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE));
+
+ pll_div =
+ ((pll & AR71XX_PLL_DIV_MASK) >> AR71XX_PLL_DIV_SHIFT) + 1;
+
+ cpu_div =
+ ((pll & AR71XX_CPU_DIV_MASK) >> AR71XX_CPU_DIV_SHIFT) + 1;
+
+ ddr_div =
+ ((pll & AR71XX_DDR_DIV_MASK) >> AR71XX_DDR_DIV_SHIFT) + 1;
+
+ ahb_div =
+ (((pll & AR71XX_AHB_DIV_MASK) >> AR71XX_AHB_DIV_SHIFT) + 1)*2;
+
+ freq = pll_div * 40000000;
+
+ if (cpu_freq)
+ *cpu_freq = freq/cpu_div;
+
+ if (ddr_freq)
+ *ddr_freq = freq/ddr_div;
+
+ if (ahb_freq)
+ *ahb_freq = (freq/cpu_div)/ahb_div;
+
+#else
+ u32 pll, pll_div, ahb_div, ddr_div, freq;
+
+ pll = readl(KSEG1ADDR(AR91XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE));
+
+ pll_div =
+ ((pll & AR91XX_PLL_DIV_MASK) >> AR91XX_PLL_DIV_SHIFT);
+
+ ddr_div =
+ ((pll & AR91XX_DDR_DIV_MASK) >> AR91XX_DDR_DIV_SHIFT) + 1;
+
+ ahb_div =
+ (((pll & AR91XX_AHB_DIV_MASK) >> AR91XX_AHB_DIV_SHIFT) + 1)*2;
+
+ freq = pll_div * 5000000;
+
+ if (cpu_freq)
+ *cpu_freq = freq;
+
+ if (ddr_freq)
+ *ddr_freq = freq/ddr_div;
+
+ if (ahb_freq)
+ *ahb_freq = freq/ahb_div;
+#endif
+}
+
+
+int serial_init(void)
+{
+ u32 div;
+ u32 ahb_freq = 100000000;
+
+ ar71xx_sys_frequency (0, 0, &ahb_freq);
+ div = ahb_freq/(16 * CONFIG_BAUDRATE);
+
+ // enable uart pins
+#ifndef CONFIG_AR91XX
+ writel(AR71XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC));
+#else
+ writel(AR91XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC));
+#endif
+
+ /* set DIAB bit */
+ UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+ /* set divisor */
+ UART16550_WRITE(OFS_DIVISOR_LSB, (div & 0xff));
+ UART16550_WRITE(OFS_DIVISOR_MSB, ((div >> 8) & 0xff));
+
+ /* clear DIAB bit*/
+ UART16550_WRITE(OFS_LINE_CONTROL, 0x00);
+
+ /* set data format */
+ UART16550_WRITE(OFS_DATA_FORMAT, 0x3);
+
+ UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+ return 0;
+}
+
+int serial_tstc (void)
+{
+ return(UART16550_READ(OFS_LINE_STATUS) & 0x1);
+}
+
+int serial_getc(void)
+{
+ while(!serial_tstc());
+
+ return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+void serial_putc(const char byte)
+{
+ if (byte == '\n') serial_putc ('\r');
+
+ while (((UART16550_READ(OFS_LINE_STATUS)) & 0x20) == 0x0);
+ UART16550_WRITE(OFS_SEND_BUFFER, byte);
+}
+
+void serial_setbrg (void)
+{
+}
+
+void serial_puts (const char *s)
+{
+ while (*s)
+ {
+ serial_putc (*s++);
+ }
+}
diff --git a/package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c b/package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c
new file mode 100644
index 0000000..f093318
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c
@@ -0,0 +1,177 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <config.h>
+#include <asm/ar71xx.h>
+
+#define REG_SIZE 4
+
+/* === END OF CONFIG === */
+
+/* register offset */
+#define OFS_RCV_BUFFER (0*REG_SIZE)
+#define OFS_TRANS_HOLD (0*REG_SIZE)
+#define OFS_SEND_BUFFER (0*REG_SIZE)
+#define OFS_INTR_ENABLE (1*REG_SIZE)
+#define OFS_INTR_ID (2*REG_SIZE)
+#define OFS_DATA_FORMAT (3*REG_SIZE)
+#define OFS_LINE_CONTROL (3*REG_SIZE)
+#define OFS_MODEM_CONTROL (4*REG_SIZE)
+#define OFS_RS232_OUTPUT (4*REG_SIZE)
+#define OFS_LINE_STATUS (5*REG_SIZE)
+#define OFS_MODEM_STATUS (6*REG_SIZE)
+#define OFS_RS232_INPUT (6*REG_SIZE)
+#define OFS_SCRATCH_PAD (7*REG_SIZE)
+
+#define OFS_DIVISOR_LSB (0*REG_SIZE)
+#define OFS_DIVISOR_MSB (1*REG_SIZE)
+
+#define UART16550_READ(y) readl(KSEG1ADDR(AR71XX_UART_BASE+y))
+#define UART16550_WRITE(x, z) writel(z, KSEG1ADDR((AR71XX_UART_BASE+x)))
+
+void
+ar71xx_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq)
+{
+#ifndef CONFIG_AR91XX
+ u32 pll, pll_div, cpu_div, ahb_div, ddr_div, freq;
+
+ pll = readl(KSEG1ADDR(AR71XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE));
+
+ pll_div =
+ ((pll & AR71XX_PLL_DIV_MASK) >> AR71XX_PLL_DIV_SHIFT) + 1;
+
+ cpu_div =
+ ((pll & AR71XX_CPU_DIV_MASK) >> AR71XX_CPU_DIV_SHIFT) + 1;
+
+ ddr_div =
+ ((pll & AR71XX_DDR_DIV_MASK) >> AR71XX_DDR_DIV_SHIFT) + 1;
+
+ ahb_div =
+ (((pll & AR71XX_AHB_DIV_MASK) >> AR71XX_AHB_DIV_SHIFT) + 1)*2;
+
+ freq = pll_div * 40000000;
+
+ if (cpu_freq)
+ *cpu_freq = freq/cpu_div;
+
+ if (ddr_freq)
+ *ddr_freq = freq/ddr_div;
+
+ if (ahb_freq)
+ *ahb_freq = (freq/cpu_div)/ahb_div;
+
+#else
+ u32 pll, pll_div, ahb_div, ddr_div, freq;
+
+ pll = readl(KSEG1ADDR(AR91XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE));
+
+ pll_div =
+ ((pll & AR91XX_PLL_DIV_MASK) >> AR91XX_PLL_DIV_SHIFT);
+
+ ddr_div =
+ ((pll & AR91XX_DDR_DIV_MASK) >> AR91XX_DDR_DIV_SHIFT) + 1;
+
+ ahb_div =
+ (((pll & AR91XX_AHB_DIV_MASK) >> AR91XX_AHB_DIV_SHIFT) + 1)*2;
+
+ freq = pll_div * 5000000;
+
+ if (cpu_freq)
+ *cpu_freq = freq;
+
+ if (ddr_freq)
+ *ddr_freq = freq/ddr_div;
+
+ if (ahb_freq)
+ *ahb_freq = freq/ahb_div;
+#endif
+}
+
+
+int serial_init(void)
+{
+ u32 div;
+ u32 ahb_freq = 100000000;
+
+ ar71xx_sys_frequency (0, 0, &ahb_freq);
+ div = ahb_freq/(16 * CONFIG_BAUDRATE);
+
+ // enable uart pins
+#ifndef CONFIG_AR91XX
+ writel(AR71XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC));
+#else
+ writel(AR91XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC));
+#endif
+
+ /* set DIAB bit */
+ UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+ /* set divisor */
+ UART16550_WRITE(OFS_DIVISOR_LSB, (div & 0xff));
+ UART16550_WRITE(OFS_DIVISOR_MSB, ((div >> 8) & 0xff));
+
+ /* clear DIAB bit*/
+ UART16550_WRITE(OFS_LINE_CONTROL, 0x00);
+
+ /* set data format */
+ UART16550_WRITE(OFS_DATA_FORMAT, 0x3);
+
+ UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+ return 0;
+}
+
+int serial_tstc (void)
+{
+ return(UART16550_READ(OFS_LINE_STATUS) & 0x1);
+}
+
+int serial_getc(void)
+{
+ while(!serial_tstc());
+
+ return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+void serial_putc(const char byte)
+{
+ if (byte == '\n') serial_putc ('\r');
+
+ while (((UART16550_READ(OFS_LINE_STATUS)) & 0x20) == 0x0);
+ UART16550_WRITE(OFS_SEND_BUFFER, byte);
+}
+
+void serial_setbrg (void)
+{
+}
+
+void serial_puts (const char *s)
+{
+ while (*s)
+ {
+ serial_putc (*s++);
+ }
+}
diff --git a/package/boot/uboot-ar71xx/files/drivers/.svn/entries b/package/boot/uboot-ar71xx/files/drivers/.svn/entries
new file mode 100644
index 0000000..47154e2
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/.svn/entries
@@ -0,0 +1,34 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/drivers
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+net
+dir
+
+spi
+dir
+
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/entries b/package/boot/uboot-ar71xx/files/drivers/net/.svn/entries
new file mode 100644
index 0000000..66da141
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/entries
@@ -0,0 +1,99 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/drivers/net
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+phy
+dir
+
+ag71xx.c
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+6e570423f54b0897dd2636e34c017bda
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+19204
+
+ag71xx.h
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+a50b2a6d1638274b6bd66f8718d059e3
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10463
+
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.c.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.c.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.h.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.h.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.h.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.c.svn-base
new file mode 100644
index 0000000..b3324c0
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.c.svn-base
@@ -0,0 +1,809 @@
+/*
+ * Atheros AR71xx built-in ethernet mac driver
+ *
+ * Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com>
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Based on Atheros' AG7100 driver
+ *
+ * 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 <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+
+#include <asm/ar71xx.h>
+
+#include "ag71xx.h"
+
+#ifdef AG71XX_DEBUG
+#define DBG(fmt,args...) printf(fmt ,##args)
+#else
+#define DBG(fmt,args...)
+#endif
+
+
+static struct ag71xx agtable[] = {
+ {
+ .mac_base = KSEG1ADDR(AR71XX_GE0_BASE),
+ .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII0_CTRL),
+ .mii_if = CONFIG_AG71XX_MII0_IIF,
+ } , {
+ .mac_base = KSEG1ADDR(AR71XX_GE1_BASE),
+ .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII1_CTRL),
+ .mii_if = CONFIG_AG71XX_MII1_IIF,
+ }
+};
+
+static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size)
+{
+ int err;
+ int i;
+ int rsize;
+
+ ring->desc_size = sizeof(struct ag71xx_desc);
+ if (ring->desc_size % (CONFIG_SYS_CACHELINE_SIZE)) {
+ rsize = roundup(ring->desc_size, CONFIG_SYS_CACHELINE_SIZE);
+ DBG("ag71xx: ring %p, desc size %u rounded to %u\n",
+ ring, ring->desc_size,
+ rsize);
+ ring->desc_size = rsize;
+ }
+
+ ring->descs_cpu = (u8 *) malloc((size * ring->desc_size)
+ + CONFIG_SYS_CACHELINE_SIZE - 1);
+ if (!ring->descs_cpu) {
+ err = -1;
+ goto err;
+ }
+ ring->descs_cpu = (u8 *) UNCACHED_SDRAM((((u32) ring->descs_cpu +
+ CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1)));
+ ring->descs_dma = (u8 *) virt_to_phys(ring->descs_cpu);
+
+ ring->size = size;
+
+ ring->buf = malloc(size * sizeof(*ring->buf));
+ if (!ring->buf) {
+ err = -1;
+ goto err;
+ }
+ memset(ring->buf, 0, size * sizeof(*ring->buf));
+
+ for (i = 0; i < size; i++) {
+ ring->buf[i].desc =
+ (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size];
+ DBG("ag71xx: ring %p, desc %d at %p\n",
+ ring, i, ring->buf[i].desc);
+ }
+
+ flush_cache( (u32) ring->buf, size * sizeof(*ring->buf));
+
+ return 0;
+
+ err:
+ return err;
+}
+
+static void ag71xx_ring_tx_init(struct ag71xx *ag)
+{
+ struct ag71xx_ring *ring = &ag->tx_ring;
+ int i;
+
+ for (i = 0; i < AG71XX_TX_RING_SIZE; i++) {
+ ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma +
+ ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE)));
+
+ ring->buf[i].desc->ctrl = DESC_EMPTY;
+ ring->buf[i].skb = NULL;
+ }
+
+ ring->curr = 0;
+}
+
+static void ag71xx_ring_rx_clean(struct ag71xx *ag)
+{
+ struct ag71xx_ring *ring = &ag->rx_ring;
+ int i;
+
+ if (!ring->buf)
+ return;
+
+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
+ ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]);
+ flush_cache((u32) NetRxPackets[i], PKTSIZE_ALIGN);
+ ring->buf[i].desc->ctrl = DESC_EMPTY;
+ }
+
+ ring->curr = 0;
+}
+
+static int ag71xx_ring_rx_init(struct ag71xx *ag)
+{
+ struct ag71xx_ring *ring = &ag->rx_ring;
+ unsigned int i;
+
+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
+ ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma +
+ ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE)));
+
+ DBG("ag71xx: RX desc at %p, next is %08x\n",
+ ring->buf[i].desc,
+ ring->buf[i].desc->next);
+ }
+
+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
+ ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]);
+ ring->buf[i].desc->ctrl = DESC_EMPTY;
+ }
+
+ ring->curr = 0;
+
+ return 0;
+}
+
+static int ag71xx_rings_init(struct ag71xx *ag)
+{
+ int ret;
+
+ ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE);
+ if (ret)
+ return ret;
+
+ ag71xx_ring_tx_init(ag);
+
+ ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE);
+ if (ret)
+ return ret;
+
+ ret = ag71xx_ring_rx_init(ag);
+ return ret;
+}
+
+static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
+{
+ uint32_t base = KSEG1ADDR(AR71XX_PLL_BASE);
+ u32 t;
+
+ t = readl(base + cfg_reg);
+ t &= ~(3 << shift);
+ t |= (2 << shift);
+ writel(t, base + cfg_reg);
+ udelay(100);
+
+ writel(pll_val, base + pll_reg);
+
+ t |= (3 << shift);
+ writel(t, base + cfg_reg);
+ udelay(100);
+
+ t &= ~(3 << shift);
+ writel(t, base + cfg_reg);
+ udelay(100);
+
+ debug("ar71xx: pll_reg %#x: %#x\n", (unsigned int)(base + pll_reg),
+ readl(base + pll_reg));
+}
+
+static void ar91xx_set_pll_ge0(int speed)
+{
+ //u32 val = ar71xx_get_eth_pll(0, speed);
+ u32 pll_val;
+
+ switch (speed) {
+ case SPEED_10:
+ pll_val = 0x00441099;
+ break;
+ case SPEED_100:
+ pll_val = 0x13000a44;
+ break;
+ case SPEED_1000:
+ pll_val = 0x1a000000;
+ break;
+ default:
+ BUG();
+ }
+
+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
+ pll_val, AR91XX_ETH0_PLL_SHIFT);
+}
+
+static void ar91xx_set_pll_ge1(int speed)
+{
+ //u32 val = ar71xx_get_eth_pll(1, speed);
+ u32 pll_val;
+
+ switch (speed) {
+ case SPEED_10:
+ pll_val = 0x00441099;
+ break;
+ case SPEED_100:
+ pll_val = 0x13000a44;
+ break;
+ case SPEED_1000:
+ pll_val = 0x1a000000;
+ break;
+ default:
+ BUG();
+ }
+
+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
+ pll_val, AR91XX_ETH1_PLL_SHIFT);
+}
+
+static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
+{
+ u32 t;
+
+ t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16)
+ | (((u32) mac[3]) << 8) | ((u32) mac[2]);
+
+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t);
+
+ t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16);
+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
+}
+
+static void ag71xx_dma_reset(struct ag71xx *ag)
+{
+ u32 val;
+ int i;
+
+ DBG("%s: txdesc reg: 0x%08x rxdesc reg: 0x%08x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_TX_DESC),
+ ag71xx_rr(ag, AG71XX_REG_RX_DESC));
+
+ /* stop RX and TX */
+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
+
+ /* clear descriptor addresses */
+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0);
+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0);
+
+ /* clear pending RX/TX interrupts */
+ for (i = 0; i < 256; i++) {
+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
+ }
+
+ /* clear pending errors */
+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
+
+ val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
+ if (val)
+ printf("%s: unable to clear DMA Rx status: %08x\n",
+ ag->dev->name, val);
+
+ val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
+
+ /* mask out reserved bits */
+ val &= ~0xff000000;
+
+ if (val)
+ printf("%s: unable to clear DMA Tx status: %08x\n",
+ ag->dev->name, val);
+}
+
+static void ag71xx_halt(struct eth_device *dev)
+{
+ struct ag71xx *ag = (struct ag71xx *) dev->priv;
+
+ /* stop RX engine */
+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
+
+ ag71xx_dma_reset(ag);
+}
+
+#define MAX_WAIT 1000
+
+static int ag71xx_send(struct eth_device *dev, volatile void *packet,
+ int length)
+{
+ struct ag71xx *ag = (struct ag71xx *) dev->priv;
+ struct ag71xx_ring *ring = &ag->tx_ring;
+ struct ag71xx_desc *desc;
+ int i;
+
+ i = ring->curr % AG71XX_TX_RING_SIZE;
+ desc = ring->buf[i].desc;
+
+ if (!ag71xx_desc_empty(desc)) {
+ printf("%s: tx buffer full\n", ag->dev->name);
+ return 1;
+ }
+
+ flush_cache((u32) packet, length);
+ desc->data = (u32) virt_to_phys(packet);
+ desc->ctrl = (length & DESC_PKTLEN_M);
+
+ DBG("%s: sending %#08x length %#08x\n",
+ ag->dev->name, desc->data, desc->ctrl);
+
+ ring->curr++;
+ if (ring->curr >= AG71XX_TX_RING_SIZE){
+ ring->curr = 0;
+ }
+
+ /* enable TX engine */
+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE);
+
+ for (i = 0; i < MAX_WAIT; i++)
+ {
+ if (ag71xx_desc_empty(desc))
+ break;
+ udelay(10);
+ }
+ if (i == MAX_WAIT) {
+ printf("%s: tx timed out!\n", ag->dev->name);
+ return -1;
+ }
+
+ /* disable TX engine */
+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
+ desc->data = 0;
+ desc->ctrl = DESC_EMPTY;
+
+ return 0;
+}
+
+static int ag71xx_recv(struct eth_device *dev)
+{
+ struct ag71xx *ag = (struct ag71xx *) dev->priv;
+ struct ag71xx_ring *ring = &ag->rx_ring;
+
+ for (;;) {
+ unsigned int i = ring->curr % AG71XX_RX_RING_SIZE;
+ struct ag71xx_desc *desc = ring->buf[i].desc;
+ int pktlen;
+
+ if (ag71xx_desc_empty(desc))
+ break;
+
+ DBG("%s: rx packets, curr=%u\n", dev->name, ring->curr);
+
+ pktlen = ag71xx_desc_pktlen(desc);
+ pktlen -= ETH_FCS_LEN;
+
+
+ NetReceive(NetRxPackets[i] , pktlen);
+ flush_cache( (u32) NetRxPackets[i], PKTSIZE_ALIGN);
+
+ ring->buf[i].desc->ctrl = DESC_EMPTY;
+ ring->curr++;
+ if (ring->curr >= AG71XX_RX_RING_SIZE){
+ ring->curr = 0;
+ }
+
+ }
+
+ if ((ag71xx_rr(ag, AG71XX_REG_RX_CTRL) & RX_CTRL_RXE) == 0) {
+ /* start RX engine */
+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
+ }
+
+ return 0;
+}
+
+#ifdef AG71XX_DEBUG
+static char *ag71xx_speed_str(struct ag71xx *ag)
+{
+ switch (ag->speed) {
+ case SPEED_1000:
+ return "1000";
+ case SPEED_100:
+ return "100";
+ case SPEED_10:
+ return "10";
+ }
+
+ return "?";
+}
+#endif
+
+void ag71xx_link_adjust(struct ag71xx *ag)
+{
+ u32 cfg2;
+ u32 ifctl;
+ u32 fifo5;
+ u32 mii_speed;
+
+ if (!ag->link) {
+ DBG("%s: link down\n", ag->dev->name);
+ return;
+ }
+
+ cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);
+ cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);
+ cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0;
+
+ ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);
+ ifctl &= ~(MAC_IFCTL_SPEED);
+
+ fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);
+ fifo5 &= ~FIFO_CFG5_BM;
+
+ switch (ag->speed) {
+ case SPEED_1000:
+ mii_speed = MII_CTRL_SPEED_1000;
+ cfg2 |= MAC_CFG2_IF_1000;
+ fifo5 |= FIFO_CFG5_BM;
+ break;
+ case SPEED_100:
+ mii_speed = MII_CTRL_SPEED_100;
+ cfg2 |= MAC_CFG2_IF_10_100;
+ ifctl |= MAC_IFCTL_SPEED;
+ break;
+ case SPEED_10:
+ mii_speed = MII_CTRL_SPEED_10;
+ cfg2 |= MAC_CFG2_IF_10_100;
+ break;
+ default:
+ BUG();
+ return;
+ }
+
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff);
+
+ if (ag->macNum == 0)
+ ar91xx_set_pll_ge0(ag->speed);
+ else
+ ar91xx_set_pll_ge1(ag->speed);
+
+ ag71xx_mii_ctrl_set_speed(ag, mii_speed);
+
+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
+ ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
+
+ DBG("%s: link up (%sMbps/%s duplex)\n",
+ ag->dev->name,
+ ag71xx_speed_str(ag),
+ (1 == ag->duplex) ? "Full" : "Half");
+
+ DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
+
+ DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
+
+ DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
+ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
+ ag71xx_mii_ctrl_rr(ag));
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int ag71xx_getMiiSpeed(struct ag71xx *ag)
+{
+ uint16_t phyreg, cap;
+
+ if (miiphy_read(ag->phyname, ag->phyid,
+ PHY_BMSR, &phyreg)) {
+ puts("PHY_BMSR read failed, assuming no link\n");
+ return -1;
+ }
+
+ if ((phyreg & PHY_BMSR_LS) == 0) {
+ return -1;
+ }
+
+ if (miiphy_read(ag->phyname, ag->phyid,
+ PHY_1000BTSR, &phyreg))
+ return -1;
+
+ if (phyreg & PHY_1000BTSR_1000FD) {
+ ag->speed = SPEED_1000;
+ ag->duplex = 1;
+ } else if (phyreg & PHY_1000BTSR_1000HD) {
+ ag->speed = SPEED_1000;
+ ag->duplex = 0;
+ } else {
+ if (miiphy_read(ag->phyname, ag->phyid,
+ PHY_ANAR, &cap))
+ return -1;
+
+ if (miiphy_read(ag->phyname, ag->phyid,
+ PHY_ANLPAR, &phyreg))
+ return -1;
+
+ cap &= phyreg;
+ if (cap & PHY_ANLPAR_TXFD) {
+ ag->speed = SPEED_100;
+ ag->duplex = 1;
+ } else if (cap & PHY_ANLPAR_TX) {
+ ag->speed = SPEED_100;
+ ag->duplex = 0;
+ } else if (cap & PHY_ANLPAR_10FD) {
+ ag->speed = SPEED_10;
+ ag->duplex = 1;
+ } else {
+ ag->speed = SPEED_10;
+ ag->duplex = 0;
+ }
+ }
+
+ ag->link = 1;
+
+ return 0;
+}
+#endif
+
+static int ag71xx_hw_start(struct eth_device *dev, bd_t * bd)
+{
+ struct ag71xx *ag = (struct ag71xx *) dev->priv;
+
+ ag71xx_dma_reset(ag);
+
+ ag71xx_ring_rx_clean(ag);
+ ag71xx_ring_tx_init(ag);
+
+ ag71xx_wr(ag, AG71XX_REG_TX_DESC,
+ (u32) virt_to_phys(ag->tx_ring.descs_dma));
+ ag71xx_wr(ag, AG71XX_REG_RX_DESC,
+ (u32) virt_to_phys(ag->rx_ring.descs_dma));
+
+ ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr);
+
+ if (ag->phyfixed) {
+ ag->link = 1;
+ ag->duplex = 1;
+ ag->speed = SPEED_1000;
+ } else {
+
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
+ if (ag71xx_getMiiSpeed(ag))
+ return -1;
+#else
+ /* only fixed, without mii */
+ return -1;
+#endif
+
+ }
+ ag71xx_link_adjust(ag);
+
+ DBG("%s: txdesc reg: %#08x rxdesc reg: %#08x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_TX_DESC),
+ ag71xx_rr(ag, AG71XX_REG_RX_DESC));
+
+ /* start RX engine */
+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
+
+ return 0;
+}
+
+#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
+
+#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
+ FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
+ FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
+ FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
+ FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
+ FIFO_CFG4_VT)
+
+#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
+ FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
+ FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
+ FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
+ FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
+ FIFO_CFG5_17 | FIFO_CFG5_SF)
+
+static int ag71xx_hw_init(struct ag71xx *ag)
+{
+ int ret = 0;
+ uint32_t reg;
+ uint32_t mask, mii_type;
+
+ if (ag->macNum == 0) {
+ mask = (RESET_MODULE_GE0_MAC | RESET_MODULE_GE0_PHY);
+ mii_type = 0x13;
+ } else {
+ mask = (RESET_MODULE_GE1_MAC | RESET_MODULE_GE1_PHY);
+ mii_type = 0x11;
+ }
+
+ // mac soft reset
+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR);
+ udelay(20);
+
+ // device stop
+ reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
+ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg | mask);
+ udelay(100 * 1000);
+
+ // device start
+ reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
+ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg & ~mask);
+ udelay(100 * 1000);
+
+ /* setup MAC configuration registers */
+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, (MAC_CFG1_RXE | MAC_CFG1_TXE));
+
+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG2,
+ MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);
+
+ /* setup FIFO configuration register 0 */
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
+
+ /* setup MII interface type */
+ ag71xx_mii_ctrl_set_if(ag, ag->mii_if);
+
+ /* setup mdio clock divisor */
+ ag71xx_wr(ag, AG71XX_REG_MII_CFG, MII_CFG_CLK_DIV_20);
+
+ /* setup FIFO configuration registers */
+ ag71xx_sb(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);
+
+ ag71xx_dma_reset(ag);
+
+ ret = ag71xx_rings_init(ag);
+ if (ret)
+ return -1;
+
+ ag71xx_wr(ag, AG71XX_REG_TX_DESC,
+ (u32) virt_to_phys(ag->tx_ring.descs_dma));
+ ag71xx_wr(ag, AG71XX_REG_RX_DESC,
+ (u32) virt_to_phys(ag->rx_ring.descs_dma));
+
+ ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr);
+
+ return 0;
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+#define AG71XX_MDIO_RETRY 1000
+#define AG71XX_MDIO_DELAY 5
+
+static inline struct ag71xx *ag71xx_name2mac(char *devname)
+{
+ if (strcmp(devname, agtable[0].dev->name) == 0)
+ return &agtable[0];
+ else if (strcmp(devname, agtable[1].dev->name) == 0)
+ return &agtable[1];
+ else
+ return NULL;
+}
+
+static inline void ag71xx_mdio_wr(struct ag71xx *ag, unsigned reg,
+ u32 value)
+{
+ uint32_t r;
+
+ r = ag->mac_base + reg;
+ writel(value, r);
+
+ /* flush write */
+ (void) readl(r);
+}
+
+static inline u32 ag71xx_mdio_rr(struct ag71xx *ag, unsigned reg)
+{
+ return readl(ag->mac_base + reg);
+}
+
+static int ag71xx_mdio_read(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short *val)
+{
+ struct ag71xx *ag = ag71xx_name2mac(devname);
+ uint16_t regData;
+ int i;
+
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR,
+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_READ);
+
+ i = AG71XX_MDIO_RETRY;
+ while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
+ if (i-- == 0) {
+ printf("%s: mii_read timed out\n",
+ ag->dev->name);
+ return -1;
+ }
+ udelay(AG71XX_MDIO_DELAY);
+ }
+
+ regData = (uint16_t) ag71xx_mdio_rr(ag, AG71XX_REG_MII_STATUS) & 0xffff;
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
+
+ DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, regData);
+
+ if (val)
+ *val = regData;
+
+ return 0;
+}
+
+static int ag71xx_mdio_write(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short val)
+{
+ struct ag71xx *ag = ag71xx_name2mac(devname);
+ int i;
+
+ if (ag == NULL)
+ return 1;
+
+ DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
+
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR,
+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_CTRL, val);
+
+ i = AG71XX_MDIO_RETRY;
+ while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
+ if (i-- == 0) {
+ printf("%s: mii_write timed out\n",
+ ag->dev->name);
+ break;
+ }
+ udelay(AG71XX_MDIO_DELAY);
+ }
+
+ return 0;
+}
+#endif
+
+int ag71xx_register(bd_t * bis, char *phyname[], uint16_t phyid[], uint16_t phyfixed[])
+{
+ int i, num = 0;
+ u8 used_ports[MAX_AG71XX_DEVS] = CONFIG_AG71XX_PORTS;
+
+ for (i = 0; i < MAX_AG71XX_DEVS; i++) {
+ /*skip if port is configured not to use */
+ if (used_ports[i] == 0)
+ continue;
+
+ agtable[i].dev = malloc(sizeof(struct eth_device));
+ if (agtable[i].dev == NULL) {
+ puts("malloc failed\n");
+ return 0;
+ }
+ memset(agtable[i].dev, 0, sizeof(struct eth_device));
+ sprintf(agtable[i].dev->name, "eth%d", i);
+
+ agtable[i].dev->iobase = 0;
+ agtable[i].dev->init = ag71xx_hw_start;
+ agtable[i].dev->halt = ag71xx_halt;
+ agtable[i].dev->send = ag71xx_send;
+ agtable[i].dev->recv = ag71xx_recv;
+ agtable[i].dev->priv = (void *) (&agtable[i]);
+ agtable[i].macNum = i;
+ eth_register(agtable[i].dev);
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+
+ if ((phyname == NULL) || (phyid == NULL) || (phyfixed == NULL))
+ return -1;
+
+ agtable[i].phyname = strdup(phyname[i]);
+ agtable[i].phyid = phyid[i];
+ agtable[i].phyfixed = phyfixed[i];
+
+ miiphy_register(agtable[i].dev->name, ag71xx_mdio_read,
+ ag71xx_mdio_write);
+#endif
+
+ if (ag71xx_hw_init(&agtable[i]))
+ continue;
+
+ num++;
+ }
+
+ return num;
+}
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.h.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.h.svn-base
new file mode 100644
index 0000000..edce429
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.h.svn-base
@@ -0,0 +1,374 @@
+/*
+ * Atheros AR71xx built-in ethernet mac driver
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Based on Atheros' AG7100 driver
+ *
+ * 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 __AG71XX_H
+#define __AG71XX_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+#include <asm/ar71xx.h>
+
+// controller has 2 ports
+#define MAX_AG71XX_DEVS 2
+
+#define ETH_FCS_LEN 4
+
+#define SPEED_10 10
+#define SPEED_100 100
+#define SPEED_1000 1000
+
+
+#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
+#define AG71XX_INT_TX (AG71XX_INT_TX_PS)
+#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF)
+
+#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX)
+#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL)
+
+#define AG71XX_TX_FIFO_LEN 2048
+#define AG71XX_TX_MTU_LEN 1536
+#define AG71XX_RX_PKT_RESERVE 64
+#define AG71XX_RX_PKT_SIZE \
+ (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN)
+
+#ifndef CONFIG_SYS_RX_ETH_BUFFER
+#define AG71XX_TX_RING_SIZE 4
+#define AG71XX_RX_RING_SIZE 4
+#else
+#define AG71XX_TX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER
+#define AG71XX_RX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER
+#endif
+
+#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4)
+#define AG71XX_TX_THRES_WAKEUP \
+ (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4))
+
+
+
+
+struct ag71xx_desc {
+ u32 data;
+ u32 ctrl;
+#define DESC_EMPTY BIT(31)
+#define DESC_MORE BIT(24)
+#define DESC_PKTLEN_M 0xfff
+ u32 next;
+ u32 pad;
+} __attribute__((aligned(4)));
+
+struct ag71xx_buf {
+ struct sk_buff *skb;
+ struct ag71xx_desc *desc;
+ dma_addr_t dma_addr;
+ u32 pad;
+};
+
+struct ag71xx_ring {
+ struct ag71xx_buf *buf;
+ u8 *descs_cpu;
+ u8 *descs_dma;
+ unsigned int desc_size;
+ unsigned int curr;
+ unsigned int size;
+};
+
+struct ag71xx {
+ uint32_t mac_base;
+ uint32_t mii_ctrl;
+
+ struct eth_device *dev;
+
+ struct ag71xx_ring rx_ring;
+ struct ag71xx_ring tx_ring;
+
+ char *phyname;
+ u16 phyid;
+ u16 phyfixed;
+ uint32_t link;
+ uint32_t speed;
+ int32_t duplex;
+ uint32_t macNum;
+ uint32_t mii_if;
+};
+
+void ag71xx_link_adjust(struct ag71xx *ag);
+
+int ag71xx_phy_connect(struct ag71xx *ag);
+void ag71xx_phy_disconnect(struct ag71xx *ag);
+void ag71xx_phy_start(struct ag71xx *ag);
+void ag71xx_phy_stop(struct ag71xx *ag);
+
+static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
+{
+ return ((desc->ctrl & DESC_EMPTY) != 0);
+}
+
+static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
+{
+ return (desc->ctrl & DESC_PKTLEN_M);
+}
+
+/* Register offsets */
+#define AG71XX_REG_MAC_CFG1 0x0000
+#define AG71XX_REG_MAC_CFG2 0x0004
+#define AG71XX_REG_MAC_IPG 0x0008
+#define AG71XX_REG_MAC_HDX 0x000c
+#define AG71XX_REG_MAC_MFL 0x0010
+#define AG71XX_REG_MII_CFG 0x0020
+#define AG71XX_REG_MII_CMD 0x0024
+#define AG71XX_REG_MII_ADDR 0x0028
+#define AG71XX_REG_MII_CTRL 0x002c
+#define AG71XX_REG_MII_STATUS 0x0030
+#define AG71XX_REG_MII_IND 0x0034
+#define AG71XX_REG_MAC_IFCTL 0x0038
+#define AG71XX_REG_MAC_ADDR1 0x0040
+#define AG71XX_REG_MAC_ADDR2 0x0044
+#define AG71XX_REG_FIFO_CFG0 0x0048
+#define AG71XX_REG_FIFO_CFG1 0x004c
+#define AG71XX_REG_FIFO_CFG2 0x0050
+#define AG71XX_REG_FIFO_CFG3 0x0054
+#define AG71XX_REG_FIFO_CFG4 0x0058
+#define AG71XX_REG_FIFO_CFG5 0x005c
+#define AG71XX_REG_FIFO_RAM0 0x0060
+#define AG71XX_REG_FIFO_RAM1 0x0064
+#define AG71XX_REG_FIFO_RAM2 0x0068
+#define AG71XX_REG_FIFO_RAM3 0x006c
+#define AG71XX_REG_FIFO_RAM4 0x0070
+#define AG71XX_REG_FIFO_RAM5 0x0074
+#define AG71XX_REG_FIFO_RAM6 0x0078
+#define AG71XX_REG_FIFO_RAM7 0x007c
+
+#define AG71XX_REG_TX_CTRL 0x0180
+#define AG71XX_REG_TX_DESC 0x0184
+#define AG71XX_REG_TX_STATUS 0x0188
+#define AG71XX_REG_RX_CTRL 0x018c
+#define AG71XX_REG_RX_DESC 0x0190
+#define AG71XX_REG_RX_STATUS 0x0194
+#define AG71XX_REG_INT_ENABLE 0x0198
+#define AG71XX_REG_INT_STATUS 0x019c
+
+#define MAC_CFG1_TXE BIT(0) /* Tx Enable */
+#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */
+#define MAC_CFG1_RXE BIT(2) /* Rx Enable */
+#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */
+#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */
+#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */
+#define MAC_CFG1_LB BIT(8) /* Loopback mode */
+#define MAC_CFG1_SR BIT(31) /* Soft Reset */
+
+#define MAC_CFG2_FDX BIT(0)
+#define MAC_CFG2_CRC_EN BIT(1)
+#define MAC_CFG2_PAD_CRC_EN BIT(2)
+#define MAC_CFG2_LEN_CHECK BIT(4)
+#define MAC_CFG2_HUGE_FRAME_EN BIT(5)
+#define MAC_CFG2_IF_1000 BIT(9)
+#define MAC_CFG2_IF_10_100 BIT(8)
+
+#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */
+#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */
+#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */
+#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */
+#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */
+#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
+ | FIFO_CFG0_TXS | FIFO_CFG0_TXF)
+
+#define FIFO_CFG0_ENABLE_SHIFT 8
+
+#define FIFO_CFG4_DE BIT(0) /* Drop Event */
+#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */
+#define FIFO_CFG4_FC BIT(2) /* False Carrier */
+#define FIFO_CFG4_CE BIT(3) /* Code Error */
+#define FIFO_CFG4_CR BIT(4) /* CRC error */
+#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */
+#define FIFO_CFG4_LO BIT(6) /* Length out of range */
+#define FIFO_CFG4_OK BIT(7) /* Packet is OK */
+#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */
+#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */
+#define FIFO_CFG4_DR BIT(10) /* Dribble */
+#define FIFO_CFG4_LE BIT(11) /* Long Event */
+#define FIFO_CFG4_CF BIT(12) /* Control Frame */
+#define FIFO_CFG4_PF BIT(13) /* Pause Frame */
+#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */
+#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */
+#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */
+#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */
+
+#define FIFO_CFG5_DE BIT(0) /* Drop Event */
+#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */
+#define FIFO_CFG5_FC BIT(2) /* False Carrier */
+#define FIFO_CFG5_CE BIT(3) /* Code Error */
+#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */
+#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */
+#define FIFO_CFG5_OK BIT(6) /* Packet is OK */
+#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */
+#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */
+#define FIFO_CFG5_DR BIT(9) /* Dribble */
+#define FIFO_CFG5_CF BIT(10) /* Control Frame */
+#define FIFO_CFG5_PF BIT(11) /* Pause Frame */
+#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */
+#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */
+#define FIFO_CFG5_LE BIT(14) /* Long Event */
+#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */
+#define FIFO_CFG5_16 BIT(16) /* unknown */
+#define FIFO_CFG5_17 BIT(17) /* unknown */
+#define FIFO_CFG5_SF BIT(18) /* Short Frame */
+#define FIFO_CFG5_BM BIT(19) /* Byte Mode */
+
+#define AG71XX_INT_TX_PS BIT(0)
+#define AG71XX_INT_TX_UR BIT(1)
+#define AG71XX_INT_TX_BE BIT(3)
+#define AG71XX_INT_RX_PR BIT(4)
+#define AG71XX_INT_RX_OF BIT(6)
+#define AG71XX_INT_RX_BE BIT(7)
+
+#define MAC_IFCTL_SPEED BIT(16)
+
+#define MII_CFG_CLK_DIV_4 0
+#define MII_CFG_CLK_DIV_6 2
+#define MII_CFG_CLK_DIV_8 3
+#define MII_CFG_CLK_DIV_10 4
+#define MII_CFG_CLK_DIV_14 5
+#define MII_CFG_CLK_DIV_20 6
+#define MII_CFG_CLK_DIV_28 7
+#define MII_CFG_RESET BIT(31)
+
+#define MII_CMD_WRITE 0x0
+#define MII_CMD_READ 0x1
+#define MII_ADDR_SHIFT 8
+#define MII_IND_BUSY BIT(0)
+#define MII_IND_INVALID BIT(2)
+
+#define TX_CTRL_TXE BIT(0) /* Tx Enable */
+
+#define TX_STATUS_PS BIT(0) /* Packet Sent */
+#define TX_STATUS_UR BIT(1) /* Tx Underrun */
+#define TX_STATUS_BE BIT(3) /* Bus Error */
+
+#define RX_CTRL_RXE BIT(0) /* Rx Enable */
+
+#define RX_STATUS_PR BIT(0) /* Packet Received */
+#define RX_STATUS_OF BIT(2) /* Rx Overflow */
+#define RX_STATUS_BE BIT(3) /* Bus Error */
+
+#define MII_CTRL_IF_MASK 3
+#define MII_CTRL_SPEED_SHIFT 4
+#define MII_CTRL_SPEED_MASK 3
+#define MII_CTRL_SPEED_10 0
+#define MII_CTRL_SPEED_100 1
+#define MII_CTRL_SPEED_1000 2
+
+static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
+{
+ __raw_writel(value, ag->mac_base + reg);
+ /* flush write */
+ (void) __raw_readl(ag->mac_base + reg);
+}
+
+static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
+{
+ return __raw_readl(ag->mac_base + reg);
+}
+
+static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask)
+{
+ uint32_t r;
+
+ r = ag->mac_base + reg;
+ __raw_writel(__raw_readl(r) | mask, r);
+ /* flush write */
+ (void)__raw_readl(r);
+}
+
+static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask)
+{
+ uint32_t r;
+
+ r = ag->mac_base + reg;
+ __raw_writel(__raw_readl(r) & ~mask, r);
+ /* flush write */
+ (void) __raw_readl(r);
+}
+
+static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
+{
+ ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);
+}
+
+static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
+{
+ ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
+}
+
+static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value)
+{
+ __raw_writel(value, ag->mii_ctrl);
+
+ /* flush write */
+ __raw_readl(ag->mii_ctrl);
+}
+
+static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
+{
+ return __raw_readl(ag->mii_ctrl);
+}
+
+static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
+ unsigned int mii_if)
+{
+ u32 t;
+
+ t = ag71xx_mii_ctrl_rr(ag);
+ t &= ~(MII_CTRL_IF_MASK);
+ t |= (mii_if & MII_CTRL_IF_MASK);
+ ag71xx_mii_ctrl_wr(ag, t);
+}
+
+static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
+ unsigned int speed)
+{
+ u32 t;
+
+ t = ag71xx_mii_ctrl_rr(ag);
+ t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
+ t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT;
+ ag71xx_mii_ctrl_wr(ag, t);
+}
+
+#ifdef CONFIG_AG71XX_AR8216_SUPPORT
+void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
+ int pktlen);
+static inline int ag71xx_has_ar8216(struct ag71xx *ag)
+{
+ return ag71xx_get_pdata(ag)->has_ar8216;
+}
+#else
+static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
+ struct sk_buff *skb)
+{
+}
+
+static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
+ struct sk_buff *skb,
+ int pktlen)
+{
+ return 0;
+}
+static inline int ag71xx_has_ar8216(struct ag71xx *ag)
+{
+ return 0;
+}
+#endif
+
+#endif /* _AG71XX_H */
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c
new file mode 100644
index 0000000..b3324c0
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c
@@ -0,0 +1,809 @@
+/*
+ * Atheros AR71xx built-in ethernet mac driver
+ *
+ * Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com>
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Based on Atheros' AG7100 driver
+ *
+ * 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 <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+
+#include <asm/ar71xx.h>
+
+#include "ag71xx.h"
+
+#ifdef AG71XX_DEBUG
+#define DBG(fmt,args...) printf(fmt ,##args)
+#else
+#define DBG(fmt,args...)
+#endif
+
+
+static struct ag71xx agtable[] = {
+ {
+ .mac_base = KSEG1ADDR(AR71XX_GE0_BASE),
+ .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII0_CTRL),
+ .mii_if = CONFIG_AG71XX_MII0_IIF,
+ } , {
+ .mac_base = KSEG1ADDR(AR71XX_GE1_BASE),
+ .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII1_CTRL),
+ .mii_if = CONFIG_AG71XX_MII1_IIF,
+ }
+};
+
+static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size)
+{
+ int err;
+ int i;
+ int rsize;
+
+ ring->desc_size = sizeof(struct ag71xx_desc);
+ if (ring->desc_size % (CONFIG_SYS_CACHELINE_SIZE)) {
+ rsize = roundup(ring->desc_size, CONFIG_SYS_CACHELINE_SIZE);
+ DBG("ag71xx: ring %p, desc size %u rounded to %u\n",
+ ring, ring->desc_size,
+ rsize);
+ ring->desc_size = rsize;
+ }
+
+ ring->descs_cpu = (u8 *) malloc((size * ring->desc_size)
+ + CONFIG_SYS_CACHELINE_SIZE - 1);
+ if (!ring->descs_cpu) {
+ err = -1;
+ goto err;
+ }
+ ring->descs_cpu = (u8 *) UNCACHED_SDRAM((((u32) ring->descs_cpu +
+ CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1)));
+ ring->descs_dma = (u8 *) virt_to_phys(ring->descs_cpu);
+
+ ring->size = size;
+
+ ring->buf = malloc(size * sizeof(*ring->buf));
+ if (!ring->buf) {
+ err = -1;
+ goto err;
+ }
+ memset(ring->buf, 0, size * sizeof(*ring->buf));
+
+ for (i = 0; i < size; i++) {
+ ring->buf[i].desc =
+ (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size];
+ DBG("ag71xx: ring %p, desc %d at %p\n",
+ ring, i, ring->buf[i].desc);
+ }
+
+ flush_cache( (u32) ring->buf, size * sizeof(*ring->buf));
+
+ return 0;
+
+ err:
+ return err;
+}
+
+static void ag71xx_ring_tx_init(struct ag71xx *ag)
+{
+ struct ag71xx_ring *ring = &ag->tx_ring;
+ int i;
+
+ for (i = 0; i < AG71XX_TX_RING_SIZE; i++) {
+ ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma +
+ ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE)));
+
+ ring->buf[i].desc->ctrl = DESC_EMPTY;
+ ring->buf[i].skb = NULL;
+ }
+
+ ring->curr = 0;
+}
+
+static void ag71xx_ring_rx_clean(struct ag71xx *ag)
+{
+ struct ag71xx_ring *ring = &ag->rx_ring;
+ int i;
+
+ if (!ring->buf)
+ return;
+
+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
+ ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]);
+ flush_cache((u32) NetRxPackets[i], PKTSIZE_ALIGN);
+ ring->buf[i].desc->ctrl = DESC_EMPTY;
+ }
+
+ ring->curr = 0;
+}
+
+static int ag71xx_ring_rx_init(struct ag71xx *ag)
+{
+ struct ag71xx_ring *ring = &ag->rx_ring;
+ unsigned int i;
+
+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
+ ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma +
+ ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE)));
+
+ DBG("ag71xx: RX desc at %p, next is %08x\n",
+ ring->buf[i].desc,
+ ring->buf[i].desc->next);
+ }
+
+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
+ ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]);
+ ring->buf[i].desc->ctrl = DESC_EMPTY;
+ }
+
+ ring->curr = 0;
+
+ return 0;
+}
+
+static int ag71xx_rings_init(struct ag71xx *ag)
+{
+ int ret;
+
+ ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE);
+ if (ret)
+ return ret;
+
+ ag71xx_ring_tx_init(ag);
+
+ ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE);
+ if (ret)
+ return ret;
+
+ ret = ag71xx_ring_rx_init(ag);
+ return ret;
+}
+
+static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
+{
+ uint32_t base = KSEG1ADDR(AR71XX_PLL_BASE);
+ u32 t;
+
+ t = readl(base + cfg_reg);
+ t &= ~(3 << shift);
+ t |= (2 << shift);
+ writel(t, base + cfg_reg);
+ udelay(100);
+
+ writel(pll_val, base + pll_reg);
+
+ t |= (3 << shift);
+ writel(t, base + cfg_reg);
+ udelay(100);
+
+ t &= ~(3 << shift);
+ writel(t, base + cfg_reg);
+ udelay(100);
+
+ debug("ar71xx: pll_reg %#x: %#x\n", (unsigned int)(base + pll_reg),
+ readl(base + pll_reg));
+}
+
+static void ar91xx_set_pll_ge0(int speed)
+{
+ //u32 val = ar71xx_get_eth_pll(0, speed);
+ u32 pll_val;
+
+ switch (speed) {
+ case SPEED_10:
+ pll_val = 0x00441099;
+ break;
+ case SPEED_100:
+ pll_val = 0x13000a44;
+ break;
+ case SPEED_1000:
+ pll_val = 0x1a000000;
+ break;
+ default:
+ BUG();
+ }
+
+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
+ pll_val, AR91XX_ETH0_PLL_SHIFT);
+}
+
+static void ar91xx_set_pll_ge1(int speed)
+{
+ //u32 val = ar71xx_get_eth_pll(1, speed);
+ u32 pll_val;
+
+ switch (speed) {
+ case SPEED_10:
+ pll_val = 0x00441099;
+ break;
+ case SPEED_100:
+ pll_val = 0x13000a44;
+ break;
+ case SPEED_1000:
+ pll_val = 0x1a000000;
+ break;
+ default:
+ BUG();
+ }
+
+ ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
+ pll_val, AR91XX_ETH1_PLL_SHIFT);
+}
+
+static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
+{
+ u32 t;
+
+ t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16)
+ | (((u32) mac[3]) << 8) | ((u32) mac[2]);
+
+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t);
+
+ t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16);
+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
+}
+
+static void ag71xx_dma_reset(struct ag71xx *ag)
+{
+ u32 val;
+ int i;
+
+ DBG("%s: txdesc reg: 0x%08x rxdesc reg: 0x%08x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_TX_DESC),
+ ag71xx_rr(ag, AG71XX_REG_RX_DESC));
+
+ /* stop RX and TX */
+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
+
+ /* clear descriptor addresses */
+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0);
+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0);
+
+ /* clear pending RX/TX interrupts */
+ for (i = 0; i < 256; i++) {
+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
+ }
+
+ /* clear pending errors */
+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
+
+ val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
+ if (val)
+ printf("%s: unable to clear DMA Rx status: %08x\n",
+ ag->dev->name, val);
+
+ val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
+
+ /* mask out reserved bits */
+ val &= ~0xff000000;
+
+ if (val)
+ printf("%s: unable to clear DMA Tx status: %08x\n",
+ ag->dev->name, val);
+}
+
+static void ag71xx_halt(struct eth_device *dev)
+{
+ struct ag71xx *ag = (struct ag71xx *) dev->priv;
+
+ /* stop RX engine */
+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
+
+ ag71xx_dma_reset(ag);
+}
+
+#define MAX_WAIT 1000
+
+static int ag71xx_send(struct eth_device *dev, volatile void *packet,
+ int length)
+{
+ struct ag71xx *ag = (struct ag71xx *) dev->priv;
+ struct ag71xx_ring *ring = &ag->tx_ring;
+ struct ag71xx_desc *desc;
+ int i;
+
+ i = ring->curr % AG71XX_TX_RING_SIZE;
+ desc = ring->buf[i].desc;
+
+ if (!ag71xx_desc_empty(desc)) {
+ printf("%s: tx buffer full\n", ag->dev->name);
+ return 1;
+ }
+
+ flush_cache((u32) packet, length);
+ desc->data = (u32) virt_to_phys(packet);
+ desc->ctrl = (length & DESC_PKTLEN_M);
+
+ DBG("%s: sending %#08x length %#08x\n",
+ ag->dev->name, desc->data, desc->ctrl);
+
+ ring->curr++;
+ if (ring->curr >= AG71XX_TX_RING_SIZE){
+ ring->curr = 0;
+ }
+
+ /* enable TX engine */
+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE);
+
+ for (i = 0; i < MAX_WAIT; i++)
+ {
+ if (ag71xx_desc_empty(desc))
+ break;
+ udelay(10);
+ }
+ if (i == MAX_WAIT) {
+ printf("%s: tx timed out!\n", ag->dev->name);
+ return -1;
+ }
+
+ /* disable TX engine */
+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
+ desc->data = 0;
+ desc->ctrl = DESC_EMPTY;
+
+ return 0;
+}
+
+static int ag71xx_recv(struct eth_device *dev)
+{
+ struct ag71xx *ag = (struct ag71xx *) dev->priv;
+ struct ag71xx_ring *ring = &ag->rx_ring;
+
+ for (;;) {
+ unsigned int i = ring->curr % AG71XX_RX_RING_SIZE;
+ struct ag71xx_desc *desc = ring->buf[i].desc;
+ int pktlen;
+
+ if (ag71xx_desc_empty(desc))
+ break;
+
+ DBG("%s: rx packets, curr=%u\n", dev->name, ring->curr);
+
+ pktlen = ag71xx_desc_pktlen(desc);
+ pktlen -= ETH_FCS_LEN;
+
+
+ NetReceive(NetRxPackets[i] , pktlen);
+ flush_cache( (u32) NetRxPackets[i], PKTSIZE_ALIGN);
+
+ ring->buf[i].desc->ctrl = DESC_EMPTY;
+ ring->curr++;
+ if (ring->curr >= AG71XX_RX_RING_SIZE){
+ ring->curr = 0;
+ }
+
+ }
+
+ if ((ag71xx_rr(ag, AG71XX_REG_RX_CTRL) & RX_CTRL_RXE) == 0) {
+ /* start RX engine */
+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
+ }
+
+ return 0;
+}
+
+#ifdef AG71XX_DEBUG
+static char *ag71xx_speed_str(struct ag71xx *ag)
+{
+ switch (ag->speed) {
+ case SPEED_1000:
+ return "1000";
+ case SPEED_100:
+ return "100";
+ case SPEED_10:
+ return "10";
+ }
+
+ return "?";
+}
+#endif
+
+void ag71xx_link_adjust(struct ag71xx *ag)
+{
+ u32 cfg2;
+ u32 ifctl;
+ u32 fifo5;
+ u32 mii_speed;
+
+ if (!ag->link) {
+ DBG("%s: link down\n", ag->dev->name);
+ return;
+ }
+
+ cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);
+ cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);
+ cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0;
+
+ ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);
+ ifctl &= ~(MAC_IFCTL_SPEED);
+
+ fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);
+ fifo5 &= ~FIFO_CFG5_BM;
+
+ switch (ag->speed) {
+ case SPEED_1000:
+ mii_speed = MII_CTRL_SPEED_1000;
+ cfg2 |= MAC_CFG2_IF_1000;
+ fifo5 |= FIFO_CFG5_BM;
+ break;
+ case SPEED_100:
+ mii_speed = MII_CTRL_SPEED_100;
+ cfg2 |= MAC_CFG2_IF_10_100;
+ ifctl |= MAC_IFCTL_SPEED;
+ break;
+ case SPEED_10:
+ mii_speed = MII_CTRL_SPEED_10;
+ cfg2 |= MAC_CFG2_IF_10_100;
+ break;
+ default:
+ BUG();
+ return;
+ }
+
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff);
+
+ if (ag->macNum == 0)
+ ar91xx_set_pll_ge0(ag->speed);
+ else
+ ar91xx_set_pll_ge1(ag->speed);
+
+ ag71xx_mii_ctrl_set_speed(ag, mii_speed);
+
+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
+ ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
+
+ DBG("%s: link up (%sMbps/%s duplex)\n",
+ ag->dev->name,
+ ag71xx_speed_str(ag),
+ (1 == ag->duplex) ? "Full" : "Half");
+
+ DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
+
+ DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
+
+ DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
+ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
+ ag71xx_mii_ctrl_rr(ag));
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int ag71xx_getMiiSpeed(struct ag71xx *ag)
+{
+ uint16_t phyreg, cap;
+
+ if (miiphy_read(ag->phyname, ag->phyid,
+ PHY_BMSR, &phyreg)) {
+ puts("PHY_BMSR read failed, assuming no link\n");
+ return -1;
+ }
+
+ if ((phyreg & PHY_BMSR_LS) == 0) {
+ return -1;
+ }
+
+ if (miiphy_read(ag->phyname, ag->phyid,
+ PHY_1000BTSR, &phyreg))
+ return -1;
+
+ if (phyreg & PHY_1000BTSR_1000FD) {
+ ag->speed = SPEED_1000;
+ ag->duplex = 1;
+ } else if (phyreg & PHY_1000BTSR_1000HD) {
+ ag->speed = SPEED_1000;
+ ag->duplex = 0;
+ } else {
+ if (miiphy_read(ag->phyname, ag->phyid,
+ PHY_ANAR, &cap))
+ return -1;
+
+ if (miiphy_read(ag->phyname, ag->phyid,
+ PHY_ANLPAR, &phyreg))
+ return -1;
+
+ cap &= phyreg;
+ if (cap & PHY_ANLPAR_TXFD) {
+ ag->speed = SPEED_100;
+ ag->duplex = 1;
+ } else if (cap & PHY_ANLPAR_TX) {
+ ag->speed = SPEED_100;
+ ag->duplex = 0;
+ } else if (cap & PHY_ANLPAR_10FD) {
+ ag->speed = SPEED_10;
+ ag->duplex = 1;
+ } else {
+ ag->speed = SPEED_10;
+ ag->duplex = 0;
+ }
+ }
+
+ ag->link = 1;
+
+ return 0;
+}
+#endif
+
+static int ag71xx_hw_start(struct eth_device *dev, bd_t * bd)
+{
+ struct ag71xx *ag = (struct ag71xx *) dev->priv;
+
+ ag71xx_dma_reset(ag);
+
+ ag71xx_ring_rx_clean(ag);
+ ag71xx_ring_tx_init(ag);
+
+ ag71xx_wr(ag, AG71XX_REG_TX_DESC,
+ (u32) virt_to_phys(ag->tx_ring.descs_dma));
+ ag71xx_wr(ag, AG71XX_REG_RX_DESC,
+ (u32) virt_to_phys(ag->rx_ring.descs_dma));
+
+ ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr);
+
+ if (ag->phyfixed) {
+ ag->link = 1;
+ ag->duplex = 1;
+ ag->speed = SPEED_1000;
+ } else {
+
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
+ if (ag71xx_getMiiSpeed(ag))
+ return -1;
+#else
+ /* only fixed, without mii */
+ return -1;
+#endif
+
+ }
+ ag71xx_link_adjust(ag);
+
+ DBG("%s: txdesc reg: %#08x rxdesc reg: %#08x\n",
+ ag->dev->name,
+ ag71xx_rr(ag, AG71XX_REG_TX_DESC),
+ ag71xx_rr(ag, AG71XX_REG_RX_DESC));
+
+ /* start RX engine */
+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
+
+ return 0;
+}
+
+#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
+
+#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
+ FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
+ FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
+ FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
+ FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
+ FIFO_CFG4_VT)
+
+#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
+ FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
+ FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
+ FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
+ FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
+ FIFO_CFG5_17 | FIFO_CFG5_SF)
+
+static int ag71xx_hw_init(struct ag71xx *ag)
+{
+ int ret = 0;
+ uint32_t reg;
+ uint32_t mask, mii_type;
+
+ if (ag->macNum == 0) {
+ mask = (RESET_MODULE_GE0_MAC | RESET_MODULE_GE0_PHY);
+ mii_type = 0x13;
+ } else {
+ mask = (RESET_MODULE_GE1_MAC | RESET_MODULE_GE1_PHY);
+ mii_type = 0x11;
+ }
+
+ // mac soft reset
+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR);
+ udelay(20);
+
+ // device stop
+ reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
+ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg | mask);
+ udelay(100 * 1000);
+
+ // device start
+ reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
+ ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg & ~mask);
+ udelay(100 * 1000);
+
+ /* setup MAC configuration registers */
+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, (MAC_CFG1_RXE | MAC_CFG1_TXE));
+
+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG2,
+ MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);
+
+ /* setup FIFO configuration register 0 */
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
+
+ /* setup MII interface type */
+ ag71xx_mii_ctrl_set_if(ag, ag->mii_if);
+
+ /* setup mdio clock divisor */
+ ag71xx_wr(ag, AG71XX_REG_MII_CFG, MII_CFG_CLK_DIV_20);
+
+ /* setup FIFO configuration registers */
+ ag71xx_sb(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);
+
+ ag71xx_dma_reset(ag);
+
+ ret = ag71xx_rings_init(ag);
+ if (ret)
+ return -1;
+
+ ag71xx_wr(ag, AG71XX_REG_TX_DESC,
+ (u32) virt_to_phys(ag->tx_ring.descs_dma));
+ ag71xx_wr(ag, AG71XX_REG_RX_DESC,
+ (u32) virt_to_phys(ag->rx_ring.descs_dma));
+
+ ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr);
+
+ return 0;
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+#define AG71XX_MDIO_RETRY 1000
+#define AG71XX_MDIO_DELAY 5
+
+static inline struct ag71xx *ag71xx_name2mac(char *devname)
+{
+ if (strcmp(devname, agtable[0].dev->name) == 0)
+ return &agtable[0];
+ else if (strcmp(devname, agtable[1].dev->name) == 0)
+ return &agtable[1];
+ else
+ return NULL;
+}
+
+static inline void ag71xx_mdio_wr(struct ag71xx *ag, unsigned reg,
+ u32 value)
+{
+ uint32_t r;
+
+ r = ag->mac_base + reg;
+ writel(value, r);
+
+ /* flush write */
+ (void) readl(r);
+}
+
+static inline u32 ag71xx_mdio_rr(struct ag71xx *ag, unsigned reg)
+{
+ return readl(ag->mac_base + reg);
+}
+
+static int ag71xx_mdio_read(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short *val)
+{
+ struct ag71xx *ag = ag71xx_name2mac(devname);
+ uint16_t regData;
+ int i;
+
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR,
+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_READ);
+
+ i = AG71XX_MDIO_RETRY;
+ while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
+ if (i-- == 0) {
+ printf("%s: mii_read timed out\n",
+ ag->dev->name);
+ return -1;
+ }
+ udelay(AG71XX_MDIO_DELAY);
+ }
+
+ regData = (uint16_t) ag71xx_mdio_rr(ag, AG71XX_REG_MII_STATUS) & 0xffff;
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
+
+ DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, regData);
+
+ if (val)
+ *val = regData;
+
+ return 0;
+}
+
+static int ag71xx_mdio_write(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short val)
+{
+ struct ag71xx *ag = ag71xx_name2mac(devname);
+ int i;
+
+ if (ag == NULL)
+ return 1;
+
+ DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
+
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR,
+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
+ ag71xx_mdio_wr(ag, AG71XX_REG_MII_CTRL, val);
+
+ i = AG71XX_MDIO_RETRY;
+ while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
+ if (i-- == 0) {
+ printf("%s: mii_write timed out\n",
+ ag->dev->name);
+ break;
+ }
+ udelay(AG71XX_MDIO_DELAY);
+ }
+
+ return 0;
+}
+#endif
+
+int ag71xx_register(bd_t * bis, char *phyname[], uint16_t phyid[], uint16_t phyfixed[])
+{
+ int i, num = 0;
+ u8 used_ports[MAX_AG71XX_DEVS] = CONFIG_AG71XX_PORTS;
+
+ for (i = 0; i < MAX_AG71XX_DEVS; i++) {
+ /*skip if port is configured not to use */
+ if (used_ports[i] == 0)
+ continue;
+
+ agtable[i].dev = malloc(sizeof(struct eth_device));
+ if (agtable[i].dev == NULL) {
+ puts("malloc failed\n");
+ return 0;
+ }
+ memset(agtable[i].dev, 0, sizeof(struct eth_device));
+ sprintf(agtable[i].dev->name, "eth%d", i);
+
+ agtable[i].dev->iobase = 0;
+ agtable[i].dev->init = ag71xx_hw_start;
+ agtable[i].dev->halt = ag71xx_halt;
+ agtable[i].dev->send = ag71xx_send;
+ agtable[i].dev->recv = ag71xx_recv;
+ agtable[i].dev->priv = (void *) (&agtable[i]);
+ agtable[i].macNum = i;
+ eth_register(agtable[i].dev);
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+
+ if ((phyname == NULL) || (phyid == NULL) || (phyfixed == NULL))
+ return -1;
+
+ agtable[i].phyname = strdup(phyname[i]);
+ agtable[i].phyid = phyid[i];
+ agtable[i].phyfixed = phyfixed[i];
+
+ miiphy_register(agtable[i].dev->name, ag71xx_mdio_read,
+ ag71xx_mdio_write);
+#endif
+
+ if (ag71xx_hw_init(&agtable[i]))
+ continue;
+
+ num++;
+ }
+
+ return num;
+}
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h
new file mode 100644
index 0000000..edce429
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h
@@ -0,0 +1,374 @@
+/*
+ * Atheros AR71xx built-in ethernet mac driver
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Based on Atheros' AG7100 driver
+ *
+ * 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 __AG71XX_H
+#define __AG71XX_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+#include <asm/ar71xx.h>
+
+// controller has 2 ports
+#define MAX_AG71XX_DEVS 2
+
+#define ETH_FCS_LEN 4
+
+#define SPEED_10 10
+#define SPEED_100 100
+#define SPEED_1000 1000
+
+
+#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
+#define AG71XX_INT_TX (AG71XX_INT_TX_PS)
+#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF)
+
+#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX)
+#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL)
+
+#define AG71XX_TX_FIFO_LEN 2048
+#define AG71XX_TX_MTU_LEN 1536
+#define AG71XX_RX_PKT_RESERVE 64
+#define AG71XX_RX_PKT_SIZE \
+ (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN)
+
+#ifndef CONFIG_SYS_RX_ETH_BUFFER
+#define AG71XX_TX_RING_SIZE 4
+#define AG71XX_RX_RING_SIZE 4
+#else
+#define AG71XX_TX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER
+#define AG71XX_RX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER
+#endif
+
+#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4)
+#define AG71XX_TX_THRES_WAKEUP \
+ (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4))
+
+
+
+
+struct ag71xx_desc {
+ u32 data;
+ u32 ctrl;
+#define DESC_EMPTY BIT(31)
+#define DESC_MORE BIT(24)
+#define DESC_PKTLEN_M 0xfff
+ u32 next;
+ u32 pad;
+} __attribute__((aligned(4)));
+
+struct ag71xx_buf {
+ struct sk_buff *skb;
+ struct ag71xx_desc *desc;
+ dma_addr_t dma_addr;
+ u32 pad;
+};
+
+struct ag71xx_ring {
+ struct ag71xx_buf *buf;
+ u8 *descs_cpu;
+ u8 *descs_dma;
+ unsigned int desc_size;
+ unsigned int curr;
+ unsigned int size;
+};
+
+struct ag71xx {
+ uint32_t mac_base;
+ uint32_t mii_ctrl;
+
+ struct eth_device *dev;
+
+ struct ag71xx_ring rx_ring;
+ struct ag71xx_ring tx_ring;
+
+ char *phyname;
+ u16 phyid;
+ u16 phyfixed;
+ uint32_t link;
+ uint32_t speed;
+ int32_t duplex;
+ uint32_t macNum;
+ uint32_t mii_if;
+};
+
+void ag71xx_link_adjust(struct ag71xx *ag);
+
+int ag71xx_phy_connect(struct ag71xx *ag);
+void ag71xx_phy_disconnect(struct ag71xx *ag);
+void ag71xx_phy_start(struct ag71xx *ag);
+void ag71xx_phy_stop(struct ag71xx *ag);
+
+static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
+{
+ return ((desc->ctrl & DESC_EMPTY) != 0);
+}
+
+static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
+{
+ return (desc->ctrl & DESC_PKTLEN_M);
+}
+
+/* Register offsets */
+#define AG71XX_REG_MAC_CFG1 0x0000
+#define AG71XX_REG_MAC_CFG2 0x0004
+#define AG71XX_REG_MAC_IPG 0x0008
+#define AG71XX_REG_MAC_HDX 0x000c
+#define AG71XX_REG_MAC_MFL 0x0010
+#define AG71XX_REG_MII_CFG 0x0020
+#define AG71XX_REG_MII_CMD 0x0024
+#define AG71XX_REG_MII_ADDR 0x0028
+#define AG71XX_REG_MII_CTRL 0x002c
+#define AG71XX_REG_MII_STATUS 0x0030
+#define AG71XX_REG_MII_IND 0x0034
+#define AG71XX_REG_MAC_IFCTL 0x0038
+#define AG71XX_REG_MAC_ADDR1 0x0040
+#define AG71XX_REG_MAC_ADDR2 0x0044
+#define AG71XX_REG_FIFO_CFG0 0x0048
+#define AG71XX_REG_FIFO_CFG1 0x004c
+#define AG71XX_REG_FIFO_CFG2 0x0050
+#define AG71XX_REG_FIFO_CFG3 0x0054
+#define AG71XX_REG_FIFO_CFG4 0x0058
+#define AG71XX_REG_FIFO_CFG5 0x005c
+#define AG71XX_REG_FIFO_RAM0 0x0060
+#define AG71XX_REG_FIFO_RAM1 0x0064
+#define AG71XX_REG_FIFO_RAM2 0x0068
+#define AG71XX_REG_FIFO_RAM3 0x006c
+#define AG71XX_REG_FIFO_RAM4 0x0070
+#define AG71XX_REG_FIFO_RAM5 0x0074
+#define AG71XX_REG_FIFO_RAM6 0x0078
+#define AG71XX_REG_FIFO_RAM7 0x007c
+
+#define AG71XX_REG_TX_CTRL 0x0180
+#define AG71XX_REG_TX_DESC 0x0184
+#define AG71XX_REG_TX_STATUS 0x0188
+#define AG71XX_REG_RX_CTRL 0x018c
+#define AG71XX_REG_RX_DESC 0x0190
+#define AG71XX_REG_RX_STATUS 0x0194
+#define AG71XX_REG_INT_ENABLE 0x0198
+#define AG71XX_REG_INT_STATUS 0x019c
+
+#define MAC_CFG1_TXE BIT(0) /* Tx Enable */
+#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */
+#define MAC_CFG1_RXE BIT(2) /* Rx Enable */
+#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */
+#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */
+#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */
+#define MAC_CFG1_LB BIT(8) /* Loopback mode */
+#define MAC_CFG1_SR BIT(31) /* Soft Reset */
+
+#define MAC_CFG2_FDX BIT(0)
+#define MAC_CFG2_CRC_EN BIT(1)
+#define MAC_CFG2_PAD_CRC_EN BIT(2)
+#define MAC_CFG2_LEN_CHECK BIT(4)
+#define MAC_CFG2_HUGE_FRAME_EN BIT(5)
+#define MAC_CFG2_IF_1000 BIT(9)
+#define MAC_CFG2_IF_10_100 BIT(8)
+
+#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */
+#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */
+#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */
+#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */
+#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */
+#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
+ | FIFO_CFG0_TXS | FIFO_CFG0_TXF)
+
+#define FIFO_CFG0_ENABLE_SHIFT 8
+
+#define FIFO_CFG4_DE BIT(0) /* Drop Event */
+#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */
+#define FIFO_CFG4_FC BIT(2) /* False Carrier */
+#define FIFO_CFG4_CE BIT(3) /* Code Error */
+#define FIFO_CFG4_CR BIT(4) /* CRC error */
+#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */
+#define FIFO_CFG4_LO BIT(6) /* Length out of range */
+#define FIFO_CFG4_OK BIT(7) /* Packet is OK */
+#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */
+#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */
+#define FIFO_CFG4_DR BIT(10) /* Dribble */
+#define FIFO_CFG4_LE BIT(11) /* Long Event */
+#define FIFO_CFG4_CF BIT(12) /* Control Frame */
+#define FIFO_CFG4_PF BIT(13) /* Pause Frame */
+#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */
+#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */
+#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */
+#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */
+
+#define FIFO_CFG5_DE BIT(0) /* Drop Event */
+#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */
+#define FIFO_CFG5_FC BIT(2) /* False Carrier */
+#define FIFO_CFG5_CE BIT(3) /* Code Error */
+#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */
+#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */
+#define FIFO_CFG5_OK BIT(6) /* Packet is OK */
+#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */
+#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */
+#define FIFO_CFG5_DR BIT(9) /* Dribble */
+#define FIFO_CFG5_CF BIT(10) /* Control Frame */
+#define FIFO_CFG5_PF BIT(11) /* Pause Frame */
+#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */
+#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */
+#define FIFO_CFG5_LE BIT(14) /* Long Event */
+#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */
+#define FIFO_CFG5_16 BIT(16) /* unknown */
+#define FIFO_CFG5_17 BIT(17) /* unknown */
+#define FIFO_CFG5_SF BIT(18) /* Short Frame */
+#define FIFO_CFG5_BM BIT(19) /* Byte Mode */
+
+#define AG71XX_INT_TX_PS BIT(0)
+#define AG71XX_INT_TX_UR BIT(1)
+#define AG71XX_INT_TX_BE BIT(3)
+#define AG71XX_INT_RX_PR BIT(4)
+#define AG71XX_INT_RX_OF BIT(6)
+#define AG71XX_INT_RX_BE BIT(7)
+
+#define MAC_IFCTL_SPEED BIT(16)
+
+#define MII_CFG_CLK_DIV_4 0
+#define MII_CFG_CLK_DIV_6 2
+#define MII_CFG_CLK_DIV_8 3
+#define MII_CFG_CLK_DIV_10 4
+#define MII_CFG_CLK_DIV_14 5
+#define MII_CFG_CLK_DIV_20 6
+#define MII_CFG_CLK_DIV_28 7
+#define MII_CFG_RESET BIT(31)
+
+#define MII_CMD_WRITE 0x0
+#define MII_CMD_READ 0x1
+#define MII_ADDR_SHIFT 8
+#define MII_IND_BUSY BIT(0)
+#define MII_IND_INVALID BIT(2)
+
+#define TX_CTRL_TXE BIT(0) /* Tx Enable */
+
+#define TX_STATUS_PS BIT(0) /* Packet Sent */
+#define TX_STATUS_UR BIT(1) /* Tx Underrun */
+#define TX_STATUS_BE BIT(3) /* Bus Error */
+
+#define RX_CTRL_RXE BIT(0) /* Rx Enable */
+
+#define RX_STATUS_PR BIT(0) /* Packet Received */
+#define RX_STATUS_OF BIT(2) /* Rx Overflow */
+#define RX_STATUS_BE BIT(3) /* Bus Error */
+
+#define MII_CTRL_IF_MASK 3
+#define MII_CTRL_SPEED_SHIFT 4
+#define MII_CTRL_SPEED_MASK 3
+#define MII_CTRL_SPEED_10 0
+#define MII_CTRL_SPEED_100 1
+#define MII_CTRL_SPEED_1000 2
+
+static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
+{
+ __raw_writel(value, ag->mac_base + reg);
+ /* flush write */
+ (void) __raw_readl(ag->mac_base + reg);
+}
+
+static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
+{
+ return __raw_readl(ag->mac_base + reg);
+}
+
+static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask)
+{
+ uint32_t r;
+
+ r = ag->mac_base + reg;
+ __raw_writel(__raw_readl(r) | mask, r);
+ /* flush write */
+ (void)__raw_readl(r);
+}
+
+static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask)
+{
+ uint32_t r;
+
+ r = ag->mac_base + reg;
+ __raw_writel(__raw_readl(r) & ~mask, r);
+ /* flush write */
+ (void) __raw_readl(r);
+}
+
+static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
+{
+ ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);
+}
+
+static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
+{
+ ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
+}
+
+static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value)
+{
+ __raw_writel(value, ag->mii_ctrl);
+
+ /* flush write */
+ __raw_readl(ag->mii_ctrl);
+}
+
+static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
+{
+ return __raw_readl(ag->mii_ctrl);
+}
+
+static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
+ unsigned int mii_if)
+{
+ u32 t;
+
+ t = ag71xx_mii_ctrl_rr(ag);
+ t &= ~(MII_CTRL_IF_MASK);
+ t |= (mii_if & MII_CTRL_IF_MASK);
+ ag71xx_mii_ctrl_wr(ag, t);
+}
+
+static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
+ unsigned int speed)
+{
+ u32 t;
+
+ t = ag71xx_mii_ctrl_rr(ag);
+ t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
+ t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT;
+ ag71xx_mii_ctrl_wr(ag, t);
+}
+
+#ifdef CONFIG_AG71XX_AR8216_SUPPORT
+void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
+ int pktlen);
+static inline int ag71xx_has_ar8216(struct ag71xx *ag)
+{
+ return ag71xx_get_pdata(ag)->has_ar8216;
+}
+#else
+static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
+ struct sk_buff *skb)
+{
+}
+
+static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
+ struct sk_buff *skb,
+ int pktlen)
+{
+ return 0;
+}
+static inline int ag71xx_has_ar8216(struct ag71xx *ag)
+{
+ return 0;
+}
+#endif
+
+#endif /* _AG71XX_H */
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/entries b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/entries
new file mode 100644
index 0000000..ad8ef18
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/drivers/net/phy
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+rtl8366_mii.c
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+2075819b75c9da42261c89c49b53bf2d
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+18599
+
+rtl8366.h
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+6bca21a0bce104b8b2de10207b04b584
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6036
+
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366.h.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366.h.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366.h.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366_mii.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366_mii.c.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366_mii.c.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366.h.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366.h.svn-base
new file mode 100644
index 0000000..f0567dd
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366.h.svn-base
@@ -0,0 +1,188 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef RTL8366_MII_H
+#define RTL8366_MII_H
+
+#define MII_CONTROL_REG 0
+#define MII_STATUS_REG 1
+#define MII_PHY_ID0 2
+#define MII_PHY_ID1 3
+#define MII_LOCAL_CAP 4
+#define MII_REMOTE_CAP 5
+#define MII_EXT_AUTONEG 6
+#define MII_LOCAL_NEXT_PAGE 7
+#define MII_REMOTE_NEXT_PAGE 8
+#define MII_GIGA_CONTROL 9
+#define MII_GIGA_STATUS 10
+#define MII_EXT_STATUS_REG 15
+
+/* Control register */
+#define MII_CONTROL_1000MBPS 6
+#define MII_CONTROL_COLL_TEST 7
+#define MII_CONTROL_FULLDUPLEX 8
+#define MII_CONTROL_RENEG 9
+#define MII_CONTROL_ISOLATE 10
+#define MII_CONTROL_POWERDOWN 11
+#define MII_CONTROL_AUTONEG 12
+#define MII_CONTROL_100MBPS 13
+#define MII_CONTROL_LOOPBACK 14
+#define MII_CONTROL_RESET 15
+
+/* Status/Extended status register */
+/* Basic status */
+#define MII_STATUS_CAPABILITY 0
+#define MII_STATUS_JABBER 1
+#define MII_STATUS_LINK_UP 2
+#define MII_STATUS_AUTONEG_ABLE 3
+#define MII_STATUS_REMOTE_FAULT 4
+#define MII_STATUS_AUTONEG_DONE 5
+#define MII_STATUS_NO_PREAMBLE 6
+#define MII_STATUS_RESERVED 7
+#define MII_STATUS_EXTENDED 8
+#define MII_STATUS_100_T2_HALF 9
+#define MII_STATUS_100_T2_FULL 10
+#define MII_STATUS_10_TX_HALF 11
+#define MII_STATUS_10_TX_FULL 12
+#define MII_STATUS_100_TX_HALF 13
+#define MII_STATUS_100_TX_FULL 14
+#define MII_STATUS_100_T4 15
+
+#define MII_GIGA_CONTROL_HALF 8
+#define MII_GIGA_CONTROL_FULL 9
+#define MII_GIGA_STATUS_HALF 10
+#define MII_GIGA_STATUS_FULL 11
+
+/* Extended status */
+#define MII_STATUS_1000_T_HALF 12
+#define MII_STATUS_1000_T_FULL 13
+#define MII_STATUS_1000_X_HALF 14
+#define MII_STATUS_1000_X_FULL 15
+
+/* Local/Remmote capability register */
+#define MII_CAP_10BASE_TX 5
+#define MII_CAP_10BASE_TX_FULL 6
+#define MII_CAP_100BASE_TX 7
+#define MII_CAP_100BASE_TX_FULL 8
+#define MII_CAP_100BASE_T4 9
+#define MII_CAP_SYMM_PAUSE 10
+#define MII_CAP_ASYMM_PAUSE 11
+#define MII_CAP_RESERVED 12
+#define MII_CAP_REMOTE_FAULT 13
+#define MII_CAP_ACKNOWLEDGE 14
+#define MII_CAP_NEXT_PAGE 15
+#define MII_CAP_IEEE_802_3 0x0001
+
+#define MII_LINK_MODE_MASK 0x1f
+
+#define REALTEK_RTL8366_CHIP_ID0 0x001C
+#define REALTEK_RTL8366_CHIP_ID1 0xC940
+#define REALTEK_RTL8366_CHIP_ID1_MP 0xC960
+
+#define REALTEK_MIN_PORT_ID 0
+#define REALTEK_MAX_PORT_ID 5
+#define REALTEK_MIN_PHY_ID REALTEK_MIN_PORT_ID
+#define REALTEK_MAX_PHY_ID 4
+#define REALTEK_CPU_PORT_ID REALTEK_MAX_PORT_ID
+#define REALTEK_PHY_PORT_MASK ((1<<(REALTEK_MAX_PHY_ID+1)) - (1<<REALTEK_MIN_PHY_ID))
+#define REALTEK_CPU_PORT_MASK (1<<REALTEK_CPU_PORT_ID)
+#define REALTEK_ALL_PORT_MASK (REALTEK_PHY_PORT_MASK | REALTEK_CPU_PORT_MASK)
+
+/* port ability */
+#define RTL8366S_PORT_ABILITY_BASE 0x0011
+
+/* port vlan control register */
+#define RTL8366S_PORT_VLAN_CTRL_BASE 0x0058
+
+/* port linking status */
+#define RTL8366S_PORT_LINK_STATUS_BASE 0x0060
+#define RTL8366S_PORT_STATUS_SPEED_BIT 0
+#define RTL8366S_PORT_STATUS_SPEED_MSK 0x0003
+#define RTL8366S_PORT_STATUS_DUPLEX_BIT 2
+#define RTL8366S_PORT_STATUS_DUPLEX_MSK 0x0004
+#define RTL8366S_PORT_STATUS_LINK_BIT 4
+#define RTL8366S_PORT_STATUS_LINK_MSK 0x0010
+#define RTL8366S_PORT_STATUS_TXPAUSE_BIT 5
+#define RTL8366S_PORT_STATUS_TXPAUSE_MSK 0x0020
+#define RTL8366S_PORT_STATUS_RXPAUSE_BIT 6
+#define RTL8366S_PORT_STATUS_RXPAUSE_MSK 0x0040
+#define RTL8366S_PORT_STATUS_AN_BIT 7
+#define RTL8366S_PORT_STATUS_AN_MSK 0x0080
+
+/* internal control */
+#define RTL8366S_RESET_CONTROL_REG 0x0100
+#define RTL8366S_RESET_QUEUE_BIT 2
+
+#define RTL8366S_CHIP_ID_REG 0x0105
+
+/* MAC control */
+#define RTL8366S_MAC_FORCE_CTRL0_REG 0x0F04
+#define RTL8366S_MAC_FORCE_CTRL1_REG 0x0F05
+
+
+/* PHY registers control */
+#define RTL8366S_PHY_ACCESS_CTRL_REG 0x8028
+#define RTL8366S_PHY_ACCESS_DATA_REG 0x8029
+
+#define RTL8366S_PHY_CTRL_READ 1
+#define RTL8366S_PHY_CTRL_WRITE 0
+
+#define RTL8366S_PHY_REG_MASK 0x1F
+#define RTL8366S_PHY_PAGE_OFFSET 5
+#define RTL8366S_PHY_PAGE_MASK (0x7<<5)
+#define RTL8366S_PHY_NO_OFFSET 9
+#define RTL8366S_PHY_NO_MASK (0x1F<<9)
+
+#define RTL8366S_PHY_NO_MAX 4
+#define RTL8366S_PHY_PAGE_MAX 7
+#define RTL8366S_PHY_ADDR_MAX 31
+
+/* cpu port control reg */
+#define RTL8366S_CPU_CTRL_REG 0x004F
+#define RTL8366S_CPU_DRP_BIT 14
+#define RTL8366S_CPU_DRP_MSK 0x4000
+#define RTL8366S_CPU_INSTAG_BIT 15
+#define RTL8366S_CPU_INSTAG_MSK 0x8000
+
+/* LED registers*/
+#define RTL8366S_LED_BLINK_REG 0x420
+#define RTL8366S_LED_BLINKRATE_BIT 0
+#define RTL8366S_LED_BLINKRATE_MSK 0x0007
+#define RTL8366S_LED_INDICATED_CONF_REG 0x421
+#define RTL8366S_LED_0_1_FORCE_REG 0x422
+#define RTL8366S_LED_2_3_FORCE_REG 0x423
+#define RTL8366S_LEDCONF_LEDFORCE 0x1F
+#define RTL8366S_LED_GROUP_MAX 4
+
+#define RTL8366S_GREEN_FEATURE_REG 0x000A
+#define RTL8366S_GREEN_FEATURE_TX_BIT 3
+#define RTL8366S_GREEN_FEATURE_TX_MSK 0x0008
+#define RTL8366S_GREEN_FEATURE_RX_BIT 4
+#define RTL8366S_GREEN_FEATURE_RX_MSK 0x0010
+
+#define RTL8366S_MODEL_ID_REG 0x5C
+#define RTL8366S_REV_ID_REG 0x5D
+#define RTL8366S_MODEL_8366SR 0x6027
+#define RTL8366S_MODEL_8366RB 0x5937
+
+#endif
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366_mii.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366_mii.c.svn-base
new file mode 100644
index 0000000..e3c5316
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366_mii.c.svn-base
@@ -0,0 +1,786 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <common.h>
+#include <net.h>
+#include <netdev.h>
+#include <miiphy.h>
+#include MII_GPIOINCLUDE
+
+#include "rtl8366.h"
+
+#ifdef DEBUG_RTL8366
+ #define DBG(fmt,args...) printf (fmt ,##args)
+#else
+ #define DBG(fmt,args...)
+#endif
+
+
+//-------------------------------------------------------------------
+// Soft SMI functions
+//-------------------------------------------------------------------
+
+#define DELAY 2
+
+static void smi_init(void)
+{
+ MII_SDAINPUT;
+ MII_SCKINPUT;
+
+ MII_SETSDA(1);
+ MII_SETSCK(1);
+
+ udelay(20);
+}
+
+static void smi_start(void)
+{
+/*
+ * rtl8366 chip needs a extra clock with
+ * SDA high before start condition
+ */
+
+ /* set gpio pins output */
+ MII_SDAOUTPUT;
+ MII_SCKOUTPUT;
+ udelay(DELAY);
+
+ /* set initial state: SCK:0, SDA:1 */
+ MII_SETSCK(0);
+ MII_SETSDA(1);
+ udelay(DELAY);
+
+ /* toggle clock */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ udelay(DELAY);
+
+ /* start condition */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSDA(0);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ udelay(DELAY);
+ MII_SETSDA(1);
+}
+
+static void smi_stop(void)
+{
+/*
+ * rtl8366 chip needs a extra clock with
+ * SDA high after stop condition
+ */
+
+ /* stop condition */
+ udelay(DELAY);
+ MII_SETSDA(0);
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSDA(1);
+ udelay(DELAY);
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ udelay(DELAY);
+
+ /* toggle clock */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ udelay(DELAY);
+ MII_SETSCK(1);
+
+ /* set gpio pins input */
+ MII_SDAINPUT;
+ MII_SCKINPUT;
+}
+
+static void smi_writeBits(uint32_t data, uint8_t length)
+{
+ uint8_t test;
+
+ for( ; length > 0; length--) {
+ udelay(DELAY);
+
+ /* output data */
+ test = (((data & (1 << (length - 1))) != 0) ? 1 : 0);
+ MII_SETSDA(test);
+ udelay(DELAY);
+
+ /* toogle clock */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ }
+}
+
+static uint32_t smi_readBits(uint8_t length)
+{
+ uint32_t ret;
+
+ MII_SDAINPUT;
+
+ for(ret = 0 ; length > 0; length--) {
+ udelay(DELAY);
+
+ ret <<= 1;
+
+ /* toogle clock */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ ret |= MII_GETSDA;
+ MII_SETSCK(0);
+ }
+
+ MII_SDAOUTPUT;
+
+ return ret;
+}
+
+static int smi_waitAck(void)
+{
+ uint32_t retry = 0;
+
+ while (smi_readBits(1)) {
+ if (retry++ == 5)
+ return -1;
+ }
+
+ return 0;
+
+}
+
+static int smi_read(uint32_t reg, uint32_t *data)
+{
+ uint32_t rawData;
+
+ /* send start condition */
+ smi_start();
+ /* send CTRL1 code: 0b1010*/
+ smi_writeBits(0x0a, 4);
+ /* send CTRL2 code: 0b100 */
+ smi_writeBits(0x04, 3);
+ /* send READ command */
+ smi_writeBits(0x01, 1);
+
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* send address low */
+ smi_writeBits(reg & 0xFF, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+ /* send address high */
+ smi_writeBits((reg & 0xFF00) >> 8, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* read data low */
+ rawData = (smi_readBits(8) & 0xFF);
+ /* send ACK */
+ smi_writeBits(0, 1);
+ /* read data high */
+ rawData |= (smi_readBits(8) & 0xFF) << 8;
+ /* send NACK */
+ smi_writeBits(1, 1);
+
+ /* send stop condition */
+ smi_stop();
+
+ if (data)
+ *data = rawData;
+
+ return 0;
+}
+
+static int smi_write(uint32_t reg, uint32_t data)
+{
+ /* send start condition */
+ smi_start();
+ /* send CTRL1 code: 0b1010*/
+ smi_writeBits(0x0a, 4);
+ /* send CTRL2 code: 0b100 */
+ smi_writeBits(0x04, 3);
+ /* send WRITE command */
+ smi_writeBits(0x00, 1);
+
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* send address low */
+ smi_writeBits(reg & 0xFF, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+ /* send address high */
+ smi_writeBits((reg & 0xFF00) >> 8, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* send data low */
+ smi_writeBits(data & 0xFF, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+ /* send data high */
+ smi_writeBits((data & 0xFF00) >> 8, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* send stop condition */
+ smi_stop();
+
+ return 0;
+}
+
+
+//-------------------------------------------------------------------
+// Switch register read / write functions
+//-------------------------------------------------------------------
+static int rtl8366_readRegister(uint32_t reg, uint16_t *data)
+{
+ uint32_t regData;
+
+ DBG("rtl8366: read register=%#04x, data=", reg);
+
+ if (smi_read(reg, &regData)) {
+ printf("\nrtl8366 smi read failed!\n");
+ return -1;
+ }
+
+ if (data)
+ *data = regData;
+
+ DBG("%#04x\n", regData);
+
+ return 0;
+}
+
+static int rtl8366_writeRegister(uint32_t reg, uint16_t data)
+{
+ DBG("rtl8366: write register=%#04x, data=%#04x\n", reg, data);
+
+ if (smi_write(reg, data)) {
+ printf("rtl8366 smi write failed!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int rtl8366_setRegisterBit(uint32_t reg, uint32_t bitNum, uint32_t value)
+{
+ uint16_t regData;
+
+ if (bitNum >= 16)
+ return -1;
+
+ if (rtl8366_readRegister(reg, &regData))
+ return -1;
+
+ if (value)
+ regData |= (1 << bitNum);
+ else
+ regData &= ~(1 << bitNum);
+
+ if (rtl8366_writeRegister(reg, regData))
+ return -1;
+
+ return 0;
+}
+
+//-------------------------------------------------------------------
+// MII PHY read / write functions
+//-------------------------------------------------------------------
+static int rtl8366_getPhyReg(uint32_t phyNum, uint32_t reg, uint16_t *data)
+{
+ uint16_t phyAddr, regData;
+
+ if (phyNum > RTL8366S_PHY_NO_MAX) {
+ printf("rtl8366s: invalid phy number!\n");
+ return -1;
+ }
+
+ if (phyNum > RTL8366S_PHY_ADDR_MAX) {
+ printf("rtl8366s: invalid phy register number!\n");
+ return -1;
+ }
+
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
+ RTL8366S_PHY_CTRL_READ))
+ return -1;
+
+ phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
+ | (reg & RTL8366S_PHY_REG_MASK);
+ if (rtl8366_writeRegister(phyAddr, 0))
+ return -1;
+
+ if (rtl8366_readRegister(RTL8366S_PHY_ACCESS_DATA_REG, &regData))
+ return -1;
+
+ if (data)
+ *data = regData;
+
+ return 0;
+}
+
+static int rtl8366_setPhyReg(uint32_t phyNum, uint32_t reg, uint16_t data)
+{
+ uint16_t phyAddr;
+
+ if (phyNum > RTL8366S_PHY_NO_MAX) {
+ printf("rtl8366s: invalid phy number!\n");
+ return -1;
+ }
+
+ if (phyNum > RTL8366S_PHY_ADDR_MAX) {
+ printf("rtl8366s: invalid phy register number!\n");
+ return -1;
+ }
+
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
+ RTL8366S_PHY_CTRL_WRITE))
+ return -1;
+
+ phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
+ | (reg & RTL8366S_PHY_REG_MASK);
+ if (rtl8366_writeRegister(phyAddr, data))
+ return -1;
+
+ return 0;
+}
+
+static int rtl8366_miiread(char *devname, uchar phy_adr, uchar reg, ushort *data)
+{
+ uint16_t regData;
+
+ DBG("rtl8366_miiread: devname=%s, addr=%#02x, reg=%#02x\n",
+ devname, phy_adr, reg);
+
+ if (strcmp(devname, RTL8366_DEVNAME) != 0)
+ return -1;
+
+ if (rtl8366_getPhyReg(phy_adr, reg, &regData)) {
+ printf("rtl8366_miiread: write failed!\n");
+ return -1;
+ }
+
+ if (data)
+ *data = regData;
+
+ return 0;
+}
+
+static int rtl8366_miiwrite(char *devname, uchar phy_adr, uchar reg, ushort data)
+{
+ DBG("rtl8366_miiwrite: devname=%s, addr=%#02x, reg=%#02x, data=%#04x\n",
+ devname, phy_adr, reg, data);
+
+ if (strcmp(devname, RTL8366_DEVNAME) != 0)
+ return -1;
+
+ if (rtl8366_setPhyReg(phy_adr, reg, data)) {
+ printf("rtl8366_miiwrite: write failed!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366_mii_register(bd_t *bis)
+{
+ miiphy_register(strdup(RTL8366_DEVNAME), rtl8366_miiread,
+ rtl8366_miiwrite);
+
+ return 0;
+}
+
+
+//-------------------------------------------------------------------
+// Switch management functions
+//-------------------------------------------------------------------
+
+int rtl8366s_setGreenFeature(uint32_t tx, uint32_t rx)
+{
+ if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
+ RTL8366S_GREEN_FEATURE_TX_BIT, tx))
+ return -1;
+
+ if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
+ RTL8366S_GREEN_FEATURE_RX_BIT, rx))
+ return -1;
+
+ return 0;
+}
+
+int rtl8366s_setPowerSaving(uint32_t phyNum, uint32_t enabled)
+{
+ uint16_t regData;
+
+ if (phyNum > RTL8366S_PHY_NO_MAX)
+ return -1;
+
+ if (rtl8366_getPhyReg(phyNum, 12, &regData))
+ return -1;
+
+ if (enabled)
+ regData |= (1 << 12);
+ else
+ regData &= ~(1 << 12);
+
+ if (rtl8366_setPhyReg(phyNum, 12, regData))
+ return -1;
+
+ return 0;
+}
+
+int rtl8366s_setGreenEthernet(uint32_t greenFeature, uint32_t powerSaving)
+{
+ uint32_t phyNum, i;
+ uint16_t regData;
+
+ const uint16_t greenSettings[][2] =
+ {
+ {0xBE5B,0x3500},
+ {0xBE5C,0xB975},
+ {0xBE5D,0xB9B9},
+ {0xBE77,0xA500},
+ {0xBE78,0x5A78},
+ {0xBE79,0x6478}
+ };
+
+ if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, &regData))
+ return -1;
+
+ switch (regData)
+ {
+ case 0x0000:
+ for (i = 0; i < 6; i++) {
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
+ return -1;
+ if (rtl8366_writeRegister(greenSettings[i][0], greenSettings[i][1]))
+ return -1;
+ }
+ break;
+
+ case RTL8366S_MODEL_8366SR:
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
+ return -1;
+ if (rtl8366_writeRegister(greenSettings[0][0], greenSettings[0][1]))
+ return -1;
+ break;
+
+ default:
+ printf("rtl8366s_initChip: unsupported chip found!\n");
+ return -1;
+ }
+
+ if (rtl8366s_setGreenFeature(greenFeature, powerSaving))
+ return -1;
+
+ for (phyNum = 0; phyNum <= RTL8366S_PHY_NO_MAX; phyNum++) {
+ if (rtl8366s_setPowerSaving(phyNum, powerSaving))
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_setCPUPortMask(uint8_t port, uint32_t enabled)
+{
+ if(port >= 6){
+ printf("rtl8366s_setCPUPortMask: invalid port number\n");
+ return -1;
+ }
+
+ return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG, port, enabled);
+}
+
+int rtl8366s_setCPUDisableInsTag(uint32_t enable)
+{
+ return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
+ RTL8366S_CPU_INSTAG_BIT, enable);
+}
+
+int rtl8366s_setCPUDropUnda(uint32_t enable)
+{
+ return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
+ RTL8366S_CPU_DRP_BIT, enable);
+}
+
+int rtl8366s_setCPUPort(uint8_t port, uint32_t noTag, uint32_t dropUnda)
+{
+ uint32_t i;
+
+ if(port >= 6){
+ printf("rtl8366s_setCPUPort: invalid port number\n");
+ return -1;
+ }
+
+ /* reset register */
+ for(i = 0; i < 6; i++)
+ {
+ if(rtl8366s_setCPUPortMask(i, 0)){
+ printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
+ return -1;
+ }
+ }
+
+ if(rtl8366s_setCPUPortMask(port, 1)){
+ printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
+ return -1;
+ }
+
+ if(rtl8366s_setCPUDisableInsTag(noTag)){
+ printf("rtl8366s_setCPUPort: rtl8366s_setCPUDisableInsTag fail\n");
+ return -1;
+ }
+
+ if(rtl8366s_setCPUDropUnda(dropUnda)){
+ printf("rtl8366s_setCPUPort: rtl8366s_setCPUDropUnda fail\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_setLedConfig(uint32_t ledNum, uint8_t config)
+{
+ uint16_t regData;
+
+ if(ledNum >= RTL8366S_LED_GROUP_MAX) {
+ DBG("rtl8366s_setLedConfig: invalid led group\n");
+ return -1;
+ }
+
+ if(config > RTL8366S_LEDCONF_LEDFORCE) {
+ DBG("rtl8366s_setLedConfig: invalid led config\n");
+ return -1;
+ }
+
+ if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, &regData)) {
+ printf("rtl8366s_setLedConfig: failed to get led register!\n");
+ return -1;
+ }
+
+ regData &= ~(0xF << (ledNum * 4));
+ regData |= config << (ledNum * 4);
+
+ if (rtl8366_writeRegister(RTL8366S_LED_INDICATED_CONF_REG, regData)) {
+ printf("rtl8366s_setLedConfig: failed to set led register!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_getLedConfig(uint32_t ledNum, uint8_t *config)
+{
+ uint16_t regData;
+
+ if(ledNum >= RTL8366S_LED_GROUP_MAX) {
+ DBG("rtl8366s_getLedConfig: invalid led group\n");
+ return -1;
+ }
+
+ if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, &regData)) {
+ printf("rtl8366s_getLedConfig: failed to get led register!\n");
+ return -1;
+ }
+
+ if (config)
+ *config = (regData >> (ledNum * 4)) & 0xF;
+
+ return 0;
+}
+
+int rtl8366s_setLedForceValue(uint32_t group0, uint32_t group1,
+ uint32_t group2, uint32_t group3)
+{
+ uint16_t regData;
+
+ regData = (group0 & 0x3F) | ((group1 & 0x3F) << 6);
+ if (rtl8366_writeRegister(RTL8366S_LED_0_1_FORCE_REG, regData)) {
+ printf("rtl8366s_setLedForceValue: failed to set led register!\n");
+ return -1;
+ }
+
+ regData = (group2 & 0x3F) | ((group3 & 0x3F) << 6);
+ if (rtl8366_writeRegister(RTL8366S_LED_2_3_FORCE_REG, regData)) {
+ printf("rtl8366s_setLedForceValue: failed to set led register!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_initChip(void)
+{
+ uint32_t ledGroup, i = 0;
+ uint16_t regData;
+ uint8_t ledData[RTL8366S_LED_GROUP_MAX];
+ const uint16_t (*chipData)[2];
+
+ const uint16_t chipB[][2] =
+ {
+ {0x0000, 0x0038},{0x8100, 0x1B37},{0xBE2E, 0x7B9F},{0xBE2B, 0xA4C8},
+ {0xBE74, 0xAD14},{0xBE2C, 0xDC00},{0xBE69, 0xD20F},{0xBE3B, 0xB414},
+ {0xBE24, 0x0000},{0xBE23, 0x00A1},{0xBE22, 0x0008},{0xBE21, 0x0120},
+ {0xBE20, 0x1000},{0xBE24, 0x0800},{0xBE24, 0x0000},{0xBE24, 0xF000},
+ {0xBE23, 0xDF01},{0xBE22, 0xDF20},{0xBE21, 0x101A},{0xBE20, 0xA0FF},
+ {0xBE24, 0xF800},{0xBE24, 0xF000},{0x0242, 0x02BF},{0x0245, 0x02BF},
+ {0x0248, 0x02BF},{0x024B, 0x02BF},{0x024E, 0x02BF},{0x0251, 0x02BF},
+ {0x0230, 0x0A32},{0x0233, 0x0A32},{0x0236, 0x0A32},{0x0239, 0x0A32},
+ {0x023C, 0x0A32},{0x023F, 0x0A32},{0x0254, 0x0A3F},{0x0255, 0x0064},
+ {0x0256, 0x0A3F},{0x0257, 0x0064},{0x0258, 0x0A3F},{0x0259, 0x0064},
+ {0x025A, 0x0A3F},{0x025B, 0x0064},{0x025C, 0x0A3F},{0x025D, 0x0064},
+ {0x025E, 0x0A3F},{0x025F, 0x0064},{0x0260, 0x0178},{0x0261, 0x01F4},
+ {0x0262, 0x0320},{0x0263, 0x0014},{0x021D, 0x9249},{0x021E, 0x0000},
+ {0x0100, 0x0004},{0xBE4A, 0xA0B4},{0xBE40, 0x9C00},{0xBE41, 0x501D},
+ {0xBE48, 0x3602},{0xBE47, 0x8051},{0xBE4C, 0x6465},{0x8000, 0x1F00},
+ {0x8001, 0x000C},{0x8008, 0x0000},{0x8007, 0x0000},{0x800C, 0x00A5},
+ {0x8101, 0x02BC},{0xBE53, 0x0005},{0x8E45, 0xAFE8},{0x8013, 0x0005},
+ {0xBE4B, 0x6700},{0x800B, 0x7000},{0xBE09, 0x0E00},
+ {0xFFFF, 0xABCD}
+ };
+
+ const uint16_t chipDefault[][2] =
+ {
+ {0x0242, 0x02BF},{0x0245, 0x02BF},{0x0248, 0x02BF},{0x024B, 0x02BF},
+ {0x024E, 0x02BF},{0x0251, 0x02BF},
+ {0x0254, 0x0A3F},{0x0256, 0x0A3F},{0x0258, 0x0A3F},{0x025A, 0x0A3F},
+ {0x025C, 0x0A3F},{0x025E, 0x0A3F},
+ {0x0263, 0x007C},{0x0100, 0x0004},
+ {0xBE5B, 0x3500},{0x800E, 0x200F},{0xBE1D, 0x0F00},{0x8001, 0x5011},
+ {0x800A, 0xA2F4},{0x800B, 0x17A3},{0xBE4B, 0x17A3},{0xBE41, 0x5011},
+ {0xBE17, 0x2100},{0x8000, 0x8304},{0xBE40, 0x8304},{0xBE4A, 0xA2F4},
+ {0x800C, 0xA8D5},{0x8014, 0x5500},{0x8015, 0x0004},{0xBE4C, 0xA8D5},
+ {0xBE59, 0x0008},{0xBE09, 0x0E00},{0xBE36, 0x1036},{0xBE37, 0x1036},
+ {0x800D, 0x00FF},{0xBE4D, 0x00FF},
+ {0xFFFF, 0xABCD}
+ };
+
+ DBG("rtl8366s_initChip\n");
+
+ /* save current led config and set to led force */
+ for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
+ if (rtl8366s_getLedConfig(ledGroup, &ledData[ledGroup]))
+ return -1;
+
+ if (rtl8366s_setLedConfig(ledGroup, RTL8366S_LEDCONF_LEDFORCE))
+ return -1;
+ }
+
+ if (rtl8366s_setLedForceValue(0,0,0,0))
+ return -1;
+
+ if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, &regData))
+ return -1;
+
+ switch (regData)
+ {
+ case 0x0000:
+ chipData = chipB;
+ break;
+
+ case RTL8366S_MODEL_8366SR:
+ chipData = chipDefault;
+ break;
+
+ default:
+ printf("rtl8366s_initChip: unsupported chip found!\n");
+ return -1;
+ }
+
+ DBG("rtl8366s_initChip: found %x chip\n", regData);
+
+ while ((chipData[i][0] != 0xFFFF) && (chipData[i][1] != 0xABCD)) {
+
+ /* phy settings*/
+ if ((chipData[i][0] & 0xBE00) == 0xBE00) {
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
+ RTL8366S_PHY_CTRL_WRITE))
+ return -1;
+ }
+
+ if (rtl8366_writeRegister(chipData[i][0], chipData[i][1]))
+ return -1;
+
+ i++;
+ }
+
+ /* chip needs some time */
+ udelay(100 * 1000);
+
+ /* restore led config */
+ for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
+ if (rtl8366s_setLedConfig(ledGroup, ledData[ledGroup]))
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_initialize(void)
+{
+ uint16_t regData;
+
+ DBG("rtl8366s_initialize: start setup\n");
+
+ smi_init();
+
+ rtl8366_readRegister(RTL8366S_CHIP_ID_REG, &regData);
+ DBG("Realtek 8366SR switch ID %#04x\n", regData);
+
+ if (regData != 0x8366) {
+ printf("rtl8366s_initialize: found unsupported switch\n");
+ return -1;
+ }
+
+ if (rtl8366s_initChip()) {
+ printf("rtl8366s_initialize: init chip failed\n");
+ return -1;
+ }
+
+ if (rtl8366s_setGreenEthernet(1, 1)) {
+ printf("rtl8366s_initialize: set green ethernet failed\n");
+ return -1;
+ }
+
+ /* Set port 5 noTag and don't dropUnda */
+ if (rtl8366s_setCPUPort(5, 1, 0)) {
+ printf("rtl8366s_initialize: set CPU port failed\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h b/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h
new file mode 100644
index 0000000..f0567dd
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h
@@ -0,0 +1,188 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef RTL8366_MII_H
+#define RTL8366_MII_H
+
+#define MII_CONTROL_REG 0
+#define MII_STATUS_REG 1
+#define MII_PHY_ID0 2
+#define MII_PHY_ID1 3
+#define MII_LOCAL_CAP 4
+#define MII_REMOTE_CAP 5
+#define MII_EXT_AUTONEG 6
+#define MII_LOCAL_NEXT_PAGE 7
+#define MII_REMOTE_NEXT_PAGE 8
+#define MII_GIGA_CONTROL 9
+#define MII_GIGA_STATUS 10
+#define MII_EXT_STATUS_REG 15
+
+/* Control register */
+#define MII_CONTROL_1000MBPS 6
+#define MII_CONTROL_COLL_TEST 7
+#define MII_CONTROL_FULLDUPLEX 8
+#define MII_CONTROL_RENEG 9
+#define MII_CONTROL_ISOLATE 10
+#define MII_CONTROL_POWERDOWN 11
+#define MII_CONTROL_AUTONEG 12
+#define MII_CONTROL_100MBPS 13
+#define MII_CONTROL_LOOPBACK 14
+#define MII_CONTROL_RESET 15
+
+/* Status/Extended status register */
+/* Basic status */
+#define MII_STATUS_CAPABILITY 0
+#define MII_STATUS_JABBER 1
+#define MII_STATUS_LINK_UP 2
+#define MII_STATUS_AUTONEG_ABLE 3
+#define MII_STATUS_REMOTE_FAULT 4
+#define MII_STATUS_AUTONEG_DONE 5
+#define MII_STATUS_NO_PREAMBLE 6
+#define MII_STATUS_RESERVED 7
+#define MII_STATUS_EXTENDED 8
+#define MII_STATUS_100_T2_HALF 9
+#define MII_STATUS_100_T2_FULL 10
+#define MII_STATUS_10_TX_HALF 11
+#define MII_STATUS_10_TX_FULL 12
+#define MII_STATUS_100_TX_HALF 13
+#define MII_STATUS_100_TX_FULL 14
+#define MII_STATUS_100_T4 15
+
+#define MII_GIGA_CONTROL_HALF 8
+#define MII_GIGA_CONTROL_FULL 9
+#define MII_GIGA_STATUS_HALF 10
+#define MII_GIGA_STATUS_FULL 11
+
+/* Extended status */
+#define MII_STATUS_1000_T_HALF 12
+#define MII_STATUS_1000_T_FULL 13
+#define MII_STATUS_1000_X_HALF 14
+#define MII_STATUS_1000_X_FULL 15
+
+/* Local/Remmote capability register */
+#define MII_CAP_10BASE_TX 5
+#define MII_CAP_10BASE_TX_FULL 6
+#define MII_CAP_100BASE_TX 7
+#define MII_CAP_100BASE_TX_FULL 8
+#define MII_CAP_100BASE_T4 9
+#define MII_CAP_SYMM_PAUSE 10
+#define MII_CAP_ASYMM_PAUSE 11
+#define MII_CAP_RESERVED 12
+#define MII_CAP_REMOTE_FAULT 13
+#define MII_CAP_ACKNOWLEDGE 14
+#define MII_CAP_NEXT_PAGE 15
+#define MII_CAP_IEEE_802_3 0x0001
+
+#define MII_LINK_MODE_MASK 0x1f
+
+#define REALTEK_RTL8366_CHIP_ID0 0x001C
+#define REALTEK_RTL8366_CHIP_ID1 0xC940
+#define REALTEK_RTL8366_CHIP_ID1_MP 0xC960
+
+#define REALTEK_MIN_PORT_ID 0
+#define REALTEK_MAX_PORT_ID 5
+#define REALTEK_MIN_PHY_ID REALTEK_MIN_PORT_ID
+#define REALTEK_MAX_PHY_ID 4
+#define REALTEK_CPU_PORT_ID REALTEK_MAX_PORT_ID
+#define REALTEK_PHY_PORT_MASK ((1<<(REALTEK_MAX_PHY_ID+1)) - (1<<REALTEK_MIN_PHY_ID))
+#define REALTEK_CPU_PORT_MASK (1<<REALTEK_CPU_PORT_ID)
+#define REALTEK_ALL_PORT_MASK (REALTEK_PHY_PORT_MASK | REALTEK_CPU_PORT_MASK)
+
+/* port ability */
+#define RTL8366S_PORT_ABILITY_BASE 0x0011
+
+/* port vlan control register */
+#define RTL8366S_PORT_VLAN_CTRL_BASE 0x0058
+
+/* port linking status */
+#define RTL8366S_PORT_LINK_STATUS_BASE 0x0060
+#define RTL8366S_PORT_STATUS_SPEED_BIT 0
+#define RTL8366S_PORT_STATUS_SPEED_MSK 0x0003
+#define RTL8366S_PORT_STATUS_DUPLEX_BIT 2
+#define RTL8366S_PORT_STATUS_DUPLEX_MSK 0x0004
+#define RTL8366S_PORT_STATUS_LINK_BIT 4
+#define RTL8366S_PORT_STATUS_LINK_MSK 0x0010
+#define RTL8366S_PORT_STATUS_TXPAUSE_BIT 5
+#define RTL8366S_PORT_STATUS_TXPAUSE_MSK 0x0020
+#define RTL8366S_PORT_STATUS_RXPAUSE_BIT 6
+#define RTL8366S_PORT_STATUS_RXPAUSE_MSK 0x0040
+#define RTL8366S_PORT_STATUS_AN_BIT 7
+#define RTL8366S_PORT_STATUS_AN_MSK 0x0080
+
+/* internal control */
+#define RTL8366S_RESET_CONTROL_REG 0x0100
+#define RTL8366S_RESET_QUEUE_BIT 2
+
+#define RTL8366S_CHIP_ID_REG 0x0105
+
+/* MAC control */
+#define RTL8366S_MAC_FORCE_CTRL0_REG 0x0F04
+#define RTL8366S_MAC_FORCE_CTRL1_REG 0x0F05
+
+
+/* PHY registers control */
+#define RTL8366S_PHY_ACCESS_CTRL_REG 0x8028
+#define RTL8366S_PHY_ACCESS_DATA_REG 0x8029
+
+#define RTL8366S_PHY_CTRL_READ 1
+#define RTL8366S_PHY_CTRL_WRITE 0
+
+#define RTL8366S_PHY_REG_MASK 0x1F
+#define RTL8366S_PHY_PAGE_OFFSET 5
+#define RTL8366S_PHY_PAGE_MASK (0x7<<5)
+#define RTL8366S_PHY_NO_OFFSET 9
+#define RTL8366S_PHY_NO_MASK (0x1F<<9)
+
+#define RTL8366S_PHY_NO_MAX 4
+#define RTL8366S_PHY_PAGE_MAX 7
+#define RTL8366S_PHY_ADDR_MAX 31
+
+/* cpu port control reg */
+#define RTL8366S_CPU_CTRL_REG 0x004F
+#define RTL8366S_CPU_DRP_BIT 14
+#define RTL8366S_CPU_DRP_MSK 0x4000
+#define RTL8366S_CPU_INSTAG_BIT 15
+#define RTL8366S_CPU_INSTAG_MSK 0x8000
+
+/* LED registers*/
+#define RTL8366S_LED_BLINK_REG 0x420
+#define RTL8366S_LED_BLINKRATE_BIT 0
+#define RTL8366S_LED_BLINKRATE_MSK 0x0007
+#define RTL8366S_LED_INDICATED_CONF_REG 0x421
+#define RTL8366S_LED_0_1_FORCE_REG 0x422
+#define RTL8366S_LED_2_3_FORCE_REG 0x423
+#define RTL8366S_LEDCONF_LEDFORCE 0x1F
+#define RTL8366S_LED_GROUP_MAX 4
+
+#define RTL8366S_GREEN_FEATURE_REG 0x000A
+#define RTL8366S_GREEN_FEATURE_TX_BIT 3
+#define RTL8366S_GREEN_FEATURE_TX_MSK 0x0008
+#define RTL8366S_GREEN_FEATURE_RX_BIT 4
+#define RTL8366S_GREEN_FEATURE_RX_MSK 0x0010
+
+#define RTL8366S_MODEL_ID_REG 0x5C
+#define RTL8366S_REV_ID_REG 0x5D
+#define RTL8366S_MODEL_8366SR 0x6027
+#define RTL8366S_MODEL_8366RB 0x5937
+
+#endif
diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366_mii.c b/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366_mii.c
new file mode 100644
index 0000000..e3c5316
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366_mii.c
@@ -0,0 +1,786 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <common.h>
+#include <net.h>
+#include <netdev.h>
+#include <miiphy.h>
+#include MII_GPIOINCLUDE
+
+#include "rtl8366.h"
+
+#ifdef DEBUG_RTL8366
+ #define DBG(fmt,args...) printf (fmt ,##args)
+#else
+ #define DBG(fmt,args...)
+#endif
+
+
+//-------------------------------------------------------------------
+// Soft SMI functions
+//-------------------------------------------------------------------
+
+#define DELAY 2
+
+static void smi_init(void)
+{
+ MII_SDAINPUT;
+ MII_SCKINPUT;
+
+ MII_SETSDA(1);
+ MII_SETSCK(1);
+
+ udelay(20);
+}
+
+static void smi_start(void)
+{
+/*
+ * rtl8366 chip needs a extra clock with
+ * SDA high before start condition
+ */
+
+ /* set gpio pins output */
+ MII_SDAOUTPUT;
+ MII_SCKOUTPUT;
+ udelay(DELAY);
+
+ /* set initial state: SCK:0, SDA:1 */
+ MII_SETSCK(0);
+ MII_SETSDA(1);
+ udelay(DELAY);
+
+ /* toggle clock */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ udelay(DELAY);
+
+ /* start condition */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSDA(0);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ udelay(DELAY);
+ MII_SETSDA(1);
+}
+
+static void smi_stop(void)
+{
+/*
+ * rtl8366 chip needs a extra clock with
+ * SDA high after stop condition
+ */
+
+ /* stop condition */
+ udelay(DELAY);
+ MII_SETSDA(0);
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSDA(1);
+ udelay(DELAY);
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ udelay(DELAY);
+
+ /* toggle clock */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ udelay(DELAY);
+ MII_SETSCK(1);
+
+ /* set gpio pins input */
+ MII_SDAINPUT;
+ MII_SCKINPUT;
+}
+
+static void smi_writeBits(uint32_t data, uint8_t length)
+{
+ uint8_t test;
+
+ for( ; length > 0; length--) {
+ udelay(DELAY);
+
+ /* output data */
+ test = (((data & (1 << (length - 1))) != 0) ? 1 : 0);
+ MII_SETSDA(test);
+ udelay(DELAY);
+
+ /* toogle clock */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ MII_SETSCK(0);
+ }
+}
+
+static uint32_t smi_readBits(uint8_t length)
+{
+ uint32_t ret;
+
+ MII_SDAINPUT;
+
+ for(ret = 0 ; length > 0; length--) {
+ udelay(DELAY);
+
+ ret <<= 1;
+
+ /* toogle clock */
+ MII_SETSCK(1);
+ udelay(DELAY);
+ ret |= MII_GETSDA;
+ MII_SETSCK(0);
+ }
+
+ MII_SDAOUTPUT;
+
+ return ret;
+}
+
+static int smi_waitAck(void)
+{
+ uint32_t retry = 0;
+
+ while (smi_readBits(1)) {
+ if (retry++ == 5)
+ return -1;
+ }
+
+ return 0;
+
+}
+
+static int smi_read(uint32_t reg, uint32_t *data)
+{
+ uint32_t rawData;
+
+ /* send start condition */
+ smi_start();
+ /* send CTRL1 code: 0b1010*/
+ smi_writeBits(0x0a, 4);
+ /* send CTRL2 code: 0b100 */
+ smi_writeBits(0x04, 3);
+ /* send READ command */
+ smi_writeBits(0x01, 1);
+
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* send address low */
+ smi_writeBits(reg & 0xFF, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+ /* send address high */
+ smi_writeBits((reg & 0xFF00) >> 8, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* read data low */
+ rawData = (smi_readBits(8) & 0xFF);
+ /* send ACK */
+ smi_writeBits(0, 1);
+ /* read data high */
+ rawData |= (smi_readBits(8) & 0xFF) << 8;
+ /* send NACK */
+ smi_writeBits(1, 1);
+
+ /* send stop condition */
+ smi_stop();
+
+ if (data)
+ *data = rawData;
+
+ return 0;
+}
+
+static int smi_write(uint32_t reg, uint32_t data)
+{
+ /* send start condition */
+ smi_start();
+ /* send CTRL1 code: 0b1010*/
+ smi_writeBits(0x0a, 4);
+ /* send CTRL2 code: 0b100 */
+ smi_writeBits(0x04, 3);
+ /* send WRITE command */
+ smi_writeBits(0x00, 1);
+
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* send address low */
+ smi_writeBits(reg & 0xFF, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+ /* send address high */
+ smi_writeBits((reg & 0xFF00) >> 8, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* send data low */
+ smi_writeBits(data & 0xFF, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+ /* send data high */
+ smi_writeBits((data & 0xFF00) >> 8, 8);
+ /* wait for ACK */
+ if (smi_waitAck())
+ return -1;
+
+ /* send stop condition */
+ smi_stop();
+
+ return 0;
+}
+
+
+//-------------------------------------------------------------------
+// Switch register read / write functions
+//-------------------------------------------------------------------
+static int rtl8366_readRegister(uint32_t reg, uint16_t *data)
+{
+ uint32_t regData;
+
+ DBG("rtl8366: read register=%#04x, data=", reg);
+
+ if (smi_read(reg, &regData)) {
+ printf("\nrtl8366 smi read failed!\n");
+ return -1;
+ }
+
+ if (data)
+ *data = regData;
+
+ DBG("%#04x\n", regData);
+
+ return 0;
+}
+
+static int rtl8366_writeRegister(uint32_t reg, uint16_t data)
+{
+ DBG("rtl8366: write register=%#04x, data=%#04x\n", reg, data);
+
+ if (smi_write(reg, data)) {
+ printf("rtl8366 smi write failed!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int rtl8366_setRegisterBit(uint32_t reg, uint32_t bitNum, uint32_t value)
+{
+ uint16_t regData;
+
+ if (bitNum >= 16)
+ return -1;
+
+ if (rtl8366_readRegister(reg, &regData))
+ return -1;
+
+ if (value)
+ regData |= (1 << bitNum);
+ else
+ regData &= ~(1 << bitNum);
+
+ if (rtl8366_writeRegister(reg, regData))
+ return -1;
+
+ return 0;
+}
+
+//-------------------------------------------------------------------
+// MII PHY read / write functions
+//-------------------------------------------------------------------
+static int rtl8366_getPhyReg(uint32_t phyNum, uint32_t reg, uint16_t *data)
+{
+ uint16_t phyAddr, regData;
+
+ if (phyNum > RTL8366S_PHY_NO_MAX) {
+ printf("rtl8366s: invalid phy number!\n");
+ return -1;
+ }
+
+ if (phyNum > RTL8366S_PHY_ADDR_MAX) {
+ printf("rtl8366s: invalid phy register number!\n");
+ return -1;
+ }
+
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
+ RTL8366S_PHY_CTRL_READ))
+ return -1;
+
+ phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
+ | (reg & RTL8366S_PHY_REG_MASK);
+ if (rtl8366_writeRegister(phyAddr, 0))
+ return -1;
+
+ if (rtl8366_readRegister(RTL8366S_PHY_ACCESS_DATA_REG, &regData))
+ return -1;
+
+ if (data)
+ *data = regData;
+
+ return 0;
+}
+
+static int rtl8366_setPhyReg(uint32_t phyNum, uint32_t reg, uint16_t data)
+{
+ uint16_t phyAddr;
+
+ if (phyNum > RTL8366S_PHY_NO_MAX) {
+ printf("rtl8366s: invalid phy number!\n");
+ return -1;
+ }
+
+ if (phyNum > RTL8366S_PHY_ADDR_MAX) {
+ printf("rtl8366s: invalid phy register number!\n");
+ return -1;
+ }
+
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
+ RTL8366S_PHY_CTRL_WRITE))
+ return -1;
+
+ phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
+ | (reg & RTL8366S_PHY_REG_MASK);
+ if (rtl8366_writeRegister(phyAddr, data))
+ return -1;
+
+ return 0;
+}
+
+static int rtl8366_miiread(char *devname, uchar phy_adr, uchar reg, ushort *data)
+{
+ uint16_t regData;
+
+ DBG("rtl8366_miiread: devname=%s, addr=%#02x, reg=%#02x\n",
+ devname, phy_adr, reg);
+
+ if (strcmp(devname, RTL8366_DEVNAME) != 0)
+ return -1;
+
+ if (rtl8366_getPhyReg(phy_adr, reg, &regData)) {
+ printf("rtl8366_miiread: write failed!\n");
+ return -1;
+ }
+
+ if (data)
+ *data = regData;
+
+ return 0;
+}
+
+static int rtl8366_miiwrite(char *devname, uchar phy_adr, uchar reg, ushort data)
+{
+ DBG("rtl8366_miiwrite: devname=%s, addr=%#02x, reg=%#02x, data=%#04x\n",
+ devname, phy_adr, reg, data);
+
+ if (strcmp(devname, RTL8366_DEVNAME) != 0)
+ return -1;
+
+ if (rtl8366_setPhyReg(phy_adr, reg, data)) {
+ printf("rtl8366_miiwrite: write failed!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366_mii_register(bd_t *bis)
+{
+ miiphy_register(strdup(RTL8366_DEVNAME), rtl8366_miiread,
+ rtl8366_miiwrite);
+
+ return 0;
+}
+
+
+//-------------------------------------------------------------------
+// Switch management functions
+//-------------------------------------------------------------------
+
+int rtl8366s_setGreenFeature(uint32_t tx, uint32_t rx)
+{
+ if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
+ RTL8366S_GREEN_FEATURE_TX_BIT, tx))
+ return -1;
+
+ if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
+ RTL8366S_GREEN_FEATURE_RX_BIT, rx))
+ return -1;
+
+ return 0;
+}
+
+int rtl8366s_setPowerSaving(uint32_t phyNum, uint32_t enabled)
+{
+ uint16_t regData;
+
+ if (phyNum > RTL8366S_PHY_NO_MAX)
+ return -1;
+
+ if (rtl8366_getPhyReg(phyNum, 12, &regData))
+ return -1;
+
+ if (enabled)
+ regData |= (1 << 12);
+ else
+ regData &= ~(1 << 12);
+
+ if (rtl8366_setPhyReg(phyNum, 12, regData))
+ return -1;
+
+ return 0;
+}
+
+int rtl8366s_setGreenEthernet(uint32_t greenFeature, uint32_t powerSaving)
+{
+ uint32_t phyNum, i;
+ uint16_t regData;
+
+ const uint16_t greenSettings[][2] =
+ {
+ {0xBE5B,0x3500},
+ {0xBE5C,0xB975},
+ {0xBE5D,0xB9B9},
+ {0xBE77,0xA500},
+ {0xBE78,0x5A78},
+ {0xBE79,0x6478}
+ };
+
+ if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, &regData))
+ return -1;
+
+ switch (regData)
+ {
+ case 0x0000:
+ for (i = 0; i < 6; i++) {
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
+ return -1;
+ if (rtl8366_writeRegister(greenSettings[i][0], greenSettings[i][1]))
+ return -1;
+ }
+ break;
+
+ case RTL8366S_MODEL_8366SR:
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
+ return -1;
+ if (rtl8366_writeRegister(greenSettings[0][0], greenSettings[0][1]))
+ return -1;
+ break;
+
+ default:
+ printf("rtl8366s_initChip: unsupported chip found!\n");
+ return -1;
+ }
+
+ if (rtl8366s_setGreenFeature(greenFeature, powerSaving))
+ return -1;
+
+ for (phyNum = 0; phyNum <= RTL8366S_PHY_NO_MAX; phyNum++) {
+ if (rtl8366s_setPowerSaving(phyNum, powerSaving))
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_setCPUPortMask(uint8_t port, uint32_t enabled)
+{
+ if(port >= 6){
+ printf("rtl8366s_setCPUPortMask: invalid port number\n");
+ return -1;
+ }
+
+ return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG, port, enabled);
+}
+
+int rtl8366s_setCPUDisableInsTag(uint32_t enable)
+{
+ return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
+ RTL8366S_CPU_INSTAG_BIT, enable);
+}
+
+int rtl8366s_setCPUDropUnda(uint32_t enable)
+{
+ return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
+ RTL8366S_CPU_DRP_BIT, enable);
+}
+
+int rtl8366s_setCPUPort(uint8_t port, uint32_t noTag, uint32_t dropUnda)
+{
+ uint32_t i;
+
+ if(port >= 6){
+ printf("rtl8366s_setCPUPort: invalid port number\n");
+ return -1;
+ }
+
+ /* reset register */
+ for(i = 0; i < 6; i++)
+ {
+ if(rtl8366s_setCPUPortMask(i, 0)){
+ printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
+ return -1;
+ }
+ }
+
+ if(rtl8366s_setCPUPortMask(port, 1)){
+ printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
+ return -1;
+ }
+
+ if(rtl8366s_setCPUDisableInsTag(noTag)){
+ printf("rtl8366s_setCPUPort: rtl8366s_setCPUDisableInsTag fail\n");
+ return -1;
+ }
+
+ if(rtl8366s_setCPUDropUnda(dropUnda)){
+ printf("rtl8366s_setCPUPort: rtl8366s_setCPUDropUnda fail\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_setLedConfig(uint32_t ledNum, uint8_t config)
+{
+ uint16_t regData;
+
+ if(ledNum >= RTL8366S_LED_GROUP_MAX) {
+ DBG("rtl8366s_setLedConfig: invalid led group\n");
+ return -1;
+ }
+
+ if(config > RTL8366S_LEDCONF_LEDFORCE) {
+ DBG("rtl8366s_setLedConfig: invalid led config\n");
+ return -1;
+ }
+
+ if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, &regData)) {
+ printf("rtl8366s_setLedConfig: failed to get led register!\n");
+ return -1;
+ }
+
+ regData &= ~(0xF << (ledNum * 4));
+ regData |= config << (ledNum * 4);
+
+ if (rtl8366_writeRegister(RTL8366S_LED_INDICATED_CONF_REG, regData)) {
+ printf("rtl8366s_setLedConfig: failed to set led register!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_getLedConfig(uint32_t ledNum, uint8_t *config)
+{
+ uint16_t regData;
+
+ if(ledNum >= RTL8366S_LED_GROUP_MAX) {
+ DBG("rtl8366s_getLedConfig: invalid led group\n");
+ return -1;
+ }
+
+ if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, &regData)) {
+ printf("rtl8366s_getLedConfig: failed to get led register!\n");
+ return -1;
+ }
+
+ if (config)
+ *config = (regData >> (ledNum * 4)) & 0xF;
+
+ return 0;
+}
+
+int rtl8366s_setLedForceValue(uint32_t group0, uint32_t group1,
+ uint32_t group2, uint32_t group3)
+{
+ uint16_t regData;
+
+ regData = (group0 & 0x3F) | ((group1 & 0x3F) << 6);
+ if (rtl8366_writeRegister(RTL8366S_LED_0_1_FORCE_REG, regData)) {
+ printf("rtl8366s_setLedForceValue: failed to set led register!\n");
+ return -1;
+ }
+
+ regData = (group2 & 0x3F) | ((group3 & 0x3F) << 6);
+ if (rtl8366_writeRegister(RTL8366S_LED_2_3_FORCE_REG, regData)) {
+ printf("rtl8366s_setLedForceValue: failed to set led register!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_initChip(void)
+{
+ uint32_t ledGroup, i = 0;
+ uint16_t regData;
+ uint8_t ledData[RTL8366S_LED_GROUP_MAX];
+ const uint16_t (*chipData)[2];
+
+ const uint16_t chipB[][2] =
+ {
+ {0x0000, 0x0038},{0x8100, 0x1B37},{0xBE2E, 0x7B9F},{0xBE2B, 0xA4C8},
+ {0xBE74, 0xAD14},{0xBE2C, 0xDC00},{0xBE69, 0xD20F},{0xBE3B, 0xB414},
+ {0xBE24, 0x0000},{0xBE23, 0x00A1},{0xBE22, 0x0008},{0xBE21, 0x0120},
+ {0xBE20, 0x1000},{0xBE24, 0x0800},{0xBE24, 0x0000},{0xBE24, 0xF000},
+ {0xBE23, 0xDF01},{0xBE22, 0xDF20},{0xBE21, 0x101A},{0xBE20, 0xA0FF},
+ {0xBE24, 0xF800},{0xBE24, 0xF000},{0x0242, 0x02BF},{0x0245, 0x02BF},
+ {0x0248, 0x02BF},{0x024B, 0x02BF},{0x024E, 0x02BF},{0x0251, 0x02BF},
+ {0x0230, 0x0A32},{0x0233, 0x0A32},{0x0236, 0x0A32},{0x0239, 0x0A32},
+ {0x023C, 0x0A32},{0x023F, 0x0A32},{0x0254, 0x0A3F},{0x0255, 0x0064},
+ {0x0256, 0x0A3F},{0x0257, 0x0064},{0x0258, 0x0A3F},{0x0259, 0x0064},
+ {0x025A, 0x0A3F},{0x025B, 0x0064},{0x025C, 0x0A3F},{0x025D, 0x0064},
+ {0x025E, 0x0A3F},{0x025F, 0x0064},{0x0260, 0x0178},{0x0261, 0x01F4},
+ {0x0262, 0x0320},{0x0263, 0x0014},{0x021D, 0x9249},{0x021E, 0x0000},
+ {0x0100, 0x0004},{0xBE4A, 0xA0B4},{0xBE40, 0x9C00},{0xBE41, 0x501D},
+ {0xBE48, 0x3602},{0xBE47, 0x8051},{0xBE4C, 0x6465},{0x8000, 0x1F00},
+ {0x8001, 0x000C},{0x8008, 0x0000},{0x8007, 0x0000},{0x800C, 0x00A5},
+ {0x8101, 0x02BC},{0xBE53, 0x0005},{0x8E45, 0xAFE8},{0x8013, 0x0005},
+ {0xBE4B, 0x6700},{0x800B, 0x7000},{0xBE09, 0x0E00},
+ {0xFFFF, 0xABCD}
+ };
+
+ const uint16_t chipDefault[][2] =
+ {
+ {0x0242, 0x02BF},{0x0245, 0x02BF},{0x0248, 0x02BF},{0x024B, 0x02BF},
+ {0x024E, 0x02BF},{0x0251, 0x02BF},
+ {0x0254, 0x0A3F},{0x0256, 0x0A3F},{0x0258, 0x0A3F},{0x025A, 0x0A3F},
+ {0x025C, 0x0A3F},{0x025E, 0x0A3F},
+ {0x0263, 0x007C},{0x0100, 0x0004},
+ {0xBE5B, 0x3500},{0x800E, 0x200F},{0xBE1D, 0x0F00},{0x8001, 0x5011},
+ {0x800A, 0xA2F4},{0x800B, 0x17A3},{0xBE4B, 0x17A3},{0xBE41, 0x5011},
+ {0xBE17, 0x2100},{0x8000, 0x8304},{0xBE40, 0x8304},{0xBE4A, 0xA2F4},
+ {0x800C, 0xA8D5},{0x8014, 0x5500},{0x8015, 0x0004},{0xBE4C, 0xA8D5},
+ {0xBE59, 0x0008},{0xBE09, 0x0E00},{0xBE36, 0x1036},{0xBE37, 0x1036},
+ {0x800D, 0x00FF},{0xBE4D, 0x00FF},
+ {0xFFFF, 0xABCD}
+ };
+
+ DBG("rtl8366s_initChip\n");
+
+ /* save current led config and set to led force */
+ for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
+ if (rtl8366s_getLedConfig(ledGroup, &ledData[ledGroup]))
+ return -1;
+
+ if (rtl8366s_setLedConfig(ledGroup, RTL8366S_LEDCONF_LEDFORCE))
+ return -1;
+ }
+
+ if (rtl8366s_setLedForceValue(0,0,0,0))
+ return -1;
+
+ if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, &regData))
+ return -1;
+
+ switch (regData)
+ {
+ case 0x0000:
+ chipData = chipB;
+ break;
+
+ case RTL8366S_MODEL_8366SR:
+ chipData = chipDefault;
+ break;
+
+ default:
+ printf("rtl8366s_initChip: unsupported chip found!\n");
+ return -1;
+ }
+
+ DBG("rtl8366s_initChip: found %x chip\n", regData);
+
+ while ((chipData[i][0] != 0xFFFF) && (chipData[i][1] != 0xABCD)) {
+
+ /* phy settings*/
+ if ((chipData[i][0] & 0xBE00) == 0xBE00) {
+ if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
+ RTL8366S_PHY_CTRL_WRITE))
+ return -1;
+ }
+
+ if (rtl8366_writeRegister(chipData[i][0], chipData[i][1]))
+ return -1;
+
+ i++;
+ }
+
+ /* chip needs some time */
+ udelay(100 * 1000);
+
+ /* restore led config */
+ for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
+ if (rtl8366s_setLedConfig(ledGroup, ledData[ledGroup]))
+ return -1;
+ }
+
+ return 0;
+}
+
+int rtl8366s_initialize(void)
+{
+ uint16_t regData;
+
+ DBG("rtl8366s_initialize: start setup\n");
+
+ smi_init();
+
+ rtl8366_readRegister(RTL8366S_CHIP_ID_REG, &regData);
+ DBG("Realtek 8366SR switch ID %#04x\n", regData);
+
+ if (regData != 0x8366) {
+ printf("rtl8366s_initialize: found unsupported switch\n");
+ return -1;
+ }
+
+ if (rtl8366s_initChip()) {
+ printf("rtl8366s_initialize: init chip failed\n");
+ return -1;
+ }
+
+ if (rtl8366s_setGreenEthernet(1, 1)) {
+ printf("rtl8366s_initialize: set green ethernet failed\n");
+ return -1;
+ }
+
+ /* Set port 5 noTag and don't dropUnda */
+ if (rtl8366s_setCPUPort(5, 1, 0)) {
+ printf("rtl8366s_initialize: set CPU port failed\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/package/boot/uboot-ar71xx/files/drivers/spi/.svn/entries b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/entries
new file mode 100644
index 0000000..cce4027
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/drivers/spi
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+ar71xx_spi.c
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+05e08eafb6374d1bcb71b0086f1da38f
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4553
+
diff --git a/package/boot/uboot-ar71xx/files/drivers/spi/.svn/prop-base/ar71xx_spi.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/prop-base/ar71xx_spi.c.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/prop-base/ar71xx_spi.c.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/drivers/spi/.svn/text-base/ar71xx_spi.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/text-base/ar71xx_spi.c.svn-base
new file mode 100644
index 0000000..bbe27b1
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/text-base/ar71xx_spi.c.svn-base
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <asm/ar71xx.h>
+
+/*-----------------------------------------------------------------------
+ * Definitions
+ */
+
+#ifdef DEBUG_SPI
+#define PRINTD(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTD(fmt,args...)
+#endif
+
+struct ar71xx_spi_slave {
+ struct spi_slave slave;
+ unsigned int mode;
+};
+
+static inline struct ar71xx_spi_slave *to_ar71xx_spi(struct spi_slave *slave)
+{
+ return container_of(slave, struct ar71xx_spi_slave, slave);
+}
+
+/*=====================================================================*/
+/* Public Functions */
+/*=====================================================================*/
+
+/*-----------------------------------------------------------------------
+ * Initialization
+ */
+
+void spi_init()
+{
+ PRINTD("ar71xx_spi: spi_init");
+
+ // Init SPI Hardware, disable remap, set clock
+ __raw_writel(0x43, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_CTRL));
+
+ PRINTD(" ---> out\n");
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ struct ar71xx_spi_slave *ss;
+
+ PRINTD("ar71xx_spi: spi_setup_slave");
+
+ if ((bus != 0) || (cs > 2))
+ return NULL;
+
+ ss = malloc(sizeof(struct ar71xx_spi_slave));
+ if (!ss)
+ return NULL;
+
+ ss->slave.bus = bus;
+ ss->slave.cs = cs;
+ ss->mode = mode;
+
+ /* TODO: Use max_hz to limit the SCK rate */
+
+ PRINTD(" ---> out\n");
+
+ return &ss->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave);
+
+ free(ss);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+ void *din, unsigned long flags)
+{
+ struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave);
+ uint8_t *rx = din;
+ const uint8_t *tx = dout;
+ uint8_t curbyte, curbitlen, restbits;
+ uint32_t bytes = bitlen / 8;
+ uint32_t out;
+ uint32_t in;
+
+ PRINTD("ar71xx_spi: spi_xfer: slave:%p bitlen:%08x dout:%p din:%p flags:%08x\n", slave, bitlen, dout, din, flags);
+
+ if (flags & SPI_XFER_BEGIN) {
+ __raw_writel(SPI_FS_GPIO, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS));
+ __raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+ }
+
+ restbits = (bitlen % 8);
+ if (restbits != 0)
+ bytes++;
+
+ // enable chip select
+ out = SPI_IOC_CS_ALL & ~(SPI_IOC_CS(slave->cs));
+
+ while (bytes--) {
+
+ curbyte = 0;
+ if (tx) {
+ curbyte = *tx++;
+ }
+
+ if (restbits != 0) {
+ curbitlen = restbits;
+ curbyte <<= 8 - restbits;
+ } else {
+ curbitlen = 8;
+ }
+
+ PRINTD("ar71xx_spi: sending: data:%02x length:%d\n", curbyte, curbitlen);
+
+ /* clock starts at inactive polarity */
+ for (curbyte <<= (8 - curbitlen); curbitlen; curbitlen--) {
+
+ if (curbyte & (1 << 7))
+ out |= SPI_IOC_DO;
+ else
+ out &= ~(SPI_IOC_DO);
+
+ /* setup MSB (to slave) on trailing edge */
+ __raw_writel(out, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+
+ __raw_writel(out | SPI_IOC_CLK, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+
+ curbyte <<= 1;
+ }
+
+ in = __raw_readl(KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_RDS));
+ PRINTD("ar71xx_spi: received:%02x\n", in);
+
+ if (rx) {
+ if (restbits == 0) {
+ *rx++ = in;
+ } else {
+ *rx++ = (in << (8 - restbits));
+ }
+ }
+ }
+
+ if (flags & SPI_XFER_END) {
+ __raw_writel(SPI_IOC_CS(slave->cs), KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+ __raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+ __raw_writel(0, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS));
+ }
+
+ PRINTD(" ---> out\n");
+
+ return 0;
+}
diff --git a/package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c b/package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c
new file mode 100644
index 0000000..bbe27b1
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <asm/ar71xx.h>
+
+/*-----------------------------------------------------------------------
+ * Definitions
+ */
+
+#ifdef DEBUG_SPI
+#define PRINTD(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTD(fmt,args...)
+#endif
+
+struct ar71xx_spi_slave {
+ struct spi_slave slave;
+ unsigned int mode;
+};
+
+static inline struct ar71xx_spi_slave *to_ar71xx_spi(struct spi_slave *slave)
+{
+ return container_of(slave, struct ar71xx_spi_slave, slave);
+}
+
+/*=====================================================================*/
+/* Public Functions */
+/*=====================================================================*/
+
+/*-----------------------------------------------------------------------
+ * Initialization
+ */
+
+void spi_init()
+{
+ PRINTD("ar71xx_spi: spi_init");
+
+ // Init SPI Hardware, disable remap, set clock
+ __raw_writel(0x43, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_CTRL));
+
+ PRINTD(" ---> out\n");
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ struct ar71xx_spi_slave *ss;
+
+ PRINTD("ar71xx_spi: spi_setup_slave");
+
+ if ((bus != 0) || (cs > 2))
+ return NULL;
+
+ ss = malloc(sizeof(struct ar71xx_spi_slave));
+ if (!ss)
+ return NULL;
+
+ ss->slave.bus = bus;
+ ss->slave.cs = cs;
+ ss->mode = mode;
+
+ /* TODO: Use max_hz to limit the SCK rate */
+
+ PRINTD(" ---> out\n");
+
+ return &ss->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave);
+
+ free(ss);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+ void *din, unsigned long flags)
+{
+ struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave);
+ uint8_t *rx = din;
+ const uint8_t *tx = dout;
+ uint8_t curbyte, curbitlen, restbits;
+ uint32_t bytes = bitlen / 8;
+ uint32_t out;
+ uint32_t in;
+
+ PRINTD("ar71xx_spi: spi_xfer: slave:%p bitlen:%08x dout:%p din:%p flags:%08x\n", slave, bitlen, dout, din, flags);
+
+ if (flags & SPI_XFER_BEGIN) {
+ __raw_writel(SPI_FS_GPIO, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS));
+ __raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+ }
+
+ restbits = (bitlen % 8);
+ if (restbits != 0)
+ bytes++;
+
+ // enable chip select
+ out = SPI_IOC_CS_ALL & ~(SPI_IOC_CS(slave->cs));
+
+ while (bytes--) {
+
+ curbyte = 0;
+ if (tx) {
+ curbyte = *tx++;
+ }
+
+ if (restbits != 0) {
+ curbitlen = restbits;
+ curbyte <<= 8 - restbits;
+ } else {
+ curbitlen = 8;
+ }
+
+ PRINTD("ar71xx_spi: sending: data:%02x length:%d\n", curbyte, curbitlen);
+
+ /* clock starts at inactive polarity */
+ for (curbyte <<= (8 - curbitlen); curbitlen; curbitlen--) {
+
+ if (curbyte & (1 << 7))
+ out |= SPI_IOC_DO;
+ else
+ out &= ~(SPI_IOC_DO);
+
+ /* setup MSB (to slave) on trailing edge */
+ __raw_writel(out, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+
+ __raw_writel(out | SPI_IOC_CLK, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+
+ curbyte <<= 1;
+ }
+
+ in = __raw_readl(KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_RDS));
+ PRINTD("ar71xx_spi: received:%02x\n", in);
+
+ if (rx) {
+ if (restbits == 0) {
+ *rx++ = in;
+ } else {
+ *rx++ = (in << (8 - restbits));
+ }
+ }
+ }
+
+ if (flags & SPI_XFER_END) {
+ __raw_writel(SPI_IOC_CS(slave->cs), KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+ __raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
+ __raw_writel(0, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS));
+ }
+
+ PRINTD(" ---> out\n");
+
+ return 0;
+}
diff --git a/package/boot/uboot-ar71xx/files/include/.svn/entries b/package/boot/uboot-ar71xx/files/include/.svn/entries
new file mode 100644
index 0000000..cbf4917
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/.svn/entries
@@ -0,0 +1,34 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/include
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+asm-mips
+dir
+
+configs
+dir
+
diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/entries b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/entries
new file mode 100644
index 0000000..809e843
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/include/asm-mips
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+ar71xx.h
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+e270582146693e6df5a2d8040e54fb39
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+15446
+
+ar71xx_gpio.h
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+7cdaa64219ae76e79afff6ad44338dc2
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1842
+
diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx.h.svn-base b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx.h.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx.h.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx_gpio.h.svn-base b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx_gpio.h.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx_gpio.h.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx.h.svn-base b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx.h.svn-base
new file mode 100644
index 0000000..e8f3f61
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx.h.svn-base
@@ -0,0 +1,515 @@
+/*
+ * Atheros AR71xx SoC specific definitions
+ *
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * 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 __ASM_MACH_AR71XX_H
+#define __ASM_MACH_AR71XX_H
+
+#include <linux/types.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+
+#ifndef __ASSEMBLER__
+
+#define BIT(x) (1<<(x))
+
+#define AR71XX_PCI_MEM_BASE 0x10000000
+#define AR71XX_PCI_MEM_SIZE 0x08000000
+#define AR71XX_APB_BASE 0x18000000
+#define AR71XX_GE0_BASE 0x19000000
+#define AR71XX_GE0_SIZE 0x01000000
+#define AR71XX_GE1_BASE 0x1a000000
+#define AR71XX_GE1_SIZE 0x01000000
+#define AR71XX_EHCI_BASE 0x1b000000
+#define AR71XX_EHCI_SIZE 0x01000000
+#define AR71XX_OHCI_BASE 0x1c000000
+#define AR71XX_OHCI_SIZE 0x01000000
+#define AR7240_OHCI_BASE 0x1b000000
+#define AR7240_OHCI_SIZE 0x01000000
+#define AR71XX_SPI_BASE 0x1f000000
+#define AR71XX_SPI_SIZE 0x01000000
+
+#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
+#define AR71XX_DDR_CTRL_SIZE 0x10000
+#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000)
+#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
+#define AR71XX_UART_SIZE 0x10000
+#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
+#define AR71XX_USB_CTRL_SIZE 0x10000
+#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
+#define AR71XX_GPIO_SIZE 0x10000
+#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
+#define AR71XX_PLL_SIZE 0x10000
+#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
+#define AR71XX_RESET_SIZE 0x10000
+#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000)
+#define AR71XX_MII_SIZE 0x10000
+#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000)
+#define AR71XX_SLIC_SIZE 0x10000
+#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000)
+#define AR71XX_DMA_SIZE 0x10000
+#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000)
+#define AR71XX_STEREO_SIZE 0x10000
+
+#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000)
+#define AR724X_PCI_CRP_SIZE 0x100
+
+#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000)
+#define AR724X_PCI_CTRL_SIZE 0x100
+
+#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
+#define AR91XX_WMAC_SIZE 0x30000
+
+#define AR71XX_MEM_SIZE_MIN 0x0200000
+#define AR71XX_MEM_SIZE_MAX 0x10000000
+
+#define AR71XX_CPU_IRQ_BASE 0
+#define AR71XX_MISC_IRQ_BASE 8
+#define AR71XX_MISC_IRQ_COUNT 8
+#define AR71XX_GPIO_IRQ_BASE 16
+#define AR71XX_GPIO_IRQ_COUNT 32
+#define AR71XX_PCI_IRQ_BASE 48
+#define AR71XX_PCI_IRQ_COUNT 8
+
+#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2)
+#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3)
+#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4)
+#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5)
+#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6)
+#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7)
+
+#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0)
+#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1)
+#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2)
+#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3)
+#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4)
+#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5)
+#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6)
+#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7)
+
+#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x))
+
+#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0)
+#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1)
+#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2)
+#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4)
+
+extern u32 ar71xx_ahb_freq;
+extern u32 ar71xx_cpu_freq;
+extern u32 ar71xx_ddr_freq;
+
+enum ar71xx_soc_type {
+ AR71XX_SOC_UNKNOWN,
+ AR71XX_SOC_AR7130,
+ AR71XX_SOC_AR7141,
+ AR71XX_SOC_AR7161,
+ AR71XX_SOC_AR7240,
+ AR71XX_SOC_AR7241,
+ AR71XX_SOC_AR7242,
+ AR71XX_SOC_AR9130,
+ AR71XX_SOC_AR9132
+};
+
+extern enum ar71xx_soc_type ar71xx_soc;
+
+/*
+ * PLL block
+ */
+#define AR71XX_PLL_REG_CPU_CONFIG 0x00
+#define AR71XX_PLL_REG_SEC_CONFIG 0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
+
+#define AR71XX_PLL_DIV_SHIFT 3
+#define AR71XX_PLL_DIV_MASK 0x1f
+#define AR71XX_CPU_DIV_SHIFT 16
+#define AR71XX_CPU_DIV_MASK 0x3
+#define AR71XX_DDR_DIV_SHIFT 18
+#define AR71XX_DDR_DIV_MASK 0x3
+#define AR71XX_AHB_DIV_SHIFT 20
+#define AR71XX_AHB_DIV_MASK 0x7
+
+#define AR71XX_ETH0_PLL_SHIFT 17
+#define AR71XX_ETH1_PLL_SHIFT 19
+
+#define AR724X_PLL_REG_CPU_CONFIG 0x00
+#define AR724X_PLL_REG_PCIE_CONFIG 0x18
+
+#define AR724X_PLL_DIV_SHIFT 0
+#define AR724X_PLL_DIV_MASK 0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT 10
+#define AR724X_PLL_REF_DIV_MASK 0xf
+#define AR724X_AHB_DIV_SHIFT 19
+#define AR724X_AHB_DIV_MASK 0x1
+#define AR724X_DDR_DIV_SHIFT 22
+#define AR724X_DDR_DIV_MASK 0x3
+
+#define AR91XX_PLL_REG_CPU_CONFIG 0x00
+#define AR91XX_PLL_REG_ETH_CONFIG 0x04
+#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14
+#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18
+
+#define AR91XX_PLL_DIV_SHIFT 0
+#define AR91XX_PLL_DIV_MASK 0x3ff
+#define AR91XX_DDR_DIV_SHIFT 22
+#define AR91XX_DDR_DIV_MASK 0x3
+#define AR91XX_AHB_DIV_SHIFT 19
+#define AR91XX_AHB_DIV_MASK 0x1
+
+#define AR91XX_ETH0_PLL_SHIFT 20
+#define AR91XX_ETH1_PLL_SHIFT 22
+
+// extern void __iomem *ar71xx_pll_base;
+
+// static inline void ar71xx_pll_wr(unsigned reg, u32 val)
+// {
+ // __raw_writel(val, ar71xx_pll_base + reg);
+// }
+
+// static inline u32 ar71xx_pll_rr(unsigned reg)
+// {
+ // return __raw_readl(ar71xx_pll_base + reg);
+// }
+
+/*
+ * USB_CONFIG block
+ */
+#define USB_CTRL_REG_FLADJ 0x00
+#define USB_CTRL_REG_CONFIG 0x04
+
+// extern void __iomem *ar71xx_usb_ctrl_base;
+
+// static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val)
+// {
+ // __raw_writel(val, ar71xx_usb_ctrl_base + reg);
+// }
+
+// static inline u32 ar71xx_usb_ctrl_rr(unsigned reg)
+// {
+ // return __raw_readl(ar71xx_usb_ctrl_base + reg);
+// }
+
+/*
+ * GPIO block
+ */
+#define GPIO_REG_OE 0x00
+#define GPIO_REG_IN 0x04
+#define GPIO_REG_OUT 0x08
+#define GPIO_REG_SET 0x0c
+#define GPIO_REG_CLEAR 0x10
+#define GPIO_REG_INT_MODE 0x14
+#define GPIO_REG_INT_TYPE 0x18
+#define GPIO_REG_INT_POLARITY 0x1c
+#define GPIO_REG_INT_PENDING 0x20
+#define GPIO_REG_INT_ENABLE 0x24
+#define GPIO_REG_FUNC 0x28
+
+#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17)
+#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16)
+#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13)
+#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12)
+#define AR71XX_GPIO_FUNC_UART_EN BIT(8)
+#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4)
+#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0)
+
+#define AR71XX_GPIO_COUNT 16
+
+#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19)
+#define AR724X_GPIO_FUNC_SPI_EN BIT(18)
+#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14)
+#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13)
+#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12)
+#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11)
+#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10)
+#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9)
+#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3)
+#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2)
+#define AR724X_GPIO_FUNC_UART_EN BIT(1)
+#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0)
+
+#define AR724X_GPIO_COUNT 18
+
+#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22)
+#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21)
+#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20)
+#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19)
+#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18)
+#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17)
+#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16)
+#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9)
+#define AR91XX_GPIO_FUNC_UART_EN BIT(8)
+#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4)
+
+#define AR91XX_GPIO_COUNT 22
+
+// extern void __iomem *ar71xx_gpio_base;
+
+// static inline void ar71xx_gpio_wr(unsigned reg, u32 value)
+// {
+ // __raw_writel(value, ar71xx_gpio_base + reg);
+// }
+
+// static inline u32 ar71xx_gpio_rr(unsigned reg)
+// {
+ // return __raw_readl(ar71xx_gpio_base + reg);
+// }
+
+// void ar71xx_gpio_init(void) __init;
+// void ar71xx_gpio_function_enable(u32 mask);
+// void ar71xx_gpio_function_disable(u32 mask);
+// void ar71xx_gpio_function_setup(u32 set, u32 clear);
+
+/*
+ * DDR_CTRL block
+ */
+#define AR71XX_DDR_REG_PCI_WIN0 0x7c
+#define AR71XX_DDR_REG_PCI_WIN1 0x80
+#define AR71XX_DDR_REG_PCI_WIN2 0x84
+#define AR71XX_DDR_REG_PCI_WIN3 0x88
+#define AR71XX_DDR_REG_PCI_WIN4 0x8c
+#define AR71XX_DDR_REG_PCI_WIN5 0x90
+#define AR71XX_DDR_REG_PCI_WIN6 0x94
+#define AR71XX_DDR_REG_PCI_WIN7 0x98
+#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
+#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
+#define AR71XX_DDR_REG_FLUSH_USB 0xa4
+#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
+
+#define AR724X_DDR_REG_FLUSH_GE0 0x7c
+#define AR724X_DDR_REG_FLUSH_GE1 0x80
+#define AR724X_DDR_REG_FLUSH_USB 0x84
+#define AR724X_DDR_REG_FLUSH_PCIE 0x88
+
+#define AR91XX_DDR_REG_FLUSH_GE0 0x7c
+#define AR91XX_DDR_REG_FLUSH_GE1 0x80
+#define AR91XX_DDR_REG_FLUSH_USB 0x84
+#define AR91XX_DDR_REG_FLUSH_WMAC 0x88
+
+#define PCI_WIN0_OFFS 0x10000000
+#define PCI_WIN1_OFFS 0x11000000
+#define PCI_WIN2_OFFS 0x12000000
+#define PCI_WIN3_OFFS 0x13000000
+#define PCI_WIN4_OFFS 0x14000000
+#define PCI_WIN5_OFFS 0x15000000
+#define PCI_WIN6_OFFS 0x16000000
+#define PCI_WIN7_OFFS 0x07000000
+
+// extern void __iomem *ar71xx_ddr_base;
+
+// static inline void ar71xx_ddr_wr(unsigned reg, u32 val)
+// {
+ // __raw_writel(val, ar71xx_ddr_base + reg);
+// }
+
+// static inline u32 ar71xx_ddr_rr(unsigned reg)
+// {
+ // return __raw_readl(ar71xx_ddr_base + reg);
+// }
+
+// void ar71xx_ddr_flush(u32 reg);
+
+/*
+ * PCI block
+ */
+#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000)
+#define AR71XX_PCI_CFG_SIZE 0x100
+
+#define PCI_REG_CRP_AD_CBE 0x00
+#define PCI_REG_CRP_WRDATA 0x04
+#define PCI_REG_CRP_RDDATA 0x08
+#define PCI_REG_CFG_AD 0x0c
+#define PCI_REG_CFG_CBE 0x10
+#define PCI_REG_CFG_WRDATA 0x14
+#define PCI_REG_CFG_RDDATA 0x18
+#define PCI_REG_PCI_ERR 0x1c
+#define PCI_REG_PCI_ERR_ADDR 0x20
+#define PCI_REG_AHB_ERR 0x24
+#define PCI_REG_AHB_ERR_ADDR 0x28
+
+#define PCI_CRP_CMD_WRITE 0x00010000
+#define PCI_CRP_CMD_READ 0x00000000
+#define PCI_CFG_CMD_READ 0x0000000a
+#define PCI_CFG_CMD_WRITE 0x0000000b
+
+#define PCI_IDSEL_ADL_START 17
+
+#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000)
+#define AR724X_PCI_CFG_SIZE 0x1000
+
+#define AR724X_PCI_REG_APP 0x00
+#define AR724X_PCI_REG_RESET 0x18
+#define AR724X_PCI_REG_INT_STATUS 0x4c
+#define AR724X_PCI_REG_INT_MASK 0x50
+
+#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0)
+#define AR724X_PCI_RESET_LINK_UP BIT(0)
+
+#define AR724X_PCI_INT_DEV0 BIT(14)
+
+/*
+ * RESET block
+ */
+#define AR71XX_RESET_REG_TIMER 0x00
+#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
+#define AR71XX_RESET_REG_WDOG_CTRL 0x08
+#define AR71XX_RESET_REG_WDOG 0x0c
+#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
+#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
+#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
+#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
+#define AR71XX_RESET_REG_RESET_MODULE 0x24
+#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
+#define AR71XX_RESET_REG_PERFC0 0x30
+#define AR71XX_RESET_REG_PERFC1 0x34
+#define AR71XX_RESET_REG_REV_ID 0x90
+
+#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18
+#define AR91XX_RESET_REG_RESET_MODULE 0x1c
+#define AR91XX_RESET_REG_PERF_CTRL 0x20
+#define AR91XX_RESET_REG_PERFC0 0x24
+#define AR91XX_RESET_REG_PERFC1 0x28
+
+#define AR724X_RESET_REG_RESET_MODULE 0x1c
+
+#define WDOG_CTRL_LAST_RESET BIT(31)
+#define WDOG_CTRL_ACTION_MASK 3
+#define WDOG_CTRL_ACTION_NONE 0 /* no action */
+#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */
+#define WDOG_CTRL_ACTION_NMI 2 /* NMI */
+#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */
+
+#define MISC_INT_DMA BIT(7)
+#define MISC_INT_OHCI BIT(6)
+#define MISC_INT_PERFC BIT(5)
+#define MISC_INT_WDOG BIT(4)
+#define MISC_INT_UART BIT(3)
+#define MISC_INT_GPIO BIT(2)
+#define MISC_INT_ERROR BIT(1)
+#define MISC_INT_TIMER BIT(0)
+
+#define PCI_INT_CORE BIT(4)
+#define PCI_INT_DEV2 BIT(2)
+#define PCI_INT_DEV1 BIT(1)
+#define PCI_INT_DEV0 BIT(0)
+
+#define RESET_MODULE_EXTERNAL BIT(28)
+#define RESET_MODULE_FULL_CHIP BIT(24)
+#define RESET_MODULE_AMBA2WMAC BIT(22)
+#define RESET_MODULE_CPU_NMI BIT(21)
+#define RESET_MODULE_CPU_COLD BIT(20)
+#define RESET_MODULE_DMA BIT(19)
+#define RESET_MODULE_SLIC BIT(18)
+#define RESET_MODULE_STEREO BIT(17)
+#define RESET_MODULE_DDR BIT(16)
+#define RESET_MODULE_GE1_MAC BIT(13)
+#define RESET_MODULE_GE1_PHY BIT(12)
+#define RESET_MODULE_USBSUS_OVERRIDE BIT(10)
+#define RESET_MODULE_GE0_MAC BIT(9)
+#define RESET_MODULE_GE0_PHY BIT(8)
+#define RESET_MODULE_USB_OHCI_DLL BIT(6)
+#define RESET_MODULE_USB_HOST BIT(5)
+#define RESET_MODULE_USB_PHY BIT(4)
+#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3)
+#define RESET_MODULE_PCI_BUS BIT(1)
+#define RESET_MODULE_PCI_CORE BIT(0)
+
+#define AR724X_RESET_GE1_MDIO BIT(23)
+#define AR724X_RESET_GE0_MDIO BIT(22)
+#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
+#define AR724X_RESET_PCIE_PHY BIT(7)
+#define AR724X_RESET_PCIE BIT(6)
+
+#define REV_ID_MAJOR_MASK 0xfff0
+#define REV_ID_MAJOR_AR71XX 0x00a0
+#define REV_ID_MAJOR_AR913X 0x00b0
+#define REV_ID_MAJOR_AR7240 0x00c0
+#define REV_ID_MAJOR_AR7241 0x0100
+#define REV_ID_MAJOR_AR7242 0x1100
+
+#define AR71XX_REV_ID_MINOR_MASK 0x3
+#define AR71XX_REV_ID_MINOR_AR7130 0x0
+#define AR71XX_REV_ID_MINOR_AR7141 0x1
+#define AR71XX_REV_ID_MINOR_AR7161 0x2
+#define AR71XX_REV_ID_REVISION_MASK 0x3
+#define AR71XX_REV_ID_REVISION_SHIFT 2
+
+#define AR91XX_REV_ID_MINOR_MASK 0x3
+#define AR91XX_REV_ID_MINOR_AR9130 0x0
+#define AR91XX_REV_ID_MINOR_AR9132 0x1
+#define AR91XX_REV_ID_REVISION_MASK 0x3
+#define AR91XX_REV_ID_REVISION_SHIFT 2
+
+#define AR724X_REV_ID_REVISION_MASK 0x3
+
+// extern void __iomem *ar71xx_reset_base;
+
+static inline void ar71xx_reset_wr(unsigned reg, u32 val)
+{
+ __raw_writel(val, KSEG1ADDR(AR71XX_RESET_BASE) + reg);
+}
+
+static inline u32 ar71xx_reset_rr(unsigned reg)
+{
+ return __raw_readl(KSEG1ADDR(AR71XX_RESET_BASE) + reg);
+}
+
+// void ar71xx_device_stop(u32 mask);
+// void ar71xx_device_start(u32 mask);
+// int ar71xx_device_stopped(u32 mask);
+
+/*
+ * SPI block
+ */
+#define SPI_REG_FS 0x00 /* Function Select */
+#define SPI_REG_CTRL 0x04 /* SPI Control */
+#define SPI_REG_IOC 0x08 /* SPI I/O Control */
+#define SPI_REG_RDS 0x0c /* Read Data Shift */
+
+#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
+
+#define SPI_CTRL_RD BIT(6) /* Remap Disable */
+#define SPI_CTRL_DIV_MASK 0x3f
+
+#define SPI_IOC_DO BIT(0) /* Data Out pin */
+#define SPI_IOC_CLK BIT(8) /* CLK pin */
+#define SPI_IOC_CS(n) BIT(16 + (n))
+#define SPI_IOC_CS0 SPI_IOC_CS(0)
+#define SPI_IOC_CS1 SPI_IOC_CS(1)
+#define SPI_IOC_CS2 SPI_IOC_CS(2)
+#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2)
+
+// void ar71xx_flash_acquire(void);
+// void ar71xx_flash_release(void);
+
+/*
+ * MII_CTRL block
+ */
+#define MII_REG_MII0_CTRL 0x00
+#define MII_REG_MII1_CTRL 0x04
+
+#define MII0_CTRL_IF_GMII 0
+#define MII0_CTRL_IF_MII 1
+#define MII0_CTRL_IF_RGMII 2
+#define MII0_CTRL_IF_RMII 3
+
+#define MII1_CTRL_IF_RGMII 0
+#define MII1_CTRL_IF_RMII 1
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __ASM_MACH_AR71XX_H */
diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx_gpio.h.svn-base b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx_gpio.h.svn-base
new file mode 100644
index 0000000..c92364b
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx_gpio.h.svn-base
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _AR71XX_GPIO_H
+#define _AR71XX_GPIO_H
+
+#include <common.h>
+#include <asm/ar71xx.h>
+
+static inline void ar71xx_setpin(uint8_t pin, uint8_t state)
+{
+ uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT));
+
+ if (state != 0) {
+ reg |= (1 << pin);
+ } else {
+ reg &= ~(1 << pin);
+ }
+
+ writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT));
+ readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT));
+}
+
+static inline uint32_t ar71xx_getpin(uint8_t pin)
+{
+ uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_IN));
+ return (((reg & (1 << pin)) != 0) ? 1 : 0);
+}
+
+static inline void ar71xx_setpindir(uint8_t pin, uint8_t direction)
+{
+ uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE));
+
+ if (direction != 0) {
+ reg |= (1 << pin);
+ } else {
+ reg &= ~(1 << pin);
+ }
+
+ writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE));
+ readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE));
+}
+
+
+#endif /* AR71XX_GPIO_H */
diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h
new file mode 100644
index 0000000..e8f3f61
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h
@@ -0,0 +1,515 @@
+/*
+ * Atheros AR71xx SoC specific definitions
+ *
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * 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 __ASM_MACH_AR71XX_H
+#define __ASM_MACH_AR71XX_H
+
+#include <linux/types.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+
+#ifndef __ASSEMBLER__
+
+#define BIT(x) (1<<(x))
+
+#define AR71XX_PCI_MEM_BASE 0x10000000
+#define AR71XX_PCI_MEM_SIZE 0x08000000
+#define AR71XX_APB_BASE 0x18000000
+#define AR71XX_GE0_BASE 0x19000000
+#define AR71XX_GE0_SIZE 0x01000000
+#define AR71XX_GE1_BASE 0x1a000000
+#define AR71XX_GE1_SIZE 0x01000000
+#define AR71XX_EHCI_BASE 0x1b000000
+#define AR71XX_EHCI_SIZE 0x01000000
+#define AR71XX_OHCI_BASE 0x1c000000
+#define AR71XX_OHCI_SIZE 0x01000000
+#define AR7240_OHCI_BASE 0x1b000000
+#define AR7240_OHCI_SIZE 0x01000000
+#define AR71XX_SPI_BASE 0x1f000000
+#define AR71XX_SPI_SIZE 0x01000000
+
+#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
+#define AR71XX_DDR_CTRL_SIZE 0x10000
+#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000)
+#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
+#define AR71XX_UART_SIZE 0x10000
+#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
+#define AR71XX_USB_CTRL_SIZE 0x10000
+#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
+#define AR71XX_GPIO_SIZE 0x10000
+#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
+#define AR71XX_PLL_SIZE 0x10000
+#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
+#define AR71XX_RESET_SIZE 0x10000
+#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000)
+#define AR71XX_MII_SIZE 0x10000
+#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000)
+#define AR71XX_SLIC_SIZE 0x10000
+#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000)
+#define AR71XX_DMA_SIZE 0x10000
+#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000)
+#define AR71XX_STEREO_SIZE 0x10000
+
+#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000)
+#define AR724X_PCI_CRP_SIZE 0x100
+
+#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000)
+#define AR724X_PCI_CTRL_SIZE 0x100
+
+#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
+#define AR91XX_WMAC_SIZE 0x30000
+
+#define AR71XX_MEM_SIZE_MIN 0x0200000
+#define AR71XX_MEM_SIZE_MAX 0x10000000
+
+#define AR71XX_CPU_IRQ_BASE 0
+#define AR71XX_MISC_IRQ_BASE 8
+#define AR71XX_MISC_IRQ_COUNT 8
+#define AR71XX_GPIO_IRQ_BASE 16
+#define AR71XX_GPIO_IRQ_COUNT 32
+#define AR71XX_PCI_IRQ_BASE 48
+#define AR71XX_PCI_IRQ_COUNT 8
+
+#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2)
+#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3)
+#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4)
+#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5)
+#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6)
+#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7)
+
+#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0)
+#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1)
+#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2)
+#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3)
+#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4)
+#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5)
+#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6)
+#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7)
+
+#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x))
+
+#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0)
+#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1)
+#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2)
+#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4)
+
+extern u32 ar71xx_ahb_freq;
+extern u32 ar71xx_cpu_freq;
+extern u32 ar71xx_ddr_freq;
+
+enum ar71xx_soc_type {
+ AR71XX_SOC_UNKNOWN,
+ AR71XX_SOC_AR7130,
+ AR71XX_SOC_AR7141,
+ AR71XX_SOC_AR7161,
+ AR71XX_SOC_AR7240,
+ AR71XX_SOC_AR7241,
+ AR71XX_SOC_AR7242,
+ AR71XX_SOC_AR9130,
+ AR71XX_SOC_AR9132
+};
+
+extern enum ar71xx_soc_type ar71xx_soc;
+
+/*
+ * PLL block
+ */
+#define AR71XX_PLL_REG_CPU_CONFIG 0x00
+#define AR71XX_PLL_REG_SEC_CONFIG 0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
+
+#define AR71XX_PLL_DIV_SHIFT 3
+#define AR71XX_PLL_DIV_MASK 0x1f
+#define AR71XX_CPU_DIV_SHIFT 16
+#define AR71XX_CPU_DIV_MASK 0x3
+#define AR71XX_DDR_DIV_SHIFT 18
+#define AR71XX_DDR_DIV_MASK 0x3
+#define AR71XX_AHB_DIV_SHIFT 20
+#define AR71XX_AHB_DIV_MASK 0x7
+
+#define AR71XX_ETH0_PLL_SHIFT 17
+#define AR71XX_ETH1_PLL_SHIFT 19
+
+#define AR724X_PLL_REG_CPU_CONFIG 0x00
+#define AR724X_PLL_REG_PCIE_CONFIG 0x18
+
+#define AR724X_PLL_DIV_SHIFT 0
+#define AR724X_PLL_DIV_MASK 0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT 10
+#define AR724X_PLL_REF_DIV_MASK 0xf
+#define AR724X_AHB_DIV_SHIFT 19
+#define AR724X_AHB_DIV_MASK 0x1
+#define AR724X_DDR_DIV_SHIFT 22
+#define AR724X_DDR_DIV_MASK 0x3
+
+#define AR91XX_PLL_REG_CPU_CONFIG 0x00
+#define AR91XX_PLL_REG_ETH_CONFIG 0x04
+#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14
+#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18
+
+#define AR91XX_PLL_DIV_SHIFT 0
+#define AR91XX_PLL_DIV_MASK 0x3ff
+#define AR91XX_DDR_DIV_SHIFT 22
+#define AR91XX_DDR_DIV_MASK 0x3
+#define AR91XX_AHB_DIV_SHIFT 19
+#define AR91XX_AHB_DIV_MASK 0x1
+
+#define AR91XX_ETH0_PLL_SHIFT 20
+#define AR91XX_ETH1_PLL_SHIFT 22
+
+// extern void __iomem *ar71xx_pll_base;
+
+// static inline void ar71xx_pll_wr(unsigned reg, u32 val)
+// {
+ // __raw_writel(val, ar71xx_pll_base + reg);
+// }
+
+// static inline u32 ar71xx_pll_rr(unsigned reg)
+// {
+ // return __raw_readl(ar71xx_pll_base + reg);
+// }
+
+/*
+ * USB_CONFIG block
+ */
+#define USB_CTRL_REG_FLADJ 0x00
+#define USB_CTRL_REG_CONFIG 0x04
+
+// extern void __iomem *ar71xx_usb_ctrl_base;
+
+// static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val)
+// {
+ // __raw_writel(val, ar71xx_usb_ctrl_base + reg);
+// }
+
+// static inline u32 ar71xx_usb_ctrl_rr(unsigned reg)
+// {
+ // return __raw_readl(ar71xx_usb_ctrl_base + reg);
+// }
+
+/*
+ * GPIO block
+ */
+#define GPIO_REG_OE 0x00
+#define GPIO_REG_IN 0x04
+#define GPIO_REG_OUT 0x08
+#define GPIO_REG_SET 0x0c
+#define GPIO_REG_CLEAR 0x10
+#define GPIO_REG_INT_MODE 0x14
+#define GPIO_REG_INT_TYPE 0x18
+#define GPIO_REG_INT_POLARITY 0x1c
+#define GPIO_REG_INT_PENDING 0x20
+#define GPIO_REG_INT_ENABLE 0x24
+#define GPIO_REG_FUNC 0x28
+
+#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17)
+#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16)
+#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13)
+#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12)
+#define AR71XX_GPIO_FUNC_UART_EN BIT(8)
+#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4)
+#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0)
+
+#define AR71XX_GPIO_COUNT 16
+
+#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19)
+#define AR724X_GPIO_FUNC_SPI_EN BIT(18)
+#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14)
+#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13)
+#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12)
+#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11)
+#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10)
+#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9)
+#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3)
+#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2)
+#define AR724X_GPIO_FUNC_UART_EN BIT(1)
+#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0)
+
+#define AR724X_GPIO_COUNT 18
+
+#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22)
+#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21)
+#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20)
+#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19)
+#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18)
+#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17)
+#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16)
+#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9)
+#define AR91XX_GPIO_FUNC_UART_EN BIT(8)
+#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4)
+
+#define AR91XX_GPIO_COUNT 22
+
+// extern void __iomem *ar71xx_gpio_base;
+
+// static inline void ar71xx_gpio_wr(unsigned reg, u32 value)
+// {
+ // __raw_writel(value, ar71xx_gpio_base + reg);
+// }
+
+// static inline u32 ar71xx_gpio_rr(unsigned reg)
+// {
+ // return __raw_readl(ar71xx_gpio_base + reg);
+// }
+
+// void ar71xx_gpio_init(void) __init;
+// void ar71xx_gpio_function_enable(u32 mask);
+// void ar71xx_gpio_function_disable(u32 mask);
+// void ar71xx_gpio_function_setup(u32 set, u32 clear);
+
+/*
+ * DDR_CTRL block
+ */
+#define AR71XX_DDR_REG_PCI_WIN0 0x7c
+#define AR71XX_DDR_REG_PCI_WIN1 0x80
+#define AR71XX_DDR_REG_PCI_WIN2 0x84
+#define AR71XX_DDR_REG_PCI_WIN3 0x88
+#define AR71XX_DDR_REG_PCI_WIN4 0x8c
+#define AR71XX_DDR_REG_PCI_WIN5 0x90
+#define AR71XX_DDR_REG_PCI_WIN6 0x94
+#define AR71XX_DDR_REG_PCI_WIN7 0x98
+#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
+#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
+#define AR71XX_DDR_REG_FLUSH_USB 0xa4
+#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
+
+#define AR724X_DDR_REG_FLUSH_GE0 0x7c
+#define AR724X_DDR_REG_FLUSH_GE1 0x80
+#define AR724X_DDR_REG_FLUSH_USB 0x84
+#define AR724X_DDR_REG_FLUSH_PCIE 0x88
+
+#define AR91XX_DDR_REG_FLUSH_GE0 0x7c
+#define AR91XX_DDR_REG_FLUSH_GE1 0x80
+#define AR91XX_DDR_REG_FLUSH_USB 0x84
+#define AR91XX_DDR_REG_FLUSH_WMAC 0x88
+
+#define PCI_WIN0_OFFS 0x10000000
+#define PCI_WIN1_OFFS 0x11000000
+#define PCI_WIN2_OFFS 0x12000000
+#define PCI_WIN3_OFFS 0x13000000
+#define PCI_WIN4_OFFS 0x14000000
+#define PCI_WIN5_OFFS 0x15000000
+#define PCI_WIN6_OFFS 0x16000000
+#define PCI_WIN7_OFFS 0x07000000
+
+// extern void __iomem *ar71xx_ddr_base;
+
+// static inline void ar71xx_ddr_wr(unsigned reg, u32 val)
+// {
+ // __raw_writel(val, ar71xx_ddr_base + reg);
+// }
+
+// static inline u32 ar71xx_ddr_rr(unsigned reg)
+// {
+ // return __raw_readl(ar71xx_ddr_base + reg);
+// }
+
+// void ar71xx_ddr_flush(u32 reg);
+
+/*
+ * PCI block
+ */
+#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000)
+#define AR71XX_PCI_CFG_SIZE 0x100
+
+#define PCI_REG_CRP_AD_CBE 0x00
+#define PCI_REG_CRP_WRDATA 0x04
+#define PCI_REG_CRP_RDDATA 0x08
+#define PCI_REG_CFG_AD 0x0c
+#define PCI_REG_CFG_CBE 0x10
+#define PCI_REG_CFG_WRDATA 0x14
+#define PCI_REG_CFG_RDDATA 0x18
+#define PCI_REG_PCI_ERR 0x1c
+#define PCI_REG_PCI_ERR_ADDR 0x20
+#define PCI_REG_AHB_ERR 0x24
+#define PCI_REG_AHB_ERR_ADDR 0x28
+
+#define PCI_CRP_CMD_WRITE 0x00010000
+#define PCI_CRP_CMD_READ 0x00000000
+#define PCI_CFG_CMD_READ 0x0000000a
+#define PCI_CFG_CMD_WRITE 0x0000000b
+
+#define PCI_IDSEL_ADL_START 17
+
+#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000)
+#define AR724X_PCI_CFG_SIZE 0x1000
+
+#define AR724X_PCI_REG_APP 0x00
+#define AR724X_PCI_REG_RESET 0x18
+#define AR724X_PCI_REG_INT_STATUS 0x4c
+#define AR724X_PCI_REG_INT_MASK 0x50
+
+#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0)
+#define AR724X_PCI_RESET_LINK_UP BIT(0)
+
+#define AR724X_PCI_INT_DEV0 BIT(14)
+
+/*
+ * RESET block
+ */
+#define AR71XX_RESET_REG_TIMER 0x00
+#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
+#define AR71XX_RESET_REG_WDOG_CTRL 0x08
+#define AR71XX_RESET_REG_WDOG 0x0c
+#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
+#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
+#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
+#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
+#define AR71XX_RESET_REG_RESET_MODULE 0x24
+#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
+#define AR71XX_RESET_REG_PERFC0 0x30
+#define AR71XX_RESET_REG_PERFC1 0x34
+#define AR71XX_RESET_REG_REV_ID 0x90
+
+#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18
+#define AR91XX_RESET_REG_RESET_MODULE 0x1c
+#define AR91XX_RESET_REG_PERF_CTRL 0x20
+#define AR91XX_RESET_REG_PERFC0 0x24
+#define AR91XX_RESET_REG_PERFC1 0x28
+
+#define AR724X_RESET_REG_RESET_MODULE 0x1c
+
+#define WDOG_CTRL_LAST_RESET BIT(31)
+#define WDOG_CTRL_ACTION_MASK 3
+#define WDOG_CTRL_ACTION_NONE 0 /* no action */
+#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */
+#define WDOG_CTRL_ACTION_NMI 2 /* NMI */
+#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */
+
+#define MISC_INT_DMA BIT(7)
+#define MISC_INT_OHCI BIT(6)
+#define MISC_INT_PERFC BIT(5)
+#define MISC_INT_WDOG BIT(4)
+#define MISC_INT_UART BIT(3)
+#define MISC_INT_GPIO BIT(2)
+#define MISC_INT_ERROR BIT(1)
+#define MISC_INT_TIMER BIT(0)
+
+#define PCI_INT_CORE BIT(4)
+#define PCI_INT_DEV2 BIT(2)
+#define PCI_INT_DEV1 BIT(1)
+#define PCI_INT_DEV0 BIT(0)
+
+#define RESET_MODULE_EXTERNAL BIT(28)
+#define RESET_MODULE_FULL_CHIP BIT(24)
+#define RESET_MODULE_AMBA2WMAC BIT(22)
+#define RESET_MODULE_CPU_NMI BIT(21)
+#define RESET_MODULE_CPU_COLD BIT(20)
+#define RESET_MODULE_DMA BIT(19)
+#define RESET_MODULE_SLIC BIT(18)
+#define RESET_MODULE_STEREO BIT(17)
+#define RESET_MODULE_DDR BIT(16)
+#define RESET_MODULE_GE1_MAC BIT(13)
+#define RESET_MODULE_GE1_PHY BIT(12)
+#define RESET_MODULE_USBSUS_OVERRIDE BIT(10)
+#define RESET_MODULE_GE0_MAC BIT(9)
+#define RESET_MODULE_GE0_PHY BIT(8)
+#define RESET_MODULE_USB_OHCI_DLL BIT(6)
+#define RESET_MODULE_USB_HOST BIT(5)
+#define RESET_MODULE_USB_PHY BIT(4)
+#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3)
+#define RESET_MODULE_PCI_BUS BIT(1)
+#define RESET_MODULE_PCI_CORE BIT(0)
+
+#define AR724X_RESET_GE1_MDIO BIT(23)
+#define AR724X_RESET_GE0_MDIO BIT(22)
+#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
+#define AR724X_RESET_PCIE_PHY BIT(7)
+#define AR724X_RESET_PCIE BIT(6)
+
+#define REV_ID_MAJOR_MASK 0xfff0
+#define REV_ID_MAJOR_AR71XX 0x00a0
+#define REV_ID_MAJOR_AR913X 0x00b0
+#define REV_ID_MAJOR_AR7240 0x00c0
+#define REV_ID_MAJOR_AR7241 0x0100
+#define REV_ID_MAJOR_AR7242 0x1100
+
+#define AR71XX_REV_ID_MINOR_MASK 0x3
+#define AR71XX_REV_ID_MINOR_AR7130 0x0
+#define AR71XX_REV_ID_MINOR_AR7141 0x1
+#define AR71XX_REV_ID_MINOR_AR7161 0x2
+#define AR71XX_REV_ID_REVISION_MASK 0x3
+#define AR71XX_REV_ID_REVISION_SHIFT 2
+
+#define AR91XX_REV_ID_MINOR_MASK 0x3
+#define AR91XX_REV_ID_MINOR_AR9130 0x0
+#define AR91XX_REV_ID_MINOR_AR9132 0x1
+#define AR91XX_REV_ID_REVISION_MASK 0x3
+#define AR91XX_REV_ID_REVISION_SHIFT 2
+
+#define AR724X_REV_ID_REVISION_MASK 0x3
+
+// extern void __iomem *ar71xx_reset_base;
+
+static inline void ar71xx_reset_wr(unsigned reg, u32 val)
+{
+ __raw_writel(val, KSEG1ADDR(AR71XX_RESET_BASE) + reg);
+}
+
+static inline u32 ar71xx_reset_rr(unsigned reg)
+{
+ return __raw_readl(KSEG1ADDR(AR71XX_RESET_BASE) + reg);
+}
+
+// void ar71xx_device_stop(u32 mask);
+// void ar71xx_device_start(u32 mask);
+// int ar71xx_device_stopped(u32 mask);
+
+/*
+ * SPI block
+ */
+#define SPI_REG_FS 0x00 /* Function Select */
+#define SPI_REG_CTRL 0x04 /* SPI Control */
+#define SPI_REG_IOC 0x08 /* SPI I/O Control */
+#define SPI_REG_RDS 0x0c /* Read Data Shift */
+
+#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
+
+#define SPI_CTRL_RD BIT(6) /* Remap Disable */
+#define SPI_CTRL_DIV_MASK 0x3f
+
+#define SPI_IOC_DO BIT(0) /* Data Out pin */
+#define SPI_IOC_CLK BIT(8) /* CLK pin */
+#define SPI_IOC_CS(n) BIT(16 + (n))
+#define SPI_IOC_CS0 SPI_IOC_CS(0)
+#define SPI_IOC_CS1 SPI_IOC_CS(1)
+#define SPI_IOC_CS2 SPI_IOC_CS(2)
+#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2)
+
+// void ar71xx_flash_acquire(void);
+// void ar71xx_flash_release(void);
+
+/*
+ * MII_CTRL block
+ */
+#define MII_REG_MII0_CTRL 0x00
+#define MII_REG_MII1_CTRL 0x04
+
+#define MII0_CTRL_IF_GMII 0
+#define MII0_CTRL_IF_MII 1
+#define MII0_CTRL_IF_RGMII 2
+#define MII0_CTRL_IF_RMII 3
+
+#define MII1_CTRL_IF_RGMII 0
+#define MII1_CTRL_IF_RMII 1
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __ASM_MACH_AR71XX_H */
diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h
new file mode 100644
index 0000000..c92364b
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _AR71XX_GPIO_H
+#define _AR71XX_GPIO_H
+
+#include <common.h>
+#include <asm/ar71xx.h>
+
+static inline void ar71xx_setpin(uint8_t pin, uint8_t state)
+{
+ uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT));
+
+ if (state != 0) {
+ reg |= (1 << pin);
+ } else {
+ reg &= ~(1 << pin);
+ }
+
+ writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT));
+ readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT));
+}
+
+static inline uint32_t ar71xx_getpin(uint8_t pin)
+{
+ uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_IN));
+ return (((reg & (1 << pin)) != 0) ? 1 : 0);
+}
+
+static inline void ar71xx_setpindir(uint8_t pin, uint8_t direction)
+{
+ uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE));
+
+ if (direction != 0) {
+ reg |= (1 << pin);
+ } else {
+ reg &= ~(1 << pin);
+ }
+
+ writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE));
+ readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE));
+}
+
+
+#endif /* AR71XX_GPIO_H */
diff --git a/package/boot/uboot-ar71xx/files/include/configs/.svn/entries b/package/boot/uboot-ar71xx/files/include/configs/.svn/entries
new file mode 100644
index 0000000..240eb56
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/configs/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/include/configs
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+nbg460n.h
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+85e62ebf6a2d7d9a9fb3a787bb7e0ec1
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4386
+
diff --git a/package/boot/uboot-ar71xx/files/include/configs/.svn/prop-base/nbg460n.h.svn-base b/package/boot/uboot-ar71xx/files/include/configs/.svn/prop-base/nbg460n.h.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/configs/.svn/prop-base/nbg460n.h.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/uboot-ar71xx/files/include/configs/.svn/text-base/nbg460n.h.svn-base b/package/boot/uboot-ar71xx/files/include/configs/.svn/text-base/nbg460n.h.svn-base
new file mode 100644
index 0000000..dd9b4c3
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/configs/.svn/text-base/nbg460n.h.svn-base
@@ -0,0 +1,136 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This file contains the configuration parameters for the zyxel nbg460n board. */
+
+#ifndef _NBG460N_CONFIG_H
+#define _NBG460N_CONFIG_H
+
+#define CONFIG_MIPS32 1 /* MIPS32 CPU core */
+#define CONFIG_AR71XX 1
+#define CONFIG_AR91XX 1
+#define CONFIG_SYS_HZ 1000
+#define CONFIG_SYS_MIPS_TIMER_FREQ (400000000/2)
+
+/* Cache Configuration */
+#define CONFIG_SYS_DCACHE_SIZE 32768
+#define CONFIG_SYS_ICACHE_SIZE 65536
+#define CONFIG_SYS_CACHELINE_SIZE 32
+/* Cache lock for stack */
+#define CONFIG_SYS_INIT_SP_OFFSET 0x1000
+
+#define CONFIG_SYS_MONITOR_BASE (TEXT_BASE)
+
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE {115200}
+
+#define CONFIG_MISC_INIT_R
+
+/* SPI-Flash support */
+#define CONFIG_SPI_FLASH
+#define CONFIG_AR71XX_SPI
+#define CONFIG_SPI_FLASH_MACRONIX
+#define CONFIG_SF_DEFAULT_HZ 25000000
+
+#define CONFIG_ENV_SPI_MAX_HZ 25000000
+#define CONFIG_ENV_SPI_BUS 0
+#define CONFIG_ENV_SPI_CS 0
+
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_ADDR 0xbfc20000
+#define CONFIG_ENV_OFFSET 0x20000
+#define CONFIG_ENV_SIZE 0x01000
+#define CONFIG_ENV_SECT_SIZE 0x10000
+#define CONFIG_SYS_MAX_FLASH_BANKS 1
+#define CONFIG_SYS_MAX_FLASH_SECT 64
+#define CONFIG_SYS_FLASH_BASE 0xbfc00000
+
+/* Net support */
+#define CONFIG_ETHADDR_ADDR 0xbfc0fff8
+#define CONFIG_SYS_RX_ETH_BUFFER 16
+#define CONFIG_AG71XX
+#define CONFIG_AG71XX_PORTS { 1, 1 }
+#define CONFIG_AG71XX_MII0_IIF MII0_CTRL_IF_RGMII
+#define CONFIG_AG71XX_MII1_IIF MII1_CTRL_IF_RGMII
+#define CONFIG_NET_MULTI
+#define CONFIG_IPADDR 192.168.1.254
+#define CONFIG_SERVERIP 192.168.1.42
+
+/* Switch support */
+#define CONFIG_MII
+#define CONFIG_RTL8366_MII
+#define RTL8366_PIN_SDA 16
+#define RTL8366_PIN_SCK 18
+#define MII_GPIOINCLUDE <asm/ar71xx_gpio.h>
+#define MII_SETSDA(x) ar71xx_setpin(RTL8366_PIN_SDA, x)
+#define MII_GETSDA ar71xx_getpin(RTL8366_PIN_SDA)
+#define MII_SETSCK(x) ar71xx_setpin(RTL8366_PIN_SCK, x)
+#define MII_SDAINPUT ar71xx_setpindir(RTL8366_PIN_SDA, 0)
+#define MII_SDAOUTPUT ar71xx_setpindir(RTL8366_PIN_SDA, 1)
+#define MII_SCKINPUT ar71xx_setpindir(RTL8366_PIN_SCK, 0)
+#define MII_SCKOUTPUT ar71xx_setpindir(RTL8366_PIN_SCK, 1)
+
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_BOOTARGS "console=ttyS0,115200 rootfstype==squashfs,jffs2 noinitrd machtype=NBG460N"
+#define CONFIG_BOOTCOMMAND "bootm 0xbfc70000"
+#define CONFIG_LZMA
+
+
+/* Commands */
+#define CONFIG_SYS_NO_FLASH
+#include <config_cmd_default.h>
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_IMI
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_LOADS
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_SPI
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_PROMPT "U-Boot> "
+#define CONFIG_SYS_CBSIZE 256
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_LONGHELP 1
+#define CONFIG_CMDLINE_EDITING 1
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN ROUND(3 * 0x10000 + 128*1024, 0x1000)
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* 128 bytes for initial data */
+
+#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024
+
+#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
+#define CONFIG_SYS_LOAD_ADDR 0x80060000 /* default load address */
+
+#define CONFIG_SYS_MEMTEST_START 0x80000800
+#define CONFIG_SYS_MEMTEST_END 0x81E00000
+
+#endif /* _NBG460N_CONFIG_H */
diff --git a/package/boot/uboot-ar71xx/files/include/configs/nbg460n.h b/package/boot/uboot-ar71xx/files/include/configs/nbg460n.h
new file mode 100644
index 0000000..dd9b4c3
--- /dev/null
+++ b/package/boot/uboot-ar71xx/files/include/configs/nbg460n.h
@@ -0,0 +1,136 @@
+/*
+ * (C) Copyright 2010
+ * Michael Kurz <michi.kurz@googlemail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This file contains the configuration parameters for the zyxel nbg460n board. */
+
+#ifndef _NBG460N_CONFIG_H
+#define _NBG460N_CONFIG_H
+
+#define CONFIG_MIPS32 1 /* MIPS32 CPU core */
+#define CONFIG_AR71XX 1
+#define CONFIG_AR91XX 1
+#define CONFIG_SYS_HZ 1000
+#define CONFIG_SYS_MIPS_TIMER_FREQ (400000000/2)
+
+/* Cache Configuration */
+#define CONFIG_SYS_DCACHE_SIZE 32768
+#define CONFIG_SYS_ICACHE_SIZE 65536
+#define CONFIG_SYS_CACHELINE_SIZE 32
+/* Cache lock for stack */
+#define CONFIG_SYS_INIT_SP_OFFSET 0x1000
+
+#define CONFIG_SYS_MONITOR_BASE (TEXT_BASE)
+
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE {115200}
+
+#define CONFIG_MISC_INIT_R
+
+/* SPI-Flash support */
+#define CONFIG_SPI_FLASH
+#define CONFIG_AR71XX_SPI
+#define CONFIG_SPI_FLASH_MACRONIX
+#define CONFIG_SF_DEFAULT_HZ 25000000
+
+#define CONFIG_ENV_SPI_MAX_HZ 25000000
+#define CONFIG_ENV_SPI_BUS 0
+#define CONFIG_ENV_SPI_CS 0
+
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_ADDR 0xbfc20000
+#define CONFIG_ENV_OFFSET 0x20000
+#define CONFIG_ENV_SIZE 0x01000
+#define CONFIG_ENV_SECT_SIZE 0x10000
+#define CONFIG_SYS_MAX_FLASH_BANKS 1
+#define CONFIG_SYS_MAX_FLASH_SECT 64
+#define CONFIG_SYS_FLASH_BASE 0xbfc00000
+
+/* Net support */
+#define CONFIG_ETHADDR_ADDR 0xbfc0fff8
+#define CONFIG_SYS_RX_ETH_BUFFER 16
+#define CONFIG_AG71XX
+#define CONFIG_AG71XX_PORTS { 1, 1 }
+#define CONFIG_AG71XX_MII0_IIF MII0_CTRL_IF_RGMII
+#define CONFIG_AG71XX_MII1_IIF MII1_CTRL_IF_RGMII
+#define CONFIG_NET_MULTI
+#define CONFIG_IPADDR 192.168.1.254
+#define CONFIG_SERVERIP 192.168.1.42
+
+/* Switch support */
+#define CONFIG_MII
+#define CONFIG_RTL8366_MII
+#define RTL8366_PIN_SDA 16
+#define RTL8366_PIN_SCK 18
+#define MII_GPIOINCLUDE <asm/ar71xx_gpio.h>
+#define MII_SETSDA(x) ar71xx_setpin(RTL8366_PIN_SDA, x)
+#define MII_GETSDA ar71xx_getpin(RTL8366_PIN_SDA)
+#define MII_SETSCK(x) ar71xx_setpin(RTL8366_PIN_SCK, x)
+#define MII_SDAINPUT ar71xx_setpindir(RTL8366_PIN_SDA, 0)
+#define MII_SDAOUTPUT ar71xx_setpindir(RTL8366_PIN_SDA, 1)
+#define MII_SCKINPUT ar71xx_setpindir(RTL8366_PIN_SCK, 0)
+#define MII_SCKOUTPUT ar71xx_setpindir(RTL8366_PIN_SCK, 1)
+
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_BOOTARGS "console=ttyS0,115200 rootfstype==squashfs,jffs2 noinitrd machtype=NBG460N"
+#define CONFIG_BOOTCOMMAND "bootm 0xbfc70000"
+#define CONFIG_LZMA
+
+
+/* Commands */
+#define CONFIG_SYS_NO_FLASH
+#include <config_cmd_default.h>
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_IMI
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_LOADS
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_SPI
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_PROMPT "U-Boot> "
+#define CONFIG_SYS_CBSIZE 256
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_LONGHELP 1
+#define CONFIG_CMDLINE_EDITING 1
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN ROUND(3 * 0x10000 + 128*1024, 0x1000)
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* 128 bytes for initial data */
+
+#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024
+
+#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
+#define CONFIG_SYS_LOAD_ADDR 0x80060000 /* default load address */
+
+#define CONFIG_SYS_MEMTEST_START 0x80000800
+#define CONFIG_SYS_MEMTEST_END 0x81E00000
+
+#endif /* _NBG460N_CONFIG_H */
diff --git a/package/boot/uboot-ar71xx/patches/.svn/entries b/package/boot/uboot-ar71xx/patches/.svn/entries
new file mode 100644
index 0000000..f3d8b90
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/.svn/entries
@@ -0,0 +1,266 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/patches
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+002-ar71xx-spi.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+c93e74225de2389588d6c1b4d30fc2d3
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+458
+
+010-enet-ag71xx.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+ca96c86b1b5a1e69d9574118712b38de
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1055
+
+021-darwin_compat.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+4bd7c68770a42e7fa70cdf0e902d99f8
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+881
+
+001-ar71xx.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+2dc4f04e60b981ffe9ad13993f924f23
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1243
+
+020-freebsd-compat.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+690ab49ce8bb8ad88ce2a16976f89b5e
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+313
+
+011-switch-rtl8366sr.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+d85aa0315186eeac81cbba96f5c83314
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1139
+
+022-getline_backport.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+88d64f3c9686f9d3de6a3d4ae2f4cafc
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+436
+
diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/001-ar71xx.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/001-ar71xx.patch.svn-base
new file mode 100644
index 0000000..409f67a
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/001-ar71xx.patch.svn-base
@@ -0,0 +1,28 @@
+diff -ur u-boot-2010.03/cpu/mips/Makefile u-boot-nbg/cpu/mips/Makefile
+--- u-boot-2010.03/cpu/mips/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/cpu/mips/Makefile 2010-04-15 18:58:01.000000000 +0200
+@@ -33,6 +33,7 @@
+ COBJS-$(CONFIG_INCA_IP) += asc_serial.o incaip_clock.o
+ COBJS-$(CONFIG_PURPLE) += asc_serial.o
+ COBJS-$(CONFIG_SOC_AU1X00) += au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o
++COBJS-$(CONFIG_AR71XX) += ar71xx_serial.o
+
+ SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+ OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+diff -ur u-boot-2010.03/Makefile u-boot-nbg/Makefile
+--- u-boot-2010.03/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/Makefile 2010-04-11 23:31:29.000000000 +0200
+@@ -3455,6 +3455,13 @@
+ @$(MKCONFIG) -a qemu-mips mips mips qemu-mips
+
+ #########################################################################
++## MIPS32 AR71XX (24K)
++#########################################################################
++
++nbg460n_550n_550nh_config : unconfig
++ @$(MKCONFIG) -a nbg460n mips mips nbg460n zyxel
++
++#########################################################################
+ ## MIPS64 5Kc
+ #########################################################################
+
diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/002-ar71xx-spi.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/002-ar71xx-spi.patch.svn-base
new file mode 100644
index 0000000..2bb1ba2
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/002-ar71xx-spi.patch.svn-base
@@ -0,0 +1,11 @@
+diff -ur u-boot-2010.03/drivers/spi/Makefile u-boot-nbg/drivers/spi/Makefile
+--- u-boot-2010.03/drivers/spi/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/drivers/spi/Makefile 2010-04-15 19:31:27.000000000 +0200
+@@ -25,6 +25,7 @@
+
+ LIB := $(obj)libspi.a
+
++COBJS-$(CONFIG_AR71XX_SPI) += ar71xx_spi.o
+ COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
+ COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o
+ COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o
diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/010-enet-ag71xx.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/010-enet-ag71xx.patch.svn-base
new file mode 100644
index 0000000..ee90e32
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/010-enet-ag71xx.patch.svn-base
@@ -0,0 +1,22 @@
+diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile
+--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200
+@@ -27,6 +27,7 @@
+
+ COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
+ COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
++COBJS-$(CONFIG_AG71XX) += ag71xx.o
+ COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
+ COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
+ COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o
+diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h
+--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200
+@@ -42,6 +42,7 @@
+
+ /* Driver initialization prototypes */
+ int au1x00_enet_initialize(bd_t*);
++int ag71xx_register(bd_t * bis, char *phyname[], u16 phyid[], u16 phyfixed[]);
+ int at91emac_register(bd_t *bis, unsigned long iobase);
+ int bfin_EMAC_initialize(bd_t *bis);
+ int cs8900_initialize(u8 dev_num, int base_addr);
diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/011-switch-rtl8366sr.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/011-switch-rtl8366sr.patch.svn-base
new file mode 100644
index 0000000..5d2ba41
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/011-switch-rtl8366sr.patch.svn-base
@@ -0,0 +1,28 @@
+diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile
+--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200
+@@ -65,6 +65,7 @@
+ COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o
+ COBJS-$(CONFIG_RTL8139) += rtl8139.o
+ COBJS-$(CONFIG_RTL8169) += rtl8169.o
++COBJS-$(CONFIG_RTL8366_MII) += phy/rtl8366_mii.o
+ COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o
+ COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
+ COBJS-$(CONFIG_SMC91111) += smc91111.o
+diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h
+--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200
+@@ -175,5 +175,13 @@
+
+ int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig);
+ #endif /* CONFIG_MV88E61XX_SWITCH */
++
++#if defined(CONFIG_RTL8366_MII)
++#define RTL8366_DEVNAME "rtl8366"
++#define RTL8366_WANPHY_ID 4
++#define RTL8366_LANPHY_ID -1
++int rtl8366_mii_register(bd_t *bis);
++int rtl8366s_initialize(void);
++#endif
+
+ #endif /* _NETDEV_H_ */
diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/020-freebsd-compat.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/020-freebsd-compat.patch.svn-base
new file mode 100644
index 0000000..fee0669
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/020-freebsd-compat.patch.svn-base
@@ -0,0 +1,11 @@
+--- a/include/compiler.h
++++ b/include/compiler.h
+@@ -46,7 +46,7 @@ extern int errno;
+ #ifdef __linux__
+ # include <endian.h>
+ # include <byteswap.h>
+-#elif defined(__MACH__)
++#elif defined(__MACH__) || defined(__FreeBSD__)
+ # include <machine/endian.h>
+ typedef unsigned long ulong;
+ typedef unsigned int uint;
diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/021-darwin_compat.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/021-darwin_compat.patch.svn-base
new file mode 100644
index 0000000..dde83d4
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/021-darwin_compat.patch.svn-base
@@ -0,0 +1,23 @@
+--- a/config.mk
++++ b/config.mk
+@@ -64,9 +64,17 @@ HOSTSTRIP = strip
+ #
+
+ ifeq ($(HOSTOS),darwin)
+-HOSTCC = cc
+-HOSTCFLAGS += -traditional-cpp
+-HOSTLDFLAGS += -multiply_defined suppress
++#get the major and minor product version (e.g. '10' and '6' for Snow Leopard)
++DARWIN_MAJOR_VERSION = $(shell sw_vers -productVersion | cut -f 1 -d '.')
++DARWIN_MINOR_VERSION = $(shell sw_vers -productVersion | cut -f 2 -d '.')
++
++before-snow-leopard = $(shell if [ $(DARWIN_MAJOR_VERSION) -le 10 -a \
++ $(DARWIN_MINOR_VERSION) -le 5 ] ; then echo "$(1)"; else echo "$(2)"; fi ;)
++
++# Snow Leopards build environment has no longer restrictions as described above
++HOSTCC = $(call before-snow-leopard, "cc", "gcc")
++HOSTCFLAGS += $(call before-snow-leopard, "-traditional-cpp")
++HOSTLDFLAGS += $(call before-snow-leopard, "-multiply_defined suppress")
+ else
+ HOSTCC = gcc
+ endif
diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/022-getline_backport.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/022-getline_backport.patch.svn-base
new file mode 100644
index 0000000..2ce2b61
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/022-getline_backport.patch.svn-base
@@ -0,0 +1,21 @@
+--- a/tools/os_support.c
++++ b/tools/os_support.c
+@@ -23,6 +23,6 @@
+ #ifdef __MINGW32__
+ #include "mingw_support.c"
+ #endif
+-#ifdef __APPLE__
++#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
+ #include "getline.c"
+ #endif
+--- a/tools/os_support.h
++++ b/tools/os_support.h
+@@ -28,7 +28,7 @@
+ #include "mingw_support.h"
+ #endif
+
+-#ifdef __APPLE__
++#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
+ #include "getline.h"
+ #endif
+
diff --git a/package/boot/uboot-ar71xx/patches/001-ar71xx.patch b/package/boot/uboot-ar71xx/patches/001-ar71xx.patch
new file mode 100644
index 0000000..409f67a
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/001-ar71xx.patch
@@ -0,0 +1,28 @@
+diff -ur u-boot-2010.03/cpu/mips/Makefile u-boot-nbg/cpu/mips/Makefile
+--- u-boot-2010.03/cpu/mips/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/cpu/mips/Makefile 2010-04-15 18:58:01.000000000 +0200
+@@ -33,6 +33,7 @@
+ COBJS-$(CONFIG_INCA_IP) += asc_serial.o incaip_clock.o
+ COBJS-$(CONFIG_PURPLE) += asc_serial.o
+ COBJS-$(CONFIG_SOC_AU1X00) += au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o
++COBJS-$(CONFIG_AR71XX) += ar71xx_serial.o
+
+ SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+ OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+diff -ur u-boot-2010.03/Makefile u-boot-nbg/Makefile
+--- u-boot-2010.03/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/Makefile 2010-04-11 23:31:29.000000000 +0200
+@@ -3455,6 +3455,13 @@
+ @$(MKCONFIG) -a qemu-mips mips mips qemu-mips
+
+ #########################################################################
++## MIPS32 AR71XX (24K)
++#########################################################################
++
++nbg460n_550n_550nh_config : unconfig
++ @$(MKCONFIG) -a nbg460n mips mips nbg460n zyxel
++
++#########################################################################
+ ## MIPS64 5Kc
+ #########################################################################
+
diff --git a/package/boot/uboot-ar71xx/patches/002-ar71xx-spi.patch b/package/boot/uboot-ar71xx/patches/002-ar71xx-spi.patch
new file mode 100644
index 0000000..2bb1ba2
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/002-ar71xx-spi.patch
@@ -0,0 +1,11 @@
+diff -ur u-boot-2010.03/drivers/spi/Makefile u-boot-nbg/drivers/spi/Makefile
+--- u-boot-2010.03/drivers/spi/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/drivers/spi/Makefile 2010-04-15 19:31:27.000000000 +0200
+@@ -25,6 +25,7 @@
+
+ LIB := $(obj)libspi.a
+
++COBJS-$(CONFIG_AR71XX_SPI) += ar71xx_spi.o
+ COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
+ COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o
+ COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o
diff --git a/package/boot/uboot-ar71xx/patches/010-enet-ag71xx.patch b/package/boot/uboot-ar71xx/patches/010-enet-ag71xx.patch
new file mode 100644
index 0000000..ee90e32
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/010-enet-ag71xx.patch
@@ -0,0 +1,22 @@
+diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile
+--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200
+@@ -27,6 +27,7 @@
+
+ COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
+ COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
++COBJS-$(CONFIG_AG71XX) += ag71xx.o
+ COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
+ COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
+ COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o
+diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h
+--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200
+@@ -42,6 +42,7 @@
+
+ /* Driver initialization prototypes */
+ int au1x00_enet_initialize(bd_t*);
++int ag71xx_register(bd_t * bis, char *phyname[], u16 phyid[], u16 phyfixed[]);
+ int at91emac_register(bd_t *bis, unsigned long iobase);
+ int bfin_EMAC_initialize(bd_t *bis);
+ int cs8900_initialize(u8 dev_num, int base_addr);
diff --git a/package/boot/uboot-ar71xx/patches/011-switch-rtl8366sr.patch b/package/boot/uboot-ar71xx/patches/011-switch-rtl8366sr.patch
new file mode 100644
index 0000000..5d2ba41
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/011-switch-rtl8366sr.patch
@@ -0,0 +1,28 @@
+diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile
+--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200
+@@ -65,6 +65,7 @@
+ COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o
+ COBJS-$(CONFIG_RTL8139) += rtl8139.o
+ COBJS-$(CONFIG_RTL8169) += rtl8169.o
++COBJS-$(CONFIG_RTL8366_MII) += phy/rtl8366_mii.o
+ COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o
+ COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
+ COBJS-$(CONFIG_SMC91111) += smc91111.o
+diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h
+--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200
++++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200
+@@ -175,5 +175,13 @@
+
+ int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig);
+ #endif /* CONFIG_MV88E61XX_SWITCH */
++
++#if defined(CONFIG_RTL8366_MII)
++#define RTL8366_DEVNAME "rtl8366"
++#define RTL8366_WANPHY_ID 4
++#define RTL8366_LANPHY_ID -1
++int rtl8366_mii_register(bd_t *bis);
++int rtl8366s_initialize(void);
++#endif
+
+ #endif /* _NETDEV_H_ */
diff --git a/package/boot/uboot-ar71xx/patches/020-freebsd-compat.patch b/package/boot/uboot-ar71xx/patches/020-freebsd-compat.patch
new file mode 100644
index 0000000..fee0669
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/020-freebsd-compat.patch
@@ -0,0 +1,11 @@
+--- a/include/compiler.h
++++ b/include/compiler.h
+@@ -46,7 +46,7 @@ extern int errno;
+ #ifdef __linux__
+ # include <endian.h>
+ # include <byteswap.h>
+-#elif defined(__MACH__)
++#elif defined(__MACH__) || defined(__FreeBSD__)
+ # include <machine/endian.h>
+ typedef unsigned long ulong;
+ typedef unsigned int uint;
diff --git a/package/boot/uboot-ar71xx/patches/021-darwin_compat.patch b/package/boot/uboot-ar71xx/patches/021-darwin_compat.patch
new file mode 100644
index 0000000..dde83d4
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/021-darwin_compat.patch
@@ -0,0 +1,23 @@
+--- a/config.mk
++++ b/config.mk
+@@ -64,9 +64,17 @@ HOSTSTRIP = strip
+ #
+
+ ifeq ($(HOSTOS),darwin)
+-HOSTCC = cc
+-HOSTCFLAGS += -traditional-cpp
+-HOSTLDFLAGS += -multiply_defined suppress
++#get the major and minor product version (e.g. '10' and '6' for Snow Leopard)
++DARWIN_MAJOR_VERSION = $(shell sw_vers -productVersion | cut -f 1 -d '.')
++DARWIN_MINOR_VERSION = $(shell sw_vers -productVersion | cut -f 2 -d '.')
++
++before-snow-leopard = $(shell if [ $(DARWIN_MAJOR_VERSION) -le 10 -a \
++ $(DARWIN_MINOR_VERSION) -le 5 ] ; then echo "$(1)"; else echo "$(2)"; fi ;)
++
++# Snow Leopards build environment has no longer restrictions as described above
++HOSTCC = $(call before-snow-leopard, "cc", "gcc")
++HOSTCFLAGS += $(call before-snow-leopard, "-traditional-cpp")
++HOSTLDFLAGS += $(call before-snow-leopard, "-multiply_defined suppress")
+ else
+ HOSTCC = gcc
+ endif
diff --git a/package/boot/uboot-ar71xx/patches/022-getline_backport.patch b/package/boot/uboot-ar71xx/patches/022-getline_backport.patch
new file mode 100644
index 0000000..2ce2b61
--- /dev/null
+++ b/package/boot/uboot-ar71xx/patches/022-getline_backport.patch
@@ -0,0 +1,21 @@
+--- a/tools/os_support.c
++++ b/tools/os_support.c
+@@ -23,6 +23,6 @@
+ #ifdef __MINGW32__
+ #include "mingw_support.c"
+ #endif
+-#ifdef __APPLE__
++#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
+ #include "getline.c"
+ #endif
+--- a/tools/os_support.h
++++ b/tools/os_support.h
+@@ -28,7 +28,7 @@
+ #include "mingw_support.h"
+ #endif
+
+-#ifdef __APPLE__
++#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
+ #include "getline.h"
+ #endif
+
diff --git a/package/boot/uboot-envtools/.svn/entries b/package/boot/uboot-envtools/.svn/entries
new file mode 100644
index 0000000..dd03750
--- /dev/null
+++ b/package/boot/uboot-envtools/.svn/entries
@@ -0,0 +1,68 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-envtools
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-03-15T01:36:53.833391Z
+36033
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+files
+dir
+
+patches
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+c912a9069ac7b571a308a7eb4a9a1dc4
+2013-03-15T01:36:53.833391Z
+36033
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2018
+
diff --git a/package/boot/uboot-envtools/.svn/text-base/Makefile.svn-base b/package/boot/uboot-envtools/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..55aaf88
--- /dev/null
+++ b/package/boot/uboot-envtools/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2006-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=uboot-envtools
+PKG_DISTNAME:=u-boot
+PKG_VERSION:=2013.01.01
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=73939f78606f89a1775c7e9acb2ca617
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/u-boot-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/uboot-envtools
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=read/modify U-Boot bootloader environment
+ URL:=http://www.denx.de/wiki/U-Boot
+endef
+
+define Package/uboot-envtools/description
+ This package includes tools to read and modify U-Boot bootloader environment.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ touch $(PKG_BUILD_DIR)/include/config.h
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ HOSTCC="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)gcc" \
+ HOSTSTRIP="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)strip" \
+ env
+endef
+
+define Package/uboot-envtools/conffiles
+/etc/config/ubootenv
+/etc/fw_env.config
+endef
+
+define Package/uboot-envtools/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/env/fw_printenv $(1)/usr/sbin
+ ln -s fw_printenv $(1)/usr/sbin/fw_setenv
+ $(INSTALL_DIR) $(1)/lib
+ $(INSTALL_DATA) ./files/uboot-envtools.sh $(1)/lib
+ifneq ($(CONFIG_TARGET_ar71xx),)
+ $(INSTALL_DIR) $(1)/etc/uci-defaults
+ $(INSTALL_BIN) ./files/ar71xx $(1)/etc/uci-defaults/uboot-envtools
+endif
+ifneq ($(CONFIG_TARGET_kirkwood),)
+ $(INSTALL_DIR) $(1)/etc/uci-defaults
+ $(INSTALL_BIN) ./files/kirkwood $(1)/etc/uci-defaults/uboot-envtools
+endif
+ifneq ($(CONFIG_TARGET_lantiq),)
+ $(INSTALL_DIR) $(1)/etc/uci-defaults
+ $(INSTALL_BIN) ./files/lantiq $(1)/etc/uci-defaults/uboot-envtools
+endif
+ifneq ($(CONFIG_TARGET_ramips),)
+ $(INSTALL_DIR) $(1)/etc/uci-defaults
+ $(INSTALL_BIN) ./files/ramips $(1)/etc/uci-defaults/uboot-envtools
+endif
+endef
+
+$(eval $(call BuildPackage,uboot-envtools))
diff --git a/package/boot/uboot-envtools/Makefile b/package/boot/uboot-envtools/Makefile
new file mode 100644
index 0000000..55aaf88
--- /dev/null
+++ b/package/boot/uboot-envtools/Makefile
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2006-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=uboot-envtools
+PKG_DISTNAME:=u-boot
+PKG_VERSION:=2013.01.01
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=73939f78606f89a1775c7e9acb2ca617
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/u-boot-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/uboot-envtools
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=read/modify U-Boot bootloader environment
+ URL:=http://www.denx.de/wiki/U-Boot
+endef
+
+define Package/uboot-envtools/description
+ This package includes tools to read and modify U-Boot bootloader environment.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ touch $(PKG_BUILD_DIR)/include/config.h
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ HOSTCC="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)gcc" \
+ HOSTSTRIP="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)strip" \
+ env
+endef
+
+define Package/uboot-envtools/conffiles
+/etc/config/ubootenv
+/etc/fw_env.config
+endef
+
+define Package/uboot-envtools/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/env/fw_printenv $(1)/usr/sbin
+ ln -s fw_printenv $(1)/usr/sbin/fw_setenv
+ $(INSTALL_DIR) $(1)/lib
+ $(INSTALL_DATA) ./files/uboot-envtools.sh $(1)/lib
+ifneq ($(CONFIG_TARGET_ar71xx),)
+ $(INSTALL_DIR) $(1)/etc/uci-defaults
+ $(INSTALL_BIN) ./files/ar71xx $(1)/etc/uci-defaults/uboot-envtools
+endif
+ifneq ($(CONFIG_TARGET_kirkwood),)
+ $(INSTALL_DIR) $(1)/etc/uci-defaults
+ $(INSTALL_BIN) ./files/kirkwood $(1)/etc/uci-defaults/uboot-envtools
+endif
+ifneq ($(CONFIG_TARGET_lantiq),)
+ $(INSTALL_DIR) $(1)/etc/uci-defaults
+ $(INSTALL_BIN) ./files/lantiq $(1)/etc/uci-defaults/uboot-envtools
+endif
+ifneq ($(CONFIG_TARGET_ramips),)
+ $(INSTALL_DIR) $(1)/etc/uci-defaults
+ $(INSTALL_BIN) ./files/ramips $(1)/etc/uci-defaults/uboot-envtools
+endif
+endef
+
+$(eval $(call BuildPackage,uboot-envtools))
diff --git a/package/boot/uboot-envtools/files/.svn/entries b/package/boot/uboot-envtools/files/.svn/entries
new file mode 100644
index 0000000..b8b2ee3
--- /dev/null
+++ b/package/boot/uboot-envtools/files/.svn/entries
@@ -0,0 +1,198 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-envtools/files
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-03-03T21:59:35.671819Z
+35866
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+lantiq
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+feaeaee38e5a27cd3fdb620527e84a40
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+388
+
+uboot-envtools.sh
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+4c8999ee23b10578d350fc5a58690e02
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+771
+
+kirkwood
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+be3738327f58fad9f27bd01a23ae277a
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+418
+
+ar71xx
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+10b2cf77277fa90f3966c145ff410c23
+2013-03-03T21:59:35.671819Z
+35866
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+630
+
+ramips
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+e8cb5e6fbb48539d2d9d74f7e858737d
+2013-02-02T17:01:52.502693Z
+35464
+juhosg
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+495
+
diff --git a/package/boot/uboot-envtools/files/.svn/text-base/ar71xx.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/ar71xx.svn-base
new file mode 100644
index 0000000..1803a9f
--- /dev/null
+++ b/package/boot/uboot-envtools/files/.svn/text-base/ar71xx.svn-base
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# Copyright (C) 2011-2013 OpenWrt.org
+#
+
+[ -e /etc/config/ubootenv ] && exit 0
+
+touch /etc/config/ubootenv
+
+. /lib/ar71xx.sh
+. /lib/uboot-envtools.sh
+. /lib/functions.sh
+
+board=$(ar71xx_board_name)
+
+case "$board" in
+all0258n | \
+cap4200ag | \
+mr600 | \
+mr600v2)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000"
+ ;;
+alfa-ap96 | \
+all0315n | \
+om2p | \
+om2p-hs | \
+om2p-lc)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x40000" "0x40000"
+ ;;
+wzr-hp-ag300h)
+ ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x10000" "0x10000"
+ ;;
+esac
+
+config_load ubootenv
+config_foreach ubootenv_add_app_config ubootenv
+
+exit 0
diff --git a/package/boot/uboot-envtools/files/.svn/text-base/kirkwood.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/kirkwood.svn-base
new file mode 100644
index 0000000..cad53aa
--- /dev/null
+++ b/package/boot/uboot-envtools/files/.svn/text-base/kirkwood.svn-base
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+
+[ -e /etc/config/ubootenv ] && exit 0
+
+touch /etc/config/ubootenv
+
+. /lib/kirkwood.sh
+. /lib/uboot-envtools.sh
+. /lib/functions.sh
+
+hardware=$(kirkwood_hardware_name)
+
+case "$hardware" in
+"RaidSonic ICY BOX IB-NAS6210")
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000"
+ ;;
+esac
+
+config_load ubootenv
+config_foreach ubootenv_add_app_config ubootenv
+
+exit 0
diff --git a/package/boot/uboot-envtools/files/.svn/text-base/lantiq.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/lantiq.svn-base
new file mode 100644
index 0000000..40befc3
--- /dev/null
+++ b/package/boot/uboot-envtools/files/.svn/text-base/lantiq.svn-base
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+
+[ -e /etc/config/ubootenv ] && exit 0
+
+touch /etc/config/ubootenv
+
+. /lib/lantiq.sh
+. /lib/uboot-envtools.sh
+. /lib/functions.sh
+
+board=$(lantiq_board_name)
+
+case "$board" in
+GIGASX76X)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" "1"
+ ;;
+esac
+
+config_load ubootenv
+config_foreach ubootenv_add_app_config ubootenv
+
+exit 0
diff --git a/package/boot/uboot-envtools/files/.svn/text-base/ramips.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/ramips.svn-base
new file mode 100644
index 0000000..3599f68
--- /dev/null
+++ b/package/boot/uboot-envtools/files/.svn/text-base/ramips.svn-base
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Copyright (C) 2011-2012 OpenWrt.org
+#
+
+[ -e /etc/config/ubootenv ] && exit 0
+
+touch /etc/config/ubootenv
+
+. /lib/ramips.sh
+. /lib/uboot-envtools.sh
+. /lib/functions.sh
+
+board=$(ramips_board_name)
+
+case "$board" in
+all0239-3g | \
+all0256n | \
+all5002)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000"
+ ;;
+esac
+
+br6425)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x10000"
+ ;;
+esac
+
+config_load ubootenv
+config_foreach ubootenv_add_app_config ubootenv
+
+exit 0
diff --git a/package/boot/uboot-envtools/files/.svn/text-base/uboot-envtools.sh.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/uboot-envtools.sh.svn-base
new file mode 100644
index 0000000..e21b283
--- /dev/null
+++ b/package/boot/uboot-envtools/files/.svn/text-base/uboot-envtools.sh.svn-base
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# Copyright (C) 2011-2012 OpenWrt.org
+#
+
+ubootenv_add_uci_config() {
+ local dev=$1
+ local offset=$2
+ local envsize=$3
+ local secsize=$4
+ local numsec=$5
+ uci batch <<EOF
+add ubootenv ubootenv
+set ubootenv.@ubootenv[-1].dev='$dev'
+set ubootenv.@ubootenv[-1].offset='$offset'
+set ubootenv.@ubootenv[-1].envsize='$envsize'
+set ubootenv.@ubootenv[-1].secsize='$secsize'
+set ubootenv.@ubootenv[-1].numsec='$numsec'
+EOF
+ uci commit ubootenv
+}
+
+ubootenv_add_app_config() {
+ local dev
+ local offset
+ local envsize
+ local secsize
+ local numsec
+ config_get dev "$1" dev
+ config_get offset "$1" offset
+ config_get envsize "$1" envsize
+ config_get secsize "$1" secsize
+ config_get numsec "$1" numsec
+ echo "$dev $offset $envsize $secsize $numsec" >>/etc/fw_env.config
+}
+
diff --git a/package/boot/uboot-envtools/files/ar71xx b/package/boot/uboot-envtools/files/ar71xx
new file mode 100644
index 0000000..1803a9f
--- /dev/null
+++ b/package/boot/uboot-envtools/files/ar71xx
@@ -0,0 +1,38 @@
+#!/bin/sh
+#
+# Copyright (C) 2011-2013 OpenWrt.org
+#
+
+[ -e /etc/config/ubootenv ] && exit 0
+
+touch /etc/config/ubootenv
+
+. /lib/ar71xx.sh
+. /lib/uboot-envtools.sh
+. /lib/functions.sh
+
+board=$(ar71xx_board_name)
+
+case "$board" in
+all0258n | \
+cap4200ag | \
+mr600 | \
+mr600v2)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000"
+ ;;
+alfa-ap96 | \
+all0315n | \
+om2p | \
+om2p-hs | \
+om2p-lc)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x40000" "0x40000"
+ ;;
+wzr-hp-ag300h)
+ ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x10000" "0x10000"
+ ;;
+esac
+
+config_load ubootenv
+config_foreach ubootenv_add_app_config ubootenv
+
+exit 0
diff --git a/package/boot/uboot-envtools/files/kirkwood b/package/boot/uboot-envtools/files/kirkwood
new file mode 100644
index 0000000..cad53aa
--- /dev/null
+++ b/package/boot/uboot-envtools/files/kirkwood
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+
+[ -e /etc/config/ubootenv ] && exit 0
+
+touch /etc/config/ubootenv
+
+. /lib/kirkwood.sh
+. /lib/uboot-envtools.sh
+. /lib/functions.sh
+
+hardware=$(kirkwood_hardware_name)
+
+case "$hardware" in
+"RaidSonic ICY BOX IB-NAS6210")
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000"
+ ;;
+esac
+
+config_load ubootenv
+config_foreach ubootenv_add_app_config ubootenv
+
+exit 0
diff --git a/package/boot/uboot-envtools/files/lantiq b/package/boot/uboot-envtools/files/lantiq
new file mode 100644
index 0000000..40befc3
--- /dev/null
+++ b/package/boot/uboot-envtools/files/lantiq
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+
+[ -e /etc/config/ubootenv ] && exit 0
+
+touch /etc/config/ubootenv
+
+. /lib/lantiq.sh
+. /lib/uboot-envtools.sh
+. /lib/functions.sh
+
+board=$(lantiq_board_name)
+
+case "$board" in
+GIGASX76X)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" "1"
+ ;;
+esac
+
+config_load ubootenv
+config_foreach ubootenv_add_app_config ubootenv
+
+exit 0
diff --git a/package/boot/uboot-envtools/files/ramips b/package/boot/uboot-envtools/files/ramips
new file mode 100644
index 0000000..3599f68
--- /dev/null
+++ b/package/boot/uboot-envtools/files/ramips
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Copyright (C) 2011-2012 OpenWrt.org
+#
+
+[ -e /etc/config/ubootenv ] && exit 0
+
+touch /etc/config/ubootenv
+
+. /lib/ramips.sh
+. /lib/uboot-envtools.sh
+. /lib/functions.sh
+
+board=$(ramips_board_name)
+
+case "$board" in
+all0239-3g | \
+all0256n | \
+all5002)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000"
+ ;;
+esac
+
+br6425)
+ ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x10000"
+ ;;
+esac
+
+config_load ubootenv
+config_foreach ubootenv_add_app_config ubootenv
+
+exit 0
diff --git a/package/boot/uboot-envtools/files/uboot-envtools.sh b/package/boot/uboot-envtools/files/uboot-envtools.sh
new file mode 100644
index 0000000..e21b283
--- /dev/null
+++ b/package/boot/uboot-envtools/files/uboot-envtools.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# Copyright (C) 2011-2012 OpenWrt.org
+#
+
+ubootenv_add_uci_config() {
+ local dev=$1
+ local offset=$2
+ local envsize=$3
+ local secsize=$4
+ local numsec=$5
+ uci batch <<EOF
+add ubootenv ubootenv
+set ubootenv.@ubootenv[-1].dev='$dev'
+set ubootenv.@ubootenv[-1].offset='$offset'
+set ubootenv.@ubootenv[-1].envsize='$envsize'
+set ubootenv.@ubootenv[-1].secsize='$secsize'
+set ubootenv.@ubootenv[-1].numsec='$numsec'
+EOF
+ uci commit ubootenv
+}
+
+ubootenv_add_app_config() {
+ local dev
+ local offset
+ local envsize
+ local secsize
+ local numsec
+ config_get dev "$1" dev
+ config_get offset "$1" offset
+ config_get envsize "$1" envsize
+ config_get secsize "$1" secsize
+ config_get numsec "$1" numsec
+ echo "$dev $offset $envsize $secsize $numsec" >>/etc/fw_env.config
+}
+
diff --git a/package/boot/uboot-envtools/patches/.svn/entries b/package/boot/uboot-envtools/patches/.svn/entries
new file mode 100644
index 0000000..d5b8a2a
--- /dev/null
+++ b/package/boot/uboot-envtools/patches/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-envtools/patches
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-03-15T01:36:53.833391Z
+36033
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-kirkwood/.svn/entries b/package/boot/uboot-kirkwood/.svn/entries
new file mode 100644
index 0000000..3077356
--- /dev/null
+++ b/package/boot/uboot-kirkwood/.svn/entries
@@ -0,0 +1,68 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-29T01:04:37.686581Z
+34401
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+files
+dir
+
+patches
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+b1a0c2e2c531d535f679f4ef6296f475
+2012-11-29T01:04:37.686581Z
+34401
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2412
+
diff --git a/package/boot/uboot-kirkwood/.svn/text-base/Makefile.svn-base b/package/boot/uboot-kirkwood/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..dc66450
--- /dev/null
+++ b/package/boot/uboot-kirkwood/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,104 @@
+#
+# Copyright (C) 2010-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2012.10
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=8655f63b1e5c4647295ac9ce44660be3
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/sheevaplug
+ TITLE:=U-Boot for the SheevaPlug
+endef
+
+define uboot/dockstar
+ TITLE:=U-Boot for the Seagate DockStar
+endef
+
+define uboot/iconnect
+ TITLE:=U-Boot for the Iomega iConnect Wireless
+endef
+
+define uboot/ib62x0
+ TITLE:=U-Boot for the RaidSonic ICY BOX NAS6210 and NAS6220
+endef
+
+UBOOTS:=sheevaplug dockstar iconnect ib62x0
+
+define Package/uboot/template
+define Package/uboot-kirkwood-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_kirkwood
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUBootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ u-boot.kwb \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/default
+ $(INSTALL_DIR) $(BIN_DIR)/uboot-$(BOARD)-$(1)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.bin \
+ $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.bin
+ $(CP) $(PKG_BUILD_DIR)/u-boot.kwb \
+ $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.kwb
+ $(INSTALL_DIR) $(BIN_DIR)/u-boot-kwboot/
+ $(CP) $(PKG_BUILD_DIR)/tools/kwboot \
+ $(BIN_DIR)/u-boot-kwboot/
+endef
+
+define Package/uboot/install/template
+define Package/uboot-kirkwood-$(1)/install
+ $(call Package/uboot/install/default,$(2))
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),$(u))) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUBootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-kirkwood-$(u))) \
+)
diff --git a/package/boot/uboot-kirkwood/Makefile b/package/boot/uboot-kirkwood/Makefile
new file mode 100644
index 0000000..dc66450
--- /dev/null
+++ b/package/boot/uboot-kirkwood/Makefile
@@ -0,0 +1,104 @@
+#
+# Copyright (C) 2010-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2012.10
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=8655f63b1e5c4647295ac9ce44660be3
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/sheevaplug
+ TITLE:=U-Boot for the SheevaPlug
+endef
+
+define uboot/dockstar
+ TITLE:=U-Boot for the Seagate DockStar
+endef
+
+define uboot/iconnect
+ TITLE:=U-Boot for the Iomega iConnect Wireless
+endef
+
+define uboot/ib62x0
+ TITLE:=U-Boot for the RaidSonic ICY BOX NAS6210 and NAS6220
+endef
+
+UBOOTS:=sheevaplug dockstar iconnect ib62x0
+
+define Package/uboot/template
+define Package/uboot-kirkwood-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_kirkwood
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUBootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ u-boot.kwb \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/default
+ $(INSTALL_DIR) $(BIN_DIR)/uboot-$(BOARD)-$(1)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.bin \
+ $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.bin
+ $(CP) $(PKG_BUILD_DIR)/u-boot.kwb \
+ $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.kwb
+ $(INSTALL_DIR) $(BIN_DIR)/u-boot-kwboot/
+ $(CP) $(PKG_BUILD_DIR)/tools/kwboot \
+ $(BIN_DIR)/u-boot-kwboot/
+endef
+
+define Package/uboot/install/template
+define Package/uboot-kirkwood-$(1)/install
+ $(call Package/uboot/install/default,$(2))
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),$(u))) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUBootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-kirkwood-$(u))) \
+)
diff --git a/package/boot/uboot-kirkwood/files/.svn/entries b/package/boot/uboot-kirkwood/files/.svn/entries
new file mode 100644
index 0000000..beb8916
--- /dev/null
+++ b/package/boot/uboot-kirkwood/files/.svn/entries
@@ -0,0 +1,34 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-22T21:16:04.130323Z
+34303
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+include
+dir
+
+board
+dir
+
diff --git a/package/boot/uboot-kirkwood/files/board/.svn/entries b/package/boot/uboot-kirkwood/files/board/.svn/entries
new file mode 100644
index 0000000..87dc985
--- /dev/null
+++ b/package/boot/uboot-kirkwood/files/board/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/board
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-22T21:16:04.130323Z
+34303
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+iomega
+dir
+
diff --git a/package/boot/uboot-kirkwood/files/board/iomega/.svn/entries b/package/boot/uboot-kirkwood/files/board/iomega/.svn/entries
new file mode 100644
index 0000000..4656309
--- /dev/null
+++ b/package/boot/uboot-kirkwood/files/board/iomega/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/board/iomega
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-22T21:16:04.130323Z
+34303
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+iconnect
+dir
+
diff --git a/package/boot/uboot-kirkwood/files/board/iomega/iconnect/.svn/entries b/package/boot/uboot-kirkwood/files/board/iomega/iconnect/.svn/entries
new file mode 100644
index 0000000..9056757
--- /dev/null
+++ b/package/boot/uboot-kirkwood/files/board/iomega/iconnect/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/board/iomega/iconnect
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-22T21:16:04.130323Z
+34303
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-kirkwood/files/include/.svn/entries b/package/boot/uboot-kirkwood/files/include/.svn/entries
new file mode 100644
index 0000000..ee6253a
--- /dev/null
+++ b/package/boot/uboot-kirkwood/files/include/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/include
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-22T21:16:04.130323Z
+34303
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+configs
+dir
+
diff --git a/package/boot/uboot-kirkwood/files/include/configs/.svn/entries b/package/boot/uboot-kirkwood/files/include/configs/.svn/entries
new file mode 100644
index 0000000..84be5da
--- /dev/null
+++ b/package/boot/uboot-kirkwood/files/include/configs/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/include/configs
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-22T21:16:04.130323Z
+34303
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-kirkwood/patches/.svn/entries b/package/boot/uboot-kirkwood/patches/.svn/entries
new file mode 100644
index 0000000..38b5197
--- /dev/null
+++ b/package/boot/uboot-kirkwood/patches/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/patches
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-11-22T21:16:04.130323Z
+34303
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+110-dockstar.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+11b1822c2274e5ec31c4552b382fe2f2
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1224
+
diff --git a/package/boot/uboot-kirkwood/patches/.svn/text-base/110-dockstar.patch.svn-base b/package/boot/uboot-kirkwood/patches/.svn/text-base/110-dockstar.patch.svn-base
new file mode 100644
index 0000000..4ff7e57
--- /dev/null
+++ b/package/boot/uboot-kirkwood/patches/.svn/text-base/110-dockstar.patch.svn-base
@@ -0,0 +1,35 @@
+--- a/include/configs/dockstar.h
++++ b/include/configs/dockstar.h
+@@ -83,22 +83,19 @@
+ * Default environment variables
+ */
+ #define CONFIG_BOOTCOMMAND \
+- "setenv bootargs ${console} ${mtdparts} ${bootargs_root}; " \
+- "ubi part root; " \
+- "ubifsmount root; " \
+- "ubifsload 0x800000 ${kernel}; " \
+- "ubifsload 0x1100000 ${initrd}; " \
+- "bootm 0x800000 0x1100000"
++ "${x_bootcmd_kernel}; " \
++ "setenv bootargs ${x_bootargs} ${x_bootargs_root}; " \
++ "${x_bootcmd_usb}; bootm 0x6400000;"
+
+-#define CONFIG_MTDPARTS "mtdparts=orion_nand:1m(uboot),-(root)\0"
++#define CONFIG_MTDPARTS \
++ "orion_nand:1M(u-boot),1M@1M(second_stage_u-boot)," \
++ "3M@2M(kernel),32M@5M(rootfs),219M@37M(data) rw\0"
+
+ #define CONFIG_EXTRA_ENV_SETTINGS \
+- "console=console=ttyS0,115200\0" \
+- "mtdids=nand0=orion_nand\0" \
+- "mtdparts="CONFIG_MTDPARTS \
+- "kernel=/boot/uImage\0" \
+- "initrd=/boot/uInitrd\0" \
+- "bootargs_root=ubi.mtd=1 root=ubi0:root rootfstype=ubifs ro\0"
++ "x_bootargs=console=ttyS0,115200 mtdparts="CONFIG_MTDPARTS \
++ "x_bootcmd_kernel=nand read 0x6400000 0x200000 0x300000\0" \
++ "x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0" \
++ "x_bootcmd_usb=usb start\0"
+
+ /*
+ * Ethernet Driver configuration
diff --git a/package/boot/uboot-kirkwood/patches/110-dockstar.patch b/package/boot/uboot-kirkwood/patches/110-dockstar.patch
new file mode 100644
index 0000000..4ff7e57
--- /dev/null
+++ b/package/boot/uboot-kirkwood/patches/110-dockstar.patch
@@ -0,0 +1,35 @@
+--- a/include/configs/dockstar.h
++++ b/include/configs/dockstar.h
+@@ -83,22 +83,19 @@
+ * Default environment variables
+ */
+ #define CONFIG_BOOTCOMMAND \
+- "setenv bootargs ${console} ${mtdparts} ${bootargs_root}; " \
+- "ubi part root; " \
+- "ubifsmount root; " \
+- "ubifsload 0x800000 ${kernel}; " \
+- "ubifsload 0x1100000 ${initrd}; " \
+- "bootm 0x800000 0x1100000"
++ "${x_bootcmd_kernel}; " \
++ "setenv bootargs ${x_bootargs} ${x_bootargs_root}; " \
++ "${x_bootcmd_usb}; bootm 0x6400000;"
+
+-#define CONFIG_MTDPARTS "mtdparts=orion_nand:1m(uboot),-(root)\0"
++#define CONFIG_MTDPARTS \
++ "orion_nand:1M(u-boot),1M@1M(second_stage_u-boot)," \
++ "3M@2M(kernel),32M@5M(rootfs),219M@37M(data) rw\0"
+
+ #define CONFIG_EXTRA_ENV_SETTINGS \
+- "console=console=ttyS0,115200\0" \
+- "mtdids=nand0=orion_nand\0" \
+- "mtdparts="CONFIG_MTDPARTS \
+- "kernel=/boot/uImage\0" \
+- "initrd=/boot/uInitrd\0" \
+- "bootargs_root=ubi.mtd=1 root=ubi0:root rootfstype=ubifs ro\0"
++ "x_bootargs=console=ttyS0,115200 mtdparts="CONFIG_MTDPARTS \
++ "x_bootcmd_kernel=nand read 0x6400000 0x200000 0x300000\0" \
++ "x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0" \
++ "x_bootcmd_usb=usb start\0"
+
+ /*
+ * Ethernet Driver configuration
diff --git a/package/boot/uboot-lantiq/.svn/entries b/package/boot/uboot-lantiq/.svn/entries
new file mode 100644
index 0000000..b679bd3
--- /dev/null
+++ b/package/boot/uboot-lantiq/.svn/entries
@@ -0,0 +1,65 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-lantiq
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+patches
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+bb017dc208140158e17d27f258ff37f8
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2983
+
diff --git a/package/boot/uboot-lantiq/.svn/text-base/Makefile.svn-base b/package/boot/uboot-lantiq/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..b3d9173
--- /dev/null
+++ b/package/boot/uboot-lantiq/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,123 @@
+#
+# Copyright (C) 2012-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2013.01
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=e58a8a7f78972248190d83de0dc362ce
+PKG_TARGETS:=bin
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ SOC:=
+ DDR_SETTINGS:=
+ IMAGE:=
+endef
+
+define uboot/arv4519pw_ram
+ TITLE:=U-Boot for Arcadyan arv4519pw (RAM)
+ SOC:=danube
+ DDR_SETTINGS:=board/arcadyan/arv4519pw/ddr_settings.h
+endef
+
+define uboot/arv4519pw_nor
+ TITLE:=U-Boot for Arcadyan arv4519pw (NOR)
+ SOC:=danube
+endef
+
+define uboot/arv7518pw_ram
+ TITLE:=U-Boot for Arcadyan arv7518pw (RAM)
+ SOC:=danube
+ DDR_SETTINGS:=board/arcadyan/arv7518pw/ddr_settings.h
+endef
+
+define uboot/arv7518pw_nor
+ TITLE:=U-Boot for Arcadyan arv7518pw (NOR)
+ SOC:=danube
+endef
+
+define uboot/gigasx76x_ram
+ TITLE:=U-Boot for Siemens Gigaset sx76x (RAM)
+ SOC:=danube
+ DDR_SETTINGS:=board/gigaset/sx76x/ddr_settings.h
+endef
+
+define uboot/gigasx76x_nor
+ TITLE:=U-Boot for Siemens Gigaset sx76x (NOR)
+ SOC:=danube
+endef
+
+UBOOTS:= \
+ arv4519pw_ram arv4519pw_nor \
+ arv7518pw_ram arv7518pw_nor \
+ gigasx76x_ram gigasx76x_nor
+
+define Package/uboot/template
+define Package/uboot-lantiq-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_lantiq_xway
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+ MAINTAINER:=Luka Perkov <luka@openwrt.org>
+endef
+endef
+
+define BuildUBootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) $(BUILD_VARIANT)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/default
+ $(CP) \
+ $(PKG_BUILD_DIR)/$(2) \
+ $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.img
+endef
+
+define Package/uboot/install/uart
+ awk -f $(PKG_BUILD_DIR)/tools/lantiq_ram_init_uart.awk \
+ -v soc=$(2) $(PKG_BUILD_DIR)/$(3) \
+ > $(PKG_BUILD_DIR)/ddr_settings
+ perl $(PKG_BUILD_DIR)/tools/gct.pl \
+ $(PKG_BUILD_DIR)/ddr_settings $(PKG_BUILD_DIR)/u-boot.srec \
+ $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.asc
+ endef
+
+define Package/uboot/install/template
+define Package/uboot-lantiq-$(1)/install
+ $(call Package/uboot/install/default,$(1),$(if $(IMAGE),$(IMAGE),u-boot.bin))
+ $(if $(DDR_SETTINGS), \
+ $(call Package/uboot/install/uart,$(1),$(SOC),$(DDR_SETTINGS)) \
+ )
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUBootPackage,$(u))) \
+ $(eval $(call Package/uboot/install/template,$(u))) \
+ $(eval $(call BuildPackage,uboot-lantiq-$(u))) \
+)
diff --git a/package/boot/uboot-lantiq/Makefile b/package/boot/uboot-lantiq/Makefile
new file mode 100644
index 0000000..b3d9173
--- /dev/null
+++ b/package/boot/uboot-lantiq/Makefile
@@ -0,0 +1,123 @@
+#
+# Copyright (C) 2012-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2013.01
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=e58a8a7f78972248190d83de0dc362ce
+PKG_TARGETS:=bin
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ SOC:=
+ DDR_SETTINGS:=
+ IMAGE:=
+endef
+
+define uboot/arv4519pw_ram
+ TITLE:=U-Boot for Arcadyan arv4519pw (RAM)
+ SOC:=danube
+ DDR_SETTINGS:=board/arcadyan/arv4519pw/ddr_settings.h
+endef
+
+define uboot/arv4519pw_nor
+ TITLE:=U-Boot for Arcadyan arv4519pw (NOR)
+ SOC:=danube
+endef
+
+define uboot/arv7518pw_ram
+ TITLE:=U-Boot for Arcadyan arv7518pw (RAM)
+ SOC:=danube
+ DDR_SETTINGS:=board/arcadyan/arv7518pw/ddr_settings.h
+endef
+
+define uboot/arv7518pw_nor
+ TITLE:=U-Boot for Arcadyan arv7518pw (NOR)
+ SOC:=danube
+endef
+
+define uboot/gigasx76x_ram
+ TITLE:=U-Boot for Siemens Gigaset sx76x (RAM)
+ SOC:=danube
+ DDR_SETTINGS:=board/gigaset/sx76x/ddr_settings.h
+endef
+
+define uboot/gigasx76x_nor
+ TITLE:=U-Boot for Siemens Gigaset sx76x (NOR)
+ SOC:=danube
+endef
+
+UBOOTS:= \
+ arv4519pw_ram arv4519pw_nor \
+ arv7518pw_ram arv7518pw_nor \
+ gigasx76x_ram gigasx76x_nor
+
+define Package/uboot/template
+define Package/uboot-lantiq-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_lantiq_xway
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+ MAINTAINER:=Luka Perkov <luka@openwrt.org>
+endef
+endef
+
+define BuildUBootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) $(BUILD_VARIANT)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/default
+ $(CP) \
+ $(PKG_BUILD_DIR)/$(2) \
+ $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.img
+endef
+
+define Package/uboot/install/uart
+ awk -f $(PKG_BUILD_DIR)/tools/lantiq_ram_init_uart.awk \
+ -v soc=$(2) $(PKG_BUILD_DIR)/$(3) \
+ > $(PKG_BUILD_DIR)/ddr_settings
+ perl $(PKG_BUILD_DIR)/tools/gct.pl \
+ $(PKG_BUILD_DIR)/ddr_settings $(PKG_BUILD_DIR)/u-boot.srec \
+ $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.asc
+ endef
+
+define Package/uboot/install/template
+define Package/uboot-lantiq-$(1)/install
+ $(call Package/uboot/install/default,$(1),$(if $(IMAGE),$(IMAGE),u-boot.bin))
+ $(if $(DDR_SETTINGS), \
+ $(call Package/uboot/install/uart,$(1),$(SOC),$(DDR_SETTINGS)) \
+ )
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUBootPackage,$(u))) \
+ $(eval $(call Package/uboot/install/template,$(u))) \
+ $(eval $(call BuildPackage,uboot-lantiq-$(u))) \
+)
diff --git a/package/boot/uboot-lantiq/patches/.svn/entries b/package/boot/uboot-lantiq/patches/.svn/entries
new file mode 100644
index 0000000..0113087
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/entries
@@ -0,0 +1,980 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-lantiq/patches
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+0015-sf-macronix-add-support-for-MX66L51235L.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+602fb08450d9ee680150b4b6378ed147
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+620
+
+0022-net-switchlib-add-driver-for-Atheros-AR8216.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+578fbe6f2d625581bdab30ad15aceacb
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3946
+
+0026-MIPS-add-board-support-for-Gigaset-SX76X.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+c557b83b9f972af2fe018d7e8bceb2d9
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7688
+
+0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+4f4c2ba4ecb1006a500ea6693062c0a8
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5685
+
+0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+d6df3ee4d0d1bb634d515eaf3c1d0bf1
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10840
+
+0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+49e21898d73d7e2914bbc83bdd486086
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4439
+
+0007-sf-eon-use-16-bit-ID-for-comparison.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+f5c77287a92ace9da6ab48ac0c8307b9
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1098
+
+0009-sf-eon-add-support-for-EN25QH256.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+0a18abd1ee5dda839e36b9ea148a7766
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+596
+
+0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+be788cc7364980b8d4b8a3840c8324fa
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3471
+
+0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+d9e3240b34b482e402e2cd8993fad402
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+248589
+
+0006-sf-add-generic-support-for-4-byte-address-mode.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+bb9f6b4f62ba46f9a635360abaaa0039
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4669
+
+0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+cf814d35e34cb938873ec8ae40bea6c7
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7484
+
+0013-sf-macronix-add-support-for-4-byte-address-mode.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+f85f2f23cede590205ce320e42968c10
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1269
+
+0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+82e2ab95e1eee1895db8cf3a457863a2
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3369
+
+0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+ca4ecb71ceab421e44e9305c09e7e0d1
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7474
+
+0005-sf-factor-out-the-flash-address-calculation.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+b75411af756e141f6998390ec2700c88
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3263
+
+0002-sf-handle-CONFIG_MANUAL_RELOC.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+e3f49d1615edf5a441a17fe1af0901c0
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1309
+
+0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+0dda929b094582fe39387a9923b77e90
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1044
+
+0008-sf-eon-add-support-for-4-byte-address-mode.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+40bc8aa4f9847b3c858cd2c3748a4dc2
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1117
+
+0018-MIPS-add-SPI-flash-init-hook.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+6b48b2e832bb1185a77cdd6c6bbbfd2b
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1183
+
+0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+fd730dc30a31d6c47027115a403069dc
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4602
+
+0017-sf-add-init-function.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+9aa02a17e92e047ec05be9695b1056fe
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1257
+
+0012-sf-spansion-add-support-for-S25FL512S.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+7cc84fd8eca16c98369a40613da48f24
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+679
+
+0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+a21e1f8f3ca4336f6b8bef85efa6e2b2
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8788
+
+0011-sf-spansion-add-support-for-4-byte-address-mode.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+6856262a607d534b2cfe33e8859409d3
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1517
+
+0014-sf-macronix-add-support-for-MX25L25635E.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+0ec732bb910a790afe321d1aaee9df87
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+619
+
+0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+bc39484ed9eea8e820f295f582343406
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+783
+
+0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+35f88c1039b8799350ce6eee51270d2f
+2013-01-22T12:55:01.537267Z
+35292
+luka
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21472
+
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0002-sf-handle-CONFIG_MANUAL_RELOC.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0002-sf-handle-CONFIG_MANUAL_RELOC.patch.svn-base
new file mode 100644
index 0000000..63a21af
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0002-sf-handle-CONFIG_MANUAL_RELOC.patch.svn-base
@@ -0,0 +1,46 @@
+From 60e8a35f0efa5a7e5d797a3f239971c84061ef11 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 21:39:47 +0100
+Subject: sf: handle CONFIG_MANUAL_RELOC
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -293,7 +293,7 @@ int spi_flash_cmd_write_status(struct sp
+ */
+ #define IDCODE_CONT_LEN 0
+ #define IDCODE_PART_LEN 5
+-static const struct {
++static struct {
+ const u8 shift;
+ const u8 idcode;
+ struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
+@@ -335,6 +335,10 @@ static const struct {
+ };
+ #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
+
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++DECLARE_GLOBAL_DATA_PTR;
++#endif
++
+ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int spi_mode)
+ {
+@@ -342,6 +346,16 @@ struct spi_flash *spi_flash_probe(unsign
+ struct spi_flash *flash = NULL;
+ int ret, i, shift;
+ u8 idcode[IDCODE_LEN], *idp;
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++ static int relocated;
++
++ if (!relocated) {
++ for (i = 0; i < ARRAY_SIZE(flashes); i++)
++ flashes[i].probe += gd->reloc_off;
++
++ relocated = 1;
++ }
++#endif
+
+ spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+ if (!spi) {
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch.svn-base
new file mode 100644
index 0000000..7f44675
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch.svn-base
@@ -0,0 +1,719 @@
+From 73d127565b5a4b19bcaacabc505689ee039f16fd Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sun, 11 Nov 2012 03:11:38 +0100
+Subject: sf: factor out malloc from SPI flash drivers
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/atmel.c
++++ b/drivers/mtd/spi/atmel.c
+@@ -40,18 +40,6 @@ struct atmel_spi_flash_params {
+ const char *name;
+ };
+
+-/* spi_flash needs to be first so upper layers can free() it */
+-struct atmel_spi_flash {
+- struct spi_flash flash;
+- const struct atmel_spi_flash_params *params;
+-};
+-
+-static inline struct atmel_spi_flash *
+-to_atmel_spi_flash(struct spi_flash *flash)
+-{
+- return container_of(flash, struct atmel_spi_flash, flash);
+-}
+-
+ static const struct atmel_spi_flash_params atmel_spi_flash_table[] = {
+ {
+ .idcode1 = 0x22,
+@@ -156,7 +144,8 @@ static int at45_wait_ready(struct spi_fl
+ * Assemble the address part of a command for AT45 devices in
+ * non-power-of-two page size mode.
+ */
+-static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset)
++static void at45_build_address(const struct atmel_spi_flash_params *params,
++ u8 *cmd, u32 offset)
+ {
+ unsigned long page_addr;
+ unsigned long byte_addr;
+@@ -167,7 +156,7 @@ static void at45_build_address(struct at
+ * The "extra" space per page is the power-of-two page size
+ * divided by 32.
+ */
+- page_shift = asf->params->l2_page_size;
++ page_shift = params->l2_page_size;
+ page_size = (1 << page_shift) + (1 << (page_shift - 5));
+ page_shift++;
+ page_addr = offset / page_size;
+@@ -181,11 +170,11 @@ static void at45_build_address(struct at
+ static int dataflash_read_fast_at45(struct spi_flash *flash,
+ u32 offset, size_t len, void *buf)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ u8 cmd[5];
+
+ cmd[0] = CMD_READ_ARRAY_FAST;
+- at45_build_address(asf, cmd + 1, offset);
++ at45_build_address(params, cmd + 1, offset);
+ cmd[4] = 0x00;
+
+ return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
+@@ -197,7 +186,7 @@ static int dataflash_read_fast_at45(stru
+ static int dataflash_write_p2(struct spi_flash *flash,
+ u32 offset, size_t len, const void *buf)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ unsigned long page_size;
+ u32 addr = offset;
+ size_t chunk_len;
+@@ -211,7 +200,7 @@ static int dataflash_write_p2(struct spi
+ * the other is being programmed into main memory.
+ */
+
+- page_size = (1 << asf->params->l2_page_size);
++ page_size = (1 << params->l2_page_size);
+
+ ret = spi_claim_bus(flash->spi);
+ if (ret) {
+@@ -263,7 +252,7 @@ out:
+ static int dataflash_write_at45(struct spi_flash *flash,
+ u32 offset, size_t len, const void *buf)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ unsigned long page_addr;
+ unsigned long byte_addr;
+ unsigned long page_size;
+@@ -279,7 +268,7 @@ static int dataflash_write_at45(struct s
+ * the other is being programmed into main memory.
+ */
+
+- page_shift = asf->params->l2_page_size;
++ page_shift = params->l2_page_size;
+ page_size = (1 << page_shift) + (1 << (page_shift - 5));
+ page_shift++;
+ page_addr = offset / page_size;
+@@ -338,7 +327,7 @@ out:
+ */
+ static int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ unsigned long page_size;
+
+ size_t actual;
+@@ -351,7 +340,7 @@ static int dataflash_erase_p2(struct spi
+ * when possible.
+ */
+
+- page_size = (1 << asf->params->l2_page_size);
++ page_size = (1 << params->l2_page_size);
+
+ if (offset % page_size || len % page_size) {
+ debug("SF: Erase offset/length not multiple of page size\n");
+@@ -397,7 +386,7 @@ out:
+
+ static int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ unsigned long page_addr;
+ unsigned long page_size;
+ unsigned int page_shift;
+@@ -411,7 +400,7 @@ static int dataflash_erase_at45(struct s
+ * when possible.
+ */
+
+- page_shift = asf->params->l2_page_size;
++ page_shift = params->l2_page_size;
+ page_size = (1 << page_shift) + (1 << (page_shift - 5));
+ page_shift++;
+ page_addr = offset / page_size;
+@@ -458,12 +447,12 @@ out:
+ return ret;
+ }
+
+-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct atmel_spi_flash_params *params;
++ struct spi_slave *spi = flash->spi;
+ unsigned page_size;
+ unsigned int family;
+- struct atmel_spi_flash *asf;
+ unsigned int i;
+ int ret;
+ u8 status;
+@@ -477,18 +466,11 @@ struct spi_flash *spi_flash_probe_atmel(
+ if (i == ARRAY_SIZE(atmel_spi_flash_table)) {
+ debug("SF: Unsupported DataFlash ID %02x\n",
+ idcode[1]);
+- return NULL;
+- }
+-
+- asf = malloc(sizeof(struct atmel_spi_flash));
+- if (!asf) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
++ return 0;
+ }
+
+- asf->params = params;
+- asf->flash.spi = spi;
+- asf->flash.name = params->name;
++ flash->priv = (void *)params;
++ flash->name = params->name;
+
+ /* Assuming power-of-two page size initially. */
+ page_size = 1 << params->l2_page_size;
+@@ -503,48 +485,44 @@ struct spi_flash *spi_flash_probe_atmel(
+ */
+ ret = spi_flash_cmd(spi, CMD_AT45_READ_STATUS, &status, 1);
+ if (ret)
+- goto err;
++ return -1;
+
+ debug("SF: AT45 status register: %02x\n", status);
+
+ if (!(status & AT45_STATUS_P2_PAGE_SIZE)) {
+- asf->flash.read = dataflash_read_fast_at45;
+- asf->flash.write = dataflash_write_at45;
+- asf->flash.erase = dataflash_erase_at45;
++ flash->read = dataflash_read_fast_at45;
++ flash->write = dataflash_write_at45;
++ flash->erase = dataflash_erase_at45;
+ page_size += 1 << (params->l2_page_size - 5);
+ } else {
+- asf->flash.read = spi_flash_cmd_read_fast;
+- asf->flash.write = dataflash_write_p2;
+- asf->flash.erase = dataflash_erase_p2;
++ flash->read = spi_flash_cmd_read_fast;
++ flash->write = dataflash_write_p2;
++ flash->erase = dataflash_erase_p2;
+ }
+
+- asf->flash.page_size = page_size;
+- asf->flash.sector_size = page_size;
++ flash->page_size = page_size;
++ flash->sector_size = page_size;
+ break;
+
+ case DF_FAMILY_AT26F:
+ case DF_FAMILY_AT26DF:
+- asf->flash.read = spi_flash_cmd_read_fast;
+- asf->flash.write = spi_flash_cmd_write_multi;
+- asf->flash.erase = spi_flash_cmd_erase;
+- asf->flash.page_size = page_size;
+- asf->flash.sector_size = 4096;
++ flash->read = spi_flash_cmd_read_fast;
++ flash->write = spi_flash_cmd_write_multi;
++ flash->erase = spi_flash_cmd_erase;
++ flash->page_size = page_size;
++ flash->sector_size = 4096;
+ /* clear SPRL# bit for locked flash */
+- spi_flash_cmd_write_status(&asf->flash, 0);
++ spi_flash_cmd_write_status(flash, 0);
+ break;
+
+ default:
+ debug("SF: Unsupported DataFlash family %u\n", family);
+- goto err;
++ return -1;
+ }
+
+- asf->flash.size = page_size * params->pages_per_block
++ flash->size = page_size * params->pages_per_block
+ * params->blocks_per_sector
+ * params->nr_sectors;
+
+- return &asf->flash;
+-
+-err:
+- free(asf);
+- return NULL;
++ return 1;
+ }
+--- a/drivers/mtd/spi/eon.c
++++ b/drivers/mtd/spi/eon.c
+@@ -29,10 +29,9 @@ static const struct eon_spi_flash_params
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct eon_spi_flash_params *params;
+- struct spi_flash *flash;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) {
+@@ -43,16 +42,10 @@ struct spi_flash *spi_flash_probe_eon(st
+
+ if (i == ARRAY_SIZE(eon_spi_flash_table)) {
+ debug("SF: Unsupported EON ID %02x\n", idcode[1]);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -63,5 +56,5 @@ struct spi_flash *spi_flash_probe_eon(st
+ flash->size = 256 * 16
+ * params->nr_sectors;
+
+- return flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/macronix.c
++++ b/drivers/mtd/spi/macronix.c
+@@ -79,10 +79,9 @@ static const struct macronix_spi_flash_p
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct macronix_spi_flash_params *params;
+- struct spi_flash *flash;
+ unsigned int i;
+ u16 id = idcode[2] | idcode[1] << 8;
+
+@@ -94,16 +93,10 @@ struct spi_flash *spi_flash_probe_macron
+
+ if (i == ARRAY_SIZE(macronix_spi_flash_table)) {
+ debug("SF: Unsupported Macronix ID %04x\n", id);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -116,5 +109,5 @@ struct spi_flash *spi_flash_probe_macron
+ /* Clear BP# bits for read-only flash */
+ spi_flash_cmd_write_status(flash, 0);
+
+- return flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/ramtron.c
++++ b/drivers/mtd/spi/ramtron.c
+@@ -69,17 +69,6 @@ struct ramtron_spi_fram_params {
+ const char *name; /* name for display and/or matching */
+ };
+
+-struct ramtron_spi_fram {
+- struct spi_flash flash;
+- const struct ramtron_spi_fram_params *params;
+-};
+-
+-static inline struct ramtron_spi_fram *to_ramtron_spi_fram(struct spi_flash
+- *flash)
+-{
+- return container_of(flash, struct ramtron_spi_fram, flash);
+-}
+-
+ /*
+ * table describing supported FRAM chips:
+ * chips without RDID command must have the values 0xff for id1 and id2
+@@ -155,18 +144,18 @@ static const struct ramtron_spi_fram_par
+ static int ramtron_common(struct spi_flash *flash,
+ u32 offset, size_t len, void *buf, u8 command)
+ {
+- struct ramtron_spi_fram *sn = to_ramtron_spi_fram(flash);
++ const struct ramtron_spi_fram_params *params = flash->priv;
+ u8 cmd[4];
+ int cmd_len;
+ int ret;
+
+- if (sn->params->addr_len == 3 && sn->params->merge_cmd == 0) {
++ if (params->addr_len == 3 && params->merge_cmd == 0) {
+ cmd[0] = command;
+ cmd[1] = offset >> 16;
+ cmd[2] = offset >> 8;
+ cmd[3] = offset;
+ cmd_len = 4;
+- } else if (sn->params->addr_len == 2 && sn->params->merge_cmd == 0) {
++ } else if (params->addr_len == 2 && params->merge_cmd == 0) {
+ cmd[0] = command;
+ cmd[1] = offset >> 8;
+ cmd[2] = offset;
+@@ -230,10 +219,9 @@ static int ramtron_erase(struct spi_flas
+ * nore: we are called here with idcode pointing to the first non-0x7f byte
+ * already!
+ */
+-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
++int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct ramtron_spi_fram_params *params;
+- struct ramtron_spi_fram *sn;
+ unsigned int i;
+ #ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
+ int ret;
+@@ -259,11 +247,11 @@ struct spi_flash *spi_fram_probe_ramtron
+ */
+ ret = spi_flash_cmd(spi, CMD_READ_STATUS, &sr, 1);
+ if (ret)
+- return NULL;
++ return 0;
+
+ /* Bits 5,4,0 are fixed 0 for all devices */
+ if ((sr & 0x31) != 0x00)
+- return NULL;
++ return 0;
+ /* now find the device */
+ for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) {
+ params = &ramtron_spi_fram_table[i];
+@@ -281,23 +269,16 @@ struct spi_flash *spi_fram_probe_ramtron
+ /* arriving here means no method has found a device we can handle */
+ debug("SF/ramtron: unsupported device id0=%02x id1=%02x id2=%02x\n",
+ idcode[0], idcode[1], idcode[2]);
+- return NULL;
++ return 0;
+
+ found:
+- sn = malloc(sizeof(*sn));
+- if (!sn) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
++ flash->priv = (void *)params;
++ flash->name = params->name;
+
+- sn->params = params;
+- sn->flash.spi = spi;
+- sn->flash.name = params->name;
+-
+- sn->flash.write = ramtron_write;
+- sn->flash.read = ramtron_read;
+- sn->flash.erase = ramtron_erase;
+- sn->flash.size = params->size;
++ flash->write = ramtron_write;
++ flash->read = ramtron_read;
++ flash->erase = ramtron_erase;
++ flash->size = params->size;
+
+- return &sn->flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/spansion.c
++++ b/drivers/mtd/spi/spansion.c
+@@ -105,10 +105,9 @@ static const struct spansion_spi_flash_p
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct spansion_spi_flash_params *params;
+- struct spi_flash *flash;
+ unsigned int i;
+ unsigned short jedec, ext_jedec;
+
+@@ -125,16 +124,10 @@ struct spi_flash *spi_flash_probe_spansi
+
+ if (i == ARRAY_SIZE(spansion_spi_flash_table)) {
+ debug("SF: Unsupported SPANSION ID %04x %04x\n", jedec, ext_jedec);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -144,5 +137,5 @@ struct spi_flash *spi_flash_probe_spansi
+ flash->sector_size = 256 * params->pages_per_sector;
+ flash->size = flash->sector_size * params->nr_sectors;
+
+- return flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -296,7 +296,7 @@ int spi_flash_cmd_write_status(struct sp
+ static struct {
+ const u8 shift;
+ const u8 idcode;
+- struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
++ int (*probe) (struct spi_flash *flash, u8 *idcode);
+ } flashes[] = {
+ /* Keep it sorted by define name */
+ #ifdef CONFIG_SPI_FLASH_ATMEL
+@@ -343,7 +343,7 @@ struct spi_flash *spi_flash_probe(unsign
+ unsigned int max_hz, unsigned int spi_mode)
+ {
+ struct spi_slave *spi;
+- struct spi_flash *flash = NULL;
++ struct spi_flash *flash;
+ int ret, i, shift;
+ u8 idcode[IDCODE_LEN], *idp;
+ #ifdef CONFIG_NEEDS_MANUAL_RELOC
+@@ -379,6 +379,15 @@ struct spi_flash *spi_flash_probe(unsign
+ print_buffer(0, idcode, 1, sizeof(idcode), 0);
+ #endif
+
++ flash = malloc(sizeof(*flash));
++ if (!flash) {
++ debug("SF: failed to alloc memory\n");
++ goto err_malloc;
++ }
++
++ memset(flash, 0, sizeof(*flash));
++ flash->spi = spi;
++
+ /* count the number of continuation bytes */
+ for (shift = 0, idp = idcode;
+ shift < IDCODE_CONT_LEN && *idp == 0x7f;
+@@ -389,12 +398,12 @@ struct spi_flash *spi_flash_probe(unsign
+ for (i = 0; i < ARRAY_SIZE(flashes); ++i)
+ if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
+ /* we have a match, call probe */
+- flash = flashes[i].probe(spi, idp);
+- if (flash)
++ ret = flashes[i].probe(flash, idp);
++ if (ret)
+ break;
+ }
+
+- if (!flash) {
++ if (ret <= 0) {
+ printf("SF: Unsupported manufacturer %02x\n", *idp);
+ goto err_manufacturer_probe;
+ }
+@@ -408,6 +417,8 @@ struct spi_flash *spi_flash_probe(unsign
+ return flash;
+
+ err_manufacturer_probe:
++ free(flash);
++err_malloc:
+ err_read_id:
+ spi_release_bus(spi);
+ err_claim_bus:
+--- a/drivers/mtd/spi/spi_flash_internal.h
++++ b/drivers/mtd/spi/spi_flash_internal.h
+@@ -98,11 +98,11 @@ int spi_flash_cmd_wait_ready(struct spi_
+ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len);
+
+ /* Manufacturer-specific probe functions */
+-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode);
++int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_stmicro(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode);
++int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode);
+--- a/drivers/mtd/spi/sst.c
++++ b/drivers/mtd/spi/sst.c
+@@ -39,11 +39,6 @@ struct sst_spi_flash_params {
+ const char *name;
+ };
+
+-struct sst_spi_flash {
+- struct spi_flash flash;
+- const struct sst_spi_flash_params *params;
+-};
+-
+ static const struct sst_spi_flash_params sst_spi_flash_table[] = {
+ {
+ .idcode1 = 0x8d,
+@@ -185,11 +180,9 @@ sst_write_wp(struct spi_flash *flash, u3
+ return ret;
+ }
+
+-struct spi_flash *
+-spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct sst_spi_flash_params *params;
+- struct sst_spi_flash *stm;
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(sst_spi_flash_table); ++i) {
+@@ -200,31 +193,24 @@ spi_flash_probe_sst(struct spi_slave *sp
+
+ if (i == ARRAY_SIZE(sst_spi_flash_table)) {
+ debug("SF: Unsupported SST ID %02x\n", idcode[1]);
+- return NULL;
+- }
+-
+- stm = malloc(sizeof(*stm));
+- if (!stm) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
++ return 0;
+ }
+
+- stm->params = params;
+- stm->flash.spi = spi;
+- stm->flash.name = params->name;
++ flash->priv = (void *)params;
++ flash->name = params->name;
+
+- if (stm->params->flags & SST_FEAT_WP)
+- stm->flash.write = sst_write_wp;
++ if (params->flags & SST_FEAT_WP)
++ flash->write = sst_write_wp;
+ else
+- stm->flash.write = spi_flash_cmd_write_multi;
+- stm->flash.erase = spi_flash_cmd_erase;
+- stm->flash.read = spi_flash_cmd_read_fast;
+- stm->flash.page_size = 256;
+- stm->flash.sector_size = 4096;
+- stm->flash.size = stm->flash.sector_size * params->nr_sectors;
++ flash->write = spi_flash_cmd_write_multi;
++ flash->erase = spi_flash_cmd_erase;
++ flash->read = spi_flash_cmd_read_fast;
++ flash->page_size = 256;
++ flash->sector_size = 4096;
++ flash->size = flash->sector_size * params->nr_sectors;
+
+ /* Flash powers up read-only, so clear BP# bits */
+- spi_flash_cmd_write_status(&stm->flash, 0);
++ spi_flash_cmd_write_status(flash, 0);
+
+- return &stm->flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/stmicro.c
++++ b/drivers/mtd/spi/stmicro.c
+@@ -112,10 +112,10 @@ static const struct stmicro_spi_flash_pa
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
++int spi_flash_probe_stmicro(struct spi_flash *flash, u8 * idcode)
+ {
+ const struct stmicro_spi_flash_params *params;
+- struct spi_flash *flash;
++ struct spi_slave *spi = flash->spi;
+ unsigned int i;
+ u16 id;
+
+@@ -123,13 +123,13 @@ struct spi_flash *spi_flash_probe_stmicr
+ i = spi_flash_cmd(spi, CMD_M25PXX_RES,
+ idcode, 4);
+ if (i)
+- return NULL;
++ return 0;
+ if ((idcode[3] & 0xf0) == 0x10) {
+ idcode[0] = 0x20;
+ idcode[1] = 0x20;
+ idcode[2] = idcode[3] + 1;
+ } else
+- return NULL;
++ return 0;
+ }
+
+ id = ((idcode[1] << 8) | idcode[2]);
+@@ -143,16 +143,10 @@ struct spi_flash *spi_flash_probe_stmicr
+
+ if (i == ARRAY_SIZE(stmicro_spi_flash_table)) {
+ debug("SF: Unsupported STMicro ID %04x\n", id);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -162,5 +156,5 @@ struct spi_flash *spi_flash_probe_stmicr
+ flash->sector_size = 256 * params->pages_per_sector;
+ flash->size = flash->sector_size * params->nr_sectors;
+
+- return flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/winbond.c
++++ b/drivers/mtd/spi/winbond.c
+@@ -69,10 +69,9 @@ static const struct winbond_spi_flash_pa
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct winbond_spi_flash_params *params;
+- struct spi_flash *flash;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
+@@ -84,16 +83,10 @@ struct spi_flash *spi_flash_probe_winbon
+ if (i == ARRAY_SIZE(winbond_spi_flash_table)) {
+ debug("SF: Unsupported Winbond ID %02x%02x\n",
+ idcode[1], idcode[2]);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -103,5 +96,5 @@ struct spi_flash *spi_flash_probe_winbon
+ flash->sector_size = 4096;
+ flash->size = 4096 * 16 * params->nr_blocks;
+
+- return flash;
++ return 1;
+ }
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -31,6 +31,7 @@ struct spi_flash {
+ struct spi_slave *spi;
+
+ const char *name;
++ void *priv;
+
+ /* Total flash size */
+ u32 size;
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch.svn-base
new file mode 100644
index 0000000..7a1ef3b
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch.svn-base
@@ -0,0 +1,131 @@
+From f9ab44c271fbd82a5702b6ba067fa90e33a30089 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:29:27 +0100
+Subject: sf: add malloc-free probe functions dedicated for SPL
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -339,11 +339,11 @@ static struct {
+ DECLARE_GLOBAL_DATA_PTR;
+ #endif
+
+-struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+- unsigned int max_hz, unsigned int spi_mode)
++int spi_flash_probe_spl(struct spi_flash *flash, unsigned int bus,
++ unsigned int cs, unsigned int max_hz,
++ unsigned int spi_mode)
+ {
+ struct spi_slave *spi;
+- struct spi_flash *flash;
+ int ret, i, shift;
+ u8 idcode[IDCODE_LEN], *idp;
+ #ifdef CONFIG_NEEDS_MANUAL_RELOC
+@@ -359,8 +359,8 @@ struct spi_flash *spi_flash_probe(unsign
+
+ spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+ if (!spi) {
+- printf("SF: Failed to set up slave\n");
+- return NULL;
++ debug("SF: Failed to set up slave\n");
++ return -1;
+ }
+
+ ret = spi_claim_bus(spi);
+@@ -379,13 +379,6 @@ struct spi_flash *spi_flash_probe(unsign
+ print_buffer(0, idcode, 1, sizeof(idcode), 0);
+ #endif
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: failed to alloc memory\n");
+- goto err_malloc;
+- }
+-
+- memset(flash, 0, sizeof(*flash));
+ flash->spi = spi;
+
+ /* count the number of continuation bytes */
+@@ -404,30 +397,58 @@ struct spi_flash *spi_flash_probe(unsign
+ }
+
+ if (ret <= 0) {
+- printf("SF: Unsupported manufacturer %02x\n", *idp);
++ debug("SF: Unsupported manufacturer %02x\n", *idp);
+ goto err_manufacturer_probe;
+ }
+
+- printf("SF: Detected %s with page size ", flash->name);
+- print_size(flash->sector_size, ", total ");
+- print_size(flash->size, "\n");
+-
+ spi_release_bus(spi);
+
+- return flash;
++ return 0;
+
+ err_manufacturer_probe:
+- free(flash);
+-err_malloc:
+ err_read_id:
+ spi_release_bus(spi);
+ err_claim_bus:
+ spi_free_slave(spi);
++
++ return ret;
++}
++
++struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
++ unsigned int max_hz, unsigned int spi_mode)
++{
++ struct spi_flash *flash;
++ int ret;
++
++ flash = malloc(sizeof(*flash));
++ if (!flash) {
++ debug("SF: Failed to malloc spi_flash\n");
++ return NULL;
++ }
++ memset(flash, 0, sizeof(*flash));
++
++ ret = spi_flash_probe_spl(flash, bus, cs, max_hz, spi_mode);
++ if (ret)
++ goto err_probe;
++
++ printf("SF: %s, page size ", flash->name);
++ print_size(flash->sector_size, ", total ");
++ print_size(flash->size, "\n");
++
++ return flash;
++
++err_probe:
++ free(flash);
+ return NULL;
+ }
+
+-void spi_flash_free(struct spi_flash *flash)
++void spi_flash_free_spl(struct spi_flash *flash)
+ {
+ spi_free_slave(flash->spi);
++}
++
++void spi_flash_free(struct spi_flash *flash)
++{
++ spi_flash_free_spl(flash);
+ free(flash);
+ }
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -52,6 +52,11 @@ struct spi_flash *spi_flash_probe(unsign
+ unsigned int max_hz, unsigned int spi_mode);
+ void spi_flash_free(struct spi_flash *flash);
+
++int spi_flash_probe_spl(struct spi_flash *flash, unsigned int bus,
++ unsigned int cs, unsigned int max_hz,
++ unsigned int spi_mode);
++void spi_flash_free_spl(struct spi_flash *flash);
++
+ static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
+ size_t len, void *buf)
+ {
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0005-sf-factor-out-the-flash-address-calculation.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0005-sf-factor-out-the-flash-address-calculation.patch.svn-base
new file mode 100644
index 0000000..356db59
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0005-sf-factor-out-the-flash-address-calculation.patch.svn-base
@@ -0,0 +1,107 @@
+From acb2721e1cd2e7488a7b08a4ed590177369a1689 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 19:10:40 +0100
+Subject: sf: factor out the flash address calculation
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -15,12 +15,22 @@
+
+ #include "spi_flash_internal.h"
+
+-static void spi_flash_addr(u32 addr, u8 *cmd)
++static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd, u8 *cmd_len)
+ {
+ /* cmd[0] is actual command */
+ cmd[1] = addr >> 16;
+ cmd[2] = addr >> 8;
+ cmd[3] = addr >> 0;
++ *cmd_len = 4;
++}
++
++static void spi_flash_page_addr(struct spi_flash *flash, u32 page_addr, u32 byte_addr, u8 *cmd, u8 *cmd_len)
++{
++ /* cmd[0] is actual command */
++ cmd[1] = page_addr >> 8;
++ cmd[2] = page_addr >> 0;
++ cmd[3] = byte_addr;
++ *cmd_len = 4;
+ }
+
+ static int spi_flash_read_write(struct spi_slave *spi,
+@@ -71,7 +81,7 @@ int spi_flash_cmd_write_multi(struct spi
+ unsigned long page_addr, byte_addr, page_size;
+ size_t chunk_len, actual;
+ int ret;
+- u8 cmd[4];
++ u8 cmd[4], cmd_len;
+
+ page_size = flash->page_size;
+ page_addr = offset / page_size;
+@@ -87,9 +97,7 @@ int spi_flash_cmd_write_multi(struct spi
+ for (actual = 0; actual < len; actual += chunk_len) {
+ chunk_len = min(len - actual, page_size - byte_addr);
+
+- cmd[1] = page_addr >> 8;
+- cmd[2] = page_addr;
+- cmd[3] = byte_addr;
++ spi_flash_page_addr(flash, page_addr, byte_addr, cmd, &cmd_len);
+
+ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+ buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+@@ -100,7 +108,7 @@ int spi_flash_cmd_write_multi(struct spi
+ break;
+ }
+
+- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
++ ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len,
+ buf + actual, chunk_len);
+ if (ret < 0) {
+ debug("SF: write failed\n");
+@@ -138,13 +146,13 @@ int spi_flash_read_common(struct spi_fla
+ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
+ size_t len, void *data)
+ {
+- u8 cmd[5];
++ u8 cmd[5], cmd_len;
+
+ cmd[0] = CMD_READ_ARRAY_FAST;
+- spi_flash_addr(offset, cmd);
+- cmd[4] = 0x00;
++ spi_flash_addr(flash, offset, cmd, &cmd_len);
++ cmd[cmd_len] = 0x00;
+
+- return spi_flash_read_common(flash, cmd, sizeof(cmd), data, len);
++ return spi_flash_read_common(flash, cmd, cmd_len + 1, data, len);
+ }
+
+ int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
+@@ -194,7 +202,7 @@ int spi_flash_cmd_erase(struct spi_flash
+ {
+ u32 start, end, erase_size;
+ int ret;
+- u8 cmd[4];
++ u8 cmd[4], cmd_len;
+
+ erase_size = flash->sector_size;
+ if (offset % erase_size || len % erase_size) {
+@@ -216,7 +224,7 @@ int spi_flash_cmd_erase(struct spi_flash
+ end = start + len;
+
+ while (offset < end) {
+- spi_flash_addr(offset, cmd);
++ spi_flash_addr(flash, offset, cmd, &cmd_len);
+ offset += erase_size;
+
+ debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+@@ -226,7 +234,7 @@ int spi_flash_cmd_erase(struct spi_flash
+ if (ret)
+ goto out;
+
+- ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0);
++ ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, NULL, 0);
+ if (ret)
+ goto out;
+
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0006-sf-add-generic-support-for-4-byte-address-mode.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0006-sf-add-generic-support-for-4-byte-address-mode.patch.svn-base
new file mode 100644
index 0000000..1623b15
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0006-sf-add-generic-support-for-4-byte-address-mode.patch.svn-base
@@ -0,0 +1,161 @@
+From fb9ed0ef6f0ba6b6535c64dcfcf45c161723e56f Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 19:31:38 +0100
+Subject: sf: add generic support for 4-byte address mode
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -18,19 +18,35 @@
+ static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd, u8 *cmd_len)
+ {
+ /* cmd[0] is actual command */
+- cmd[1] = addr >> 16;
+- cmd[2] = addr >> 8;
+- cmd[3] = addr >> 0;
+- *cmd_len = 4;
++ if (spi_flash_use_4byte_mode(flash)) {
++ cmd[1] = addr >> 24;
++ cmd[2] = addr >> 16;
++ cmd[3] = addr >> 8;
++ cmd[4] = addr >> 0;
++ *cmd_len = 5;
++ } else {
++ cmd[1] = addr >> 16;
++ cmd[2] = addr >> 8;
++ cmd[3] = addr >> 0;
++ *cmd_len = 4;
++ }
+ }
+
+ static void spi_flash_page_addr(struct spi_flash *flash, u32 page_addr, u32 byte_addr, u8 *cmd, u8 *cmd_len)
+ {
+ /* cmd[0] is actual command */
+- cmd[1] = page_addr >> 8;
+- cmd[2] = page_addr >> 0;
+- cmd[3] = byte_addr;
+- *cmd_len = 4;
++ if (spi_flash_use_4byte_mode(flash)) {
++ cmd[1] = page_addr >> 16;
++ cmd[2] = page_addr >> 8;
++ cmd[3] = page_addr >> 0;
++ cmd[4] = byte_addr;
++ *cmd_len = 5;
++ } else {
++ cmd[1] = page_addr >> 8;
++ cmd[2] = page_addr >> 0;
++ cmd[3] = byte_addr;
++ *cmd_len = 4;
++ }
+ }
+
+ static int spi_flash_read_write(struct spi_slave *spi,
+@@ -81,7 +97,7 @@ int spi_flash_cmd_write_multi(struct spi
+ unsigned long page_addr, byte_addr, page_size;
+ size_t chunk_len, actual;
+ int ret;
+- u8 cmd[4], cmd_len;
++ u8 cmd[5], cmd_len;
+
+ page_size = flash->page_size;
+ page_addr = offset / page_size;
+@@ -99,8 +115,8 @@ int spi_flash_cmd_write_multi(struct spi
+
+ spi_flash_page_addr(flash, page_addr, byte_addr, cmd, &cmd_len);
+
+- debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+- buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
++ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x%02x } chunk_len = %zu\n",
++ buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], chunk_len);
+
+ ret = spi_flash_cmd_write_enable(flash);
+ if (ret < 0) {
+@@ -146,7 +162,7 @@ int spi_flash_read_common(struct spi_fla
+ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
+ size_t len, void *data)
+ {
+- u8 cmd[5], cmd_len;
++ u8 cmd[6], cmd_len;
+
+ cmd[0] = CMD_READ_ARRAY_FAST;
+ spi_flash_addr(flash, offset, cmd, &cmd_len);
+@@ -202,7 +218,7 @@ int spi_flash_cmd_erase(struct spi_flash
+ {
+ u32 start, end, erase_size;
+ int ret;
+- u8 cmd[4], cmd_len;
++ u8 cmd[5], cmd_len;
+
+ erase_size = flash->sector_size;
+ if (offset % erase_size || len % erase_size) {
+@@ -227,8 +243,8 @@ int spi_flash_cmd_erase(struct spi_flash
+ spi_flash_addr(flash, offset, cmd, &cmd_len);
+ offset += erase_size;
+
+- debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+- cmd[2], cmd[3], offset);
++ debug("SF: erase %2x %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
++ cmd[2], cmd[3], cmd[4], offset);
+
+ ret = spi_flash_cmd_write_enable(flash);
+ if (ret)
+@@ -409,6 +425,12 @@ int spi_flash_probe_spl(struct spi_flash
+ goto err_manufacturer_probe;
+ }
+
++ ret = spi_flash_set_4byte_mode(flash);
++ if (ret) {
++ debug("SF: Failed to enable 4 byte mode: %d\n", ret);
++ goto err_manufacturer_probe;
++ }
++
+ spi_release_bus(spi);
+
+ return 0;
+--- a/drivers/mtd/spi/spi_flash_internal.h
++++ b/drivers/mtd/spi/spi_flash_internal.h
+@@ -97,6 +97,31 @@ int spi_flash_cmd_wait_ready(struct spi_
+ /* Erase sectors. */
+ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len);
+
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++static inline int spi_flash_use_4byte_mode(struct spi_flash *flash)
++{
++ return NULL != flash->set_4byte_mode;
++}
++
++static inline int spi_flash_set_4byte_mode(struct spi_flash *flash)
++{
++ if (spi_flash_use_4byte_mode(flash))
++ return flash->set_4byte_mode(flash);
++
++ return 0;
++}
++#else
++static inline int spi_flash_use_4byte_mode(struct spi_flash *flash)
++{
++ return 0;
++}
++
++static inline int spi_flash_set_4byte_mode(struct spi_flash *flash)
++{
++ return 0;
++}
++#endif
++
+ /* Manufacturer-specific probe functions */
+ int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode);
+ int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode);
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -46,6 +46,9 @@ struct spi_flash {
+ size_t len, const void *buf);
+ int (*erase)(struct spi_flash *flash, u32 offset,
+ size_t len);
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++ int (*set_4byte_mode)(struct spi_flash *flash);
++#endif
+ };
+
+ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0007-sf-eon-use-16-bit-ID-for-comparison.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0007-sf-eon-use-16-bit-ID-for-comparison.patch.svn-base
new file mode 100644
index 0000000..6836674
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0007-sf-eon-use-16-bit-ID-for-comparison.patch.svn-base
@@ -0,0 +1,45 @@
+From d32f45357f0475a2f810752eeb9412fe692e1c0a Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:09:21 +0100
+Subject: sf: eon: use 16 bit ID for comparison
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/eon.c
++++ b/drivers/mtd/spi/eon.c
+@@ -11,19 +11,19 @@
+ #include "spi_flash_internal.h"
+
+ struct eon_spi_flash_params {
+- u8 idcode1;
++ u16 idcode;
+ u16 nr_sectors;
+ const char *name;
+ };
+
+ static const struct eon_spi_flash_params eon_spi_flash_table[] = {
+ {
+- .idcode1 = 0x16,
++ .idcode = 0x3016,
+ .nr_sectors = 1024,
+ .name = "EN25Q32B",
+ },
+ {
+- .idcode1 = 0x18,
++ .idcode = 0x3018,
+ .nr_sectors = 4096,
+ .name = "EN25Q128",
+ },
+@@ -33,10 +33,11 @@ int spi_flash_probe_eon(struct spi_flash
+ {
+ const struct eon_spi_flash_params *params;
+ unsigned int i;
++ u16 id = idcode[2] | idcode[1] << 8;
+
+ for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) {
+ params = &eon_spi_flash_table[i];
+- if (params->idcode1 == idcode[2])
++ if (params->idcode == id)
+ break;
+ }
+
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0008-sf-eon-add-support-for-4-byte-address-mode.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0008-sf-eon-add-support-for-4-byte-address-mode.patch.svn-base
new file mode 100644
index 0000000..c037a86
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0008-sf-eon-add-support-for-4-byte-address-mode.patch.svn-base
@@ -0,0 +1,43 @@
+From 37254e3284f61ea495f73a78b7c8efae983781e2 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:10:07 +0100
+Subject: sf: eon: add support for 4-byte address mode
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/eon.c
++++ b/drivers/mtd/spi/eon.c
+@@ -10,6 +10,8 @@
+
+ #include "spi_flash_internal.h"
+
++#define EN25XX_EN4B 0xb7 /* Enter 4-byte mode */
++
+ struct eon_spi_flash_params {
+ u16 idcode;
+ u16 nr_sectors;
+@@ -29,6 +31,13 @@ static const struct eon_spi_flash_params
+ },
+ };
+
++static __maybe_unused int eon_set_4byte_mode(struct spi_flash *flash)
++{
++ struct spi_slave *spi = flash->spi;
++
++ return spi_flash_cmd(spi, EN25XX_EN4B, NULL, 0);
++}
++
+ int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct eon_spi_flash_params *params;
+@@ -57,5 +66,10 @@ int spi_flash_probe_eon(struct spi_flash
+ flash->size = 256 * 16
+ * params->nr_sectors;
+
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++ if (flash->size > (1 << 24))
++ flash->set_4byte_mode = eon_set_4byte_mode;
++#endif
++
+ return 1;
+ }
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0009-sf-eon-add-support-for-EN25QH256.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0009-sf-eon-add-support-for-EN25QH256.patch.svn-base
new file mode 100644
index 0000000..18f5823
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0009-sf-eon-add-support-for-EN25QH256.patch.svn-base
@@ -0,0 +1,21 @@
+From e510be1145796cd44cf5800e187a94ad7c19e764 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:10:34 +0100
+Subject: sf: eon: add support for EN25QH256
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/eon.c
++++ b/drivers/mtd/spi/eon.c
+@@ -29,6 +29,11 @@ static const struct eon_spi_flash_params
+ .nr_sectors = 4096,
+ .name = "EN25Q128",
+ },
++ {
++ .idcode = 0x7019,
++ .nr_sectors = 8192,
++ .name = "EN25QH256",
++ },
+ };
+
+ static __maybe_unused int eon_set_4byte_mode(struct spi_flash *flash)
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch.svn-base
new file mode 100644
index 0000000..af8c7a1
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch.svn-base
@@ -0,0 +1,30 @@
+From 81a8e9e192d53ce8b5cafd47190d6c6826519d09 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:58:59 +0100
+Subject: sf: spansion: fix device IDs and sector architecture for S25FL256S
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spansion.c
++++ b/drivers/mtd/spi/spansion.c
+@@ -97,11 +97,18 @@ static const struct spansion_spi_flash_p
+ .name = "S25FL129P_64K",
+ },
+ {
+- .idcode1 = 0x2019,
++ .idcode1 = 0x0219,
+ .idcode2 = 0x4d01,
+ .pages_per_sector = 256,
+ .nr_sectors = 512,
+- .name = "S25FL256S",
++ .name = "S25FL256S_64K",
++ },
++ {
++ .idcode1 = 0x0219,
++ .idcode2 = 0x4d00,
++ .pages_per_sector = 1024,
++ .nr_sectors = 128,
++ .name = "S25FL256S_256K",
+ },
+ };
+
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0011-sf-spansion-add-support-for-4-byte-address-mode.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0011-sf-spansion-add-support-for-4-byte-address-mode.patch.svn-base
new file mode 100644
index 0000000..9471d47
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0011-sf-spansion-add-support-for-4-byte-address-mode.patch.svn-base
@@ -0,0 +1,55 @@
+From 0add8e5c60961d2b99174610df8d3d9d6d192b74 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:16:11 +0100
+Subject: sf: spansion: add support for 4-byte address mode
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spansion.c
++++ b/drivers/mtd/spi/spansion.c
+@@ -31,6 +31,10 @@
+
+ #include "spi_flash_internal.h"
+
++#define S25FLXX_BRRD 0x16 /* Read Bank Register */
++#define S25FLXX_BRWR 0x17 /* Write Bank Register */
++#define S25FLXX_BAR_EXTADD (1 << 7) /* Extended address enable */
++
+ struct spansion_spi_flash_params {
+ u16 idcode1;
+ u16 idcode2;
+@@ -112,6 +116,23 @@ static const struct spansion_spi_flash_p
+ },
+ };
+
++static __maybe_unused int spansion_set_4byte_mode(struct spi_flash *flash)
++{
++ struct spi_slave *spi = flash->spi;
++ u8 bar, cmd;
++ int err;
++
++ cmd = S25FLXX_BRRD;
++ err = spi_flash_cmd(spi, cmd, &bar, 1);
++ if (err)
++ return err;
++
++ bar |= S25FLXX_BAR_EXTADD;
++ cmd = S25FLXX_BRWR;
++
++ return spi_flash_cmd_write(spi, &cmd, 1, &bar, 1);
++}
++
+ int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct spansion_spi_flash_params *params;
+@@ -144,5 +165,10 @@ int spi_flash_probe_spansion(struct spi_
+ flash->sector_size = 256 * params->pages_per_sector;
+ flash->size = flash->sector_size * params->nr_sectors;
+
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++ if (flash->size > (1 << 24))
++ flash->set_4byte_mode = spansion_set_4byte_mode;
++#endif
++
+ return 1;
+ }
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0012-sf-spansion-add-support-for-S25FL512S.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0012-sf-spansion-add-support-for-S25FL512S.patch.svn-base
new file mode 100644
index 0000000..5f415a9
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0012-sf-spansion-add-support-for-S25FL512S.patch.svn-base
@@ -0,0 +1,23 @@
+From bff335ac524843bc90163c3b231091a5016f8670 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:07:54 +0100
+Subject: sf: spansion: add support for S25FL512S
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spansion.c
++++ b/drivers/mtd/spi/spansion.c
+@@ -114,6 +114,13 @@ static const struct spansion_spi_flash_p
+ .nr_sectors = 128,
+ .name = "S25FL256S_256K",
+ },
++ {
++ .idcode1 = 0x0220,
++ .idcode2 = 0x4d00,
++ .pages_per_sector = 1024,
++ .nr_sectors = 256,
++ .name = "S25FL512S_256K",
++ },
+ };
+
+ static __maybe_unused int spansion_set_4byte_mode(struct spi_flash *flash)
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0013-sf-macronix-add-support-for-4-byte-address-mode.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0013-sf-macronix-add-support-for-4-byte-address-mode.patch.svn-base
new file mode 100644
index 0000000..70015c9
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0013-sf-macronix-add-support-for-4-byte-address-mode.patch.svn-base
@@ -0,0 +1,44 @@
+From 207662a9270cc542709fbab0d25fbc361b39748c Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:13:49 +0100
+Subject: sf: macronix: add support for 4-byte address mode
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/macronix.c
++++ b/drivers/mtd/spi/macronix.c
+@@ -35,6 +35,8 @@
+
+ #include "spi_flash_internal.h"
+
++#define MX25XX_EN4B 0xb7 /* Enter 4-byte mode */
++
+ struct macronix_spi_flash_params {
+ u16 idcode;
+ u16 nr_blocks;
+@@ -79,6 +81,13 @@ static const struct macronix_spi_flash_p
+ },
+ };
+
++static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash)
++{
++ struct spi_slave *spi = flash->spi;
++
++ return spi_flash_cmd(spi, MX25XX_EN4B, NULL, 0);
++}
++
+ int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct macronix_spi_flash_params *params;
+@@ -106,6 +115,11 @@ int spi_flash_probe_macronix(struct spi_
+ flash->sector_size = 256 * 16 * 16;
+ flash->size = flash->sector_size * params->nr_blocks;
+
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++ if (flash->size > (1 << 24))
++ flash->set_4byte_mode = macronix_set_4byte_mode;
++#endif
++
+ /* Clear BP# bits for read-only flash */
+ spi_flash_cmd_write_status(flash, 0);
+
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0014-sf-macronix-add-support-for-MX25L25635E.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0014-sf-macronix-add-support-for-MX25L25635E.patch.svn-base
new file mode 100644
index 0000000..8e33836
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0014-sf-macronix-add-support-for-MX25L25635E.patch.svn-base
@@ -0,0 +1,21 @@
+From 0f31fef3d6a5110684ea31c5064c45fc448013d6 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:14:24 +0100
+Subject: sf: macronix: add support for MX25L25635E
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/macronix.c
++++ b/drivers/mtd/spi/macronix.c
+@@ -79,6 +79,11 @@ static const struct macronix_spi_flash_p
+ .nr_blocks = 256,
+ .name = "MX25L12855E",
+ },
++ {
++ .idcode = 0x2019,
++ .nr_blocks = 512,
++ .name = "MX25L25635E",
++ },
+ };
+
+ static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash)
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0015-sf-macronix-add-support-for-MX66L51235L.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0015-sf-macronix-add-support-for-MX66L51235L.patch.svn-base
new file mode 100644
index 0000000..fbc22e4
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0015-sf-macronix-add-support-for-MX66L51235L.patch.svn-base
@@ -0,0 +1,21 @@
+From a2d80b6b91ac63beea31455ce8d136230c030500 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:14:40 +0100
+Subject: sf: macronix: add support for MX66L51235L
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/macronix.c
++++ b/drivers/mtd/spi/macronix.c
+@@ -84,6 +84,11 @@ static const struct macronix_spi_flash_p
+ .nr_blocks = 512,
+ .name = "MX25L25635E",
+ },
++ {
++ .idcode = 0x201A,
++ .nr_blocks = 1024,
++ .name = "MX66L51235L",
++ },
+ };
+
+ static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash)
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch.svn-base
new file mode 100644
index 0000000..a9ee560
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch.svn-base
@@ -0,0 +1,133 @@
+From 7f6ded11965b09daf6da44d4fa98da17b9fba36c Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 19:41:26 +0100
+Subject: sf: add MTD layer driver for SPI flash devices
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/Makefile
++++ b/drivers/mtd/spi/Makefile
+@@ -30,6 +30,7 @@ COBJS-$(CONFIG_SPL_SPI_LOAD) += spi_spl_
+ endif
+
+ COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o
++COBJS-$(CONFIG_SPI_FLASH_MTD) += spi_flash_mtd.o
+ COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o
+ COBJS-$(CONFIG_SPI_FLASH_EON) += eon.o
+ COBJS-$(CONFIG_SPI_FLASH_MACRONIX) += macronix.o
+--- a/drivers/mtd/spi/spi_flash_internal.h
++++ b/drivers/mtd/spi/spi_flash_internal.h
+@@ -122,6 +122,9 @@ static inline int spi_flash_set_4byte_mo
+ }
+ #endif
+
++/* SPI flash MTD adapter init */
++int spi_flash_mtd_init(struct spi_flash *flash);
++
+ /* Manufacturer-specific probe functions */
+ int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode);
+ int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode);
+--- /dev/null
++++ b/drivers/mtd/spi/spi_flash_mtd.c
+@@ -0,0 +1,101 @@
++/*
++ * (C) Copyright 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * MTD layer driver for SPI flash devices
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <asm/errno.h>
++#include <linux/mtd/mtd.h>
++#include <spi_flash.h>
++
++static struct mtd_info sf_mtd_info;
++static char sf_mtd_name[8];
++
++static int spi_flash_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
++{
++ struct spi_flash *flash = mtd->priv;
++ int err;
++
++ instr->state = MTD_ERASING;
++
++ err = spi_flash_erase(flash, instr->addr, instr->len);
++ if (err) {
++ instr->state = MTD_ERASE_FAILED;
++ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
++ return -EIO;
++ }
++
++ instr->state = MTD_ERASE_DONE;
++ mtd_erase_callback(instr);
++
++ return 0;
++}
++
++static int spi_flash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
++ size_t *retlen, u_char *buf)
++{
++ struct spi_flash *flash = mtd->priv;
++ int err;
++
++ err = spi_flash_read(flash, from, len, buf);
++ if (!err)
++ *retlen = len;
++
++ return err;
++}
++
++static int spi_flash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
++ size_t *retlen, const u_char *buf)
++{
++ struct spi_flash *flash = mtd->priv;
++ int err;
++
++ err = spi_flash_write(flash, to, len, buf);
++ if (!err)
++ *retlen = len;
++
++ return err;
++}
++
++static void spi_flash_mtd_sync(struct mtd_info *mtd)
++{
++}
++
++static int spi_flash_mtd_number(void)
++{
++#ifdef CONFIG_SYS_MAX_FLASH_BANKS
++ return CONFIG_SYS_MAX_FLASH_BANKS;
++#else
++ return 0;
++#endif
++}
++
++int spi_flash_mtd_init(struct spi_flash *flash)
++{
++ memset(&sf_mtd_info, 0, sizeof(sf_mtd_info));
++ sprintf(sf_mtd_name, "nor%d", spi_flash_mtd_number());
++
++ sf_mtd_info.name = sf_mtd_name;
++ sf_mtd_info.type = MTD_NORFLASH;
++ sf_mtd_info.flags = MTD_CAP_NORFLASH;
++ sf_mtd_info.writesize = 1;
++
++ sf_mtd_info.erase = spi_flash_mtd_erase;
++ sf_mtd_info.read = spi_flash_mtd_read;
++ sf_mtd_info.write = spi_flash_mtd_write;
++ sf_mtd_info.sync = spi_flash_mtd_sync;
++
++ sf_mtd_info.size = flash->size;
++ sf_mtd_info.priv = flash;
++
++ /* Only uniform flash devices for now */
++ sf_mtd_info.numeraseregions = 0;
++ sf_mtd_info.erasesize = flash->sector_size;
++
++ return add_mtd_device(&sf_mtd_info);
++}
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0017-sf-add-init-function.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0017-sf-add-init-function.patch.svn-base
new file mode 100644
index 0000000..2d29051
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0017-sf-add-init-function.patch.svn-base
@@ -0,0 +1,57 @@
+From aa9d5d64ca6441cb24e22dc3c1f707da62da2887 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 19:35:17 +0100
+Subject: sf: add init function
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -482,3 +482,36 @@ void spi_flash_free(struct spi_flash *fl
+ spi_flash_free_spl(flash);
+ free(flash);
+ }
++
++#ifdef CONFIG_SPI_FLASH_MTD
++static int spi_flash_mtd_register(void)
++{
++ struct spi_flash *flash;
++ int err;
++
++ flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
++ CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
++ if (!flash)
++ return -1;
++
++ err = spi_flash_mtd_init(flash);
++ if (err)
++ spi_flash_free(flash);
++
++ return err;
++}
++#else
++static int spi_flash_mtd_register(void)
++{
++ return 0;
++}
++#endif
++
++int spi_flash_init(void)
++{
++ int err;
++
++ err = spi_flash_mtd_register();
++
++ return err;
++}
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -51,6 +51,8 @@ struct spi_flash {
+ #endif
+ };
+
++int spi_flash_init(void);
++
+ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int spi_mode);
+ void spi_flash_free(struct spi_flash *flash);
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0018-MIPS-add-SPI-flash-init-hook.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0018-MIPS-add-SPI-flash-init-hook.patch.svn-base
new file mode 100644
index 0000000..71f094b
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0018-MIPS-add-SPI-flash-init-hook.patch.svn-base
@@ -0,0 +1,47 @@
+From 888b33e84082fe72d60d528c05c885c0c9d70bc4 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 21:19:43 +0100
+Subject: MIPS: add SPI flash init hook
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/arch/mips/lib/board.c
++++ b/arch/mips/lib/board.c
+@@ -32,6 +32,7 @@
+ #include <nand.h>
+ #include <onenand_uboot.h>
+ #include <spi.h>
++#include <spi_flash.h>
+
+ #ifdef CONFIG_BITBANGMII
+ #include <miiphy.h>
+@@ -312,6 +313,16 @@ void board_init_r(gd_t *id, ulong dest_a
+ onenand_init();
+ #endif
+
++#ifdef CONFIG_CMD_SPI
++ puts("SPI: ");
++ spi_init(); /* go init the SPI */
++ puts("ready\n");
++#endif
++
++#if defined(CONFIG_SPI_FLASH)
++ spi_flash_init();
++#endif
++
+ /* relocate environment function pointers etc. */
+ env_relocate();
+
+@@ -335,12 +346,6 @@ void board_init_r(gd_t *id, ulong dest_a
+ /* Initialize from environment */
+ load_addr = getenv_ulong("loadaddr", 16, load_addr);
+
+-#ifdef CONFIG_CMD_SPI
+- puts("SPI: ");
+- spi_init(); /* go init the SPI */
+- puts("ready\n");
+-#endif
+-
+ #if defined(CONFIG_MISC_INIT_R)
+ /* miscellaneous platform dependent initialisations */
+ misc_init_r();
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch.svn-base
new file mode 100644
index 0000000..a215d1a
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch.svn-base
@@ -0,0 +1,239 @@
+From d8b1597130d228bc7e2bafd0c8d097529018c833 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 29 Aug 2012 22:08:15 +0200
+Subject: net: switchlib: add framework for ethernet switch drivers
+
+Add a generic framework similar to phylib for ethernet switch
+drivers and devices. This is useful to share the init and
+setup code for switch devices across different boards.
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Cc: Joe Hershberger <joe.hershberger@gmail.com>
+
+--- a/Makefile
++++ b/Makefile
+@@ -291,6 +291,7 @@ LIBS-y += drivers/mtd/ubi/libubi.o
+ LIBS-y += drivers/mtd/spi/libspi_flash.o
+ LIBS-y += drivers/net/libnet.o
+ LIBS-y += drivers/net/phy/libphy.o
++LIBS-y += drivers/net/switch/libswitch.o
+ LIBS-y += drivers/pci/libpci.o
+ LIBS-y += drivers/pcmcia/libpcmcia.o
+ LIBS-y += drivers/power/libpower.o \
+--- /dev/null
++++ b/drivers/net/switch/Makefile
+@@ -0,0 +1,31 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB := $(obj)libswitch.o
++
++COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
++
++COBJS := $(COBJS-y)
++SRCS := $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++
++all: $(LIB)
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/drivers/net/switch/switch.c
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <switch.h>
++
++static struct list_head switch_drivers;
++static struct list_head switch_devices;
++
++void switch_init(void)
++{
++ INIT_LIST_HEAD(&switch_drivers);
++ INIT_LIST_HEAD(&switch_devices);
++
++ board_switch_init();
++}
++
++void switch_driver_register(struct switch_driver *drv)
++{
++ INIT_LIST_HEAD(&drv->list);
++ list_add_tail(&drv->list, &switch_drivers);
++}
++
++int switch_device_register(struct switch_device *dev)
++{
++ struct switch_driver *drv;
++
++ /* Add switch device only, if an adequate driver is registered */
++ list_for_each_entry(drv, &switch_drivers, list) {
++ if (!strcmp(drv->name, dev->name)) {
++ dev->drv = drv;
++
++ INIT_LIST_HEAD(&dev->list);
++ list_add_tail(&dev->list, &switch_devices);
++
++ return 0;
++ }
++ }
++
++ return -1;
++}
++
++struct switch_device *switch_connect(struct mii_dev *bus)
++{
++ struct switch_device *sw;
++ int err;
++
++ list_for_each_entry(sw, &switch_devices, list) {
++ sw->bus = bus;
++
++ err = sw->drv->probe(sw);
++ if (!err)
++ return sw;
++ }
++
++ return NULL;
++}
+--- /dev/null
++++ b/include/switch.h
+@@ -0,0 +1,95 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __SWITCH_H
++#define __SWITCH_H
++
++#include <linux/list.h>
++
++#define SWITCH_NAME_SIZE 32
++
++struct switch_device;
++struct mii_dev;
++
++struct switch_driver {
++ struct list_head list;
++
++ /* Switch device name */
++ const char name[SWITCH_NAME_SIZE];
++
++ /*
++ * Called to probe the switch chip. Must return 0 if the switch
++ * chip matches the given switch device/driver combination. Otherwise
++ * 1 must be returned.
++ */
++ int (*probe) (struct switch_device *dev);
++
++ /*
++ * Called to initialize the switch chip.
++ */
++ void (*setup) (struct switch_device *dev);
++};
++
++struct switch_device {
++ struct list_head list;
++ struct switch_driver *drv;
++
++ /* MII bus the switch chip is connected to */
++ struct mii_dev *bus;
++
++ /* Switch device name */
++ const char name[SWITCH_NAME_SIZE];
++
++ /* Bitmask for board specific setup of used switch ports */
++ u16 port_mask;
++
++ /* Number of switch port that is connected to host CPU */
++ u16 cpu_port;
++};
++
++/*
++ * Board specific switch initialization.
++ *
++ * Called from switch_init to register the board specific switch_device
++ * structure.
++ */
++extern int board_switch_init(void);
++
++/* Initialize switch subsystem */
++#ifdef CONFIG_SWITCH_MULTI
++extern void switch_init(void);
++#else
++static inline void switch_init(void)
++{
++}
++#endif
++
++/* Register a switch driver */
++extern void switch_driver_register(struct switch_driver *drv);
++
++/* Register a switch device */
++extern int switch_device_register(struct switch_device *dev);
++
++/*
++ * Probe the available switch chips and connect the found one
++ * with the given MII bus
++ */
++extern struct switch_device *switch_connect(struct mii_dev *bus);
++
++/*
++ * Setup the given switch device
++ */
++static inline void switch_setup(struct switch_device *dev)
++{
++ if (dev->drv->setup)
++ dev->drv->setup(dev);
++}
++
++/* Init functions for supported Switch drivers */
++
++#endif /* __SWITCH_H */
++
+--- a/net/eth.c
++++ b/net/eth.c
+@@ -26,6 +26,7 @@
+ #include <net.h>
+ #include <miiphy.h>
+ #include <phy.h>
++#include <switch.h>
+
+ void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
+ {
+@@ -303,6 +304,8 @@ int eth_initialize(bd_t *bis)
+ phy_init();
+ #endif
+
++ switch_init();
++
+ eth_env_init(bis);
+
+ /*
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch.svn-base
new file mode 100644
index 0000000..c017e0f
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch.svn-base
@@ -0,0 +1,162 @@
+From b8c666eda693906488637c414db9db35b6760e4a Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 29 Aug 2012 22:08:15 +0200
+Subject: net: switchlib: add driver for Lantiq PSB697X switch family
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -11,6 +11,7 @@ include $(TOPDIR)/config.mk
+ LIB := $(obj)libswitch.o
+
+ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
++COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/psb697x.c
+@@ -0,0 +1,119 @@
++/*
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <switch.h>
++#include <miiphy.h>
++
++#define PSB697X_CHIPID1 0x2599
++#define PSB697X_PORT_COUNT 7
++
++#define PSB697X_PORT_BASE(p) (p * 0x20)
++#define PSB697X_REG_PS(p) (PSB697X_PORT_BASE(p) + 0x00)
++#define PSB697X_REG_PBC(p) (PSB697X_PORT_BASE(p) + 0x01)
++#define PSB697X_REG_PEC(p) (PSB697X_PORT_BASE(p) + 0x02)
++
++#define PSB697X_REG_SGC1 0x0E0 /* Switch Global Control Register 1 */
++#define PSB697X_REG_SGC2 0x0E1 /* Switch Global Control Register 2 */
++#define PSB697X_REG_CMH 0x0E2 /* CPU Port & Mirror Control */
++#define PSB697X_REG_MIICR 0x0F5 /* MII Port Control */
++#define PSB697X_REG_CI0 0x100 /* Chip Identifier 0 */
++#define PSB697X_REG_CI1 0x101 /* Chip Identifier 1 */
++#define PSB697X_REG_MIIAC 0x120 /* MII Indirect Access Control */
++#define PSB697X_REG_MIIWD 0x121 /* MII Indirect Write Data */
++#define PSB697X_REG_MIIRD 0x122 /* MII Indirect Read Data */
++
++#define PSB697X_REG_PORT_FLP (1 << 2) /* Force link up */
++#define PSB697X_REG_PORT_FLD (1 << 1) /* Force link down */
++
++#define PSB697X_REG_SGC2_SE (1 << 15) /* Switch enable */
++
++#define PSB697X_REG_CMH_CPN_MASK 0x7
++#define PSB697X_REG_CMH_CPN_SHIFT 5
++
++
++static inline int psb697x_mii_read(struct mii_dev *bus, u16 reg)
++{
++ int ret;
++
++ ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f);
++
++ return ret;
++}
++
++static inline int psb697x_mii_write(struct mii_dev *bus, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE,
++ reg & 0x1f, val);
++
++ return ret;
++}
++
++static int psb697x_probe(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ int ci1;
++
++ ci1 = psb697x_mii_read(bus, PSB697X_REG_CI1);
++
++ if (ci1 == PSB697X_CHIPID1)
++ return 0;
++
++ return 1;
++}
++
++static void psb697x_setup(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ int i, state;
++
++ /* Enable switch */
++ psb697x_mii_write(bus, PSB697X_REG_SGC2, PSB697X_REG_SGC2_SE);
++
++ /*
++ * Force 100 Mbps as default value for CPU ports 5 and 6 to get
++ * full speed.
++ */
++ psb697x_mii_write(bus, PSB697X_REG_MIICR, 0x0773);
++
++ for (i = 0; i < PSB697X_PORT_COUNT; i++) {
++ state = dev->port_mask & (1 << i);
++
++ /*
++ * Software workaround from Errata Sheet:
++ * Force link down and reset internal PHY, keep that state
++ * for all unconnected ports and disable force link down
++ * for all connected ports
++ */
++ psb697x_mii_write(bus, PSB697X_REG_PBC(i),
++ PSB697X_REG_PORT_FLD);
++
++ if (i == dev->cpu_port)
++ /* Force link up for CPU port */
++ psb697x_mii_write(bus, PSB697X_REG_PBC(i),
++ PSB697X_REG_PORT_FLP);
++ else if (state)
++ /* Disable force link down for active LAN ports */
++ psb697x_mii_write(bus, PSB697X_REG_PBC(i), 0);
++ }
++}
++
++static struct switch_driver psb697x_drv = {
++ .name = "psb697x",
++};
++
++void switch_psb697x_init(void)
++{
++ /* For archs with manual relocation */
++ psb697x_drv.probe = psb697x_probe;
++ psb697x_drv.setup = psb697x_setup;
++
++ switch_driver_register(&psb697x_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -18,6 +18,10 @@ void switch_init(void)
+ INIT_LIST_HEAD(&switch_drivers);
+ INIT_LIST_HEAD(&switch_devices);
+
++#if defined(CONFIG_SWITCH_PSB697X)
++ switch_psb697x_init();
++#endif
++
+ board_switch_init();
+ }
+
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -90,6 +90,7 @@ static inline void switch_setup(struct s
+ }
+
+ /* Init functions for supported Switch drivers */
++extern void switch_psb697x_init(void);
+
+ #endif /* __SWITCH_H */
+
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch.svn-base
new file mode 100644
index 0000000..342fa46
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch.svn-base
@@ -0,0 +1,158 @@
+From fcbbb1beb2ae862f5c703c5719ed0e155cbbf82f Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 29 Aug 2012 22:08:16 +0200
+Subject: net: switchlib: add driver for Lantiq ADM6996I switch family
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -12,6 +12,7 @@ LIB := $(obj)libswitch.o
+
+ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
+ COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
++COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/adm6996i.c
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <switch.h>
++#include <miiphy.h>
++
++#define ADM6996I_CHIPID0 0x1020
++#define ADM6996I_CHIPID1 0x0007
++#define ADM6996I_PORT_COUNT 6
++
++#define ADM6996I_REG_P0BC 0x001 /* P0 Basic Control */
++#define ADM6996I_REG_P1BC 0x003 /* P1 Basic Control */
++#define ADM6996I_REG_P2BC 0x005 /* P2 Basic Control */
++#define ADM6996I_REG_P3BC 0x007 /* P3 Basic Control */
++#define ADM6996I_REG_P4BC 0x008 /* P4 Basic Control */
++#define ADM6996I_REG_P5BC 0x009 /* P5 Basic Control */
++
++#define ADM6996I_REG_P0EC 0x002 /* P0 Extended Control */
++#define ADM6996I_REG_P1EC 0x002 /* P1 Extended Control */
++#define ADM6996I_REG_P2EC 0x004 /* P2 Extended Control */
++#define ADM6996I_REG_P3EC 0x004 /* P3 Extended Control */
++#define ADM6996I_REG_P4EC 0x006 /* P4 Extended Control */
++#define ADM6996I_REG_P5EC 0x006 /* P5 Extended Control */
++
++#define ADM6996I_REG_SC4 0x012 /* System Control 4 */
++
++#define ADM6996I_REG_CI0 0xA0 /* Chip Identifier 0 */
++#define ADM6996I_REG_CI1 0xA1 /* Chip Identifier 1 */
++
++#define ADM6996I_REG_PXBC_DEFAULT 0x040F
++#define ADM6996I_REG_PXBC_CROSS_EE (1 << 15)
++#define ADM6996I_REG_PXBC_PD (1 << 5)
++
++#define ADM6996I_REG_SC4_DEFAULT 0x3600
++#define ADM6996I_REG_SC4_LED_ENABLE (1 << 1)
++
++#define ADM6996I_REG_CI0_PC_MASK 0xFFF0
++#define ADM6996I_REG_CI0_VN_MASK 0xF
++#define ADM6996I_REG_CI1_PC_MASK 0xF
++
++
++static inline int adm6996i_mii_read(struct mii_dev *bus, u16 reg)
++{
++ int ret;
++
++ ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f);
++
++ return ret;
++}
++
++static inline int adm6996i_mii_write(struct mii_dev *bus, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE,
++ reg & 0x1f, val);
++
++ return ret;
++}
++
++static int adm6996i_probe(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ u16 ci0, ci1;
++
++ ci0 = adm6996i_mii_read(bus, ADM6996I_REG_CI0);
++ ci1 = adm6996i_mii_read(bus, ADM6996I_REG_CI1);
++
++ ci0 &= ADM6996I_REG_CI0_PC_MASK;
++ ci1 &= ADM6996I_REG_CI1_PC_MASK;
++
++ if (ci0 == ADM6996I_CHIPID0 && ci1 == ADM6996I_CHIPID1)
++ return 0;
++
++ return 1;
++}
++
++static void adm6996i_setup(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ u16 val;
++
++ /*
++ * Write default values (Port enable, 100 Mbps, Full Duplex,
++ * Auto negotiation, Flow control) and enable crossover auto-detect
++ */
++ val = ADM6996I_REG_PXBC_DEFAULT | ADM6996I_REG_PXBC_CROSS_EE;
++ adm6996i_mii_write(bus, ADM6996I_REG_P0BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P1BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P2BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P3BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P4BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P5BC, val);
++
++ val = ADM6996I_REG_SC4_DEFAULT | ADM6996I_REG_SC4_LED_ENABLE;
++ adm6996i_mii_write(bus, ADM6996I_REG_SC4, val);
++}
++
++static struct switch_driver adm6996i_drv = {
++ .name = "adm6996i",
++};
++
++void switch_adm6996i_init(void)
++{
++ /* For archs with manual relocation */
++ adm6996i_drv.probe = adm6996i_probe;
++ adm6996i_drv.setup = adm6996i_setup;
++
++ switch_driver_register(&adm6996i_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -21,6 +21,9 @@ void switch_init(void)
+ #if defined(CONFIG_SWITCH_PSB697X)
+ switch_psb697x_init();
+ #endif
++#if defined(CONFIG_SWITCH_ADM6996I)
++ switch_adm6996i_init();
++#endif
+
+ board_switch_init();
+ }
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -91,6 +91,7 @@ static inline void switch_setup(struct s
+
+ /* Init functions for supported Switch drivers */
+ extern void switch_psb697x_init(void);
++extern void switch_adm6996i_init(void);
+
+ #endif /* __SWITCH_H */
+
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch.svn-base
new file mode 100644
index 0000000..127c0d8
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch.svn-base
@@ -0,0 +1,158 @@
+From 16b8c52f80f20e07866e397ff52ff9658766437b Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Wed, 29 Aug 2012 22:08:16 +0200
+Subject: net: switchlib: add driver for Atheros AR8216
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -13,6 +13,7 @@ LIB := $(obj)libswitch.o
+ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
+ COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
+ COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o
++COBJS-$(CONFIG_SWITCH_AR8216) += ar8216.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/ar8216.c
+@@ -0,0 +1,115 @@
++/*
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <miiphy.h>
++#include <switch.h>
++#include <netdev.h>
++
++#define BITS(_s, _n) (((1UL << (_n)) - 1) << _s)
++
++#define AR8216_REG_CTRL 0x0000
++#define AR8216_CTRL_REVISION BITS(0, 8)
++#define AR8216_CTRL_VERSION BITS(8, 8)
++
++#define AR8216_PROBE_RETRIES 10
++
++static void split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
++{
++ regaddr >>= 1;
++ *r1 = regaddr & 0x1e;
++
++ regaddr >>= 5;
++ *r2 = regaddr & 0x7;
++
++ regaddr >>= 3;
++ *page = regaddr & 0x1ff;
++}
++
++static int ar8216_mii_read(struct mii_dev *bus, u32 reg)
++{
++ u16 r1, r2, page;
++ u16 lo, hi;
++
++ split_addr(reg, &r1, &r2, &page);
++
++ bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, page);
++ __udelay(1000);
++
++ lo = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1);
++ hi = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1);
++
++ return (hi << 16) | lo;
++}
++
++static void ar8216_mii_write(struct mii_dev *bus, u16 reg, u32 val)
++{
++ u16 r1, r2, r3;
++ u16 lo, hi;
++
++ split_addr((u32) reg, &r1, &r2, &r3);
++
++ bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, r3);
++ __udelay(1000);
++
++ lo = val & 0xffff;
++ hi = (u16) (val >> 16);
++ bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1, hi);
++ bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1, lo);
++}
++
++static int ar8216_probe(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ u32 val;
++ u16 id;
++
++ val = ar8216_mii_read(bus, AR8216_REG_CTRL);
++ if (val == ~0)
++ return 1;
++
++ id = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION);
++
++ switch (id) {
++ case 0x0101:
++ return 0;
++ default:
++ return 1;
++ }
++}
++
++static void ar8216_setup(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++
++ ar8216_mii_write(bus, 0x200, 0x200);
++ ar8216_mii_write(bus, 0x300, 0x200);
++ ar8216_mii_write(bus, 0x400, 0x200);
++ ar8216_mii_write(bus, 0x500, 0x200);
++ ar8216_mii_write(bus, 0x600, 0x7d);
++ ar8216_mii_write(bus, 0x38, 0xc000050e);
++ ar8216_mii_write(bus, 0x104, 0x4004);
++ ar8216_mii_write(bus, 0x60, 0xffffffff);
++ ar8216_mii_write(bus, 0x64, 0xaaaaaaaa);
++ ar8216_mii_write(bus, 0x68, 0x55555555);
++ ar8216_mii_write(bus, 0x6c, 0x0);
++ ar8216_mii_write(bus, 0x70, 0x41af);
++}
++
++static struct switch_driver ar8216_drv = {
++ .name = "ar8216",
++};
++
++void switch_ar8216_init(void)
++{
++ /* for archs with manual relocation */
++ ar8216_drv.probe = ar8216_probe;
++ ar8216_drv.setup = ar8216_setup;
++
++ switch_driver_register(&ar8216_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -24,6 +24,9 @@ void switch_init(void)
+ #if defined(CONFIG_SWITCH_ADM6996I)
+ switch_adm6996i_init();
+ #endif
++#if defined(CONFIG_SWITCH_AR8216)
++ switch_ar8216_init();
++#endif
+
+ board_switch_init();
+ }
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -92,6 +92,7 @@ static inline void switch_setup(struct s
+ /* Init functions for supported Switch drivers */
+ extern void switch_psb697x_init(void);
+ extern void switch_adm6996i_init(void);
++extern void switch_ar8216_init(void);
+
+ #endif /* __SWITCH_H */
+
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch.svn-base
new file mode 100644
index 0000000..2582c16
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch.svn-base
@@ -0,0 +1,9496 @@
+From ed2effe0839929d00f05ec0e1e16fb467f324e1b Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Thu, 20 Dec 2012 19:05:54 +0100
+Subject: MIPS: add support for Lantiq XWAY SoCs
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/.gitignore
++++ b/.gitignore
+@@ -44,6 +44,13 @@
+ /u-boot.sb
+ /u-boot.geany
+ /include/u-boot.lst
++/u-boot.bin.lzma
++/u-boot.bin.lzo
++/u-boot.ltq.lzma.norspl
++/u-boot.ltq.lzo.norspl
++/u-boot.ltq.norspl
++/u-boot.lzma.img
++/u-boot.lzo.img
+
+ #
+ # Generated files
+--- a/Makefile
++++ b/Makefile
+@@ -441,6 +441,12 @@ $(obj)u-boot.bin: $(obj)u-boot
+ $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+ $(BOARD_SIZE_CHECK)
+
++$(obj)u-boot.bin.lzma: $(obj)u-boot.bin
++ cat $< | lzma -9 -f - > $@
++
++$(obj)u-boot.bin.lzo: $(obj)u-boot.bin
++ cat $< | lzop -9 -f - > $@
++
+ $(obj)u-boot.ldr: $(obj)u-boot
+ $(CREATE_LDR_ENV)
+ $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
+@@ -460,13 +466,23 @@ ifndef CONFIG_SYS_UBOOT_START
+ CONFIG_SYS_UBOOT_START := 0
+ endif
+
+-$(obj)u-boot.img: $(obj)u-boot.bin
+- $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
++define GEN_UBOOT_IMAGE
++ $(obj)tools/mkimage -A $(ARCH) -T firmware -C $(1) \
+ -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \
+ -e $(CONFIG_SYS_UBOOT_START) \
+ -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
+ sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
+ -d $< $@
++endef
++
++$(obj)u-boot.img: $(obj)u-boot.bin
++ $(call GEN_UBOOT_IMAGE,none)
++
++$(obj)u-boot.lzma.img: $(obj)u-boot.bin.lzma
++ $(call GEN_UBOOT_IMAGE,lzma)
++
++$(obj)u-boot.lzo.img: $(obj)u-boot.bin.lzo
++ $(call GEN_UBOOT_IMAGE,lzo)
+
+ $(obj)u-boot.imx: $(obj)u-boot.bin
+ $(obj)tools/mkimage -n $(CONFIG_IMX_CONFIG) -T imximage \
+@@ -549,6 +565,27 @@ endif
+ $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
+ cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@
+
++$(obj)u-boot.ltq.sfspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.lzo.sfspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
++ cat $(obj)spl/u-boot-spl.bin $< > $@
++
++$(obj)u-boot.ltq.lzo.norspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
++ cat $(obj)spl/u-boot-spl.bin $< > $@
++
++$(obj)u-boot.ltq.lzma.norspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
++ cat $(obj)spl/u-boot-spl.bin $< > $@
++
+ ifeq ($(CONFIG_SANDBOX),y)
+ GEN_UBOOT = \
+ cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
+--- a/README
++++ b/README
+@@ -460,6 +460,11 @@ The following options need to be configu
+ CONF_CM_CACHABLE_CUW
+ CONF_CM_CACHABLE_ACCELERATED
+
++ CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++ Enable this to use extended cache initialization for recent
++ MIPS CPU cores.
++
+ CONFIG_SYS_XWAY_EBU_BOOTCFG
+
+ Special option for Lantiq XWAY SoCs for booting from NOR flash.
+--- a/arch/mips/config.mk
++++ b/arch/mips/config.mk
+@@ -61,7 +61,10 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__M
+ # On the other hand, we want PIC in the U-Boot code to relocate it from ROM
+ # to RAM. $28 is always used as gp.
+ #
+-PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS)
++PF_ABICALLS ?= -mabicalls
++PF_PIC ?= -fpic
++
++PLATFORM_CPPFLAGS += -G 0 $(PF_ABICALLS) $(PF_PIC) $(ENDIANNESS)
+ PLATFORM_CPPFLAGS += -msoft-float
+ PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS)
+ PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
+--- a/arch/mips/cpu/mips32/cache.S
++++ b/arch/mips/cpu/mips32/cache.S
+@@ -45,7 +45,11 @@
+ */
+ #define MIPS_MAX_CACHE_SIZE 0x10000
+
++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
++#define INDEX_BASE 0x9fc00000
++#else
+ #define INDEX_BASE CKSEG0
++#endif
+
+ .macro cache_op op addr
+ .set push
+@@ -81,7 +85,11 @@
+ */
+ LEAF(mips_init_icache)
+ blez a1, 9f
++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
++ mtc0 zero, CP0_ITAGLO
++#else
+ mtc0 zero, CP0_TAGLO
++#endif
+ /* clear tag to invalidate */
+ PTR_LI t0, INDEX_BASE
+ PTR_ADDU t1, t0, a1
+@@ -106,7 +114,11 @@ LEAF(mips_init_icache)
+ */
+ LEAF(mips_init_dcache)
+ blez a1, 9f
++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
++ mtc0 zero, CP0_DTAGLO
++#else
+ mtc0 zero, CP0_TAGLO
++#endif
+ /* clear all tags */
+ PTR_LI t0, INDEX_BASE
+ PTR_ADDU t1, t0, a1
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/Makefile
+@@ -0,0 +1,33 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(SOC).o
++
++COBJS-y += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
++SOBJS-y += cgu_init.o mem_init.o
++
++COBJS := $(COBJS-y)
++SOBJS := $(SOBJS-y)
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
++
++all: $(LIB)
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/cgu.c
+@@ -0,0 +1,118 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_CGU_SYS_DDR_MASK 0x0003
++#define LTQ_CGU_SYS_DDR_SHIFT 0
++#define LTQ_CGU_SYS_CPU0_MASK 0x000C
++#define LTQ_CGU_SYS_CPU0_SHIFT 2
++#define LTQ_CGU_SYS_FPI_MASK 0x0040
++#define LTQ_CGU_SYS_FPI_SHIFT 6
++
++struct ltq_cgu_regs {
++ u32 rsvd0;
++ u32 pll0_cfg; /* PLL0 config */
++ u32 pll1_cfg; /* PLL1 config */
++ u32 pll2_cfg; /* PLL2 config */
++ u32 sys; /* System clock */
++ u32 update; /* CGU update control */
++ u32 if_clk; /* Interface clock */
++ u32 osc_con; /* Update OSC Control */
++ u32 smd; /* SDRAM Memory Control */
++ u32 rsvd1[3];
++ u32 pcm_cr; /* PCM control */
++ u32 pci_cr; /* PCI clock control */
++};
++
++static struct ltq_cgu_regs *ltq_cgu_regs =
++ (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
++
++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
++{
++ return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
++}
++
++unsigned long ltq_get_io_region_clock(void)
++{
++ u32 ddr_sel;
++ unsigned long clk;
++
++ ddr_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_DDR_MASK,
++ LTQ_CGU_SYS_DDR_SHIFT);
++
++ switch (ddr_sel) {
++ case 0:
++ clk = CLOCK_166_MHZ;
++ break;
++ case 1:
++ clk = CLOCK_133_MHZ;
++ break;
++ case 2:
++ clk = CLOCK_111_MHZ;
++ break;
++ case 3:
++ clk = CLOCK_83_MHZ;
++ break;
++ default:
++ clk = 0;
++ break;
++ }
++
++ return clk;
++}
++
++unsigned long ltq_get_cpu_clock(void)
++{
++ u32 cpu0_sel;
++ unsigned long clk;
++
++ cpu0_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU0_MASK,
++ LTQ_CGU_SYS_CPU0_SHIFT);
++
++ switch (cpu0_sel) {
++ /* Same as PLL0 output (333,33 MHz) */
++ case 0:
++ clk = CLOCK_333_MHZ;
++ break;
++ /* 1/1 fixed ratio to DDR clock */
++ case 1:
++ clk = ltq_get_io_region_clock();
++ break;
++ /* 1/2 fixed ratio to DDR clock */
++ case 2:
++ clk = ltq_get_io_region_clock() << 1;
++ break;
++ default:
++ clk = 0;
++ break;
++ }
++
++ return clk;
++}
++
++unsigned long ltq_get_bus_clock(void)
++{
++ u32 fpi_sel;
++ unsigned long clk;
++
++ fpi_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_FPI_MASK,
++ LTQ_CGU_SYS_FPI_SHIFT);
++
++ if (fpi_sel)
++ /* Half the DDR clock */
++ clk = ltq_get_io_region_clock() >> 1;
++ else
++ /* Same as DDR clock */
++ clk = ltq_get_io_region_clock();
++
++ return clk;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/cgu_init.S
+@@ -0,0 +1,143 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* RCU module register */
++#define LTQ_RCU_RST_REQ 0x0010
++#define LTQ_RCU_RST_STAT 0x0014
++#define LTQ_RCU_RST_REQ_VALUE 0x40000008
++#define LTQ_RCU_RST_STAT_XTAL_F 0x20000
++
++/* CGU module register */
++#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
++#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
++#define LTQ_CGU_PLL2_CFG 0x000C /* PLL2 config */
++#define LTQ_CGU_SYS 0x0010 /* System clock */
++
++/* Valid SYS.CPU0/1 values */
++#define LTQ_CGU_SYS_CPU0_SHIFT 2
++#define LTQ_CGU_SYS_CPU1_SHIFT 4
++#define LTQ_CGU_SYS_CPU_PLL0 0x0
++#define LTQ_CGU_SYS_CPU_DDR_EQUAL 0x1
++#define LTQ_CGU_SYS_CPU_DDR_TWICE 0x2
++
++/* Valid SYS.DDR values */
++#define LTQ_CGU_SYS_DDR_SHIFT 0
++#define LTQ_CGU_SYS_DDR_167_MHZ 0x0
++#define LTQ_CGU_SYS_DDR_133_MHZ 0x1
++#define LTQ_CGU_SYS_DDR_111_MHZ 0x2
++#define LTQ_CGU_SYS_DDR_83_MHZ 0x3
++
++/* Valid SYS.FPI values */
++#define LTQ_CGU_SYS_FPI_SHIFT 6
++#define LTQ_CGU_SYS_FPI_DDR_EQUAL 0x0
++#define LTQ_CGU_SYS_FPI_DDR_HALF 0x1
++
++/* Valid SYS.PPE values */
++#define LTQ_CGU_SYS_PPE_SHIFT 7
++#define LTQ_CGU_SYS_PPE_266_MHZ 0x0
++#define LTQ_CGU_SYS_PPE_240_MHZ 0x1
++#define LTQ_CGU_SYS_PPE_222_MHZ 0x2
++#define LTQ_CGU_SYS_PPE_133_MHZ 0x3
++
++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167)
++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_TWICE
++#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_167_MHZ
++#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
++#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_266_MHZ
++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111)
++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_EQUAL
++#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_111_MHZ
++#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
++#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_133_MHZ
++#else
++#error "Invalid system clock configuration!"
++#endif
++
++/* Build register values */
++#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_PPE_CONFIG << \
++ LTQ_CGU_SYS_PPE_SHIFT) | \
++ (LTQ_CGU_SYS_FPI_CONFIG << \
++ LTQ_CGU_SYS_FPI_SHIFT) | \
++ (LTQ_CGU_SYS_CPU_CONFIG << \
++ LTQ_CGU_SYS_CPU1_SHIFT) | \
++ (LTQ_CGU_SYS_CPU_CONFIG << \
++ LTQ_CGU_SYS_CPU0_SHIFT) | \
++ LTQ_CGU_SYS_DDR_CONFIG)
++
++/* Reset values for PLL registers for usage with 35.328 MHz crystal */
++#define PLL0_35MHZ_CONFIG 0x9D861059
++#define PLL1_35MHZ_CONFIG 0x1A260CD9
++#define PLL2_35MHZ_CONFIG 0x8000f1e5
++
++/* Reset values for PLL registers for usage with 36 MHz crystal */
++#define PLL0_36MHZ_CONFIG 0x1000125D
++#define PLL1_36MHZ_CONFIG 0x1B1E0C99
++#define PLL2_36MHZ_CONFIG 0x8002f2a1
++
++LEAF(ltq_cgu_init)
++ /* Load current CGU register value */
++ li t0, (LTQ_CGU_BASE | KSEG1)
++ lw t1, LTQ_CGU_SYS(t0)
++
++ /* Load target CGU register values */
++ li t3, LTQ_CGU_SYS_VALUE
++
++ /* Only update registers if values differ */
++ beq t1, t3, finished
++
++ /*
++ * Check whether the XTAL_F bit in RST_STAT register is set or not.
++ * This bit is latched in via pin strapping. If bit is set then
++ * clock source is a 36 MHz crystal. Otherwise a 35.328 MHz crystal.
++ */
++ li t1, (LTQ_RCU_BASE | KSEG1)
++ lw t2, LTQ_RCU_RST_STAT(t1)
++ and t2, t2, LTQ_RCU_RST_STAT_XTAL_F
++ beq t2, LTQ_RCU_RST_STAT_XTAL_F, boot_36mhz
++
++boot_35mhz:
++ /* Configure PLL for 35.328 MHz */
++ li t2, PLL0_35MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL0_CFG(t0)
++ li t2, PLL1_35MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL1_CFG(t0)
++ li t2, PLL2_35MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL2_CFG(t0)
++
++ b do_reset
++
++boot_36mhz:
++ /* Configure PLL for 36 MHz */
++ li t2, PLL0_36MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL0_CFG(t0)
++ li t2, PLL1_36MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL1_CFG(t0)
++ li t2, PLL2_36MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL2_CFG(t0)
++
++do_reset:
++ /* Store new clock config */
++ sw t3, LTQ_CGU_SYS(t0)
++
++ /* Perform software reset to activate new clock config */
++ li t2, LTQ_RCU_RST_REQ_VALUE
++ sw t2, LTQ_RCU_RST_REQ(t1)
++
++wait_reset:
++ b wait_reset
++
++finished:
++ jr ra
++
++ END(ltq_cgu_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/chipid.c
+@@ -0,0 +1,60 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_CHIPID_VERSION_SHIFT 28
++#define LTQ_CHIPID_VERSION_MASK (0xF << LTQ_CHIPID_VERSION_SHIFT)
++#define LTQ_CHIPID_PNUM_SHIFT 12
++#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
++
++struct ltq_chipid_regs {
++ u32 manid; /* Manufacturer identification */
++ u32 chipid; /* Chip identification */
++};
++
++static struct ltq_chipid_regs *ltq_chipid_regs =
++ (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
++
++unsigned int ltq_chip_version_get(void)
++{
++ u32 chipid;
++
++ chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++ return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
++}
++
++unsigned int ltq_chip_partnum_get(void)
++{
++ u32 chipid;
++
++ chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++ return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
++}
++
++const char *ltq_chip_partnum_str(void)
++{
++ enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
++
++ switch (partnum) {
++ case LTQ_SOC_DANUBE:
++ return "Danube";
++ case LTQ_SOC_DANUBE_S:
++ return "Danube-S";
++ case LTQ_SOC_TWINPASS:
++ return "Twinpass";
++ default:
++ printf("Unknown partnum: %x\n", partnum);
++ }
++
++ return "";
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/config.mk
+@@ -0,0 +1,27 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,)
++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE)
++
++ifdef CONFIG_SPL_BUILD
++PF_ABICALLS := -mno-abicalls
++PF_PIC := -fno-pic
++USE_PRIVATE_LIBGCC := yes
++endif
++
++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
++
++ifndef CONFIG_SPL_BUILD
++ifdef CONFIG_SYS_BOOT_NORSPL
++ALL-y += $(obj)u-boot.ltq.norspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
++endif
++endif
++
++LDSCRIPT := $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot.lds
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/ebu.c
+@@ -0,0 +1,51 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_EBU_CON_0_RST_VAL 0x8001F7FF
++
++#define LTQ_EBU_CON_WRDIS (1 << 31)
++
++struct ltq_ebu_regs {
++ u32 clc;
++ u32 rsvd0[3];
++ u32 con;
++ u32 rsvd1[3];
++ u32 addr_sel_0;
++ u32 addr_sel_1;
++ u32 rsvd2[14];
++ u32 con_0;
++ u32 con_1;
++};
++
++static struct ltq_ebu_regs *ltq_ebu_regs =
++ (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
++
++void ltq_ebu_init(void)
++{
++ /*
++ * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
++ * region control. This supports up to 32 MiB NOR flash in
++ * bank 0.
++ */
++ ltq_writel(&ltq_ebu_regs->addr_sel_0, 0x10000011);
++
++ /*
++ * Restore reset value to fix modifications by internal BootROM.
++ * Also disable write protection.
++ */
++ ltq_writel(&ltq_ebu_regs->con_0,
++ LTQ_EBU_CON_0_RST_VAL & ~LTQ_EBU_CON_WRDIS);
++}
++
++void *flash_swap_addr(unsigned long addr)
++{
++ return (void *)(addr ^ 2);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/mem.c
+@@ -0,0 +1,31 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
++
++static inline u32 ltq_mc_dc_read(u32 index)
++{
++ return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
++}
++
++phys_size_t initdram(int board_type)
++{
++ u32 col, row, dc04, dc19, dc20;
++
++ dc04 = ltq_mc_dc_read(4);
++ dc19 = ltq_mc_dc_read(19);
++ dc20 = ltq_mc_dc_read(20);
++
++ row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
++ col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
++
++ return (1 << (row + col)) * 4 * 2;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/mem_init.S
+@@ -0,0 +1,115 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* Must be configured in BOARDDIR */
++#include <ddr_settings.h>
++
++#define LTQ_MC_GEN_ERRCAUSE 0x0010
++#define LTQ_MC_GEN_ERRADDR 0x0020
++#define LTQ_MC_GEN_CON 0x0060
++#define LTQ_MC_GEN_STAT 0x0070
++#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE 0x5
++#define LTQ_MC_GEN_STAT_DLCK_PWRON 0xC
++
++#define LTQ_MC_DDR_DC03_MC_START 0x100
++
++ /* Store given value in MC DDR CCRx register */
++ .macro dc_sw num, val
++ li t2, \val
++ sw t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
++ .endm
++
++LEAF(ltq_mem_init)
++ /* Load MC General and MC DDR module base */
++ li t0, (LTQ_MC_GEN_BASE | KSEG1)
++ li t1, (LTQ_MC_DDR_BASE | KSEG1)
++
++ /* Clear access error log registers */
++ sw zero, LTQ_MC_GEN_ERRCAUSE(t0)
++ sw zero, LTQ_MC_GEN_ERRADDR(t0)
++
++ /* Enable DDR and SRAM module in memory controller */
++ li t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE
++ sw t2, LTQ_MC_GEN_CON(t0)
++
++ /* Clear start bit of DDR memory controller */
++ sw zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
++
++ /* Init memory controller registers with values ddr_settings.h */
++ dc_sw 0, MC_DC00_VALUE
++ dc_sw 1, MC_DC01_VALUE
++ dc_sw 2, MC_DC02_VALUE
++ dc_sw 4, MC_DC04_VALUE
++ dc_sw 5, MC_DC05_VALUE
++ dc_sw 6, MC_DC06_VALUE
++ dc_sw 7, MC_DC07_VALUE
++ dc_sw 8, MC_DC08_VALUE
++ dc_sw 9, MC_DC09_VALUE
++
++ dc_sw 10, MC_DC10_VALUE
++ dc_sw 11, MC_DC11_VALUE
++ dc_sw 12, MC_DC12_VALUE
++ dc_sw 13, MC_DC13_VALUE
++ dc_sw 14, MC_DC14_VALUE
++ dc_sw 15, MC_DC15_VALUE
++ dc_sw 16, MC_DC16_VALUE
++ dc_sw 17, MC_DC17_VALUE
++ dc_sw 18, MC_DC18_VALUE
++ dc_sw 19, MC_DC19_VALUE
++
++ dc_sw 20, MC_DC20_VALUE
++ dc_sw 21, MC_DC21_VALUE
++ dc_sw 22, MC_DC22_VALUE
++ dc_sw 23, MC_DC23_VALUE
++ dc_sw 24, MC_DC24_VALUE
++ dc_sw 25, MC_DC25_VALUE
++ dc_sw 26, MC_DC26_VALUE
++ dc_sw 27, MC_DC27_VALUE
++ dc_sw 28, MC_DC28_VALUE
++ dc_sw 29, MC_DC29_VALUE
++
++ dc_sw 30, MC_DC30_VALUE
++ dc_sw 31, MC_DC31_VALUE
++ dc_sw 32, MC_DC32_VALUE
++ dc_sw 33, MC_DC33_VALUE
++ dc_sw 34, MC_DC34_VALUE
++ dc_sw 35, MC_DC35_VALUE
++ dc_sw 36, MC_DC36_VALUE
++ dc_sw 37, MC_DC37_VALUE
++ dc_sw 38, MC_DC38_VALUE
++ dc_sw 39, MC_DC39_VALUE
++
++ dc_sw 40, MC_DC40_VALUE
++ dc_sw 41, MC_DC41_VALUE
++ dc_sw 42, MC_DC42_VALUE
++ dc_sw 43, MC_DC43_VALUE
++ dc_sw 44, MC_DC44_VALUE
++ dc_sw 45, MC_DC45_VALUE
++ dc_sw 46, MC_DC46_VALUE
++
++ /* Set start bit of DDR memory controller */
++ li t2, LTQ_MC_DDR_DC03_MC_START
++ sw t2, LTQ_MC_DDR_DC_OFFSET(3)(t1)
++
++ /* Wait until DLL has locked and core is ready for data transfers */
++wait_ready:
++ lw t2, LTQ_MC_GEN_STAT(t0)
++ li t3, LTQ_MC_GEN_STAT_DLCK_PWRON
++ and t2, t3
++ bne t2, t3, wait_ready
++
++finished:
++ jr ra
++
++ END(ltq_mem_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/pmu.c
+@@ -0,0 +1,118 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PMU_PWDCR_RESERVED 0xFD0C001C
++
++#define LTQ_PMU_PWDCR_TDM (1 << 25)
++#define LTQ_PMU_PWDCR_PPE_ENET0 (1 << 23)
++#define LTQ_PMU_PWDCR_PPE_ENET1 (1 << 22)
++#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
++#define LTQ_PMU_PWDCR_DEU (1 << 20)
++#define LTQ_PMU_PWDCR_UART1 (1 << 17)
++#define LTQ_PMU_PWDCR_SDIO (1 << 16)
++#define LTQ_PMU_PWDCR_AHB (1 << 15)
++#define LTQ_PMU_PWDCR_FPI0 (1 << 14)
++#define LTQ_PMU_PWDCR_PPE (1 << 13)
++#define LTQ_PMU_PWDCR_GPTC (1 << 12)
++#define LTQ_PMU_PWDCR_LEDC (1 << 11)
++#define LTQ_PMU_PWDCR_EBU (1 << 10)
++#define LTQ_PMU_PWDCR_DSL (1 << 9)
++#define LTQ_PMU_PWDCR_SPI (1 << 8)
++#define LTQ_PMU_PWDCR_UART0 (1 << 7)
++#define LTQ_PMU_PWDCR_USB (1 << 6)
++#define LTQ_PMU_PWDCR_DMA (1 << 5)
++#define LTQ_PMU_PWDCR_FPI1 (1 << 1)
++#define LTQ_PMU_PWDCR_USB_PHY (1 << 0)
++
++struct ltq_pmu_regs {
++ u32 rsvd0[7];
++ u32 pwdcr;
++ u32 sr;
++ u32 pwdcr1;
++ u32 sr1;
++};
++
++static struct ltq_pmu_regs *ltq_pmu_regs =
++ (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
++
++u32 ltq_pm_map(enum ltq_pm_modules module)
++{
++ u32 val;
++
++ switch (module) {
++ case LTQ_PM_CORE:
++ val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 |
++ LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
++ break;
++ case LTQ_PM_DMA:
++ val = LTQ_PMU_PWDCR_DMA;
++ break;
++ case LTQ_PM_ETH:
++ val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC |
++ LTQ_PMU_PWDCR_PPE;
++ break;
++ case LTQ_PM_SPI:
++ val = LTQ_PMU_PWDCR_SPI;
++ break;
++ default:
++ val = 0;
++ break;
++ }
++
++ return val;
++}
++
++int ltq_pm_enable(enum ltq_pm_modules module)
++{
++ const unsigned long timeout = 1000;
++ unsigned long timebase;
++ u32 sr, val;
++
++ val = ltq_pm_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
++
++ timebase = get_timer(0);
++
++ do {
++ sr = ltq_readl(&ltq_pmu_regs->sr);
++ if (~sr & val)
++ return 0;
++ } while (get_timer(timebase) < timeout);
++
++ return 1;
++}
++
++int ltq_pm_disable(enum ltq_pm_modules module)
++{
++ u32 val;
++
++ val = ltq_pm_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_setbits(&ltq_pmu_regs->pwdcr, val);
++
++ return 0;
++}
++
++void ltq_pmu_init(void)
++{
++ u32 set, clr;
++
++ clr = ltq_pm_map(LTQ_PM_CORE);
++ set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
++
++ ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/rcu.c
+@@ -0,0 +1,126 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
++#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
++#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
++#define LTQ_RCU_RD_DFE_AFE (1 << 12) /* Voice DFE/AFE */
++#define LTQ_RCU_RD_DSL_AFE (1 << 11) /* DSL AFE */
++#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
++#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
++#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
++#define LTQ_RCU_RD_ARC_DFE (1 << 7) /* ARC/DFE core */
++#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
++#define LTQ_RCU_RD_ENET_MAC1 (1 << 5) /* Ethernet MAC1 */
++#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
++#define LTQ_RCU_RD_CPU1 (1 << 3) /* CPU1 subsystem */
++#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
++#define LTQ_RCU_RD_CPU0 (1 << 1) /* CPU0 subsystem */
++#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
++
++#define LTQ_RCU_STAT_BOOT_SHIFT 18
++#define LTQ_RCU_STAT_BOOT_MASK (0x7 << LTQ_RCU_STAT_BOOT_SHIFT)
++
++struct ltq_rcu_regs {
++ u32 rsvd0[4];
++ u32 req; /* Reset request */
++ u32 stat; /* Reset status */
++ u32 usb_cfg; /* USB configure */
++ u32 rsvd1[2];
++ u32 pci_rdy; /* PCI boot ready */
++};
++
++static struct ltq_rcu_regs *ltq_rcu_regs =
++ (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
++
++u32 ltq_reset_map(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ switch (module) {
++ case LTQ_RESET_CORE:
++ case LTQ_RESET_SOFT:
++ val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1;
++ break;
++ case LTQ_RESET_DMA:
++ val = LTQ_RCU_RD_DMA;
++ break;
++ case LTQ_RESET_ETH:
++ val = LTQ_RCU_RD_PPE;
++ break;
++ case LTQ_RESET_HARD:
++ val = LTQ_RCU_RD_HRST;
++ break;
++ default:
++ val = 0;
++ break;
++ }
++
++ return val;
++}
++
++int ltq_reset_activate(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ val = ltq_reset_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_setbits(&ltq_rcu_regs->req, val);
++
++ return 0;
++}
++
++int ltq_reset_deactivate(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ val = ltq_reset_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_clrbits(&ltq_rcu_regs->req, val);
++
++ return 0;
++}
++
++enum ltq_boot_select ltq_boot_select(void)
++{
++ u32 stat;
++ unsigned int bootstrap;
++
++ stat = ltq_readl(&ltq_rcu_regs->stat);
++ bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
++
++ switch (bootstrap) {
++ case 0:
++ return BOOT_NOR_NO_BOOTROM;
++ case 1:
++ return BOOT_NOR;
++ case 2:
++ return BOOT_MII0;
++ case 3:
++ return BOOT_PCI;
++ case 4:
++ return BOOT_UART;
++ case 5:
++ return BOOT_SPI;
++ case 6:
++ return BOOT_NAND;
++ case 7:
++ return BOOT_RMII0;
++ default:
++ return BOOT_UNKNOWN;
++ }
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/u-boot.lds
+@@ -0,0 +1,69 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
++OUTPUT_ARCH(mips)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++
++ . = ALIGN(4);
++ .text : {
++ *(.text*)
++ }
++
++ . = ALIGN(4);
++ .rodata : {
++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
++ }
++
++ . = ALIGN(4);
++ .data : {
++ *(.data*)
++ }
++
++ . = ALIGN(4);
++ .sdata : {
++ *(.sdata*)
++ }
++
++ . = .;
++ _gp = ALIGN(16) + 0x7ff0;
++
++ .got : {
++ __got_start = .;
++ *(.got)
++ __got_end = .;
++ }
++
++ num_got_entries = (__got_end - __got_start) >> 2;
++
++#ifndef CONFIG_SPL_BUILD
++ . = ALIGN(4);
++ .u_boot_list : {
++ #include <u-boot.lst>
++ }
++#endif
++
++ . = ALIGN(4);
++ __image_copy_end = .;
++ uboot_end_data = .;
++
++ .bss (NOLOAD) : {
++ __bss_start = .;
++ *(.bss*)
++ *(.sbss*)
++ . = ALIGN(4);
++ __bss_end = .;
++ }
++
++ . = ALIGN(4);
++ __end = .;
++ uboot_end = .;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/Makefile
+@@ -0,0 +1,36 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)liblantiq-common.o
++
++START = start.o
++COBJS-y = cpu.o pmu.o
++COBJS-$(CONFIG_SPL_BUILD) += spl.o
++SOBJS-y = lowlevel_init.o
++
++COBJS := $(COBJS-y)
++SOBJS := $(SOBJS-y)
++SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
++START := $(addprefix $(obj),$(START))
++
++all: $(LIB)
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
+@@ -0,0 +1,60 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++
++static const char ltq_bootsel_strings[][16] = {
++ "NOR",
++ "NOR w/o BootROM",
++ "UART",
++ "UART w/o EEPROM",
++ "SPI",
++ "NAND",
++ "PCI",
++ "MII0",
++ "RMII0",
++ "RGMII1",
++ "unknown",
++};
++
++const char *ltq_boot_select_str(void)
++{ enum ltq_boot_select bootsel = ltq_boot_select();
++
++ if (bootsel > BOOT_UNKNOWN)
++ bootsel = BOOT_UNKNOWN;
++
++ return ltq_bootsel_strings[bootsel];
++}
++
++void ltq_chip_print_info(void)
++{
++ char buf[32];
++
++ printf("SoC: Lantiq %s v1.%u\n", ltq_chip_partnum_str(),
++ ltq_chip_version_get());
++ printf("CPU: %s MHz\n", strmhz(buf, ltq_get_cpu_clock()));
++ printf("IO: %s MHz\n", strmhz(buf, ltq_get_io_region_clock()));
++ printf("BUS: %s MHz\n", strmhz(buf, ltq_get_bus_clock()));
++ printf("BOOT: %s\n", ltq_boot_select_str());
++}
++
++int arch_cpu_init(void)
++{
++ ltq_pmu_init();
++ ltq_ebu_init();
++
++ return 0;
++}
++
++void _machine_restart(void)
++{
++ ltq_reset_activate(LTQ_RESET_CORE);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
+@@ -0,0 +1,21 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <asm/asm.h>
++#include <asm/regdef.h>
++
++NESTED(lowlevel_init, 0, ra)
++ move t8, ra
++
++ la t7, ltq_cgu_init
++ jalr t7
++
++ la t7, ltq_mem_init
++ jalr t7
++
++ jr t8
++ END(lowlevel_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c
+@@ -0,0 +1,10 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/pm.h>
++
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/spl.c
+@@ -0,0 +1,385 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <image.h>
++#include <version.h>
++#include <spi_flash.h>
++#include <linux/compiler.h>
++#include <lzma/LzmaDec.h>
++#include <linux/lzo.h>
++#include <asm/mipsregs.h>
++
++#if defined(CONFIG_LTQ_SPL_CONSOLE)
++#define spl_has_console 1
++
++#if defined(CONFIG_LTQ_SPL_DEBUG)
++#define spl_has_debug 1
++#else
++#define spl_has_debug 0
++#endif
++
++#else
++#define spl_has_console 0
++#endif
++
++#define spl_debug(fmt, args...) \
++ do { \
++ if (spl_has_debug) \
++ printf(fmt, ##args); \
++ } while (0)
++
++#define spl_puts(msg) \
++ do { \
++ if (spl_has_console) \
++ puts(msg); \
++ } while (0)
++
++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
++#define spl_boot_spi_flash 1
++#else
++#define spl_boot_spi_flash 0
++#ifndef CONFIG_SPL_SPI_BUS
++#define CONFIG_SPL_SPI_BUS 0
++#endif
++#ifndef CONFIG_SPL_SPI_CS
++#define CONFIG_SPL_SPI_CS 0
++#endif
++#ifndef CONFIG_SPL_SPI_MAX_HZ
++#define CONFIG_SPL_SPI_MAX_HZ 0
++#endif
++#ifndef CONFIG_SPL_SPI_MODE
++#define CONFIG_SPL_SPI_MODE 0
++#endif
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
++#define spl_boot_nor_flash 1
++#else
++#define spl_boot_nor_flash 0
++#endif
++
++#define spl_sync() __asm__ __volatile__("sync");
++
++struct spl_image {
++ ulong data_addr;
++ ulong entry_addr;
++ size_t data_size;
++ size_t entry_size;
++ u8 comp;
++};
++
++extern ulong __image_copy_end;
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/* Emulated malloc area needed for LZMA allocator in BSS */
++static u8 *spl_mem_ptr __maybe_unused;
++static size_t spl_mem_size __maybe_unused;
++
++static int spl_is_comp_lzma(const struct spl_image *spl)
++{
++#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
++ return spl->comp == IH_COMP_LZMA;
++#else
++ return 0;
++#endif
++}
++
++static int spl_is_comp_lzo(const struct spl_image *spl)
++{
++#if defined(CONFIG_LTQ_SPL_COMP_LZO)
++ return spl->comp == IH_COMP_LZO;
++#else
++ return 0;
++#endif
++}
++
++static int spl_is_compressed(const struct spl_image *spl)
++{
++ if (spl_is_comp_lzma(spl))
++ return 1;
++
++ if (spl_is_comp_lzo(spl))
++ return 1;
++
++ return 0;
++}
++
++static void spl_console_init(void)
++{
++ if (!spl_has_console)
++ return;
++
++ gd->flags |= GD_FLG_RELOC;
++ gd->baudrate = CONFIG_BAUDRATE;
++
++ serial_init();
++
++ gd->have_console = 1;
++
++ spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
++ U_BOOT_TIME ")\n");
++}
++
++static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl)
++{
++ u32 magic;
++
++ spl_puts("SPL: checking U-Boot image\n");
++
++ magic = image_get_magic(hdr);
++ if (magic != IH_MAGIC)
++ return -1;
++
++ spl->data_addr += image_get_header_size();
++ spl->entry_addr = image_get_load(hdr);
++ spl->data_size = image_get_data_size(hdr);
++ spl->comp = image_get_comp(hdr);
++
++ spl_debug("SPL: data %08lx, size %zu, entry %08lx, comp %u\n",
++ spl->data_addr, spl->data_size, spl->entry_addr, spl->comp);
++
++ return 0;
++}
++
++static void *spl_lzma_alloc(void *p, size_t size)
++{
++ u8 *ret;
++
++ if (size > spl_mem_size)
++ return NULL;
++
++ ret = spl_mem_ptr;
++ spl_mem_ptr += size;
++ spl_mem_size -= size;
++
++ return ret;
++}
++
++static void spl_lzma_free(void *p, void *addr)
++{
++}
++
++static int spl_copy_image(struct spl_image *spl)
++{
++ spl_puts("SPL: copying U-Boot to RAM\n");
++
++ memcpy((void *) spl->entry_addr, (const void *) spl->data_addr,
++ spl->data_size);
++
++ spl->entry_size = spl->data_size;
++
++ return 0;
++}
++
++static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr)
++{
++ SRes res;
++ const Byte *prop = (const Byte *) loadaddr;
++ const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE +
++ sizeof(uint64_t);
++ Byte *dest = (Byte *) spl->entry_addr;
++ SizeT dest_len = 0xFFFFFFFF;
++ SizeT src_len = spl->data_size - LZMA_PROPS_SIZE;
++ ELzmaStatus status = 0;
++ ISzAlloc alloc;
++
++ spl_puts("SPL: decompressing U-Boot with LZMA\n");
++
++ alloc.Alloc = spl_lzma_alloc;
++ alloc.Free = spl_lzma_free;
++ spl_mem_ptr = (u8 *) CONFIG_SPL_MALLOC_BASE;
++ spl_mem_size = CONFIG_SPL_MALLOC_MAX_SIZE;
++
++ res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE,
++ LZMA_FINISH_ANY, &status, &alloc);
++ if (res != SZ_OK)
++ return 1;
++
++ spl->entry_size = dest_len;
++
++ return 0;
++}
++
++static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr)
++{
++ size_t len;
++ int ret;
++
++ spl_puts("SPL: decompressing U-Boot with LZO\n");
++
++ ret = lzop_decompress(
++ (const unsigned char*) loadaddr, spl->data_size,
++ (unsigned char *) spl->entry_addr, &len);
++
++ spl->entry_size = len;
++
++ return ret;
++}
++
++static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr)
++{
++ int ret;
++
++ if (spl_is_comp_lzma(spl))
++ ret = spl_uncompress_lzma(spl, loadaddr);
++ else if (spl_is_comp_lzo(spl))
++ ret = spl_uncompress_lzo(spl, loadaddr);
++ else
++ ret = 1;
++
++ return ret;
++}
++
++static int spl_load_spi_flash(struct spl_image *spl)
++{
++ struct spi_flash sf;
++ image_header_t hdr;
++ int ret;
++ unsigned long loadaddr;
++
++ /*
++ * Image format:
++ *
++ * - 12 byte non-volatile bootstrap header
++ * - SPL binary
++ * - 12 byte non-volatile bootstrap header
++ * - 64 byte U-Boot mkimage header
++ * - U-Boot binary
++ */
++ spl->data_addr = (ulong) &__image_copy_end - CONFIG_SPL_TEXT_BASE + 24;
++
++ spl_puts("SPL: probing SPI flash\n");
++
++ spi_init();
++ ret = spi_flash_probe_spl(&sf, CONFIG_SPL_SPI_BUS, CONFIG_SPL_SPI_CS,
++ CONFIG_SPL_SPI_MAX_HZ, CONFIG_SPL_SPI_MODE);
++ if (ret)
++ return ret;
++
++ spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr);
++
++ ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr);
++ if (ret)
++ return ret;
++
++ spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr);
++
++ ret = spl_parse_image(&hdr, spl);
++ if (ret)
++ return ret;
++
++ if (spl_is_compressed(spl))
++ loadaddr = CONFIG_LOADADDR;
++ else
++ loadaddr = spl->entry_addr;
++
++ spl_puts("SPL: loading U-Boot to RAM\n");
++
++ ret = spi_flash_read(&sf, spl->data_addr, spl->data_size,
++ (void *) loadaddr);
++
++ if (spl_is_compressed(spl))
++ ret = spl_uncompress(spl, loadaddr);
++
++ return ret;
++}
++
++static int spl_load_nor_flash(struct spl_image *spl)
++{
++ const image_header_t *hdr;
++ int ret;
++
++ /*
++ * Image format:
++ *
++ * - SPL binary
++ * - 64 byte U-Boot mkimage header
++ * - U-Boot binary
++ */
++ spl->data_addr = (ulong) &__image_copy_end;
++ hdr = (const image_header_t *) &__image_copy_end;
++
++ spl_debug("SPL: checking image header at address %p\n", hdr);
++
++ ret = spl_parse_image(hdr, spl);
++ if (ret)
++ return ret;
++
++ if (spl_is_compressed(spl))
++ ret = spl_uncompress(spl, spl->data_addr);
++ else
++ ret = spl_copy_image(spl);
++
++ return ret;
++}
++
++static int spl_load(struct spl_image *spl)
++{
++ int ret;
++
++ if (spl_boot_spi_flash)
++ ret = spl_load_spi_flash(spl);
++ else if (spl_boot_nor_flash)
++ ret = spl_load_nor_flash(spl);
++ else
++ ret = 1;
++
++ return ret;
++}
++
++void __noreturn spl_lantiq_init(void)
++{
++ void (*uboot)(void) __noreturn;
++ struct spl_image spl;
++ gd_t gd_data;
++ int ret;
++
++ gd = &gd_data;
++ barrier();
++ memset((void *)gd, 0, sizeof(gd_t));
++
++ spl_console_init();
++
++ spl_debug("SPL: initializing\n");
++
++#if 0
++ spl_debug("CP0_CONFIG: %08x\n", read_c0_config());
++ spl_debug("CP0_CONFIG1: %08x\n", read_c0_config1());
++ spl_debug("CP0_CONFIG2: %08x\n", read_c0_config2());
++ spl_debug("CP0_CONFIG3: %08x\n", read_c0_config3());
++ spl_debug("CP0_CONFIG6: %08x\n", read_c0_config6());
++ spl_debug("CP0_CONFIG7: %08x\n", read_c0_config7());
++ spl_debug("CP0_STATUS: %08x\n", read_c0_status());
++ spl_debug("CP0_PRID: %08x\n", read_c0_prid());
++#endif
++
++ board_early_init_f();
++ timer_init();
++
++ memset(&spl, 0, sizeof(spl));
++
++ ret = spl_load(&spl);
++ if (ret)
++ goto hang;
++
++ spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr);
++ spl_puts("SPL: jumping to U-Boot\n");
++
++ flush_cache(spl.entry_addr, spl.entry_size);
++ spl_sync();
++
++ uboot = (void *) spl.entry_addr;
++ uboot();
++
++hang:
++ spl_puts("SPL: cannot start U-Boot\n");
++
++ for (;;)
++ ;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/start.S
+@@ -0,0 +1,144 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2003 Wolfgang Denk, wd@denx.de
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/regdef.h>
++#include <asm/mipsregs.h>
++
++#define S_PRIdCoID 16 /* Company ID (R) */
++#define M_PRIdCoID (0xff << S_PRIdCoID)
++#define S_PRIdImp 8 /* Implementation ID (R) */
++#define M_PRIdImp (0xff << S_PRIdImp)
++
++#define K_CacheAttrCWTnWA 0 /* Cacheable, write-thru, no write allocate */
++#define K_CacheAttrCWTWA 1 /* Cacheable, write-thru, write allocate */
++#define K_CacheAttrU 2 /* Uncached */
++#define K_CacheAttrC 3 /* Cacheable */
++#define K_CacheAttrCN 3 /* Cacheable, non-coherent */
++#define K_CacheAttrCCE 4 /* Cacheable, coherent, exclusive */
++#define K_CacheAttrCCS 5 /* Cacheable, coherent, shared */
++#define K_CacheAttrCCU 6 /* Cacheable, coherent, update */
++#define K_CacheAttrUA 7 /* Uncached accelerated */
++
++#define S_ConfigK23 28 /* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */
++#define M_ConfigK23 (0x7 << S_ConfigK23)
++#define W_ConfigK23 3
++#define S_ConfigKU 25 /* Kuseg coherency algorithm (FM MMU only) (R/W) */
++#define M_ConfigKU (0x7 << S_ConfigKU)
++#define W_ConfigKU 3
++
++#define S_ConfigMM 18 /* Merge mode (implementation specific) */
++#define M_ConfigMM (0x1 << S_ConfigMM)
++
++#define S_StatusBEV 22 /* Enable Boot Exception Vectors (R/W) */
++#define M_StatusBEV (0x1 << S_StatusBEV)
++
++#define S_StatusFR 26 /* Enable 64-bit FPRs (R/W) */
++#define M_StatusFR (0x1 << S_StatusFR)
++
++#define S_ConfigK0 0 /* Kseg0 coherency algorithm (R/W) */
++#define M_ConfigK0 (0x7 << S_ConfigK0)
++
++#define CONFIG0_MIPS32_64_MSK 0x8000ffff
++#define STATUS_MIPS32_64_MSK 0xfffcffff
++
++#define STATUS_MIPS24K 0
++#define CONFIG0_MIPS24K ((K_CacheAttrCN << S_ConfigK23) |\
++ (K_CacheAttrCN << S_ConfigKU) |\
++ (M_ConfigMM))
++
++#define STATUS_MIPS34K 0
++#define CONFIG0_MIPS34K ((K_CacheAttrCN << S_ConfigK23) |\
++ (K_CacheAttrCN << S_ConfigKU) |\
++ (M_ConfigMM))
++
++#define STATUS_MIPS32_64 (M_StatusBEV | M_StatusFR)
++#define CONFIG0_MIPS32_64 (K_CacheAttrCN << S_ConfigK0)
++
++#ifdef CONFIG_SOC_XWAY_DANUBE
++#define CONFIG0_LANTIQ (CONFIG0_MIPS24K | CONFIG0_MIPS32_64)
++#define STATUS_LANTIQ (STATUS_MIPS24K | STATUS_MIPS32_64)
++#endif
++
++#ifdef CONFIG_SOC_XWAY_VRX200
++#define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
++#define STATUS_LANTIQ (STATUS_MIPS34K | STATUS_MIPS32_64)
++#endif
++
++
++ .set noreorder
++
++ .globl _start
++ .text
++_start:
++ /* Entry point */
++ b main
++ nop
++
++ /* Lantiq SoC Boot config word */
++ .org 0x10
++#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
++ .word CONFIG_SYS_XWAY_EBU_BOOTCFG
++#else
++ .word 0
++#endif
++ .word 0
++
++ .align 4
++main:
++
++ /* Init Timer */
++ mtc0 zero, CP0_COUNT
++ mtc0 zero, CP0_COMPARE
++
++ /* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */
++ mfc0 t0, CP0_CONFIG
++ li t1, CONFIG0_MIPS32_64_MSK
++ and t0, t1
++ li t1, CONFIG0_LANTIQ
++ or t0, t1
++ mtc0 t0, CP0_CONFIG
++
++ mfc0 t0, CP0_STATUS
++ li t1, STATUS_MIPS32_64_MSK
++ and t0, t1
++ li t1, STATUS_LANTIQ
++ or t0, t1
++ mtc0 t0, CP0_STATUS
++
++ /* Initialize CGU */
++ la t9, ltq_cgu_init
++ jalr t9
++ nop
++
++ /* Initialize memory controller */
++ la t9, ltq_mem_init
++ jalr t9
++ nop
++
++ /* Initialize caches... */
++ la t9, mips_cache_reset
++ jalr t9
++ nop
++
++ /* Clear BSS */
++ la t1, __bss_start
++ la t2, __bss_end
++ sub t1, 4
++1:
++ addi t1, 4
++ bltl t1, t2, 1b
++ sw zero, 0(t1)
++
++ /* Setup stack pointer and force alignment on a 16 byte boundary */
++ li t0, (CONFIG_SPL_STACK_BASE & ~0xF)
++ la sp, 0(t0)
++
++ la t9, spl_lantiq_init
++ jr t9
++ nop
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
+@@ -0,0 +1,49 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \
++ LENGTH = CONFIG_SPL_MAX_SIZE }
++MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_BASE, \
++ LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
++
++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
++OUTPUT_ARCH(mips)
++ENTRY(_start)
++SECTIONS
++{
++ . = ALIGN(4);
++ .text : {
++ *(.text*)
++ } > .spl_mem
++
++ . = ALIGN(4);
++ .rodata : {
++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
++ } > .spl_mem
++
++ . = ALIGN(4);
++ .data : {
++ *(SORT_BY_ALIGNMENT(.data*))
++ *(SORT_BY_ALIGNMENT(.sdata*))
++ } > .spl_mem
++
++ . = ALIGN(4);
++ __image_copy_end = .;
++ uboot_end_data = .;
++
++ .bss : {
++ __bss_start = .;
++ *(.bss*)
++ *(.sbss*)
++ . = ALIGN(4);
++ __bss_end = .;
++ } > .bss_mem
++
++ . = ALIGN(4);
++ __end = .;
++ uboot_end = .;
++}
+--- a/arch/mips/cpu/mips32/start.S
++++ b/arch/mips/cpu/mips32/start.S
+@@ -55,166 +55,63 @@
+ #endif
+ .endm
+
+-#define RVECENT(f,n) \
+- b f; nop
+-#define XVECENT(f,bev) \
+- b f ; \
+- li k0,bev
+-
+- .set noreorder
+-
+- .globl _start
+- .text
+-_start:
+- RVECENT(reset,0) # U-boot entry point
+- RVECENT(reset,1) # software reboot
+-#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
+ /*
+ * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to
+ * access external NOR flashes. If the board boots from NOR flash the
+ * internal BootROM does a blind read at address 0xB0000010 to read the
+ * initial configuration for that EBU in order to access the flash
+ * device with correct parameters. This config option is board-specific.
++ * Default to 0 if this option is not set.
+ */
+- .word CONFIG_SYS_XWAY_EBU_BOOTCFG
+- .word 0x00000000
++ .macro lantiq_soc_bootcfg
++ .set push
++ .set noreorder
++ .org 0x10
++#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
++ .word CONFIG_SYS_XWAY_EBU_BOOTCFG
+ #else
+- RVECENT(romReserved,2)
++ .word 0
+ #endif
+- RVECENT(romReserved,3)
+- RVECENT(romReserved,4)
+- RVECENT(romReserved,5)
+- RVECENT(romReserved,6)
+- RVECENT(romReserved,7)
+- RVECENT(romReserved,8)
+- RVECENT(romReserved,9)
+- RVECENT(romReserved,10)
+- RVECENT(romReserved,11)
+- RVECENT(romReserved,12)
+- RVECENT(romReserved,13)
+- RVECENT(romReserved,14)
+- RVECENT(romReserved,15)
+- RVECENT(romReserved,16)
+- RVECENT(romReserved,17)
+- RVECENT(romReserved,18)
+- RVECENT(romReserved,19)
+- RVECENT(romReserved,20)
+- RVECENT(romReserved,21)
+- RVECENT(romReserved,22)
+- RVECENT(romReserved,23)
+- RVECENT(romReserved,24)
+- RVECENT(romReserved,25)
+- RVECENT(romReserved,26)
+- RVECENT(romReserved,27)
+- RVECENT(romReserved,28)
+- RVECENT(romReserved,29)
+- RVECENT(romReserved,30)
+- RVECENT(romReserved,31)
+- RVECENT(romReserved,32)
+- RVECENT(romReserved,33)
+- RVECENT(romReserved,34)
+- RVECENT(romReserved,35)
+- RVECENT(romReserved,36)
+- RVECENT(romReserved,37)
+- RVECENT(romReserved,38)
+- RVECENT(romReserved,39)
+- RVECENT(romReserved,40)
+- RVECENT(romReserved,41)
+- RVECENT(romReserved,42)
+- RVECENT(romReserved,43)
+- RVECENT(romReserved,44)
+- RVECENT(romReserved,45)
+- RVECENT(romReserved,46)
+- RVECENT(romReserved,47)
+- RVECENT(romReserved,48)
+- RVECENT(romReserved,49)
+- RVECENT(romReserved,50)
+- RVECENT(romReserved,51)
+- RVECENT(romReserved,52)
+- RVECENT(romReserved,53)
+- RVECENT(romReserved,54)
+- RVECENT(romReserved,55)
+- RVECENT(romReserved,56)
+- RVECENT(romReserved,57)
+- RVECENT(romReserved,58)
+- RVECENT(romReserved,59)
+- RVECENT(romReserved,60)
+- RVECENT(romReserved,61)
+- RVECENT(romReserved,62)
+- RVECENT(romReserved,63)
+- XVECENT(romExcHandle,0x200) # bfc00200: R4000 tlbmiss vector
+- RVECENT(romReserved,65)
+- RVECENT(romReserved,66)
+- RVECENT(romReserved,67)
+- RVECENT(romReserved,68)
+- RVECENT(romReserved,69)
+- RVECENT(romReserved,70)
+- RVECENT(romReserved,71)
+- RVECENT(romReserved,72)
+- RVECENT(romReserved,73)
+- RVECENT(romReserved,74)
+- RVECENT(romReserved,75)
+- RVECENT(romReserved,76)
+- RVECENT(romReserved,77)
+- RVECENT(romReserved,78)
+- RVECENT(romReserved,79)
+- XVECENT(romExcHandle,0x280) # bfc00280: R4000 xtlbmiss vector
+- RVECENT(romReserved,81)
+- RVECENT(romReserved,82)
+- RVECENT(romReserved,83)
+- RVECENT(romReserved,84)
+- RVECENT(romReserved,85)
+- RVECENT(romReserved,86)
+- RVECENT(romReserved,87)
+- RVECENT(romReserved,88)
+- RVECENT(romReserved,89)
+- RVECENT(romReserved,90)
+- RVECENT(romReserved,91)
+- RVECENT(romReserved,92)
+- RVECENT(romReserved,93)
+- RVECENT(romReserved,94)
+- RVECENT(romReserved,95)
+- XVECENT(romExcHandle,0x300) # bfc00300: R4000 cache vector
+- RVECENT(romReserved,97)
+- RVECENT(romReserved,98)
+- RVECENT(romReserved,99)
+- RVECENT(romReserved,100)
+- RVECENT(romReserved,101)
+- RVECENT(romReserved,102)
+- RVECENT(romReserved,103)
+- RVECENT(romReserved,104)
+- RVECENT(romReserved,105)
+- RVECENT(romReserved,106)
+- RVECENT(romReserved,107)
+- RVECENT(romReserved,108)
+- RVECENT(romReserved,109)
+- RVECENT(romReserved,110)
+- RVECENT(romReserved,111)
+- XVECENT(romExcHandle,0x380) # bfc00380: R4000 general vector
+- RVECENT(romReserved,113)
+- RVECENT(romReserved,114)
+- RVECENT(romReserved,115)
+- RVECENT(romReserved,116)
+- RVECENT(romReserved,116)
+- RVECENT(romReserved,118)
+- RVECENT(romReserved,119)
+- RVECENT(romReserved,120)
+- RVECENT(romReserved,121)
+- RVECENT(romReserved,122)
+- RVECENT(romReserved,123)
+- RVECENT(romReserved,124)
+- RVECENT(romReserved,125)
+- RVECENT(romReserved,126)
+- RVECENT(romReserved,127)
++ .word 0
++ .set pop
++ .endm
++
++ .macro reset_vector branch
++ .set push
++ .set noreorder
++ b \branch
++ nop
++ .set pop
++ .endm
++
++ .macro exception_vector offset branch
++ .set push
++ .set noreorder
++ .org \offset
++ b \branch
++ li k0, \offset
++ .set pop
++ .endm
++
++ .set noreorder
++
++ .globl _start
++ .text
++_start:
++ reset_vector reset # U-boot entry point
++ reset_vector reset # software reboot
++
++ lantiq_soc_bootcfg # Lantiq SoC Boot config word
++
++ exception_vector 0x200, halt # TLB miss
++ exception_vector 0x280, halt # XTLB miss
++ exception_vector 0x300, halt # Cache error
++ exception_vector 0x380, halt # General
++ exception_vector 0x400, halt # Interrupt, CauseIV
++ exception_vector 0x480, ejtag_exception # EJTAG debug
+
+- /*
+- * We hope there are no more reserved vectors!
+- * 128 * 8 == 1024 == 0x400
+- * so this is address R_VEC+0x400 == 0xbfc00400
+- */
+ .align 4
+ reset:
+-
+ /* Clear watch registers */
+ mtc0 zero, CP0_WATCHLO
+ mtc0 zero, CP0_WATCHHI
+@@ -222,13 +119,15 @@ reset:
+ /* WP(Watch Pending), SW0/1 should be cleared */
+ mtc0 zero, CP0_CAUSE
+
++#if 0
+ setup_c0_status_reset
++#endif
+
+ /* Init Timer */
+ mtc0 zero, CP0_COUNT
+ mtc0 zero, CP0_COMPARE
+
+-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
++#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_SYS_DISABLE_CACHE)
+ /* CONFIG0 register */
+ li t0, CONF_CM_UNCACHED
+ mtc0 t0, CP0_CONFIG
+@@ -323,6 +222,8 @@ relocate_code:
+ jalr t9
+ nop
+
++ sync
++
+ /* Jump to where we've relocated ourselves */
+ addi t0, s2, in_ram - _start
+ jr t0
+@@ -378,8 +279,12 @@ in_ram:
+ .end relocate_code
+
+ /* Exception handlers */
+-romReserved:
+- b romReserved
++ejtag_exception:
++ /* Set DEPC to halt and exit debug mode */
++ la k1, halt
++ mtc0 k1, CP0_DEPC
++ deret
++ nop
+
+-romExcHandle:
+- b romExcHandle
++halt:
++ b halt
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/Makefile
+@@ -0,0 +1,34 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(SOC).o
++
++COBJS-y += cgu.o chipid.o dcdc.o ebu.o gphy.o mem.o pmu.o rcu.o
++SOBJS-y += cgu_init.o mem_init.o
++SOBJS-y += gphy_fw.o
++
++COBJS := $(COBJS-y)
++SOBJS := $(SOBJS-y)
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
++
++all: $(LIB)
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/cgu.c
+@@ -0,0 +1,209 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/gphy.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_CGU_PLL1_PLLN_SHIFT 6
++#define LTQ_CGU_PLL1_PLLN_MASK (0x3F << LTQ_CGU_PLL1_PLLN_SHIFT)
++#define LTQ_CGU_PLL1_PLLM_SHIFT 2
++#define LTQ_CGU_PLL1_PLLM_MASK (0xF << LTQ_CGU_PLL1_PLLM_SHIFT)
++#define LTQ_CGU_PLL1_PLLL (1 << 1)
++#define LTQ_CGU_PLL1_PLL_EN 1
++
++#define LTQ_CGU_SYS_OCP_SHIFT 0
++#define LTQ_CGU_SYS_OCP_MASK (0x3 << LTQ_CGU_SYS_OCP_SHIFT)
++#define LTQ_CGU_SYS_CPU_SHIFT 4
++#define LTQ_CGU_SYS_CPU_MASK (0xF << LTQ_CGU_SYS_CPU_SHIFT)
++
++#define LTQ_CGU_UPDATE 1
++
++#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT 2
++#define LTQ_CGU_IFCLK_GPHY_SEL_MASK (0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT)
++
++struct ltq_cgu_regs {
++ u32 rsvd0;
++ u32 pll0_cfg; /* PLL0 config */
++ u32 pll1_cfg; /* PLL1 config */
++ u32 sys; /* System clock */
++ u32 clk_fsr; /* Clock frequency select */
++ u32 clk_gsr; /* Clock gating status */
++ u32 clk_gcr0; /* Clock gating control 0 */
++ u32 clk_gcr1; /* Clock gating control 1 */
++ u32 update; /* CGU update control */
++ u32 if_clk; /* Interface clock */
++ u32 ddr; /* DDR memory control */
++ u32 ct1_sr; /* CT status 1 */
++ u32 ct_kval; /* CT K value */
++ u32 pcm_cr; /* PCM control */
++ u32 pci_cr; /* PCI clock control */
++ u32 rsvd1;
++ u32 gphy1_cfg; /* GPHY1 config */
++ u32 gphy0_cfg; /* GPHY0 config */
++ u32 rsvd2[6];
++ u32 pll2_cfg; /* PLL2 config */
++};
++
++static struct ltq_cgu_regs *ltq_cgu_regs =
++ (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
++
++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
++{
++ return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
++}
++
++unsigned long ltq_get_io_region_clock(void)
++{
++ unsigned int ocp_sel;
++ unsigned long clk, cpu_clk;
++
++ cpu_clk = ltq_get_cpu_clock();
++
++ ocp_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_OCP_MASK,
++ LTQ_CGU_SYS_OCP_SHIFT);
++
++ switch (ocp_sel) {
++ case 0:
++ /* OCP ratio 1 */
++ clk = cpu_clk;
++ break;
++ case 2:
++ /* OCP ratio 2 */
++ clk = cpu_clk / 2;
++ break;
++ case 3:
++ /* OCP ratio 2.5 */
++ clk = (cpu_clk * 2) / 5;
++ break;
++ case 4:
++ /* OCP ratio 3 */
++ clk = cpu_clk / 3;
++ break;
++ default:
++ clk = 0;
++ break;
++ }
++
++ return clk;
++}
++
++unsigned long ltq_get_cpu_clock(void)
++{
++ unsigned int cpu_sel;
++ unsigned long clk;
++
++ cpu_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU_MASK,
++ LTQ_CGU_SYS_CPU_SHIFT);
++
++ switch (cpu_sel) {
++ case 0:
++ clk = CLOCK_600_MHZ;
++ break;
++ case 1:
++ clk = CLOCK_500_MHZ;
++ break;
++ case 2:
++ clk = CLOCK_393_MHZ;
++ break;
++ case 3:
++ clk = CLOCK_333_MHZ;
++ break;
++ case 5:
++ case 6:
++ clk = CLOCK_197_MHZ;
++ break;
++ case 7:
++ clk = CLOCK_166_MHZ;
++ break;
++ case 4:
++ case 8:
++ case 9:
++ clk = CLOCK_125_MHZ;
++ break;
++ default:
++ clk = 0;
++ break;
++ }
++
++ return clk;
++}
++
++unsigned long ltq_get_bus_clock(void)
++{
++ return ltq_get_io_region_clock();
++}
++
++void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk)
++{
++ ltq_clrbits(&ltq_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK);
++ ltq_setbits(&ltq_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT);
++}
++
++static inline int ltq_cgu_pll1_locked(void)
++{
++ u32 pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
++
++ return pll1_cfg & LTQ_CGU_PLL1_PLLL;
++}
++
++static inline void ltq_cgu_pll1_restart(unsigned m, unsigned n)
++{
++ u32 pll1_cfg;
++
++ ltq_clrbits(&ltq_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN);
++ ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
++
++ pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
++ pll1_cfg &= ~(LTQ_CGU_PLL1_PLLN_MASK | LTQ_CGU_PLL1_PLLM_MASK);
++ pll1_cfg |= n << LTQ_CGU_PLL1_PLLN_SHIFT;
++ pll1_cfg |= m << LTQ_CGU_PLL1_PLLM_SHIFT;
++ pll1_cfg |= LTQ_CGU_PLL1_PLL_EN;
++ ltq_writel(&ltq_cgu_regs->pll1_cfg, pll1_cfg);
++ ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
++
++ __udelay(1000);
++}
++
++/*
++ * From chapter 9 in errata sheet:
++ *
++ * Under certain condition, the PLL1 may failed to enter into lock
++ * status by hardware default N, M setting.
++ *
++ * Since system always starts from PLL0, the system software can run
++ * and re-program the PLL1 settings.
++ */
++static void ltq_cgu_pll1_init(void)
++{
++ unsigned i;
++ const unsigned pll1_m[] = { 1, 2, 3, 4 };
++ const unsigned pll1_n[] = { 21, 32, 43, 54 };
++
++ /* Check if PLL1 has locked with hardware default settings */
++ if (ltq_cgu_pll1_locked())
++ return;
++
++ for (i = 0; i < 4; i++) {
++ ltq_cgu_pll1_restart(pll1_m[i], pll1_n[i]);
++
++ if (ltq_cgu_pll1_locked())
++ goto done;
++ }
++
++done:
++ /* Restart with hardware default values M=5, N=64 */
++ ltq_cgu_pll1_restart(5, 64);
++}
++
++void ltq_pll_init(void)
++{
++ ltq_cgu_pll1_init();
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/cgu_init.S
+@@ -0,0 +1,120 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* RCU module register */
++#define LTQ_RCU_RST_REQ 0x0010 /* Reset request */
++#define LTQ_RCU_RST_REQ_VALUE ((1 << 14) | (1 << 1))
++
++/* CGU module register */
++#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
++#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
++#define LTQ_CGU_PLL2_CFG 0x0060 /* PLL2 config */
++#define LTQ_CGU_SYS 0x000C /* System clock */
++#define LTQ_CGU_CLK_FSR 0x0010 /* Clock frequency select */
++#define LTQ_CGU_UPDATE 0x0020 /* Clock update control */
++
++/* Valid SYS.CPU values */
++#define LTQ_CGU_SYS_CPU_SHIFT 4
++#define LTQ_CGU_SYS_CPU_600_MHZ 0x0
++#define LTQ_CGU_SYS_CPU_500_MHZ 0x1
++#define LTQ_CGU_SYS_CPU_393_MHZ 0x2
++#define LTQ_CGU_SYS_CPU_333_MHZ 0x3
++#define LTQ_CGU_SYS_CPU_197_MHZ 0x5
++#define LTQ_CGU_SYS_CPU_166_MHZ 0x7
++#define LTQ_CGU_SYS_CPU_125_MHZ 0x9
++
++/* Valid SYS.OCP values */
++#define LTQ_CGU_SYS_OCP_SHIFT 0
++#define LTQ_CGU_SYS_OCP_1 0x0
++#define LTQ_CGU_SYS_OCP_2 0x2
++#define LTQ_CGU_SYS_OCP_2_5 0x3
++#define LTQ_CGU_SYS_OCP_3 0x4
++
++/* Valid CLK_FSR.ETH values */
++#define LTQ_CGU_CLK_FSR_ETH_SHIFT 24
++#define LTQ_CGU_CLK_FSR_ETH_50_MHZ 0x0
++#define LTQ_CGU_CLK_FSR_ETH_25_MHZ 0x1
++#define LTQ_CGU_CLK_FSR_ETH_2_5_MHZ 0x2
++#define LTQ_CGU_CLK_FSR_ETH_125_MHZ 0x3
++
++/* Valid CLK_FSR.PPE values */
++#define LTQ_CGU_CLK_FSR_PPE_SHIFT 16
++#define LTQ_CGU_CLK_FSR_PPE_500_MHZ 0x0 /* Overclock frequency */
++#define LTQ_CGU_CLK_FSR_PPE_450_MHZ 0x1 /* High frequency */
++#define LTQ_CGU_CLK_FSR_PPE_400_MHZ 0x2 /* Low frequency */
++
++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_500_DDR_250)
++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_500_MHZ
++#define LTQ_CGU_SYS_OCP_CONFIG LTQ_CGU_SYS_OCP_2
++#define LTQ_CGU_CLK_FSR_ETH_CONFIG LTQ_CGU_CLK_FSR_ETH_125_MHZ
++#define LTQ_CGU_CLK_FSR_PPE_CONFIG LTQ_CGU_CLK_FSR_PPE_450_MHZ
++#else
++#error "Invalid system clock configuration!"
++#endif
++
++/* Build register values */
++#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_CPU_CONFIG << \
++ LTQ_CGU_SYS_CPU_SHIFT) | \
++ LTQ_CGU_SYS_OCP_CONFIG)
++
++#define LTQ_CGU_CLK_FSR_VALUE ((LTQ_CGU_CLK_FSR_ETH_CONFIG << \
++ LTQ_CGU_CLK_FSR_ETH_SHIFT) | \
++ (LTQ_CGU_CLK_FSR_PPE_CONFIG << \
++ LTQ_CGU_CLK_FSR_PPE_SHIFT))
++
++ .set noreorder
++
++LEAF(ltq_cgu_init)
++ /* Load current CGU register values */
++ li t0, (LTQ_CGU_BASE | KSEG1)
++ lw t1, LTQ_CGU_SYS(t0)
++ lw t2, LTQ_CGU_CLK_FSR(t0)
++
++ /* Load target CGU register values */
++ li t3, LTQ_CGU_SYS_VALUE
++ li t4, LTQ_CGU_CLK_FSR_VALUE
++
++ /* Only update registers if values differ */
++ bne t1, t3, update
++ nop
++ beq t2, t4, finished
++ nop
++
++update:
++ /* Store target register values */
++ sw t3, LTQ_CGU_SYS(t0)
++ sw t4, LTQ_CGU_CLK_FSR(t0)
++
++ /* Perform software reset to activate new clock config */
++#if 0
++ li t0, (LTQ_RCU_BASE | KSEG1)
++ lw t1, LTQ_RCU_RST_REQ(t0)
++ or t1, LTQ_RCU_RST_REQ_VALUE
++ sw t1, LTQ_RCU_RST_REQ(t0)
++#else
++ li t1, 1
++ sw t1, LTQ_CGU_UPDATE(t0)
++#endif
++
++#if 0
++wait_reset:
++ b wait_reset
++ nop
++#endif
++
++finished:
++ jr ra
++ nop
++
++ END(ltq_cgu_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/chipid.c
+@@ -0,0 +1,63 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_CHIPID_VERSION_SHIFT 28
++#define LTQ_CHIPID_VERSION_MASK (0x7 << LTQ_CHIPID_VERSION_SHIFT)
++#define LTQ_CHIPID_PNUM_SHIFT 12
++#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
++
++struct ltq_chipid_regs {
++ u32 manid; /* Manufacturer identification */
++ u32 chipid; /* Chip identification */
++};
++
++static struct ltq_chipid_regs *ltq_chipid_regs =
++ (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
++
++unsigned int ltq_chip_version_get(void)
++{
++ u32 chipid;
++
++ chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++ return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
++}
++
++unsigned int ltq_chip_partnum_get(void)
++{
++ u32 chipid;
++
++ chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++ return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
++}
++
++const char *ltq_chip_partnum_str(void)
++{
++ enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
++
++ switch (partnum) {
++ case LTQ_SOC_VRX268:
++ case LTQ_SOC_VRX268_2:
++ return "VRX268";
++ case LTQ_SOC_VRX288:
++ case LTQ_SOC_VRX288_2:
++ return "VRX288";
++ case LTQ_SOC_GRX288:
++ case LTQ_SOC_GRX288_2:
++ return "GRX288";
++ default:
++ printf("Unknown partnum: %x\n", partnum);
++ }
++
++ return "";
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/config.mk
+@@ -0,0 +1,32 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
++
++ifdef CONFIG_SPL_BUILD
++PF_ABICALLS := -mno-abicalls
++PF_PIC := -fno-pic
++USE_PRIVATE_LIBGCC := yes
++endif
++
++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
++
++ifndef CONFIG_SPL_BUILD
++ifdef CONFIG_SYS_BOOT_SFSPL
++ALL-y += $(obj)u-boot.ltq.sfspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl
++endif
++ifdef CONFIG_SYS_BOOT_NORSPL
++ALL-y += $(obj)u-boot.ltq.norspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
++endif
++endif
++
++LDSCRIPT := $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot.lds
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/dcdc.c
+@@ -0,0 +1,107 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_DCDC_CLK_SET0_CLK_SEL_P (1 << 6)
++#define LTQ_DCDC_CLK_SET1_SEL_DIV25 (1 << 5)
++#define LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE (1 << 5)
++
++struct ltq_dcdc_regs {
++ u8 b0_coeh; /* Coefficient b0 */
++ u8 b0_coel; /* Coefficient b0 */
++ u8 b1_coeh; /* Coefficient b1 */
++ u8 b1_coel; /* Coefficient b1 */
++ u8 b2_coeh; /* Coefficient b2 */
++ u8 b2_coel; /* Coefficient b2 */
++ u8 clk_set0; /* Clock setup */
++ u8 clk_set1; /* Clock setup */
++ u8 pwm_confh; /* Configure PWM */
++ u8 pwm_confl; /* Configure PWM */
++ u8 bias_vreg0; /* Bias and regulator setup */
++ u8 bias_vreg1; /* Bias and regulator setup */
++ u8 adc_gen0; /* ADC and general control */
++ u8 adc_gen1; /* ADC and general control */
++ u8 adc_con0; /* ADC and general config */
++ u8 adc_con1; /* ADC and general config */
++ u8 conf_test_ana; /* not documented */
++ u8 conf_test_dig; /* not documented */
++ u8 dcdc_status; /* not documented */
++ u8 pid_status; /* not documented */
++ u8 duty_cycle; /* not documented */
++ u8 non_ov_delay; /* not documented */
++ u8 analog_gain; /* not documented */
++ u8 duty_cycle_max_sat; /* not documented */
++ u8 duty_cycle_min_sat; /* not documented */
++ u8 duty_cycle_max; /* not documented */
++ u8 duty_cycle_min; /* not documented */
++ u8 error_max; /* not documented */
++ u8 error_read; /* not documented */
++ u8 delay_deglitch; /* not documented */
++ u8 latch_control; /* not documented */
++ u8 rsvd[240];
++ u8 osc_conf; /* OSC general config */
++ u8 osc_stat; /* OSC general status */
++};
++
++static struct ltq_dcdc_regs *ltq_dcdc_regs =
++ (struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE);
++
++void ltq_dcdc_init(unsigned int dig_ref)
++{
++ u8 dig_ref_cur, val;
++
++ /* Set duty cycle max sat. to 70/90, enable PID freeze */
++ ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x5A);
++ ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x46);
++ val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
++ val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
++ ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
++
++ /* Program new coefficients */
++ ltq_writeb(&ltq_dcdc_regs->b0_coeh, 0x00);
++ ltq_writeb(&ltq_dcdc_regs->b0_coel, 0x00);
++ ltq_writeb(&ltq_dcdc_regs->b1_coeh, 0xFF);
++ ltq_writeb(&ltq_dcdc_regs->b1_coel, 0xE6);
++ ltq_writeb(&ltq_dcdc_regs->b2_coeh, 0x00);
++ ltq_writeb(&ltq_dcdc_regs->b2_coel, 0x1B);
++ ltq_writeb(&ltq_dcdc_regs->non_ov_delay, 0x8B);
++
++ /* Set duty cycle max sat. to 60/108, disable PID freeze */
++ ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x6C);
++ ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x3C);
++ val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
++ val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
++ ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
++
++ /* Init clock and DLL settings */
++ val = ltq_readb(&ltq_dcdc_regs->clk_set0);
++ val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P;
++ ltq_writeb(&ltq_dcdc_regs->clk_set0, val);
++ val = ltq_readb(&ltq_dcdc_regs->clk_set1);
++ val |= LTQ_DCDC_CLK_SET1_SEL_DIV25;
++ ltq_writeb(&ltq_dcdc_regs->clk_set1, val);
++ ltq_writeb(&ltq_dcdc_regs->pwm_confh, 0xF9);
++
++ wmb();
++
++ /* Adapt value of digital reference of DCDC converter */
++ dig_ref_cur = ltq_readb(&ltq_dcdc_regs->bias_vreg1);
++
++ while (dig_ref_cur != dig_ref) {
++ if (dig_ref >= dig_ref_cur)
++ dig_ref_cur++;
++ else if (dig_ref < dig_ref_cur)
++ dig_ref_cur--;
++
++ ltq_writeb(&ltq_dcdc_regs->bias_vreg1, dig_ref_cur);
++ __udelay(1000);
++ }
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/ebu.c
+@@ -0,0 +1,112 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4)
++#define EBU_ADDRSEL_REGEN (1 << 0)
++
++#define EBU_CON_WRDIS (1 << 31)
++#define EBU_CON_AGEN_DEMUX (0x0 << 24)
++#define EBU_CON_AGEN_MUX (0x2 << 24)
++#define EBU_CON_SETUP (1 << 22)
++#define EBU_CON_WAIT_DIS (0x0 << 20)
++#define EBU_CON_WAIT_ASYNC (0x1 << 20)
++#define EBU_CON_WAIT_SYNC (0x2 << 20)
++#define EBU_CON_WINV (1 << 19)
++#define EBU_CON_PW_8BIT (0x0 << 16)
++#define EBU_CON_PW_16BIT (0x1 << 16)
++#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14)
++#define EBU_CON_BCGEN_CS (0x0 << 12)
++#define EBU_CON_BCGEN_INTEL (0x1 << 12)
++#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12)
++#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8)
++#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6)
++#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4)
++#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2)
++#define EBU_CON_CMULT_1 0x0
++#define EBU_CON_CMULT_4 0x1
++#define EBU_CON_CMULT_8 0x2
++#define EBU_CON_CMULT_16 0x3
++
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define ebu_region0_enable 1
++#else
++#define ebu_region0_enable 0
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define ebu_region1_enable 1
++#else
++#define ebu_region1_enable 0
++#endif
++
++struct ltq_ebu_regs {
++ u32 clc;
++ u32 rsvd0;
++ u32 id;
++ u32 rsvd1;
++ u32 con;
++ u32 rsvd2[3];
++ u32 addr_sel_0;
++ u32 addr_sel_1;
++ u32 addr_sel_2;
++ u32 addr_sel_3;
++ u32 rsvd3[12];
++ u32 con_0;
++ u32 con_1;
++ u32 con_2;
++ u32 con_3;
++};
++
++static struct ltq_ebu_regs *ltq_ebu_regs =
++ (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
++
++void ltq_ebu_init(void)
++{
++ if (ebu_region0_enable) {
++ /*
++ * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
++ * region control. This supports up to 32 MiB NOR flash in
++ * bank 0.
++ */
++ ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
++ EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
++
++ ltq_writel(&ltq_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
++ EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
++ EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++ EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
++ EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
++ EBU_CON_CMULT_16);
++ } else
++ ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
++
++ if (ebu_region1_enable) {
++ /*
++ * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
++ * region control. This supports NAND flash in bank 1.
++ */
++ ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
++ EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
++
++ ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
++ EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
++ EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++ EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
++ EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
++ EBU_CON_CMULT_4);
++ } else
++ ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
++}
++
++void *flash_swap_addr(unsigned long addr)
++{
++ return (void *)(addr ^ 2);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/gphy.c
+@@ -0,0 +1,59 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/gphy.h>
++
++static inline void ltq_gphy_copy(const void *fw_start, const void *fw_end,
++ ulong dst_addr)
++{
++ const ulong fw_len = (ulong) fw_end - (ulong) fw_start;
++ const ulong addr = CKSEG1ADDR(dst_addr);
++
++ debug("ltq_gphy_copy: addr %08lx, fw_start %p, fw_end %p\n",
++ addr, fw_start, fw_end);
++
++ memcpy((void *) addr, fw_start, fw_len);
++}
++
++void ltq_gphy_phy11g_a1x_load(ulong addr)
++{
++ extern ulong __ltq_fw_phy11g_a1x_start;
++ extern ulong __ltq_fw_phy11g_a1x_end;
++
++ ltq_gphy_copy(&__ltq_fw_phy11g_a1x_start, &__ltq_fw_phy11g_a1x_end,
++ addr);
++}
++
++void ltq_gphy_phy11g_a2x_load(ulong addr)
++{
++ extern ulong __ltq_fw_phy11g_a2x_start;
++ extern ulong __ltq_fw_phy11g_a2x_end;
++
++ ltq_gphy_copy(&__ltq_fw_phy11g_a2x_start, &__ltq_fw_phy11g_a2x_end,
++ addr);
++}
++
++void ltq_gphy_phy22f_a1x_load(ulong addr)
++{
++ extern ulong __ltq_fw_phy22f_a1x_start;
++ extern ulong __ltq_fw_phy22f_a1x_end;
++
++ ltq_gphy_copy(&__ltq_fw_phy22f_a1x_start, &__ltq_fw_phy22f_a1x_end,
++ addr);
++}
++
++void ltq_gphy_phy22f_a2x_load(ulong addr)
++{
++ extern ulong __ltq_fw_phy22f_a2x_start;
++ extern ulong __ltq_fw_phy22f_a2x_end;
++
++ ltq_gphy_copy(&__ltq_fw_phy22f_a2x_start, &__ltq_fw_phy22f_a2x_end,
++ addr);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
+@@ -0,0 +1,28 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <asm/asm.h>
++
++ .section .rodata.__ltq_fw_phy11g_a1x
++EXPORT(__ltq_fw_phy11g_a1x_start)
++ .incbin "fw_phy11g_a1x.bin"
++EXPORT(__ltq_fw_phy11g_a1x_end)
++
++ .section .rodata.__ltq_fw_phy11g_a2x
++EXPORT(__ltq_fw_phy11g_a2x_start)
++ .incbin "fw_phy11g_a2x.bin"
++EXPORT(__ltq_fw_phy11g_a2x_end)
++
++ .section .rodata.__ltq_fw_phy22f_a1x
++EXPORT(__ltq_fw_phy22f_a1x_start)
++ .incbin "fw_phy22f_a1x.bin"
++EXPORT(__ltq_fw_phy22f_a1x_end)
++
++ .section .rodata.__ltq_fw_phy22f_a2x
++EXPORT(__ltq_fw_phy22f_a2x_start)
++ .incbin "fw_phy22f_a2x.bin"
++EXPORT(__ltq_fw_phy22f_a2x_end)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/mem.c
+@@ -0,0 +1,58 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_CCR03_EIGHT_BANK_MODE (1 << 0)
++#define LTQ_CCR08_CS_MAP_SHIFT 24
++#define LTQ_CCR08_CS_MAP_MASK (0x3 << LTQ_CCR08_CS_MAP_SHIFT)
++#define LTQ_CCR11_COLUMN_SIZE_SHIFT 24
++#define LTQ_CCR11_COLUMN_SIZE_MASK (0x7 << LTQ_CCR11_COLUMN_SIZE_SHIFT)
++#define LTQ_CCR11_ADDR_PINS_MASK 0x7
++#define LTQ_CCR15_MAX_COL_REG_SHIFT 24
++#define LTQ_CCR15_MAX_COL_REG_MASK (0xF << LTQ_CCR15_MAX_COL_REG_SHIFT)
++#define LTQ_CCR16_MAX_ROW_REG_MASK 0xF
++
++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
++
++static inline u32 ltq_mc_ccr_read(u32 index)
++{
++ return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index));
++}
++
++phys_size_t initdram(int board_type)
++{
++ u32 max_col_reg, max_row_reg, column_size, addr_pins;
++ u32 banks, cs_map;
++ phys_size_t size;
++
++ banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4;
++
++ cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >>
++ LTQ_CCR08_CS_MAP_SHIFT;
++
++ column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >>
++ LTQ_CCR11_COLUMN_SIZE_SHIFT;
++
++ addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK;
++
++ max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >>
++ LTQ_CCR15_MAX_COL_REG_SHIFT;
++
++ max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK;
++
++ /*
++ * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects
++ * * datawidth (bytes)
++ */
++ size = (2 << (max_col_reg - column_size - 1)) *
++ (2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2;
++
++ return size;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/mem_init.S
+@@ -0,0 +1,234 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* Must be configured in BOARDDIR */
++#include <ddr_settings.h>
++
++#define LTQ_MC_DDR_START (1 << 8)
++#define LTQ_MC_DDR_DLL_LOCK_IND 1
++
++#define CCS_ALWAYS_LAST 0x0430
++#define CCS_AHBM_CR_BURST_EN (1 << 2)
++#define CCS_FPIM_CR_BURST_EN (1 << 1)
++
++#define CCR03_EIGHT_BANK_MODE (1 << 0)
++
++ /* Store given value in MC DDR CCRx register */
++ .macro ccr_sw num, val
++ li t1, \val
++ sw t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0)
++ .endm
++
++LEAF(ltq_mem_init)
++ /* Load MC DDR module base */
++ li t0, (LTQ_MC_DDR_BASE | KSEG1)
++
++ /* Put memory controller in inactive mode */
++ sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++
++ /* Init MC DDR CCR registers with values from ddr_settings.h */
++ ccr_sw 0, MC_CCR00_VALUE
++ ccr_sw 1, MC_CCR01_VALUE
++ ccr_sw 2, MC_CCR02_VALUE
++ ccr_sw 3, MC_CCR03_VALUE
++ ccr_sw 4, MC_CCR04_VALUE
++ ccr_sw 5, MC_CCR05_VALUE
++ ccr_sw 6, MC_CCR06_VALUE
++ ccr_sw 7, MC_CCR07_VALUE
++ ccr_sw 8, MC_CCR08_VALUE
++ ccr_sw 9, MC_CCR09_VALUE
++
++ ccr_sw 10, MC_CCR10_VALUE
++ ccr_sw 11, MC_CCR11_VALUE
++ ccr_sw 12, MC_CCR12_VALUE
++ ccr_sw 13, MC_CCR13_VALUE
++ ccr_sw 14, MC_CCR14_VALUE
++ ccr_sw 15, MC_CCR15_VALUE
++ ccr_sw 16, MC_CCR16_VALUE
++ ccr_sw 17, MC_CCR17_VALUE
++ ccr_sw 18, MC_CCR18_VALUE
++ ccr_sw 19, MC_CCR19_VALUE
++
++ ccr_sw 20, MC_CCR20_VALUE
++ ccr_sw 21, MC_CCR21_VALUE
++ ccr_sw 22, MC_CCR22_VALUE
++ ccr_sw 23, MC_CCR23_VALUE
++ ccr_sw 24, MC_CCR24_VALUE
++ ccr_sw 25, MC_CCR25_VALUE
++ ccr_sw 26, MC_CCR26_VALUE
++ ccr_sw 27, MC_CCR27_VALUE
++ ccr_sw 28, MC_CCR28_VALUE
++ ccr_sw 29, MC_CCR29_VALUE
++
++ ccr_sw 30, MC_CCR30_VALUE
++ ccr_sw 31, MC_CCR31_VALUE
++ ccr_sw 32, MC_CCR32_VALUE
++ ccr_sw 33, MC_CCR33_VALUE
++ ccr_sw 34, MC_CCR34_VALUE
++ ccr_sw 35, MC_CCR35_VALUE
++ ccr_sw 36, MC_CCR36_VALUE
++ ccr_sw 37, MC_CCR37_VALUE
++ ccr_sw 38, MC_CCR38_VALUE
++ ccr_sw 39, MC_CCR39_VALUE
++
++ ccr_sw 40, MC_CCR40_VALUE
++ ccr_sw 41, MC_CCR41_VALUE
++ ccr_sw 42, MC_CCR42_VALUE
++ ccr_sw 43, MC_CCR43_VALUE
++ ccr_sw 44, MC_CCR44_VALUE
++ ccr_sw 45, MC_CCR45_VALUE
++ ccr_sw 46, MC_CCR46_VALUE
++
++ ccr_sw 52, MC_CCR52_VALUE
++ ccr_sw 53, MC_CCR53_VALUE
++ ccr_sw 54, MC_CCR54_VALUE
++ ccr_sw 55, MC_CCR55_VALUE
++ ccr_sw 56, MC_CCR56_VALUE
++ ccr_sw 57, MC_CCR57_VALUE
++ ccr_sw 58, MC_CCR58_VALUE
++ ccr_sw 59, MC_CCR59_VALUE
++
++ ccr_sw 60, MC_CCR60_VALUE
++ ccr_sw 61, MC_CCR61_VALUE
++
++ /* Disable bursts between FPI Master bus and XBAR bus */
++ li t4, (LTQ_MC_GLOBAL_BASE | KSEG1)
++ li t5, CCS_AHBM_CR_BURST_EN
++ sw t5, CCS_ALWAYS_LAST(t4)
++
++ /* Init abort condition for DRAM probe */
++ move t4, zero
++
++ /*
++ * Put memory controller in active mode and start initialitation
++ * sequence for connected DDR-SDRAM device
++ */
++mc_start:
++ lw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++ li t2, LTQ_MC_DDR_START
++ or t1, t1, t2
++ sw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++
++ /*
++ * Wait until DLL has locked and core is ready for data transfers.
++ * DLL lock indication is in register CCR47 and CCR48
++ */
++wait_ready:
++ li t1, LTQ_MC_DDR_DLL_LOCK_IND
++ lw t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0)
++ and t2, t2, t1
++ bne t1, t2, wait_ready
++
++ lw t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0)
++ and t2, t2, t1
++ bne t1, t2, wait_ready
++
++#ifdef CONFIG_SYS_DRAM_PROBE
++dram_probe:
++ /* Initialization is finished after the second MC start */
++ bnez t4, mc_finished
++
++ /*
++ * Preload register values for CCR03 and CCR11. Initial settings
++ * are 8-bank mode enabled, 14 use address row bits, 10 used
++ * column address bits.
++ */
++ li t1, CONFIG_SYS_SDRAM_BASE_UC
++ li t5, MC_CCR03_VALUE
++ li t6, MC_CCR11_VALUE
++ addi t4, t4, 1
++
++ /*
++ * Store test values to DRAM at offsets 0 and 2^13 (bit 2 in bank select
++ * address BA[3]) and read back the value at offset 0. If the resulting
++ * value is equal to 1 we can skip to the next test. Otherwise
++ * the 8-bank mode does not work with the current DRAM device,
++ * thus we need to clear the according bit in register CCR03.
++ */
++ li t2, 1
++ sw t2, 0x0(t1)
++ li t3, (1 << 13)
++ add t3, t3, t1
++ sw zero, 0(t3)
++ lw t3, 0(t1)
++ bnez t3, row_col_test
++
++ /* Clear CCR03.EIGHT_BANK_MODE */
++ li t3, ~CCR03_EIGHT_BANK_MODE
++ and t5, t5, t3
++
++row_col_test:
++ /*
++ * Store test values to DRAM at offsets 0, 2^27 (bit 13 of row address
++ * RA[14]) and 2^26 (bit 12 of RA[14]). The chosen test values
++ * represent the difference between max. row address bits (14) and used
++ * row address bits. Then the read back value at offset 0 indicates
++ * the useable row address bits with the current DRAM device. This
++ * value must be set in the CCR11 register.
++ */
++ sw zero, 0(t1)
++
++ li t2, 1
++ li t3, (1 << 27)
++ add t3, t3, t1
++ sw t2, 0(t3)
++
++ li t2, 2
++ li t3, (1 << 26)
++ add t3, t3, t1
++ sw t2, 0(t3)
++
++ /* Update CCR11.ADDR_PINS */
++ lw t3, 0(t1)
++ add t6, t6, t3
++
++ /*
++ * Store test values to DRAM at offsets 0, 2^10 (bit 9 of column address
++ * CA[10]) and 2^9 (bit 8 of CA[10]). The chosen test values represent
++ * the difference between max. column address bits (12) and used
++ * column address bits. Then the read back value at offset 0 indicates
++ * the useable column address bits with the current DRAM device. This
++ * value must be set in the CCR11 register.
++ */
++ sw zero, 0(t1)
++
++ li t2, 1
++ li t3, (1 << 10)
++ add t3, t3, t1
++ sw t2, 0(t3)
++
++ li t2, 2
++ li t3, (1 << 9)
++ add t3, t3, t1
++ sw t2, 0(t3)
++
++ /* Update CCR11.COLUMN_SIZE */
++ lw t3, 0(t1)
++ sll t3, t3, 24
++ add t6, t6, t3
++
++ /* Put memory controller in inactive mode */
++ sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++
++ /* Update CCR03 and CCR11 and restart memory controller initialiation */
++ sw t5, LTQ_MC_DDR_CCR_OFFSET(3)(t0)
++ sw t6, LTQ_MC_DDR_CCR_OFFSET(11)(t0)
++ b mc_start
++
++mc_finished:
++#endif /* CONFIG_SYS_DRAM_PROBE */
++
++ jr ra
++
++ END(ltq_mem_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/pmu.c
+@@ -0,0 +1,131 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PMU_PWDCR_RESERVED ((1 << 13) | (1 << 4))
++
++#define LTQ_PMU_PWDCR_PCIELOC_EN (1 << 31)
++#define LTQ_PMU_PWDCR_GPHY (1 << 30)
++#define LTQ_PMU_PWDCR_PPE_TOP (1 << 29)
++#define LTQ_PMU_PWDCR_SWITCH (1 << 28)
++#define LTQ_PMU_PWDCR_USB1 (1 << 27)
++#define LTQ_PMU_PWDCR_USB1_PHY (1 << 26)
++#define LTQ_PMU_PWDCR_TDM (1 << 25)
++#define LTQ_PMU_PWDCR_PPE_DPLUS (1 << 24)
++#define LTQ_PMU_PWDCR_PPE_DPLUM (1 << 23)
++#define LTQ_PMU_PWDCR_PPE_EMA (1 << 22)
++#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
++#define LTQ_PMU_PWDCR_DEU (1 << 20)
++#define LTQ_PMU_PWDCR_PPE_SLL01 (1 << 19)
++#define LTQ_PMU_PWDCR_PPE_QSB (1 << 18)
++#define LTQ_PMU_PWDCR_UART1 (1 << 17)
++#define LTQ_PMU_PWDCR_SDIO (1 << 16)
++#define LTQ_PMU_PWDCR_AHBM (1 << 15)
++#define LTQ_PMU_PWDCR_FPIM (1 << 14)
++#define LTQ_PMU_PWDCR_GPTC (1 << 12)
++#define LTQ_PMU_PWDCR_LEDC (1 << 11)
++#define LTQ_PMU_PWDCR_EBU (1 << 10)
++#define LTQ_PMU_PWDCR_DSL (1 << 9)
++#define LTQ_PMU_PWDCR_SPI (1 << 8)
++#define LTQ_PMU_PWDCR_USIF (1 << 7)
++#define LTQ_PMU_PWDCR_USB0 (1 << 6)
++#define LTQ_PMU_PWDCR_DMA (1 << 5)
++#define LTQ_PMU_PWDCR_DFEV1 (1 << 3)
++#define LTQ_PMU_PWDCR_DFEV0 (1 << 2)
++#define LTQ_PMU_PWDCR_FPIS (1 << 1)
++#define LTQ_PMU_PWDCR_USB0_PHY (1 << 0)
++
++struct ltq_pmu_regs {
++ u32 rsvd0[7];
++ u32 pwdcr; /* Power down control */
++ u32 sr; /* Power down status */
++ u32 pwdcr1; /* Power down control 1 */
++ u32 sr1; /* Power down status 1 */
++};
++
++static struct ltq_pmu_regs *ltq_pmu_regs =
++ (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
++
++u32 ltq_pm_map(enum ltq_pm_modules module)
++{
++ u32 val;
++
++ switch (module) {
++ case LTQ_PM_CORE:
++ val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM |
++ LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
++ break;
++ case LTQ_PM_DMA:
++ val = LTQ_PMU_PWDCR_DMA;
++ break;
++ case LTQ_PM_ETH:
++ val = LTQ_PMU_PWDCR_GPHY | LTQ_PMU_PWDCR_PPE_TOP |
++ LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DPLUS |
++ LTQ_PMU_PWDCR_PPE_DPLUM | LTQ_PMU_PWDCR_PPE_EMA |
++ LTQ_PMU_PWDCR_PPE_TC | LTQ_PMU_PWDCR_PPE_SLL01 |
++ LTQ_PMU_PWDCR_PPE_QSB;
++ break;
++ case LTQ_PM_SPI:
++ val = LTQ_PMU_PWDCR_SPI;
++ break;
++ default:
++ val = 0;
++ break;
++ }
++
++ return val;
++}
++
++int ltq_pm_enable(enum ltq_pm_modules module)
++{
++ const unsigned long timeout = 1000;
++ unsigned long timebase;
++ u32 sr, val;
++
++ val = ltq_pm_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
++
++ timebase = get_timer(0);
++
++ do {
++ sr = ltq_readl(&ltq_pmu_regs->sr);
++ if (~sr & val)
++ return 0;
++ } while (get_timer(timebase) < timeout);
++
++ return 1;
++}
++
++int ltq_pm_disable(enum ltq_pm_modules module)
++{
++ u32 val;
++
++ val = ltq_pm_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_setbits(&ltq_pmu_regs->pwdcr, val);
++
++ return 0;
++}
++
++void ltq_pmu_init(void)
++{
++ u32 set, clr;
++
++ clr = ltq_pm_map(LTQ_PM_CORE);
++ set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
++
++ ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/rcu.c
+@@ -0,0 +1,195 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_RCU_RD_GPHY0 (1 << 31) /* GPHY0 */
++#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
++#define LTQ_RCU_RD_GPHY1 (1 << 29) /* GPHY1 */
++#define LTQ_RCU_RD_ENMIP2 (1 << 28) /* Enable NMI of PLL2 */
++#define LTQ_RCU_RD_REG25_PD (1 << 26) /* Power down 2.5V regulator */
++#define LTQ_RCU_RD_ENDINIT (1 << 25) /* FPI slave bus access */
++#define LTQ_RCU_RD_PPE_ATM_TC (1 << 23) /* PPE ATM TC */
++#define LTQ_RCU_RD_PCIE (1 << 22) /* PCI-E core */
++#define LTQ_RCU_RD_ETHSW (1 << 21) /* Ethernet switch */
++#define LTQ_RCU_RD_DSP_DEN (1 << 20) /* Enable DSP JTAG */
++#define LTQ_RCU_RD_TDM (1 << 19) /* TDM module interface */
++#define LTQ_RCU_RD_ENMIP1 (1 << 18) /* Enable NMI of PLL1 */
++#define LTQ_RCU_RD_SWBCK (1 << 17) /* Switch backward compat */
++#define LTQ_RCU_RD_HSNAND (1 << 16) /* HSNAND controller */
++#define LTQ_RCU_RD_ENMIP0 (1 << 15) /* Enable NMI of PLL0 */
++#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
++#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
++#define LTQ_RCU_RD_PCIE_PHY (1 << 12) /* PCI-E Phy */
++#define LTQ_RCU_RD_DFE_CORE (1 << 11) /* DFE core */
++#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
++#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
++#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
++#define LTQ_RCU_RD_DFE (1 << 7) /* DFE core */
++#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
++#define LTQ_RCU_RD_HRST_CFG (1 << 5) /* HW reset configuration */
++#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
++#define LTQ_RCU_RD_PPE_DSP (1 << 3) /* PPE DSP interface */
++#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
++#define LTQ_RCU_RD_CPU (1 << 1) /* CPU subsystem */
++#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
++
++#define LTQ_RCU_STAT_BOOT_SHIFT 17
++#define LTQ_RCU_STAT_BOOT_MASK (0xF << LTQ_RCU_STAT_BOOT_SHIFT)
++#define LTQ_RCU_STAT_BOOT_H (1 << 12)
++
++#define LTQ_RCU_GP_STRAP_CLOCKSOURCE (1 << 15)
++
++struct ltq_rcu_regs {
++ u32 rsvd0[4];
++ u32 req; /* Reset request */
++ u32 stat; /* Reset status */
++ u32 usb0_cfg; /* USB0 configure */
++ u32 gp_strap; /* GPIO strapping */
++ u32 gfs_add0; /* GPHY0 firmware base addr */
++ u32 stat2; /* SLIC and USB reset status */
++ u32 pci_rdy; /* PCI boot ready */
++ u32 ppe_conf; /* PPE ethernet config */
++ u32 pcie_phy_con; /* PCIE PHY config/status */
++ u32 usb1_cfg; /* USB1 configure */
++ u32 usb_ana_cfg1a; /* USB analog config 1a */
++ u32 usb_ana_cfg1b; /* USB analog config 1b */
++ u32 rsvd1;
++ u32 gf_mdio_add; /* GPHY0/1 MDIO address */
++ u32 req2; /* SLIC and USB reset request */
++ u32 ahb_endian; /* AHB bus endianess */
++ u32 rsvd2[4];
++ u32 gcc; /* General CPU config */
++ u32 rsvd3;
++ u32 gfs_add1; /* GPHY1 firmware base addr */
++};
++
++static struct ltq_rcu_regs *ltq_rcu_regs =
++ (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
++
++u32 ltq_reset_map(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ switch (module) {
++ case LTQ_RESET_CORE:
++ case LTQ_RESET_SOFT:
++ val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU | LTQ_RCU_RD_ENMIP2 |
++ LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
++ break;
++ case LTQ_RESET_DMA:
++ val = LTQ_RCU_RD_DMA;
++ break;
++ case LTQ_RESET_ETH:
++ val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
++ break;
++ case LTQ_RESET_PHY:
++ val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
++ break;
++ case LTQ_RESET_HARD:
++ val = LTQ_RCU_RD_HRST;
++ break;
++ default:
++ val = 0;
++ break;
++ }
++
++ return val;
++}
++
++int ltq_reset_activate(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ val = ltq_reset_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_setbits(&ltq_rcu_regs->req, val);
++
++ return 0;
++}
++
++int ltq_reset_deactivate(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ val = ltq_reset_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_clrbits(&ltq_rcu_regs->req, val);
++
++ return 0;
++}
++
++enum ltq_boot_select ltq_boot_select(void)
++{
++ u32 stat;
++ unsigned int bootstrap;
++
++ /*
++ * Boot select value is built from bits 20-17 and bit 12.
++ * The bit sequence is read as 4-2-1-0-3.
++ */
++ stat = ltq_readl(&ltq_rcu_regs->stat);
++ bootstrap = ((stat & LTQ_RCU_STAT_BOOT_H) << 4) |
++ ((stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT);
++
++ switch (bootstrap) {
++ case 0:
++ return BOOT_NOR_NO_BOOTROM;
++ case 1:
++ return BOOT_RGMII1;
++ case 2:
++ return BOOT_NOR;
++ case 4:
++ return BOOT_UART_NO_EEPROM;
++ case 6:
++ return BOOT_PCI;
++ case 8:
++ return BOOT_UART;
++ case 10:
++ return BOOT_SPI;
++ case 12:
++ return BOOT_NAND;
++ default:
++ return BOOT_UNKNOWN;
++ }
++}
++
++void ltq_rcu_gphy_boot(unsigned int id, ulong addr)
++{
++ u32 module;
++ void *gfs_add;
++
++ switch (id) {
++ case 0:
++ module = LTQ_RCU_RD_GPHY0;
++ gfs_add = &ltq_rcu_regs->gfs_add0;
++ break;
++ case 1:
++ module = LTQ_RCU_RD_GPHY1;
++ gfs_add = &ltq_rcu_regs->gfs_add1;
++ break;
++ default:
++ BUG();
++ }
++
++ /* Stop and reset GPHY */
++ ltq_setbits(&ltq_rcu_regs->req, module);
++
++ /* Configure firmware and boot address */
++ ltq_writel(gfs_add, CPHYSADDR(addr & 0xFFFFC000));
++
++ /* Start GPHY by releasing reset */
++ ltq_clrbits(&ltq_rcu_regs->req, module);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/u-boot.lds
+@@ -0,0 +1,69 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
++OUTPUT_ARCH(mips)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++
++ . = ALIGN(4);
++ .text : {
++ *(.text*)
++ }
++
++ . = ALIGN(4);
++ .rodata : {
++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
++ }
++
++ . = ALIGN(4);
++ .data : {
++ *(.data*)
++ }
++
++ . = ALIGN(4);
++ .sdata : {
++ *(.sdata*)
++ }
++
++ . = .;
++ _gp = ALIGN(16) + 0x7ff0;
++
++ .got : {
++ __got_start = .;
++ *(.got)
++ __got_end = .;
++ }
++
++ num_got_entries = (__got_end - __got_start) >> 2;
++
++#ifndef CONFIG_SPL_BUILD
++ . = ALIGN(4);
++ .u_boot_list : {
++ #include <u-boot.lst>
++ }
++#endif
++
++ . = ALIGN(4);
++ __image_copy_end = .;
++ uboot_end_data = .;
++
++ .bss (NOLOAD) : {
++ __bss_start = .;
++ *(.bss*)
++ *(.sbss*)
++ . = ALIGN(4);
++ __bss_end = .;
++ }
++
++ . = ALIGN(4);
++ __end = .;
++ uboot_end = .;
++}
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/config.h
+@@ -0,0 +1,156 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ *
++ * Common board configuration for Lantiq XWAY Danube family
++ *
++ * Use following defines in your board config to enable specific features
++ * and drivers for this SoC:
++ *
++ * CONFIG_LTQ_SUPPORT_UART
++ * - support the Danube ASC/UART interface and console
++ *
++ * CONFIG_LTQ_SUPPORT_NOR_FLASH
++ * - support a parallel NOR flash via the CFI interface in flash bank 0
++ *
++ * CONFIG_LTQ_SUPPORT_ETHERNET
++ * - support the Danube ETOP and MAC interface
++ *
++ * CONFIG_LTQ_SUPPORT_SPI_FLASH
++ * - support the Danube SPI interface and serial flash drivers
++ * - specific SPI flash drivers must be configured separately
++ */
++
++#ifndef __DANUBE_CONFIG_H__
++#define __DANUBE_CONFIG_H__
++
++/* CPU and SoC type */
++#define CONFIG_SOC_LANTIQ
++#define CONFIG_SOC_XWAY_DANUBE
++
++/* Cache configuration */
++#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
++#define CONFIG_SYS_DCACHE_SIZE (16 * 1024)
++#define CONFIG_SYS_ICACHE_SIZE (16 * 1024)
++#define CONFIG_SYS_CACHELINE_SIZE 32
++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++/*
++ * Supported clock modes
++ * PLL0 clock output is 333 MHz
++ * PLL1 clock output is 262.144 MHz
++ */
++#define LTQ_CLK_CPU_333_DDR_167 0 /* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_111_DDR_111 1 /* Base PLL0, OCP 1 */
++
++/* CPU speed */
++#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_333_DDR_167
++#define CONFIG_SYS_MIPS_TIMER_FREQ 166666667
++#define CONFIG_SYS_HZ 1000
++
++/* RAM */
++#define CONFIG_NR_DRAM_BANKS 1
++#define CONFIG_SYS_SDRAM_BASE 0x80000000
++#define CONFIG_SYS_MEMTEST_START 0x81000000
++#define CONFIG_SYS_MEMTEST_END 0x82000000
++#define CONFIG_SYS_LOAD_ADDR 0x81000000
++#define CONFIG_SYS_INIT_SP_OFFSET 0x4000
++
++/* SRAM */
++#define CONFIG_SYS_SRAM_BASE 0xBE180000
++#define CONFIG_SYS_SRAM_SIZE 0x10000
++
++/* ASC/UART driver and console */
++#define CONFIG_LANTIQ_SERIAL
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/* GPIO */
++#define CONFIG_LANTIQ_GPIO
++#define CONFIG_LTQ_GPIO_MAX_BANKS 2
++
++/* FLASH driver */
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT 256
++#define CONFIG_SYS_FLASH_BASE 0xB0000000
++#define CONFIG_FLASH_16BIT
++#define CONFIG_SYS_FLASH_CFI
++#define CONFIG_FLASH_CFI_DRIVER
++#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++#define CONFIG_FLASH_SHOW_PROGRESS 50
++#define CONFIG_SYS_FLASH_PROTECTION
++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++
++#define CONFIG_CMD_FLASH
++#else
++#define CONFIG_SYS_NO_FLASH
++#endif /* CONFIG_NOR_FLASH */
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_LANTIQ_SPI
++#define CONFIG_SPI_FLASH
++
++#define CONFIG_CMD_SF
++#define CONFIG_CMD_SPI
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
++#define CONFIG_LANTIQ_DMA
++#define CONFIG_LANTIQ_DANUBE_ETOP
++
++#define CONFIG_PHYLIB
++#define CONFIG_MII
++
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#endif
++
++#define CONFIG_SPL_MAX_SIZE (32 * 1024)
++#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024)
++#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024)
++#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024)
++/*#define CONFIG_SPL_STACK_BSS_IN_SRAM*/
++
++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \
++ CONFIG_SPL_MAX_SIZE + \
++ CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \
++ CONFIG_SYS_INIT_SP_OFFSET)
++#else
++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \
++ CONFIG_SYS_INIT_SP_OFFSET + \
++ CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \
++ CONFIG_SPL_BSS_MAX_SIZE)
++#endif
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define CONFIG_SYS_TEXT_BASE 0xa0100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_SYS_TEXT_BASE 0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SPL_TEXT_BASE 0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C
++#define CONFIG_XWAY_SWAP_BYTES
++#endif
++
++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
++
++#endif /* __DANUBE_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/gpio.h
+@@ -0,0 +1,13 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __DANUBE_GPIO_H__
++#define __DANUBE_GPIO_H__
++
++#include <asm/lantiq/gpio.h>
++
++#endif /* __DANUBE_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/soc.h
+@@ -0,0 +1,40 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __DANUBE_SOC_H__
++#define __DANUBE_SOC_H__
++
++#define LTQ_ASC0_BASE 0x1E100400
++#define LTQ_SPI_BASE 0x1E100800
++#define LTQ_GPIO_BASE 0x1E100B00
++#define LTQ_SSIO_BASE 0x1E100BB0
++#define LTQ_ASC1_BASE 0x1E100C00
++#define LTQ_DMA_BASE 0x1E104100
++
++#define LTQ_EBU_BASE 0x1E105300
++#define LTQ_EBU_REGION0_BASE 0x10000000
++#define LTQ_EBU_REGION0_SIZE (64 * 1024 * 1024)
++#define LTQ_EBU_REGION1_BASE 0x14000000
++#define LTQ_EBU_REGION1_SIZE (32 * 1024 * 1024)
++
++#define LTQ_PPE_BASE 0x1E180000
++#define LTQ_PPE_ETOP_BASE (LTQ_PPE_BASE + 0x11800)
++#define LTQ_PPE_ENET0_BASE (LTQ_PPE_BASE + 0x11840)
++
++#define LTQ_PMU_BASE 0x1F102000
++#define LTQ_CGU_BASE 0x1F103000
++#define LTQ_MPS_BASE 0x1F107000
++#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340)
++#define LTQ_RCU_BASE 0x1F203000
++
++#define LTQ_MC_GEN_BASE 0x1F800000
++#define LTQ_MC_SDR_BASE 0x1F800200
++#define LTQ_MC_DDR_BASE 0x1F801000
++#define LTQ_MC_DDR_DC_OFFSET(x) (x * 0x10)
++
++#endif /* __DANUBE_SOC_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/config.h
+@@ -0,0 +1,185 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ *
++ * Common board configuration for Lantiq XWAY VRX200 family
++ *
++ * Use following defines in your board config to enable specific features
++ * and drivers for this SoC:
++ *
++ * CONFIG_LTQ_SUPPORT_UART
++ * - support the VRX200 ASC/UART interface and console
++ *
++ * CONFIG_LTQ_SUPPORT_NOR_FLASH
++ * - support a parallel NOR flash via the CFI interface in flash bank 0
++ *
++ * CONFIG_LTQ_SUPPORT_SPI_FLASH
++ * - support the VRX200 SPI interface and serial flash drivers
++ * - specific SPI flash drivers must be configured separately
++ *
++ * CONFIG_LTQ_SUPPORT_ETHERNET
++ * - support the VRX200 internal switch
++ *
++ * CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH
++ * - build a preloader that runs in the internal SRAM and loads
++ * the U-Boot from SPI flash into RAM
++ */
++
++#ifndef __VRX200_CONFIG_H__
++#define __VRX200_CONFIG_H__
++
++/* CPU and SoC type */
++#define CONFIG_SOC_LANTIQ
++#define CONFIG_SOC_XWAY_VRX200
++
++/* Cache configuration */
++#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
++#define CONFIG_SYS_DCACHE_SIZE (32 * 1024)
++#define CONFIG_SYS_ICACHE_SIZE (32 * 1024)
++#define CONFIG_SYS_CACHELINE_SIZE 32
++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++/*
++ * Supported clock modes
++ * PLL0 clock output is 1000 MHz
++ * PLL1 clock output is 393.219 MHz
++ */
++#define LTQ_CLK_CPU_600_DDR_300 0 /* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_600_DDR_200 1 /* Base PLL0, OCP 3 */
++#define LTQ_CLK_CPU_500_DDR_250 2 /* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_500_DDR_200 3 /* Base PLL0, OCP 2.5 */
++#define LTQ_CLK_CPU_333_DDR_167 4 /* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_167_DDR_167 5 /* Base PLL0, OCP 1 */
++#define LTQ_CLK_CPU_125_DDR_125 6 /* Base PLL0, OCP 1 */
++#define LTQ_CLK_CPU_393_DDR_197 7 /* Base PLL1, OCP 2 */
++#define LTQ_CLK_CPU_197_DDR_197 8 /* Base PLL1, OCP 1 */
++
++/* CPU speed */
++#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_500_DDR_250
++#define CONFIG_SYS_MIPS_TIMER_FREQ 250000000
++#define CONFIG_SYS_HZ 1000
++
++/* RAM */
++#define CONFIG_NR_DRAM_BANKS 1
++#define CONFIG_SYS_SDRAM_BASE 0x80000000
++#define CONFIG_SYS_SDRAM_BASE_UC 0xa0000000
++#define CONFIG_SYS_MEMTEST_START 0x81000000
++#define CONFIG_SYS_MEMTEST_END 0x82000000
++#define CONFIG_SYS_LOAD_ADDR 0x81000000
++#define CONFIG_SYS_INIT_SP_OFFSET (32 * 1024)
++
++/* SRAM */
++#define CONFIG_SYS_SRAM_BASE 0xBE220000
++#define CONFIG_SYS_SRAM_SIZE 0x10000
++
++/* ASC/UART driver and console */
++#define CONFIG_LANTIQ_SERIAL
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/* GPIO */
++#define CONFIG_LANTIQ_GPIO
++#define CONFIG_LTQ_GPIO_MAX_BANKS 3
++#define CONFIG_LTQ_HAS_GPIO_BANK3
++
++/* FLASH driver */
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT 256
++#define CONFIG_SYS_FLASH_BASE 0xB0000000
++#define CONFIG_FLASH_16BIT
++#define CONFIG_SYS_FLASH_CFI
++#define CONFIG_FLASH_CFI_DRIVER
++#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++#define CONFIG_FLASH_SHOW_PROGRESS 50
++#define CONFIG_SYS_FLASH_PROTECTION
++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++
++#define CONFIG_CMD_FLASH
++#else
++#define CONFIG_SYS_NO_FLASH
++#endif /* CONFIG_NOR_FLASH */
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_LANTIQ_SPI
++#define CONFIG_SPI_FLASH
++
++#define CONFIG_CMD_SF
++#define CONFIG_CMD_SPI
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define CONFIG_NAND_LANTIQ
++#define CONFIG_SYS_MAX_NAND_DEVICE 1
++#define CONFIG_SYS_NAND_BASE 0xB4000000
++
++#define CONFIG_CMD_NAND
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
++#define CONFIG_LANTIQ_DMA
++#define CONFIG_LANTIQ_VRX200_SWITCH
++#define CONFIG_PHY_LANTIQ
++
++#define CONFIG_SYS_RX_ETH_BUFFER 8
++#define CONFIG_PHYLIB
++#define CONFIG_MII
++#define CONFIG_UDP_CHECKSUM
++
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#endif
++
++#define CONFIG_SPL_MAX_SIZE (32 * 1024)
++#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024)
++#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024)
++#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024)
++#define CONFIG_SPL_STACK_BSS_IN_SRAM
++
++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \
++ CONFIG_SPL_MAX_SIZE + \
++ CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \
++ CONFIG_SYS_INIT_SP_OFFSET)
++#else
++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \
++ CONFIG_SYS_INIT_SP_OFFSET + \
++ CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \
++ CONFIG_SPL_BSS_MAX_SIZE)
++#endif
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define CONFIG_SYS_TEXT_BASE 0xA0100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_SYS_TEXT_BASE 0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SPL_TEXT_BASE 0xBE220000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SPL_TEXT_BASE 0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C
++#define CONFIG_XWAY_SWAP_BYTES
++#endif
++
++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
++
++#endif /* __VRX200_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/gphy.h
+@@ -0,0 +1,66 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __VRX200_GPHY_H__
++#define __VRX200_GPHY_H__
++
++enum ltq_gphy_clk {
++ /* XTAL 36 MHz input */
++ LTQ_GPHY_CLK_36MHZ_XTAL = 1,
++ /* 25 MHz from PLL0 with divider */
++ LTQ_GPHY_CLK_25MHZ_PLL0 = 2,
++ /* derived from PLL2 output (XTAL is 36 MHz) */
++ LTQ_GPHY_CLK_24MHZ_PLL2 = 3,
++ /* 25 MHz Clock from Pin GPIO3 */
++ LTQ_GPHY_CLK_25MHZ_GPIO3 = 4,
++};
++
++/*
++ * Load PHY11G firmware for VRX200 v1.1 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy11g_a1x_load(ulong addr);
++
++/*
++ * Load PHY11G firmware for VRX200 v1.2 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy11g_a2x_load(ulong addr);
++
++/*
++ * Load PHY22F firmware for VRX200 v1.1 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy22f_a1x_load(ulong addr);
++
++/*
++ * Load PHY22F firmware for VRX200 v1.2 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy22f_a2x_load(ulong addr);
++
++/*
++ * Set clock source of internal GPHYs
++ *
++ * According registers resides in CGU address space. Thus this function
++ * is implemented by the CGU driver.
++ */
++extern void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk);
++
++/*
++ * Boot internal GPHY with id from given RAM address
++ *
++ * According registers resides in RCU address space. Thus this function
++ * is implemented by the RCU driver.
++ */
++extern void ltq_rcu_gphy_boot(unsigned int id, ulong addr);
++
++#endif /* __VRX200_GPHY_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/gpio.h
+@@ -0,0 +1,13 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __VRX200_GPIO_H__
++#define __VRX200_GPIO_H__
++
++#include <asm/lantiq/gpio.h>
++
++#endif /* __VRX200_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/nand.h
+@@ -0,0 +1,14 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#ifndef __VRX200_NAND_H__
++#define __VRX200_NAND_H__
++
++struct nand_chip;
++int ltq_nand_init(struct nand_chip *nand);
++
++#endif /* __VRX200_NAND_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/soc.h
+@@ -0,0 +1,46 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __VRX200_SOC_H__
++#define __VRX200_SOC_H__
++
++#define LTQ_ASC0_BASE 0x1E100400
++#define LTQ_SPI_BASE 0x1E100800
++#define LTQ_GPIO_BASE 0x1E100B00
++#define LTQ_SSIO_BASE 0x1E100BB0
++#define LTQ_ASC1_BASE 0x1E100C00
++#define LTQ_DMA_BASE 0x1E104100
++
++#define LTQ_EBU_BASE 0x1E105300
++#define LTQ_EBU_REGION0_BASE 0x10000000
++#define LTQ_EBU_REGION1_BASE 0x14000000
++#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0)
++
++#define LTQ_SWITCH_BASE 0x1E108000
++#define LTQ_SWITCH_CORE_BASE LTQ_SWITCH_BASE
++#define LTQ_SWITCH_TOP_PDI_BASE LTQ_SWITCH_CORE_BASE
++#define LTQ_SWITCH_BM_PDI_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x40)
++#define LTQ_SWITCH_MAC_PDI_0_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x900)
++#define LTQ_SWITCH_MAC_PDI_X_BASE(x) (LTQ_SWITCH_MAC_PDI_0_BASE + x * 0x30)
++#define LTQ_SWITCH_TOPLEVEL_BASE (LTQ_SWITCH_BASE + 4 * 0xC40)
++#define LTQ_SWITCH_MDIO_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE)
++#define LTQ_SWITCH_MII_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x36)
++#define LTQ_SWITCH_PMAC_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x82)
++
++#define LTQ_PMU_BASE 0x1F102000
++#define LTQ_CGU_BASE 0x1F103000
++#define LTQ_DCDC_BASE 0x1F106A00
++#define LTQ_MPS_BASE 0x1F107000
++#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340)
++#define LTQ_RCU_BASE 0x1F203000
++
++#define LTQ_MC_GLOBAL_BASE 0x1F400000
++#define LTQ_MC_DDR_BASE 0x1F401000
++#define LTQ_MC_DDR_CCR_OFFSET(x) (x * 0x10)
++
++#endif /* __VRX200_SOC_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/switch.h
+@@ -0,0 +1,514 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
++ */
++
++#ifndef __VR9_SWITCH_H__
++#define __VR9_SWITCH_H__
++
++/* Switch core registers */
++struct vr9_switch_core_regs {
++ __be32 swres;
++ /* TODO: implement registers */
++ __be32 rsvd0[0x3f];
++};
++
++/* Switch buffer management registers */
++struct vr9_switch_bm_regs {
++ struct bm_core {
++ __be32 ram_val3; /* RAM value 3 */
++ __be32 ram_val2; /* RAM value 2 */
++ __be32 ram_val1; /* RAM value 1 */
++ __be32 ram_val0; /* RAM value 0 */
++ __be32 ram_addr; /* RAM address */
++ __be32 ram_ctrl; /* RAM access control */
++ __be32 fsqm_gctrl; /* Free segment queue global control */
++ __be32 cons_sel; /* Number of consumed segments */
++ __be32 cons_pkt; /* Number of consumed packet pointers */
++ __be32 gctrl; /* Global control */
++ __be32 queue_gctrl; /* Queue manager global control */
++ /* TODO: implement registers */
++ __be32 rsvd0[0x35];
++ } core;
++
++ struct bm_port {
++ __be32 pcfg; /* Port config */
++ __be32 rmon_ctrl; /* RMON control */
++ } port[13];
++
++ __be32 rsvd0[0x66];
++
++ struct bm_queue {
++ __be32 rsvd0;
++ __be32 pqm_rs; /* Packet queue manager rate shape assignment */
++ } queue[32];
++
++ struct bm_shaper {
++ __be32 ctrl; /* Rate shaper control */
++ __be32 cbs; /* Rate shaper committed burst size */
++ __be32 ibs; /* Rate shaper instantaneous burst size */
++ __be32 cir_ext; /* Rate shaper rate exponent */
++ __be32 cir_mant; /* Rate shaper rate mantissa */
++ } shaper[16];
++
++ __be32 rsvd1[0x2a8];
++};
++
++/* Switch parser and classification engine registers */
++struct vr9_switch_pce_regs {
++ struct pce_core {
++ __be32 tbl_key[16]; /* Table key data */
++ __be32 tbl_mask; /* Table mask */
++ __be32 tbl_val[5]; /* Table value */
++ __be32 tbl_addr; /* Table entry address */
++ __be32 tbl_ctrl; /* Table access control */
++ __be32 tbl_stat; /* Table general status */
++ __be32 age_0; /* Aging counter config 0 */
++ __be32 age_1; /* Aging counter config 1 */
++ __be32 pmap_1; /* Port map (monitoring) */
++ __be32 pmap_2; /* Port map (multicast) */
++ __be32 pmap_3; /* Port map (unknown unicast) */
++ __be32 gctrl_0; /* Global control 0 */
++ __be32 gctrl_1; /* Global control 1 */
++ __be32 tcm_gctrl; /* Three-color marker global control */
++ __be32 igmp_ctrl; /* IGMP control */
++ __be32 igmp_drpm; /* IGMP default router port map */
++ __be32 igmp_age_0; /* IGMP aging 0 */
++ __be32 igmp_age_1; /* IGMP aging 1 */
++ __be32 igmp_stat; /* IGMP status */
++ __be32 wol_gctrl; /* Wake-on-LAN control */
++ __be32 wol_da_0; /* Wake-on-LAN destination address 0 */
++ __be32 wol_da_1; /* Wake-on-LAN destination address 1 */
++ __be32 wol_da_2; /* Wake-on-LAN destination address 2 */
++ __be32 wol_pw_0; /* Wake-on-LAN password 0 */
++ __be32 wol_pw_1; /* Wake-on-LAN password 1 */
++ __be32 wol_pw_2; /* Wake-on-LAN password 2 */
++ __be32 ier_0; /* PCE global interrupt enable 0 */
++ __be32 ier_1; /* PCE global interrupt enable 1 */
++ __be32 isr_0; /* PCE global interrupt status 0 */
++ __be32 isr_1; /* PCE global interrupt status 1 */
++ __be32 parser_stat; /* Parser status */
++ __be32 rsvd0[0x6];
++ } core;
++
++ __be32 rsvd0[0x10];
++
++ struct pce_port {
++ __be32 pctrl_0; /* Port control 0 */
++ __be32 pctrl_1; /* Port control 1 */
++ __be32 pctrl_2; /* Port control 2 */
++ __be32 pctrl_3; /* Port control 3 */
++ __be32 wol_ctrl; /* Wake-on-LAN control */
++ __be32 vlan_ctrl; /* VLAN control */
++ __be32 def_pvid; /* Default port VID */
++ __be32 pstat; /* Port status */
++ __be32 pier; /* Interrupt enable */
++ __be32 pisr; /* Interrupt status */
++ } port[13];
++
++ __be32 rsvd1[0x7e];
++
++ struct pce_meter {
++ /* TODO: implement registers */
++ __be32 rsvd0[0x7];
++ } meter[8];
++
++ __be32 rsvd2[0x308];
++};
++
++static inline unsigned int to_pce_tbl_key_id(unsigned int id)
++{
++ BUG_ON(id > 15);
++
++ return 15 - id;
++}
++
++static inline unsigned int to_pce_tbl_value_id(unsigned int id)
++{
++ BUG_ON(id > 4);
++
++ return 4 - id;
++}
++
++/* Switch ethernet MAC registers */
++struct vr9_switch_mac_regs {
++ struct mac_core {
++ __be32 test; /* MAC test */
++ __be32 pfad_cfg; /* Pause frame source address config */
++ __be32 pfsa_0; /* Pause frame source address 0 */
++ __be32 pfsa_1; /* Pause frame source address 1 */
++ __be32 pfsa_2; /* Pause frame source address 2 */
++ __be32 flen; /* Frame length */
++ __be32 vlan_etype_0; /* VLAN ethertype 0 */
++ __be32 vlan_etype_1; /* VLAN ethertype 1 */
++ __be32 ier; /* Interrupt enable */
++ __be32 isr; /* Interrupt status */
++ __be32 rsvd0[0x36];
++ } core;
++
++ struct mac_port {
++ __be32 pstat; /* Port status */
++ __be32 pisr; /* Interrupt status */
++ __be32 pier; /* Interrupt enable */
++ __be32 ctrl_0; /* Control 0 */
++ __be32 ctrl_1; /* Control 1 */
++ __be32 ctrl_2; /* Control 2 */
++ __be32 ctrl_3; /* Control 3 */
++ __be32 ctrl_4; /* Control 4 */
++ __be32 ctrl_5; /* Control 5 */
++ __be32 rsvd0[0x2];
++ __be32 testen; /* Test enable */
++ } port[13];
++
++ __be32 rsvd0[0xa4];
++};
++
++/* Switch Fetch DMA registers */
++struct vr9_switch_fdma_regs {
++ struct fdma_core {
++ __be32 ctrl; /* FDMA control */
++ __be32 stetype; /* Special tag ethertype control */
++ __be32 vtetype; /* VLAN tag ethertype control */
++ __be32 stat; /* FDMA status */
++ __be32 ier; /* FDMA interrupt enable */
++ __be32 isr; /* FDMA interrupt status */
++ } core;
++
++ __be32 rsvd0[0x3a];
++
++ struct fdma_port {
++ __be32 pctrl; /* Port control */
++ __be32 prio; /* Port priority */
++ __be32 pstat_0; /* Port status 0 */
++ __be32 pstat_1; /* Port status 1 */
++ __be32 tstamp_0; /* Egress time stamp 0 */
++ __be32 tstamp_1; /* Egress time stamp 1 */
++ } port[13];
++
++ __be32 rsvd1[0x72];
++};
++
++/* Switch Store DMA registers */
++struct vr9_switch_sdma_regs {
++ struct sdma_core {
++ __be32 ctrl; /* SDMA Control */
++ __be32 fcthr_1; /* Flow control threshold 1 */
++ __be32 rsvd0;
++ __be32 fcthr_3; /* Flow control threshold 3 */
++ __be32 fcthr_4; /* Flow control threshold 4 */
++ __be32 fcthr_5; /* Flow control threshold 5 */
++ __be32 fcthr_6; /* Flow control threshold 6 */
++ __be32 fcthr_7; /* Flow control threshold 7 */
++ __be32 stat_0; /* SDMA status 0 */
++ __be32 stat_1; /* SDMA status 1 */
++ __be32 stat_2; /* SDMA status 2 */
++ __be32 ier; /* SDMA interrupt enable */
++ __be32 isr; /* SDMA interrupt status */
++ } core;
++
++ __be32 rsvd0[0x73];
++
++ struct sdma_port {
++ __be32 pctrl; /* Port control */
++ __be32 prio; /* Port priority */
++ __be32 pstat_0; /* Port status 0 */
++ __be32 pstat_1; /* Port status 1 */
++ __be32 tstamp_0; /* Ingress time stamp 0 */
++ __be32 tstamp_1; /* Ingress time stamp 1 */
++ } port[13];
++
++ __be32 rsvd1[0x32];
++};
++
++/* Switch MDIO control and status registers */
++struct vr9_switch_mdio_regs {
++ __be32 glob_ctrl; /* Global control 0 */
++ __be32 rsvd0[7];
++ __be32 mdio_ctrl; /* MDIO control */
++ __be32 mdio_read; /* MDIO read data */
++ __be32 mdio_write; /* MDIO write data */
++ __be32 mdc_cfg_0; /* MDC clock configuration 0 */
++ __be32 mdc_cfg_1; /* MDC clock configuration 1 */
++ __be32 rsvd1[0x3];
++ __be32 phy_addr[6]; /* PHY address port 5..0 */
++ __be32 mdio_stat[6]; /* MDIO PHY polling status port 0..5 */
++ __be32 aneg_eee[6]; /* EEE auto-neg overrides port 0..5 */
++ __be32 rsvd2[0x14];
++};
++
++static inline unsigned int to_mdio_phyaddr_id(unsigned int id)
++{
++ BUG_ON(id > 5);
++
++ return 5 - id;
++}
++
++/* Switch xMII control registers */
++struct vr9_switch_mii_regs {
++ __be32 mii_cfg0; /* xMII port 0 configuration */
++ __be32 pcdu0; /* Port 0 clock delay configuration */
++ __be32 mii_cfg1; /* xMII port 1 configuration */
++ __be32 pcdu1; /* Port 1 clock delay configuration */
++ __be32 rsvd0[0x6];
++ __be32 mii_cfg5; /* xMII port 5 configuration */
++ __be32 pcdu5; /* Port 5 clock delay configuration */
++ __be32 rsvd1[0x14];
++ __be32 rxb_ctl_0; /* Port 0 receive buffer control */
++ __be32 rxb_ctl_1; /* Port 1 receive buffer control */
++ __be32 rxb_ctl_5; /* Port 5 receive buffer control */
++ __be32 rsvd2[0x28];
++ __be32 dbg_ctl; /* Debug control */
++};
++
++/* Switch Pseudo-MAC registers */
++struct vr9_switch_pmac_regs {
++ __be32 hd_ctl; /* PMAC header control */
++ __be32 tl; /* PMAC type/length */
++ __be32 sa1; /* PMAC source address 1 */
++ __be32 sa2; /* PMAC source address 2 */
++ __be32 sa3; /* PMAC source address 3 */
++ __be32 da1; /* PMAC destination address 1 */
++ __be32 da2; /* PMAC destination address 2 */
++ __be32 da3; /* PMAC destination address 3 */
++ __be32 vlan; /* PMAC VLAN */
++ __be32 rx_ipg; /* PMAC interpacket gap in RX direction */
++ __be32 st_etype; /* PMAC special tag ethertype */
++ __be32 ewan; /* PMAC ethernet WAN group */
++ __be32 ctl; /* PMAC control */
++ __be32 rsvd0[0x2];
++};
++
++struct vr9_switch_regs {
++ struct vr9_switch_core_regs core;
++ struct vr9_switch_bm_regs bm;
++ struct vr9_switch_pce_regs pce;
++ struct vr9_switch_mac_regs mac;
++ struct vr9_switch_fdma_regs fdma;
++ struct vr9_switch_sdma_regs sdma;
++ struct vr9_switch_mdio_regs mdio;
++ struct vr9_switch_mii_regs mii;
++ struct vr9_switch_pmac_regs pmac;
++};
++
++static inline void *to_pce_tbl_key(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ return &regs->pce.core.tbl_key[to_pce_tbl_key_id(id)];
++}
++
++static inline void *to_pce_tbl_value(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ return &regs->pce.core.tbl_val[to_pce_tbl_value_id(id)];
++}
++
++static inline void *to_mac_ctrl(struct vr9_switch_regs *regs,
++ unsigned int id, unsigned int ctrl)
++{
++ struct mac_port *mac = &regs->mac.port[id];
++
++ switch (ctrl) {
++ case 0:
++ return &mac->ctrl_0;
++ case 1:
++ return &mac->ctrl_1;
++ case 2:
++ return &mac->ctrl_2;
++ case 3:
++ return &mac->ctrl_3;
++ case 4:
++ return &mac->ctrl_4;
++ case 5:
++ return &mac->ctrl_5;
++ default:
++ return NULL;
++ }
++}
++
++static inline void *to_mdio_phyaddr(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ return &regs->mdio.phy_addr[to_mdio_phyaddr_id(id)];
++}
++
++static inline void *to_mii_miicfg(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ switch (id) {
++ case 0:
++ return &regs->mii.mii_cfg0;
++ case 1:
++ return &regs->mii.mii_cfg1;
++ case 5:
++ return &regs->mii.mii_cfg5;
++ default:
++ return NULL;
++ }
++}
++
++static inline void *to_mii_pcdu(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ switch (id) {
++ case 0:
++ return &regs->mii.pcdu0;
++ case 1:
++ return &regs->mii.pcdu1;
++ case 5:
++ return &regs->mii.pcdu5;
++ default:
++ return NULL;
++ }
++}
++
++#define VR9_SWITCH_REG_OFFSET(reg) (4 * (reg))
++
++#define BUILD_CHECK_VR9_REG(name, offset) \
++ BUILD_BUG_ON(offsetof(struct vr9_switch_regs, name) != (4 * offset))
++
++static inline void build_check_vr9_registers(void)
++{
++ BUILD_CHECK_VR9_REG(core, 0x0);
++ BUILD_CHECK_VR9_REG(bm.core, 0x40);
++ BUILD_CHECK_VR9_REG(bm.core.queue_gctrl, 0x4a);
++ BUILD_CHECK_VR9_REG(bm.port[0], 0x80);
++ BUILD_CHECK_VR9_REG(bm.queue, 0x100);
++ BUILD_CHECK_VR9_REG(bm.shaper, 0x140);
++ BUILD_CHECK_VR9_REG(pce.core, 0x438);
++ BUILD_CHECK_VR9_REG(pce.core.tbl_ctrl, 0x44f);
++ BUILD_CHECK_VR9_REG(pce.core.parser_stat, 0x469);
++ BUILD_CHECK_VR9_REG(pce.port[0], 0x480);
++ BUILD_CHECK_VR9_REG(pce.meter[0], 0x580);
++ BUILD_CHECK_VR9_REG(mac.core, 0x8c0);
++ BUILD_CHECK_VR9_REG(mac.port[0].pstat, 0x900);
++ BUILD_CHECK_VR9_REG(mac.port[0].ctrl_0, 0x903);
++ BUILD_CHECK_VR9_REG(mac.port[1].pstat, 0x90c);
++ BUILD_CHECK_VR9_REG(mac.port[1].ctrl_0, 0x90f);
++ BUILD_CHECK_VR9_REG(mac.port[2].pstat, 0x918);
++ BUILD_CHECK_VR9_REG(mac.port[2].ctrl_0, 0x91b);
++ BUILD_CHECK_VR9_REG(fdma.core, 0xa40);
++ BUILD_CHECK_VR9_REG(fdma.port[0], 0xa80);
++ BUILD_CHECK_VR9_REG(sdma.core, 0xb40);
++ BUILD_CHECK_VR9_REG(sdma.port[0], 0xbc0);
++ BUILD_CHECK_VR9_REG(mdio, 0xc40);
++ BUILD_CHECK_VR9_REG(mii, (0xc40 + 0x36));
++ BUILD_CHECK_VR9_REG(pmac, (0xc40 + 0x82));
++}
++
++#define BM_GCTRL_F_SRES 1
++
++#define MAC_CTRL0_BM (1 << 12)
++#define MAC_CTRL0_APADEN (1 << 11)
++#define MAC_CTRL0_VPAD2EN (1 << 10)
++#define MAC_CTRL0_VPADEN (1 << 9)
++#define MAC_CTRL0_PADEN (1 << 8)
++#define MAC_CTRL0_FCS (1 << 7)
++#define MAC_CTRL0_FCON_SHIFT 4
++#define MAC_CTRL0_FCON_AUTO (0x0 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_RX (0x1 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_TX (0x2 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_RXTX (0x3 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_NONE (0x4 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FDUP_SHIFT 2
++#define MAC_CTRL0_FDUP_AUTO (0x0 << MAC_CTRL0_FDUP_SHIFT)
++#define MAC_CTRL0_FDUP_EN (0x1 << MAC_CTRL0_FDUP_SHIFT)
++#define MAC_CTRL0_FDUP_DIS (0x3 << MAC_CTRL0_FDUP_SHIFT)
++#define MAC_CTRL0_GMII_AUTO 0x0
++#define MAC_CTRL0_GMII_MII 0x1
++#define MAC_CTRL0_GMII_GMII 0x2
++#define MAC_CTRL0_GMII_GMII_2G 0x3
++
++#define MAC_CTRL1_DEFERMODE (1 << 15)
++#define MAC_CTRL1_SHORTPRE (1 << 8)
++
++#define MAC_CTRL2_MLEN (1 << 3)
++#define MAC_CTRL2_LCHKL (1 << 2)
++#define MAC_CTRL2_LCHKS_DIS 0x0
++#define MAC_CTRL2_LCHKS_UNTAG 0x1
++#define MAC_CTRL2_LCHKS_TAG 0x2
++
++#define PHY_ADDR_LNKST_SHIFT 13
++#define PHY_ADDR_LNKST_AUTO (0x0 << PHY_ADDR_LNKST_SHIFT)
++#define PHY_ADDR_LNKST_UP (0x1 << PHY_ADDR_LNKST_SHIFT)
++#define PHY_ADDR_LNKST_DOWN (0x2 << PHY_ADDR_LNKST_SHIFT)
++#define PHY_ADDR_SPEED_SHIFT 11
++#define PHY_ADDR_SPEED_M10 (0x0 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_SPEED_M100 (0x1 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_SPEED_G1 (0x2 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_SPEED_AUTO (0x3 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_FDUP_SHIFT 9
++#define PHY_ADDR_FDUP_AUTO (0x0 << PHY_ADDR_FDUP_SHIFT)
++#define PHY_ADDR_FDUP_EN (0x1 << PHY_ADDR_FDUP_SHIFT)
++#define PHY_ADDR_FDUP_DIS (0x3 << PHY_ADDR_FDUP_SHIFT)
++#define PHY_ADDR_FCONTX_SHIFT 7
++#define PHY_ADDR_FCONTX_AUTO (0x0 << PHY_ADDR_FCONTX_SHIFT)
++#define PHY_ADDR_FCONTX_EN (0x1 << PHY_ADDR_FCONTX_SHIFT)
++#define PHY_ADDR_FCONTX_DIS (0x3 << PHY_ADDR_FCONTX_SHIFT)
++#define PHY_ADDR_FCONRX_SHIFT 5
++#define PHY_ADDR_FCONRX_AUTO (0x0 << PHY_ADDR_FCONRX_SHIFT)
++#define PHY_ADDR_FCONRX_EN (0x1 << PHY_ADDR_FCONRX_SHIFT)
++#define PHY_ADDR_FCONRX_DIS (0x3 << PHY_ADDR_FCONRX_SHIFT)
++
++#define MII_CFG_RES (1 << 15)
++#define MII_CFG_EN (1 << 14)
++#define MII_CFG_LDCLKDIS (1 << 12)
++#define MII_CFG_MIIRATE_SHIFT 4
++#define MII_CFG_MIIRATE_MASK (0x7 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M2P5 (0x0 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M25 (0x1 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M125 (0x2 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M50 (0x3 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_AUTO (0x4 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIMODE_MASK 0xf
++#define MII_CFG_MIIMODE_MIIP 0x0
++#define MII_CFG_MIIMODE_MIIM 0x1
++#define MII_CFG_MIIMODE_RMIIP 0x2
++#define MII_CFG_MIIMODE_RMIIM 0x3
++#define MII_CFG_MIIMODE_RGMII 0x4
++
++#define PCDU_RXDLY_SHIFT 7
++#define PCDU_RXDLY_MASK (0x7 << PCDU_RXDLY_SHIFT)
++#define PCDU_TXDLY_MASK 0x7
++
++#define PMAC_HD_CTL_FC (1 << 10)
++#define PMAC_HD_CTL_CCRC (1 << 9)
++#define PMAC_HD_CTL_RST (1 << 8)
++#define PMAC_HD_CTL_AST (1 << 7)
++#define PMAC_HD_CTL_RXSH (1 << 6)
++#define PMAC_HD_CTL_RC (1 << 4)
++#define PMAC_HD_CTL_AS (1 << 3)
++#define PMAC_HD_CTL_AC (1 << 2)
++
++#define PCE_PCTRL_0_IGSTEN (1 << 11)
++
++#define FDMA_PCTRL_STEN (1 << 1)
++#define FDMA_PCTRL_EN (1 << 0)
++
++#define SDMA_PCTRL_EN (1 << 0)
++
++#define MDIO_GLOB_CTRL_SE (1 << 15)
++
++#define MDIO_MDC_CFG1_RES (1 << 15)
++#define MDIO_MDC_CFG1_MCEN (1 << 8)
++
++#define MDIO_CTRL_MBUSY (1 << 12)
++#define MDIO_CTRL_OP_READ (1 << 11)
++#define MDIO_CTRL_OP_WRITE (1 << 10)
++#define MDIO_CTRL_PHYAD_SHIFT 5
++#define MDIO_CTRL_PHYAD_MASK (0x1f << MDIO_CTRL_PHYAD_SHIFT)
++#define MDIO_CTRL_REGAD_MASK 0x1f
++
++#endif
+--- a/arch/mips/include/asm/asm.h
++++ b/arch/mips/include/asm/asm.h
+@@ -53,6 +53,7 @@
+ .align 2; \
+ .type symbol, @function; \
+ .ent symbol, 0; \
++ .section .text.symbol,"x"; \
+ symbol: .frame sp, 0, ra
+
+ /*
+@@ -62,7 +63,8 @@ symbol: .frame sp, 0, ra
+ .globl symbol; \
+ .align 2; \
+ .type symbol, @function; \
+- .ent symbol, 0; \
++ .ent symbol, 0; \
++ .section .text.symbol,"x"; \
+ symbol: .frame sp, framesize, rpc
+
+ /*
+--- /dev/null
++++ b/arch/mips/include/asm/gpio.h
+@@ -0,0 +1,7 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <asm/arch/gpio.h>
++#include <asm-generic/gpio.h>
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/chipid.h
+@@ -0,0 +1,74 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_CHIPID_H__
++#define __LANTIQ_CHIPID_H__
++
++enum ltq_chip_partnum {
++ LTQ_SOC_UNKNOWN = 0,
++ LTQ_SOC_VRX288_2 = 0x000B, /* VRX288 v1.2 */
++ LTQ_SOC_VRX268_2 = 0x000C, /* VRX268 v1.2 */
++ LTQ_SOC_GRX288_2 = 0x000D, /* GRX288 v1.2 */
++ LTQ_SOC_DANUBE = 0x0129,
++ LTQ_SOC_DANUBE_S = 0x012B,
++ LTQ_SOC_TWINPASS = 0x012D,
++ LTQ_SOC_VRX288 = 0x01C0, /* VRX288 v1.1 */
++ LTQ_SOC_VRX268 = 0x01C2, /* VRX268 v1.1 */
++ LTQ_SOC_GRX288 = 0x01C9, /* GRX288 v1.1 */
++};
++
++extern unsigned int ltq_chip_version_get(void);
++extern unsigned int ltq_chip_partnum_get(void);
++extern const char *ltq_chip_partnum_str(void);
++
++extern void ltq_chip_print_info(void);
++
++#ifdef CONFIG_SOC_XWAY_DANUBE
++static inline int ltq_soc_is_danube(void)
++{
++ return 1;
++}
++#else
++static inline int ltq_soc_is_danube(void)
++{
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_SOC_XWAY_VRX200
++static inline int ltq_soc_is_vrx200(void)
++{
++ return 1;
++}
++
++static inline int ltq_soc_is_vrx200_v1(void)
++{
++ return ltq_chip_version_get() == 1;
++}
++
++static inline int ltq_soc_is_vrx200_v2(void)
++{
++ return ltq_chip_version_get() == 2;
++}
++#else
++static inline int ltq_soc_is_vrx200(void)
++{
++ return 0;
++}
++
++static inline int ltq_soc_is_vrx200_v1(void)
++{
++ return 0;
++}
++
++static inline int ltq_soc_is_vrx200_v2(void)
++{
++ return 0;
++}
++#endif
++
++#endif /* __LANTIQ_CHIPID_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/clk.h
+@@ -0,0 +1,33 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ *
++ * Based on Lantiq port in Linux kernel
++ */
++
++#ifndef __LANTIQ_CLK_H__
++#define __LANTIQ_CLK_H__
++
++/* Symbolic clock speeds */
++enum ltq_clk {
++ CLOCK_83_MHZ = 83333333,
++ CLOCK_111_MHZ = 111111111,
++ CLOCK_125_MHZ = 125000000,
++ CLOCK_133_MHZ = 133333333,
++ CLOCK_166_MHZ = 166666667,
++ CLOCK_197_MHZ = 197000000,
++ CLOCK_333_MHZ = 333333333,
++ CLOCK_393_MHZ = 393219000,
++ CLOCK_500_MHZ = 500000000,
++ CLOCK_600_MHZ = 600000000,
++ CLOCK_1000_MHZ = 1000000000,
++};
++
++extern unsigned long ltq_get_cpu_clock(void);
++extern unsigned long ltq_get_bus_clock(void);
++extern unsigned long ltq_get_io_region_clock(void);
++
++#endif /* __LANTIQ_CLK_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/config.h
+@@ -0,0 +1,166 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_CONFIG_H__
++#define __LANTIQ_CONFIG_H__
++
++/* Memory usage */
++#define CONFIG_SYS_MAXARGS 24
++#define CONFIG_SYS_MALLOC_LEN 1024*1024
++#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024
++
++/* Command line */
++#define CONFIG_SYS_PROMPT CONFIG_MACH_TYPE " # "
++#define CONFIG_SYS_CBSIZE 512
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
++ sizeof(CONFIG_SYS_PROMPT)+16)
++
++#define CONFIG_SYS_HUSH_PARSER
++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
++
++/*
++ * Enable advanced console features on demand to reduce
++ * flash and RAM footprint
++ */
++#if defined(CONFIG_LTQ_ADVANCED_CONSOLE)
++#define CONFIG_SYS_LONGHELP
++#define CONFIG_AUTO_COMPLETE
++#define CONFIG_CMDLINE_EDITING
++#endif
++
++/* SPI flash SPL */
++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_SPL
++#define CONFIG_SPL_SPI_SUPPORT
++#define CONFIG_SPL_SPI_FLASH_SUPPORT
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SPL
++#endif
++
++/* Common SPL */
++#if defined(CONFIG_SPL)
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SPL_LIBGENERIC_SUPPORT
++#define CONFIG_SPL_GPIO_SUPPORT
++#define CONFIG_SPL_START_S_PATH \
++ "arch/mips/cpu/mips32/lantiq-common"
++#define CONFIG_SPL_LDSCRIPT \
++ "arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds"
++#endif
++
++#if defined(CONFIG_LTQ_SPL_CONSOLE)
++#define CONFIG_SPL_SERIAL_SUPPORT
++#define CONFIG_SPL_LIBCOMMON_SUPPORT
++#endif
++
++#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
++#define CONFIG_LZMA
++#define CONFIG_SPL_LZMA_SUPPORT
++#endif
++
++#if defined(CONFIG_LTQ_SPL_COMP_LZO)
++#define CONFIG_LZO
++#define CONFIG_SPL_LZO_SUPPORT
++#endif
++
++/* Basic commands */
++#define CONFIG_CMD_BDI
++#define CONFIG_CMD_EDITENV
++#define CONFIG_CMD_IMI
++#define CONFIG_CMD_MEMORY
++#define CONFIG_CMD_RUN
++#define CONFIG_CMD_SAVEENV
++#define CONFIG_CMD_LOADS
++#define CONFIG_CMD_LOADB
++
++/* Other U-Boot settings */
++#define CONFIG_UBOOT_VERSION
++#define CONFIG_TIMESTAMP
++
++/* Default environment */
++#define CONFIG_ENV_CONSOLEDEV \
++ "consoledev=" CONFIG_CONSOLE_DEV "\0"
++
++#define CONFIG_ENV_ADDCONSOLE \
++ "addconsole=setenv bootargs $bootargs" \
++ " console=$consoledev,$baudrate\0"
++
++#if defined(CONFIG_NET_DEV)
++#define CONFIG_ENV_NETDEV \
++ "netdev=" CONFIG_NET_DEV "\0"
++#else
++#define CONFIG_ENV_NETDEV \
++ "netdev=eth0\0"
++#endif
++
++#define CONFIG_ENV_ADDIP \
++ "addip=setenv bootargs $bootargs" \
++ " ip=$ipaddr:$serverip::::$netdev:off\0"
++
++#define CONFIG_ENV_ADDETH \
++ "addeth=setenv bootargs $bootargs" \
++ " ethaddr=$ethaddr\0"
++
++#define CONFIG_ENV_ADDMACHTYPE \
++ "addmachtype=setenv bootargs $bootargs" \
++ " machtype=" CONFIG_MACH_TYPE "\0"
++
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define CONFIG_ENV_WRITE_UBOOT_NOR \
++ "write-uboot-nor=" \
++ "protect off " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
++ "erase " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
++ "cp.b $fileaddr " __stringify(CONFIG_SYS_FLASH_BASE) " $filesize\0"
++
++#define CONFIG_ENV_LOAD_UBOOT_NOR \
++ "load-uboot-nor=tftpboot u-boot.bin\0" \
++ "load-uboot-norspl=tftpboot u-boot.ltq.norspl\0" \
++ "load-uboot-norspl-lzo=tftpboot u-boot.ltq.lzo.norspl\0" \
++ "load-uboot-norspl-lzma=tftpboot u-boot.ltq.lzma.norspl\0"
++#else
++#define CONFIG_ENV_WRITE_UBOOT_NOR
++#define CONFIG_ENV_LOAD_UBOOT_NOR
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_ENV_SF_PROBE \
++ "sf-probe=sf probe " __stringify(CONFIG_ENV_SPI_CS) " " \
++ __stringify(CONFIG_ENV_SPI_MAX_HZ) " " \
++ __stringify(CONFIG_ENV_SPI_MODE) " \0"
++
++#define CONFIG_ENV_WRITE_UBOOT_SF \
++ "write-uboot-sf=" \
++ "run sf-probe && sf erase 0 +$filesize && " \
++ "sf write $fileaddr 0 $filesize\0"
++
++#define CONFIG_ENV_LOAD_UBOOT_SF \
++ "load-uboot-sfspl=tftpboot u-boot.ltq.sfspl\0" \
++ "load-uboot-sfspl-lzo=tftpboot u-boot.ltq.lzo.sfspl\0" \
++ "load-uboot-sfspl-lzma=tftpboot u-boot.ltq.lzma.sfspl\0"
++#else
++#define CONFIG_ENV_SF_PROBE
++#define CONFIG_ENV_WRITE_UBOOT_SF
++#define CONFIG_ENV_LOAD_UBOOT_SF
++#endif
++
++#define CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_CONSOLEDEV \
++ CONFIG_ENV_ADDCONSOLE \
++ CONFIG_ENV_NETDEV \
++ CONFIG_ENV_ADDIP \
++ CONFIG_ENV_ADDETH \
++ CONFIG_ENV_ADDMACHTYPE \
++ CONFIG_ENV_WRITE_UBOOT_NOR \
++ CONFIG_ENV_LOAD_UBOOT_NOR \
++ CONFIG_ENV_SF_PROBE \
++ CONFIG_ENV_WRITE_UBOOT_SF \
++ CONFIG_ENV_LOAD_UBOOT_SF
++
++#endif /* __LANTIQ_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/cpu.h
+@@ -0,0 +1,35 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#ifndef __LANTIQ_CPU_H__
++#define __LANTIQ_CPU_H__
++
++enum ltq_boot_select {
++ BOOT_NOR,
++ BOOT_NOR_NO_BOOTROM,
++ BOOT_UART,
++ BOOT_UART_NO_EEPROM,
++ BOOT_SPI,
++ BOOT_NAND,
++ BOOT_PCI,
++ BOOT_MII0,
++ BOOT_RMII0,
++ BOOT_RGMII1,
++ BOOT_UNKNOWN,
++};
++
++enum ltq_boot_select ltq_boot_select(void);
++const char *ltq_boot_select_str(void);
++
++void ltq_pmu_init(void);
++void ltq_ebu_init(void);
++void ltq_gpio_init(void);
++
++void ltq_pll_init(void);
++void ltq_dcdc_init(unsigned int dig_ref);
++
++#endif /* __LANTIQ_CPU_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/dma.h
+@@ -0,0 +1,95 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_DMA_H__
++#define __LANTIQ_DMA_H__
++
++enum ltq_dma_endianess {
++ LTQ_DMA_ENDIANESS_B0_B1_B2_B3, /* No byte swapping */
++ LTQ_DMA_ENDIANESS_B1_B0_B3_B2, /* B0B1B2B3 => B1B0B3B2 */
++ LTQ_DMA_ENDIANESS_B2_B3_B0_B1, /* B0B1B2B3 => B2B3B0B1 */
++ LTQ_DMA_ENDIANESS_B3_B2_B1_B0, /* B0B1B2B3 => B3B2B1B0 */
++};
++
++enum ltq_dma_burst_len {
++ LTQ_DMA_BURST_2WORDS = 1,
++ LTQ_DMA_BURST_4WORDS = 2,
++ LTQ_DMA_BURST_8WORDS = 3,
++};
++
++struct ltq_dma_desc {
++ u32 ctl;
++ u32 addr;
++};
++
++struct ltq_dma_channel {
++ struct ltq_dma_device *dev;
++ u8 chan_no;
++ u8 class;
++ u16 num_desc;
++ struct ltq_dma_desc *desc_base;
++ void *mem_base;
++ u32 dma_addr;
++};
++
++struct ltq_dma_device {
++ enum ltq_dma_endianess rx_endian_swap;
++ enum ltq_dma_endianess tx_endian_swap;
++ enum ltq_dma_burst_len rx_burst_len;
++ enum ltq_dma_burst_len tx_burst_len;
++ struct ltq_dma_channel rx_chan;
++ struct ltq_dma_channel tx_chan;
++ u8 port;
++};
++
++/**
++ * Initialize DMA hardware and driver
++ */
++void ltq_dma_init(void);
++
++/**
++ * Register given DMA client context
++ *
++ * @returns 0 on success, negative value otherwise
++ */
++int ltq_dma_register(struct ltq_dma_device *dev);
++
++/**
++ * Reset and halt all channels related to given DMA client
++ */
++void ltq_dma_reset(struct ltq_dma_device *dev);
++void ltq_dma_enable(struct ltq_dma_device *dev);
++void ltq_dma_disable(struct ltq_dma_device *dev);
++
++/**
++ * Map RX DMA descriptor to memory region
++ *
++ * @returns 0 on success, negative value otherwise
++ */
++int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len);
++
++/**
++ * Check if new data is available.
++ *
++ * @returns length of received data, 0 otherwise
++ */
++int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index);
++
++int ltq_dma_rx_length(struct ltq_dma_device *dev, int index);
++
++/**
++ * Map TX DMA descriptor to memory region
++ *
++ * @returns 0 on success, negative value otherwise
++ */
++int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
++ unsigned long timeout);
++
++int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
++ unsigned long timeout);
++
++#endif /* __LANTIQ_DMA_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/eth.h
+@@ -0,0 +1,36 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_ETH_H__
++#define __LANTIQ_ETH_H__
++
++#include <phy.h>
++
++enum LTQ_ETH_PORT_FLAGS {
++ LTQ_ETH_PORT_NONE = 0,
++ LTQ_ETH_PORT_PHY = 1,
++ LTQ_ETH_PORT_SWITCH = (1 << 1),
++ LTQ_ETH_PORT_MAC = (1 << 2),
++};
++
++struct ltq_eth_port_config {
++ u8 num;
++ u8 phy_addr;
++ u16 flags;
++ phy_interface_t phy_if;
++ u8 rgmii_rx_delay;
++ u8 rgmii_tx_delay;
++};
++
++struct ltq_eth_board_config {
++ const struct ltq_eth_port_config *ports;
++ int num_ports;
++};
++
++extern int ltq_eth_initialize(const struct ltq_eth_board_config *board_config);
++
++#endif /* __LANTIQ_ETH_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/gpio.h
+@@ -0,0 +1,51 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_GPIO_H__
++#define __LANTIQ_GPIO_H__
++
++enum ltq_gpio_dir {
++ GPIO_DIR_IN = 0,
++ GPIO_DIR_OUT
++};
++
++enum ltq_gpio_od {
++ GPIO_OD_ACTIVE = 0,
++ GPIO_OD_NORMAL
++};
++
++enum ltq_gpio_altsel {
++ GPIO_ALTSEL_CLR = 0,
++ GPIO_ALTSEL_SET
++};
++
++extern int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir);
++extern int gpio_set_opendrain(unsigned gpio, int od);
++
++static inline int gpio_to_port(unsigned gpio)
++{
++ return gpio >> 4;
++}
++
++static inline int gpio_to_pin(unsigned gpio)
++{
++ return gpio & 0xF;
++}
++
++static inline int gpio_to_bit(unsigned gpio)
++{
++ return 1 << gpio_to_pin(gpio);
++}
++
++static inline int gpio_to_gpio(unsigned port, unsigned pin)
++{
++ return (port << 4) | (pin & 0xF);
++}
++
++#include <asm-generic/gpio.h>
++
++#endif /* __LANTIQ_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/io.h
+@@ -0,0 +1,38 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_IO_H__
++#define __LANTIQ_IO_H__
++
++#include <asm/io.h>
++
++#define ltq_readb(a) __raw_readb(a)
++#define ltq_writeb(a, v) __raw_writeb(v, a)
++
++#define ltq_readl(a) __raw_readl(a)
++#define ltq_writel(a, v) __raw_writel(v, a)
++
++#define ltq_clrbits(a, clear) \
++ ltq_writel(a, ltq_readl(a) & ~(clear))
++
++#define ltq_setbits(a, set) \
++ ltq_writel(a, ltq_readl(a) | (set))
++
++#define ltq_clrsetbits(a, clear, set) \
++ ltq_writel(a, (ltq_readl(a) & ~(clear)) | (set))
++
++static inline void ltq_reg_dump(const void *addr, const char *desc)
++{
++ u32 data;
++
++ data = ltq_readl(addr);
++ printf("ltq_reg_dump: %s 0x%p = 0x%08x\n",
++ desc, addr, data);
++}
++
++#endif /* __LANTIQ_IO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/pm.h
+@@ -0,0 +1,22 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_PM_H__
++#define __LANTIQ_PM_H__
++
++enum ltq_pm_modules {
++ LTQ_PM_CORE,
++ LTQ_PM_DMA,
++ LTQ_PM_ETH,
++ LTQ_PM_SPI,
++};
++
++u32 ltq_pm_map(enum ltq_pm_modules module);
++int ltq_pm_enable(enum ltq_pm_modules module);
++int ltq_pm_disable(enum ltq_pm_modules module);
++
++#endif /* __LANTIQ_PM_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/reset.h
+@@ -0,0 +1,38 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_RESET_H__
++#define __LANTIQ_RESET_H__
++
++enum ltq_reset_modules {
++ LTQ_RESET_CORE,
++ LTQ_RESET_DMA,
++ LTQ_RESET_ETH,
++ LTQ_RESET_PHY,
++ LTQ_RESET_HARD,
++ LTQ_RESET_SOFT,
++};
++
++extern u32 ltq_reset_map(enum ltq_reset_modules module);
++extern int ltq_reset_activate(enum ltq_reset_modules module);
++extern int ltq_reset_deactivate(enum ltq_reset_modules module);
++
++static inline int ltq_reset_once(enum ltq_reset_modules module, ulong usec)
++{
++ int ret;
++
++ ret = ltq_reset_activate(module);
++ if (ret)
++ return ret;
++
++ __udelay(usec);
++ ret = ltq_reset_deactivate(module);
++
++ return ret;
++}
++
++#endif /* __LANTIQ_RESET_H__ */
+--- a/arch/mips/include/asm/mipsregs.h
++++ b/arch/mips/include/asm/mipsregs.h
+@@ -46,7 +46,10 @@
+ #define CP0_ENTRYLO1 $3
+ #define CP0_CONF $3
+ #define CP0_CONTEXT $4
++#define CP0_CONTEXTCONFIG $4,1
++#define CP0_USERLOCAL $4,1
+ #define CP0_PAGEMASK $5
++#define CP0_PAGEGRAIN $5,1
+ #define CP0_WIRED $6
+ #define CP0_INFO $7
+ #define CP0_BADVADDR $8
+@@ -54,10 +57,19 @@
+ #define CP0_ENTRYHI $10
+ #define CP0_COMPARE $11
+ #define CP0_STATUS $12
++#define CP0_INTCTL $12,1
++#define CP0_SRSCTL $12,2
++#define CP0_SRSMAP $12,3
++#define CP0_SRSHIGH $12,4
+ #define CP0_CAUSE $13
+ #define CP0_EPC $14
+ #define CP0_PRID $15
++#define CP0_EBASE $15,1
+ #define CP0_CONFIG $16
++#define CP0_CONFIG1 $16,1
++#define CP0_CONFIG2 $16,2
++#define CP0_CONFIG3 $16,3
++#define CP0_CONFIG7 $16,7
+ #define CP0_LLADDR $17
+ #define CP0_WATCHLO $18
+ #define CP0_WATCHHI $19
+@@ -70,7 +82,17 @@
+ #define CP0_ECC $26
+ #define CP0_CACHEERR $27
+ #define CP0_TAGLO $28
++#define CP0_ITAGLO $28
++#define CP0_IDATALO $28,1
++#define CP0_DTAGLO $28,2
++#define CP0_DDATALO $28,3
++#define CP0_L23TAGLO $28,4
++#define CP0_L23DATALO $28,5
+ #define CP0_TAGHI $29
++#define CP0_IDATAHI $29,1
++#define CP0_DTAGHI $29,2
++#define CP0_L23TAGHI $29,4
++#define CP0_L23DATAHI $29,5
+ #define CP0_ERROREPC $30
+ #define CP0_DESAVE $31
+
+@@ -395,6 +417,12 @@
+ #define CAUSEF_BD (_ULCAST_(1) << 31)
+
+ /*
++ * Bits in the coprocessor 0 EBase register.
++ */
++#define EBASEB_CPUNUM 0
++#define EBASEF_CPUNUM (_ULCAST_(1023))
++
++/*
+ * Bits in the coprocessor 0 config register.
+ */
+ /* Generic bits. */
+--- a/arch/mips/include/asm/u-boot-mips.h
++++ b/arch/mips/include/asm/u-boot-mips.h
+@@ -9,3 +9,4 @@ extern ulong uboot_end_data;
+ extern ulong uboot_end;
+
+ extern int incaip_set_cpuclk(void);
++extern int arch_cpu_init(void);
+--- a/arch/mips/lib/board.c
++++ b/arch/mips/lib/board.c
+@@ -50,6 +50,16 @@ static char *failed = "*** failed ***\n"
+ */
+ const unsigned long mips_io_port_base = -1;
+
++int __arch_cpu_init(void)
++{
++ /*
++ * Nothing to do in this dummy implementation
++ */
++ return 0;
++}
++int arch_cpu_init(void)
++ __attribute__((weak, alias("__arch_cpu_init")));
++
+ int __board_early_init_f(void)
+ {
+ /*
+@@ -123,6 +133,7 @@ static int init_baudrate(void)
+ typedef int (init_fnc_t)(void);
+
+ init_fnc_t *init_sequence[] = {
++ arch_cpu_init,
+ board_early_init_f,
+ timer_init,
+ env_init, /* initialize environment */
+--- /dev/null
++++ b/board/lantiq/easy50712/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/lantiq/easy50712/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/lantiq/easy50712/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define MC_DC00_VALUE 0x1B1B
++#define MC_DC01_VALUE 0x0
++#define MC_DC02_VALUE 0x0
++#define MC_DC03_VALUE 0x0
++#define MC_DC04_VALUE 0x0
++#define MC_DC05_VALUE 0x200
++#define MC_DC06_VALUE 0x605
++#define MC_DC07_VALUE 0x303
++#define MC_DC08_VALUE 0x102
++#define MC_DC09_VALUE 0x70a
++#define MC_DC10_VALUE 0x203
++#define MC_DC11_VALUE 0xc02
++#define MC_DC12_VALUE 0x1C8
++#define MC_DC13_VALUE 0x1
++#define MC_DC14_VALUE 0x0
++#define MC_DC15_VALUE 0x13c
++#define MC_DC16_VALUE 0xC800
++#define MC_DC17_VALUE 0xd
++#define MC_DC18_VALUE 0x300
++#define MC_DC19_VALUE 0x200
++#define MC_DC20_VALUE 0xA04
++#define MC_DC21_VALUE 0xd00
++#define MC_DC22_VALUE 0xd0d
++#define MC_DC23_VALUE 0x0
++#define MC_DC24_VALUE 0x62
++#define MC_DC25_VALUE 0x0
++#define MC_DC26_VALUE 0x0
++#define MC_DC27_VALUE 0x0
++#define MC_DC28_VALUE 0x510
++#define MC_DC29_VALUE 0x2d89
++#define MC_DC30_VALUE 0x8300
++#define MC_DC31_VALUE 0x0
++#define MC_DC32_VALUE 0x0
++#define MC_DC33_VALUE 0x0
++#define MC_DC34_VALUE 0x0
++#define MC_DC35_VALUE 0x0
++#define MC_DC36_VALUE 0x0
++#define MC_DC37_VALUE 0x0
++#define MC_DC38_VALUE 0x0
++#define MC_DC39_VALUE 0x0
++#define MC_DC40_VALUE 0x0
++#define MC_DC41_VALUE 0x0
++#define MC_DC42_VALUE 0x0
++#define MC_DC43_VALUE 0x0
++#define MC_DC44_VALUE 0x0
++#define MC_DC45_VALUE 0x500
++#define MC_DC46_VALUE 0x0
+--- /dev/null
++++ b/board/lantiq/easy50712/easy50712.c
+@@ -0,0 +1,106 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <spi.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++static void gpio_init(void)
++{
++ /* SPI/CS output (low-active) for serial flash */
++ gpio_direction_output(22, 1);
++
++ /* enable CLK_OUT2 for external switch */
++ gpio_set_altfunc(3, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++ gpio_init();
++
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* MAC0: Lantiq ADM6996I switch */
++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device adm6996i_dev = {
++ .name = "adm6996i",
++ .cpu_port = 5,
++ .port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++ /* Deactivate HRST line to release reset of ADM6996I switch */
++ ltq_reset_once(LTQ_RESET_HARD, 200000);
++
++ /* ADM6996I needs some time to come out of reset */
++ __udelay(50000);
++
++ return switch_device_register(&adm6996i_dev);
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++ if (bus)
++ return 0;
++
++ switch (cs) {
++ case 2:
++ return 1;
++ default:
++ return 0;
++ }
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 2:
++ gpio_set_value(22, 0);
++ break;
++ default:
++ break;
++ }
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 2:
++ gpio_set_value(22, 1);
++ break;
++ default:
++ break;
++ }
++}
+--- /dev/null
++++ b/board/lantiq/easy80920/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/lantiq/easy80920/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/lantiq/easy80920/ddr_settings.h
+@@ -0,0 +1,70 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define MC_CCR00_VALUE 0x101
++#define MC_CCR01_VALUE 0x1000100
++#define MC_CCR02_VALUE 0x1010000
++#define MC_CCR03_VALUE 0x101
++#define MC_CCR04_VALUE 0x1000000
++#define MC_CCR05_VALUE 0x1000101
++#define MC_CCR06_VALUE 0x1000100
++#define MC_CCR07_VALUE 0x1010000
++#define MC_CCR08_VALUE 0x1000101
++#define MC_CCR09_VALUE 0x0
++#define MC_CCR10_VALUE 0x2000100
++#define MC_CCR11_VALUE 0x2000300
++#define MC_CCR12_VALUE 0x30000
++#define MC_CCR13_VALUE 0x202
++#define MC_CCR14_VALUE 0x7080A0F
++#define MC_CCR15_VALUE 0x2040F
++#define MC_CCR16_VALUE 0x40000
++#define MC_CCR17_VALUE 0x70102
++#define MC_CCR18_VALUE 0x4020002
++#define MC_CCR19_VALUE 0x30302
++#define MC_CCR20_VALUE 0x8000700
++#define MC_CCR21_VALUE 0x40F020A
++#define MC_CCR22_VALUE 0x0
++#define MC_CCR23_VALUE 0xC020000
++#define MC_CCR24_VALUE 0x4401B04
++#define MC_CCR25_VALUE 0x0
++#define MC_CCR26_VALUE 0x0
++#define MC_CCR27_VALUE 0x6420000
++#define MC_CCR28_VALUE 0x0
++#define MC_CCR29_VALUE 0x0
++#define MC_CCR30_VALUE 0x798
++#define MC_CCR31_VALUE 0x0
++#define MC_CCR32_VALUE 0x0
++#define MC_CCR33_VALUE 0x650000
++#define MC_CCR34_VALUE 0x200C8
++#define MC_CCR35_VALUE 0x1D445D
++#define MC_CCR36_VALUE 0xC8
++#define MC_CCR37_VALUE 0xC351
++#define MC_CCR38_VALUE 0x0
++#define MC_CCR39_VALUE 0x141F04
++#define MC_CCR40_VALUE 0x142704
++#define MC_CCR41_VALUE 0x141b42
++#define MC_CCR42_VALUE 0x141b42
++#define MC_CCR43_VALUE 0x566504
++#define MC_CCR44_VALUE 0x566504
++#define MC_CCR45_VALUE 0x565F17
++#define MC_CCR46_VALUE 0x565F17
++#define MC_CCR47_VALUE 0x0
++#define MC_CCR48_VALUE 0x0
++#define MC_CCR49_VALUE 0x0
++#define MC_CCR50_VALUE 0x0
++#define MC_CCR51_VALUE 0x0
++#define MC_CCR52_VALUE 0x133
++#define MC_CCR53_VALUE 0xF3014B27
++#define MC_CCR54_VALUE 0xF3014B27
++#define MC_CCR55_VALUE 0xF3014B27
++#define MC_CCR56_VALUE 0xF3014B27
++#define MC_CCR57_VALUE 0x7800301
++#define MC_CCR58_VALUE 0x7800301
++#define MC_CCR59_VALUE 0x7800301
++#define MC_CCR60_VALUE 0x7800301
++#define MC_CCR61_VALUE 0x4
+--- /dev/null
++++ b/board/lantiq/easy80920/easy80920.c
+@@ -0,0 +1,139 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <spi.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SPL_BUILD)
++#define do_gpio_init 1
++#define do_pll_init 1
++#define do_dcdc_init 0
++#elif defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init 1
++#define do_pll_init 0
++#define do_dcdc_init 1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define do_gpio_init 1
++#define do_pll_init 1
++#define do_dcdc_init 1
++#else
++#define do_gpio_init 0
++#define do_pll_init 0
++#define do_dcdc_init 1
++#endif
++
++static void gpio_init(void)
++{
++ /* SPI CS 0.4 to serial flash */
++ gpio_direction_output(10, 1);
++
++ /* EBU.FL_CS1 as output for NAND CE */
++ gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* EBU.FL_A23 as output for NAND CLE */
++ gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* EBU.FL_A24 as output for NAND ALE */
++ gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* GPIO 3.0 as input for NAND Ready Busy */
++ gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++ /* GPIO 3.1 as output for NAND Read */
++ gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++ if (do_gpio_init)
++ gpio_init();
++
++ if (do_pll_init)
++ ltq_pll_init();
++
++ if (do_dcdc_init)
++ ltq_dcdc_init(0x7F);
++
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++ /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
++ { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++ /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++ /* GMAC3: unused */
++ { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++ /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
++ { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++ const ulong fw_addr = 0x80FF0000;
++
++ ltq_gphy_phy11g_a1x_load(fw_addr);
++
++ ltq_cgu_gphy_clk_src(clk);
++
++ ltq_rcu_gphy_boot(0, fw_addr);
++ ltq_rcu_gphy_boot(1, fw_addr);
++
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++ if (bus)
++ return 0;
++
++ if (cs == 4)
++ return 1;
++
++ return 0;
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 4:
++ gpio_set_value(10, 0);
++ break;
++ default:
++ break;
++ }
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 4:
++ gpio_set_value(10, 1);
++ break;
++ default:
++ break;
++ }
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -444,10 +444,17 @@ dbau1500 mips
+ dbau1550 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550
+ dbau1550_el mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN
+ pb1000 mips mips32 pb1x00 - au1x00 pb1x00:PB1000
++easy50712_nor mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NOR
++easy50712_norspl mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NORSPL
++easy50712_ram mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_RAM
+ incaip mips mips32 incaip - incaip
+ incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000
+ incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000
+ incaip_150MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=150000000
++easy80920_nor mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NOR
++easy80920_norspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NORSPL
++easy80920_ram mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_RAM
++easy80920_sfspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_SFSPL
+ qi_lb60 mips xburst qi_lb60 qi
+ adp-ag101 nds32 n1213 adp-ag101 AndesTech ag101
+ adp-ag101p nds32 n1213 adp-ag101p AndesTech ag101
+--- a/drivers/dma/Makefile
++++ b/drivers/dma/Makefile
+@@ -28,6 +28,7 @@ LIB := $(obj)libdma.o
+ COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
+ COBJS-$(CONFIG_APBH_DMA) += apbh_dma.o
+ COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
++COBJS-$(CONFIG_LANTIQ_DMA) += lantiq_dma.o
+ COBJS-$(CONFIG_OMAP3_DMA) += omap3_dma.o
+
+ COBJS := $(COBJS-y)
+--- /dev/null
++++ b/drivers/dma/lantiq_dma.c
+@@ -0,0 +1,388 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <watchdog.h>
++#include <linux/compiler.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/dma.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/arch/soc.h>
++#include <asm/processor.h>
++
++#define DMA_CTRL_PKTARB (1 << 31)
++#define DMA_CTRL_MBRSTARB (1 << 30)
++#define DMA_CTRL_MBRSTCNT_SHIFT 16
++#define DMA_CTRL_MBRSTCNT_MASK (0x3ff << DMA_CTRL_MBRSTCNT_SHIFT)
++#define DMA_CTRL_DRB (1 << 8)
++#define DMA_CTRL_RESET (1 << 0)
++
++#define DMA_CPOLL_EN (1 << 31)
++#define DMA_CPOLL_CNT_SHIFT 4
++#define DMA_CPOLL_CNT_MASK (0xFFF << DMA_CPOLL_CNT_SHIFT)
++
++#define DMA_CCTRL_TXWGT_SHIFT 16
++#define DMA_CCTRL_TXWGT_MASK (0x3 << DMA_CCTRL_TXWGT_SHIFT)
++#define DMA_CCTRL_CLASS_SHIFT 9
++#define DMA_CCTRL_CLASS_MASK (0x3 << DMA_CCTRL_CLASS_SHIFT)
++#define DMA_CCTRL_RST (1 << 1)
++#define DMA_CCTRL_ONOFF (1 << 0)
++
++#define DMA_PCTRL_TXBL_SHIFT 4
++#define DMA_PCTRL_TXBL_2WORDS (1 << DMA_PCTRL_TXBL_SHIFT)
++#define DMA_PCTRL_TXBL_4WORDS (2 << DMA_PCTRL_TXBL_SHIFT)
++#define DMA_PCTRL_TXBL_8WORDS (3 << DMA_PCTRL_TXBL_SHIFT)
++#define DMA_PCTRL_RXBL_SHIFT 2
++#define DMA_PCTRL_RXBL_2WORDS (1 << DMA_PCTRL_RXBL_SHIFT)
++#define DMA_PCTRL_RXBL_4WORDS (2 << DMA_PCTRL_RXBL_SHIFT)
++#define DMA_PCTRL_RXBL_8WORDS (3 << DMA_PCTRL_RXBL_SHIFT)
++#define DMA_PCTRL_TXENDI_SHIFT 10
++#define DMA_PCTRL_TXENDI_MASK (0x3 << DMA_PCTRL_TXENDI_SHIFT)
++#define DMA_PCTRL_RXENDI_SHIFT 8
++#define DMA_PCTRL_RXENDI_MASK (0x3 << DMA_PCTRL_RXENDI_SHIFT)
++
++#define DMA_DESC_OWN (1 << 31)
++#define DMA_DESC_C (1 << 30)
++#define DMA_DESC_SOP (1 << 29)
++#define DMA_DESC_EOP (1 << 28)
++#define DMA_DESC_TX_OFFSET(x) ((x & 0x1f) << 23)
++#define DMA_DESC_RX_OFFSET(x) ((x & 0x3) << 23)
++#define DMA_DESC_LENGTH(x) (x & 0xffff)
++
++#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
++
++struct ltq_dma_regs {
++ u32 clc; /* Clock control */
++ u32 rsvd0;
++ u32 id; /* Identification */
++ u32 rsvd1;
++ u32 ctrl; /* Control */
++ u32 cpoll; /* Channel polling */
++ u32 cs; /* Channel select */
++ u32 cctrl; /* Channel control */
++ u32 cdba; /* Channel descriptor base address */
++ u32 cdlen; /* Channel descriptor length */
++ u32 cis; /* Channel interrupt status */
++ u32 cie; /* Channel interrupt enable */
++ u32 cgbl; /* Channel global buffer length */
++ u32 cdptnrd; /* Current descriptor pointer */
++ u32 rsvd2[2];
++ u32 ps; /* Port select */
++ u32 pctrl; /* Port control */
++ u32 rsvd3[43];
++ u32 irnen; /* Interrupt node enable */
++ u32 irncr; /* Interrupt node control */
++ u32 irnicr; /* Interrupt capture */
++};
++
++static struct ltq_dma_regs *ltq_dma_regs =
++ (struct ltq_dma_regs *) CKSEG1ADDR(LTQ_DMA_BASE);
++
++static inline unsigned long ltq_dma_addr_to_virt(u32 dma_addr)
++{
++ return KSEG0ADDR(dma_addr);
++}
++
++static inline u32 ltq_virt_to_dma_addr(void *addr)
++{
++ return CPHYSADDR(addr);
++}
++
++static inline int ltq_dma_burst_align(enum ltq_dma_burst_len burst_len)
++{
++ switch (burst_len) {
++ case LTQ_DMA_BURST_2WORDS:
++ return 2 * 4;
++ case LTQ_DMA_BURST_4WORDS:
++ return 4 * 4;
++ case LTQ_DMA_BURST_8WORDS:
++ return 8 * 4;
++ }
++
++ return 0;
++}
++
++static inline void ltq_dma_sync(void)
++{
++ __asm__ __volatile__("sync");
++}
++
++static inline void ltq_dma_dcache_wb_inv(const void *ptr, size_t size)
++{
++ unsigned long addr = (unsigned long) ptr;
++
++ flush_dcache_range(addr, addr + size);
++ ltq_dma_sync();
++}
++
++static inline void ltq_dma_dcache_inv(const void *ptr, size_t size)
++{
++ unsigned long addr = (unsigned long) ptr;
++
++ invalidate_dcache_range(addr, addr + size);
++}
++
++void ltq_dma_init(void)
++{
++ /* Power up DMA */
++ ltq_pm_enable(LTQ_PM_DMA);
++
++ /* Reset DMA */
++ ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_RESET);
++
++ /* Disable and clear all interrupts */
++ ltq_writel(&ltq_dma_regs->irnen, 0);
++ ltq_writel(&ltq_dma_regs->irncr, 0xFFFFF);
++
++#if 0
++ /* Enable packet arbitration */
++ ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_PKTARB);
++#endif
++
++#if 0
++ /* Enable descriptor read back */
++ ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_DRB);
++#endif
++
++ /* Enable polling for descriptor fetching for all channels */
++ ltq_writel(&ltq_dma_regs->cpoll, DMA_CPOLL_EN |
++ (4 << DMA_CPOLL_CNT_SHIFT));
++}
++
++static void ltq_dma_channel_reset(struct ltq_dma_channel *chan)
++{
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
++}
++
++static void ltq_dma_channel_enable(struct ltq_dma_channel *chan)
++{
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
++}
++
++static void ltq_dma_channel_disable(struct ltq_dma_channel *chan)
++{
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_clrbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
++}
++
++static void ltq_dma_port_init(struct ltq_dma_device *dev)
++{
++ u32 pctrl;
++
++ pctrl = dev->tx_endian_swap << DMA_PCTRL_TXENDI_SHIFT;
++ pctrl |= dev->rx_endian_swap << DMA_PCTRL_RXENDI_SHIFT;
++ pctrl |= dev->tx_burst_len << DMA_PCTRL_TXBL_SHIFT;
++ pctrl |= dev->rx_burst_len << DMA_PCTRL_RXBL_SHIFT;
++
++ ltq_writel(&ltq_dma_regs->ps, dev->port);
++ ltq_writel(&ltq_dma_regs->pctrl, pctrl);
++}
++
++static int ltq_dma_alloc_descriptors(struct ltq_dma_device *dev,
++ struct ltq_dma_channel *chan)
++{
++ size_t size;
++ void *desc_base;
++
++ size = ALIGN(sizeof(struct ltq_dma_desc) * chan->num_desc +
++ ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
++
++ chan->mem_base = malloc(size);
++ if (!chan->mem_base)
++ return 1;
++
++ memset(chan->mem_base, 0, size);
++ ltq_dma_dcache_wb_inv(chan->mem_base, size);
++
++ desc_base = PTR_ALIGN(chan->mem_base, ARCH_DMA_MINALIGN);
++
++ debug("DMA: mem %p, desc %p\n", chan->mem_base, desc_base);
++
++ /* Align descriptor base to 8 bytes */
++ chan->desc_base = (void *) CKSEG1ADDR(desc_base);
++ chan->dma_addr = CPHYSADDR(desc_base);
++ chan->dev = dev;
++
++ debug("DMA: desc_base %p, size %u\n", chan->desc_base, size);
++
++ /* Configure hardware with location of descriptor list */
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_writel(&ltq_dma_regs->cdba, chan->dma_addr);
++ ltq_writel(&ltq_dma_regs->cdlen, chan->num_desc);
++ ltq_writel(&ltq_dma_regs->cctrl, (3 << DMA_CCTRL_TXWGT_SHIFT) |
++ (chan->class << DMA_CCTRL_CLASS_SHIFT));
++ ltq_writel(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
++
++ return 0;
++}
++
++static void ltq_dma_free_descriptors(struct ltq_dma_channel *chan)
++{
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_writel(&ltq_dma_regs->cdba, 0);
++ ltq_writel(&ltq_dma_regs->cdlen, 0);
++
++ ltq_dma_channel_reset(chan);
++
++ free(chan->mem_base);
++}
++
++int ltq_dma_register(struct ltq_dma_device *dev)
++{
++ int ret;
++
++ ltq_dma_port_init(dev);
++
++ ret = ltq_dma_alloc_descriptors(dev, &dev->rx_chan);
++ if (ret)
++ return ret;
++
++ ret = ltq_dma_alloc_descriptors(dev, &dev->tx_chan);
++ if (ret) {
++ ltq_dma_free_descriptors(&dev->rx_chan);
++ return ret;
++ }
++
++ return 0;
++}
++
++void ltq_dma_reset(struct ltq_dma_device *dev)
++{
++ ltq_dma_channel_reset(&dev->rx_chan);
++ ltq_dma_channel_reset(&dev->tx_chan);
++}
++
++void ltq_dma_enable(struct ltq_dma_device *dev)
++{
++ ltq_dma_channel_enable(&dev->rx_chan);
++ ltq_dma_channel_enable(&dev->tx_chan);
++}
++
++void ltq_dma_disable(struct ltq_dma_device *dev)
++{
++ ltq_dma_channel_disable(&dev->rx_chan);
++ ltq_dma_channel_disable(&dev->tx_chan);
++}
++
++int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len)
++{
++ struct ltq_dma_channel *chan = &dev->rx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++ u32 dma_addr = ltq_virt_to_dma_addr(data);
++ unsigned int offset;
++
++ offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
++
++ ltq_dma_dcache_inv(data, len);
++
++#if 0
++ printf("%s: index %d, data %p, dma_addr %08x, offset %u, len %d\n",
++ __func__, index, data, dma_addr, offset, len);
++#endif
++
++
++ desc->addr = dma_addr - offset;
++ desc->ctl = DMA_DESC_OWN | DMA_DESC_RX_OFFSET(offset) |
++ DMA_DESC_LENGTH(len);
++
++#if 0
++ printf("%s: index %d, desc %p, desc->ctl %08x\n",
++ __func__, index, desc, desc->ctl);
++#endif
++
++ return 0;
++}
++
++int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index)
++{
++ struct ltq_dma_channel *chan = &dev->rx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++
++#if 0
++ printf("%s: index %d, desc %p, desc->ctl %08x\n",
++ __func__, index, desc, desc->ctl);
++#endif
++
++ if (desc->ctl & DMA_DESC_OWN)
++ return 0;
++
++ if (desc->ctl & DMA_DESC_C)
++ return 1;
++
++ return 0;
++}
++
++int ltq_dma_rx_length(struct ltq_dma_device *dev, int index)
++{
++ struct ltq_dma_channel *chan = &dev->rx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++
++ return DMA_DESC_LENGTH(desc->ctl);
++}
++
++int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
++ unsigned long timeout)
++{
++ struct ltq_dma_channel *chan = &dev->tx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++ unsigned int offset;
++ unsigned long timebase = get_timer(0);
++ u32 dma_addr = ltq_virt_to_dma_addr(data);
++
++ while (desc->ctl & DMA_DESC_OWN) {
++ WATCHDOG_RESET();
++
++ if (get_timer(timebase) >= timeout) {
++#if 0
++ printf("%s: timeout: index %d, desc %p, desc->ctl %08x\n",
++ __func__, index, desc, desc->ctl);
++#endif
++ return -1;
++ }
++ }
++
++ offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
++
++#if 0
++ printf("%s: index %d, desc %p, data %p, dma_addr %08x, offset %u, len %d\n",
++ __func__, index, desc, data, dma_addr, offset, len);
++#endif
++
++ ltq_dma_dcache_wb_inv(data, len);
++
++ desc->addr = dma_addr - offset;
++ desc->ctl = DMA_DESC_OWN | DMA_DESC_SOP | DMA_DESC_EOP |
++ DMA_DESC_TX_OFFSET(offset) | DMA_DESC_LENGTH(len);
++
++#if 0
++ printf("%s: index %d, desc %p, desc->ctl %08x\n",
++ __func__, index, desc, desc->ctl);
++#endif
++
++ return 0;
++}
++
++int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
++ unsigned long timeout)
++{
++ struct ltq_dma_channel *chan = &dev->tx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++ unsigned long timebase = get_timer(0);
++
++ while ((desc->ctl & (DMA_DESC_OWN | DMA_DESC_C)) != DMA_DESC_C) {
++ WATCHDOG_RESET();
++
++ if (get_timer(timebase) >= timeout)
++ return -1;
++ }
++
++ return 0;
++}
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -28,6 +28,7 @@ LIB := $(obj)libgpio.o
+ COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o
+ COBJS-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
+ COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
++COBJS-$(CONFIG_LANTIQ_GPIO) += lantiq_gpio.o
+ COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o
+ COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o
+ COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o
+--- /dev/null
++++ b/drivers/gpio/lantiq_gpio.c
+@@ -0,0 +1,330 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/gpio.h>
++#include <asm/lantiq/io.h>
++
++#define SSIO_GPIO_BASE 64
++
++#define SSIO_CON0_SWU (1 << 31)
++#define SSIO_CON0_RZFL (1 << 26)
++#define SSIO_CON0_GPHY1_SHIFT 27
++#define SSIO_CON0_GPHY1_CONFIG ((CONFIG_LTQ_SSIO_GPHY1_MODE & 0x7) << 27)
++
++#define SSIO_CON1_US_FPI (2 << 30)
++#define SSIO_CON1_FPID_2HZ (0 << 23)
++#define SSIO_CON1_FPID_4HZ (1 << 23)
++#define SSIO_CON1_FPID_8HZ (2 << 23)
++#define SSIO_CON1_FPID_10HZ (3 << 23)
++#define SSIO_CON1_FPIS_1_2 (1 << 20)
++#define SSIO_CON1_FPIS_1_32 (2 << 20)
++#define SSIO_CON1_FPIS_1_64 (3 << 20)
++
++#define SSIO_CON1_GPHY2_SHIFT 15
++#define SSIO_CON1_GPHY2_CONFIG ((CONFIG_LTQ_SSIO_GPHY2_MODE & 0x7) << 15)
++
++#define SSIO_CON1_GROUP2 (1 << 2)
++#define SSIO_CON1_GROUP1 (1 << 1)
++#define SSIO_CON1_GROUP0 (1 << 0)
++#define SSIO_CON1_GROUP_CONFIG (0x3)
++
++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
++#define enable_ssio 1
++#else
++#define enable_ssio 0
++
++#define CONFIG_LTQ_SSIO_GPHY1_MODE 0
++#define CONFIG_LTQ_SSIO_GPHY2_MODE 0
++#define CONFIG_LTQ_SSIO_INIT_VALUE 0
++#endif
++
++#ifdef CONFIG_LTQ_SSIO_EDGE_FALLING
++#define SSIO_RZFL_CONFIG SSIO_CON0_RZFL
++#else
++#define SSIO_RZFL_CONFIG 0
++#endif
++
++struct ltq_gpio_port_regs {
++ __be32 out;
++ __be32 in;
++ __be32 dir;
++ __be32 altsel0;
++ __be32 altsel1;
++ __be32 od;
++ __be32 stoff;
++ __be32 pudsel;
++ __be32 puden;
++ __be32 rsvd1[3];
++};
++
++struct ltq_gpio_regs {
++ u32 rsvd[4];
++ struct ltq_gpio_port_regs ports[CONFIG_LTQ_GPIO_MAX_BANKS];
++};
++
++struct ltq_gpio3_regs {
++ u32 rsvd0[13];
++ __be32 od;
++ __be32 pudsel;
++ __be32 puden;
++ u32 rsvd1[9];
++ __be32 altsel1;
++ u32 rsvd2[14];
++ __be32 out;
++ __be32 in;
++ __be32 dir;
++ __be32 altsel0;
++};
++
++struct ltq_ssio_regs {
++ __be32 con0;
++ __be32 con1;
++ __be32 cpu0;
++ __be32 cpu1;
++ __be32 ar;
++};
++
++static struct ltq_gpio_regs *ltq_gpio_regs =
++ (struct ltq_gpio_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
++
++static struct ltq_gpio3_regs *ltq_gpio3_regs =
++ (struct ltq_gpio3_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
++
++static struct ltq_ssio_regs *ltq_ssio_regs =
++ (struct ltq_ssio_regs *) CKSEG1ADDR(LTQ_SSIO_BASE);
++
++static int is_gpio_bank3(unsigned int port)
++{
++#ifdef CONFIG_LTQ_HAS_GPIO_BANK3
++ return port == 3;
++#else
++ return 0;
++#endif
++}
++
++static int is_gpio_ssio(unsigned int gpio)
++{
++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
++ return gpio >= SSIO_GPIO_BASE;
++#else
++ return 0;
++#endif
++}
++
++static inline int ssio_gpio_to_bit(unsigned gpio)
++{
++ return 1 << (gpio - SSIO_GPIO_BASE);
++}
++
++int ltq_gpio_init(void)
++{
++ ltq_writel(&ltq_ssio_regs->ar, 0);
++ ltq_writel(&ltq_ssio_regs->cpu0, CONFIG_LTQ_SSIO_INIT_VALUE);
++ ltq_writel(&ltq_ssio_regs->cpu1, 0);
++ ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_SWU);
++
++ if (enable_ssio) {
++ ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_GPHY1_CONFIG |
++ SSIO_RZFL_CONFIG);
++ ltq_writel(&ltq_ssio_regs->con1, SSIO_CON1_US_FPI |
++ SSIO_CON1_FPID_8HZ | SSIO_CON1_GPHY2_CONFIG |
++ SSIO_CON1_GROUP_CONFIG);
++ }
++
++ return 0;
++}
++
++int gpio_request(unsigned gpio, const char *label)
++{
++ return 0;
++}
++
++int gpio_free(unsigned gpio)
++{
++ return 0;
++}
++
++int gpio_direction_input(unsigned gpio)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++ const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
++ const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
++ const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
++
++ if (is_gpio_ssio(gpio))
++ return 0;
++
++ if (is_gpio_bank3(port)) {
++ gpio_od = &ltq_gpio3_regs->od;
++ gpio_altsel0 = &ltq_gpio3_regs->altsel0;
++ gpio_altsel1 = &ltq_gpio3_regs->altsel1;
++ gpio_dir = &ltq_gpio3_regs->dir;
++ }
++
++ /*
++ * Reset open drain and altsel configs to workaround improper
++ * reset values or unwanted modifications by BootROM
++ */
++ ltq_clrbits(gpio_od, gpio_to_bit(gpio));
++ ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
++ ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
++
++ /* Switch to input */
++ ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
++
++ return 0;
++}
++
++int gpio_direction_output(unsigned gpio, int value)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++ const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
++ const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
++ const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
++ const void *gpio_out = &ltq_gpio_regs->ports[port].out;
++ u32 data = gpio_to_bit(gpio);
++
++ if (is_gpio_ssio(gpio)) {
++ data = ssio_gpio_to_bit(gpio);
++ if (value)
++ ltq_setbits(&ltq_ssio_regs->cpu0, data);
++ else
++ ltq_clrbits(&ltq_ssio_regs->cpu0, data);
++
++ return 0;
++ }
++
++ if (is_gpio_bank3(port)) {
++ gpio_od = &ltq_gpio3_regs->od;
++ gpio_altsel0 = &ltq_gpio3_regs->altsel0;
++ gpio_altsel1 = &ltq_gpio3_regs->altsel1;
++ gpio_dir = &ltq_gpio3_regs->dir;
++ gpio_out = &ltq_gpio3_regs->out;
++ }
++
++ /*
++ * Reset open drain and altsel configs to workaround improper
++ * reset values or unwanted modifications by BootROM
++ */
++ ltq_setbits(gpio_od, data);
++ ltq_clrbits(gpio_altsel0, data);
++ ltq_clrbits(gpio_altsel1, data);
++
++ if (value)
++ ltq_setbits(gpio_out, data);
++ else
++ ltq_clrbits(gpio_out, data);
++
++ /* Switch to output */
++ ltq_setbits(gpio_dir, data);
++
++ return 0;
++}
++
++int gpio_get_value(unsigned gpio)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_in = &ltq_gpio_regs->ports[port].in;
++ u32 data = gpio_to_bit(gpio);
++ u32 val;
++
++ if (is_gpio_ssio(gpio)) {
++ gpio_in = &ltq_ssio_regs->cpu0;
++ data = ssio_gpio_to_bit(gpio);
++ }
++
++ if (is_gpio_bank3(port))
++ gpio_in = &ltq_gpio3_regs->in;
++
++ val = ltq_readl(gpio_in);
++
++ return !!(val & data);
++}
++
++int gpio_set_value(unsigned gpio, int value)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_out = &ltq_gpio_regs->ports[port].out;
++ u32 data = gpio_to_bit(gpio);
++
++ if (is_gpio_ssio(gpio)) {
++ gpio_out = &ltq_ssio_regs->cpu0;
++ data = ssio_gpio_to_bit(gpio);
++ }
++
++ if (is_gpio_bank3(port))
++ gpio_out = &ltq_gpio3_regs->out;
++
++ if (value)
++ ltq_setbits(gpio_out, data);
++ else
++ ltq_clrbits(gpio_out, data);
++
++ return 0;
++}
++
++int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++ const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
++ const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
++ const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
++
++ if (is_gpio_ssio(gpio))
++ return 0;
++
++ if (is_gpio_bank3(port)) {
++ gpio_od = &ltq_gpio3_regs->od;
++ gpio_altsel0 = &ltq_gpio3_regs->altsel0;
++ gpio_altsel1 = &ltq_gpio3_regs->altsel1;
++ gpio_dir = &ltq_gpio3_regs->dir;
++ }
++
++ if (altsel0)
++ ltq_setbits(gpio_altsel0, gpio_to_bit(gpio));
++ else
++ ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
++
++ if (altsel1)
++ ltq_setbits(gpio_altsel1, gpio_to_bit(gpio));
++ else
++ ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
++
++ if (dir) {
++ ltq_setbits(gpio_od, gpio_to_bit(gpio));
++ ltq_setbits(gpio_dir, gpio_to_bit(gpio));
++ } else {
++ ltq_clrbits(gpio_od, gpio_to_bit(gpio));
++ ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
++ }
++
++ return 0;
++}
++
++int gpio_set_opendrain(unsigned gpio, int od)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++
++ if (is_gpio_ssio(gpio))
++ return 0;
++
++ if (is_gpio_bank3(port))
++ gpio_od = &ltq_gpio3_regs->od;
++
++ if (od)
++ ltq_setbits(gpio_od, gpio_to_bit(gpio));
++ else
++ ltq_clrbits(gpio_od, gpio_to_bit(gpio));
++
++ return 0;
++}
+--- a/drivers/mtd/cfi_flash.c
++++ b/drivers/mtd/cfi_flash.c
+@@ -177,6 +177,18 @@ u64 flash_read64(void *addr)__attribute_
+ #define flash_read64 __flash_read64
+ #endif
+
++static inline void *__flash_swap_addr(unsigned long addr)
++{
++ return (void *) addr;
++}
++
++#ifdef CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++void *flash_swap_addr(unsigned long addr)
++ __attribute__((weak, alias("__flash_swap_addr")));
++#else
++#define flash_swap_addr __flash_swap_addr
++#endif
++
+ /*-----------------------------------------------------------------------
+ */
+ #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
+@@ -212,7 +224,7 @@ flash_map (flash_info_t * info, flash_se
+ {
+ unsigned int byte_offset = offset * info->portwidth;
+
+- return (void *)(info->start[sect] + byte_offset);
++ return flash_swap_addr(info->start[sect] + byte_offset);
+ }
+
+ static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -67,6 +67,7 @@ COBJS-$(CONFIG_NAND_JZ4740) += jz4740_na
+ COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
+ COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
+ COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
++COBJS-$(CONFIG_NAND_LANTIQ) += lantiq_nand.o
+ COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
+ COBJS-$(CONFIG_NAND_MXC) += mxc_nand.o
+ COBJS-$(CONFIG_NAND_MXS) += mxs_nand.o
+--- /dev/null
++++ b/drivers/mtd/nand/lantiq_nand.c
+@@ -0,0 +1,127 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#include <common.h>
++#include <linux/mtd/nand.h>
++#include <linux/compiler.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/nand.h>
++#include <asm/lantiq/io.h>
++
++#define NAND_CON_ECC_ON (1 << 31)
++#define NAND_CON_LATCH_PRE (1 << 23)
++#define NAND_CON_LATCH_WP (1 << 22)
++#define NAND_CON_LATCH_SE (1 << 21)
++#define NAND_CON_LATCH_CS (1 << 20)
++#define NAND_CON_LATCH_CLE (1 << 19)
++#define NAND_CON_LATCH_ALE (1 << 18)
++#define NAND_CON_OUT_CS1 (1 << 10)
++#define NAND_CON_IN_CS1 (1 << 8)
++#define NAND_CON_PRE_P (1 << 7)
++#define NAND_CON_WP_P (1 << 6)
++#define NAND_CON_SE_P (1 << 5)
++#define NAND_CON_CS_P (1 << 4)
++#define NAND_CON_CLE_P (1 << 3)
++#define NAND_CON_ALE_P (1 << 2)
++#define NAND_CON_CSMUX (1 << 1)
++#define NAND_CON_NANDM (1 << 0)
++
++#define NAND_WAIT_WR_C (1 << 3)
++#define NAND_WAIT_RDBY (1 << 0)
++
++#define NAND_CMD_ALE (1 << 2)
++#define NAND_CMD_CLE (1 << 3)
++#define NAND_CMD_CS (1 << 4)
++#define NAND_CMD_SE (1 << 5)
++#define NAND_CMD_WP (1 << 6)
++#define NAND_CMD_PRE (1 << 7)
++
++struct ltq_nand_regs {
++ __be32 con; /* NAND controller control */
++ __be32 wait; /* NAND Flash Device RD/BY State */
++ __be32 ecc0; /* NAND Flash ECC Register 0 */
++ __be32 ecc_ac; /* NAND Flash ECC Register address counter */
++ __be32 ecc_cr; /* NAND Flash ECC Comparison */
++};
++
++static struct ltq_nand_regs *ltq_nand_regs =
++ (struct ltq_nand_regs *) CKSEG1ADDR(LTQ_EBU_NAND_BASE);
++
++static void ltq_nand_wait_ready(void)
++{
++ while ((ltq_readl(&ltq_nand_regs->wait) & NAND_WAIT_WR_C) == 0)
++ ;
++}
++
++static int ltq_nand_dev_ready(struct mtd_info *mtd)
++{
++ u32 data = ltq_readl(&ltq_nand_regs->wait);
++ return data & NAND_WAIT_RDBY;
++}
++
++static void ltq_nand_select_chip(struct mtd_info *mtd, int chip)
++{
++ if (chip == 0) {
++ ltq_setbits(&ltq_nand_regs->con, NAND_CON_NANDM);
++ ltq_setbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
++ } else {
++ ltq_clrbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
++ ltq_clrbits(&ltq_nand_regs->con, NAND_CON_NANDM);
++ }
++}
++
++static void ltq_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
++{
++ struct nand_chip *chip = mtd->priv;
++ unsigned long addr = (unsigned long) chip->IO_ADDR_W;
++
++ if (ctrl & NAND_CTRL_CHANGE) {
++ if (ctrl & NAND_ALE)
++ addr |= NAND_CMD_ALE;
++ else
++ addr &= ~NAND_CMD_ALE;
++
++ if (ctrl & NAND_CLE)
++ addr |= NAND_CMD_CLE;
++ else
++ addr &= ~NAND_CMD_CLE;
++
++ chip->IO_ADDR_W = (void __iomem *) addr;
++ }
++
++ if (cmd != NAND_CMD_NONE) {
++ writeb(cmd, chip->IO_ADDR_W);
++ ltq_nand_wait_ready();
++ }
++}
++
++int ltq_nand_init(struct nand_chip *nand)
++{
++ /* Enable NAND, set NAND CS to EBU CS1, enable EBU CS mux */
++ ltq_writel(&ltq_nand_regs->con, NAND_CON_OUT_CS1 | NAND_CON_IN_CS1 |
++ NAND_CON_PRE_P | NAND_CON_WP_P | NAND_CON_SE_P |
++ NAND_CON_CS_P | NAND_CON_CSMUX);
++
++ nand->dev_ready = ltq_nand_dev_ready;
++ nand->select_chip = ltq_nand_select_chip;
++ nand->cmd_ctrl = ltq_nand_cmd_ctrl;
++
++ nand->chip_delay = 30;
++ nand->options = 0;
++ nand->ecc.mode = NAND_ECC_SOFT;
++
++ /* Enable CS bit in address offset */
++ nand->IO_ADDR_R = nand->IO_ADDR_R + NAND_CMD_CS;
++ nand->IO_ADDR_W = nand->IO_ADDR_W + NAND_CMD_CS;
++
++ return 0;
++}
++
++__weak int board_nand_init(struct nand_chip *chip)
++{
++ return ltq_nand_init(chip);
++}
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -51,6 +51,8 @@ COBJS-$(CONFIG_GRETH) += greth.o
+ COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
+ COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
+ COBJS-$(CONFIG_LAN91C96) += lan91c96.o
++COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o
++COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o
+ COBJS-$(CONFIG_MACB) += macb.o
+ COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
+ COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
+--- /dev/null
++++ b/drivers/net/lantiq_danube_etop.c
+@@ -0,0 +1,411 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <switch.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/dma.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PPE_ETOP_MDIO_ACC_RA (1 << 31)
++#define LTQ_PPE_ETOP_MDIO_CFG_UMM1 (1 << 2)
++#define LTQ_PPE_ETOP_MDIO_CFG_UMM0 (1 << 1)
++
++#define LTQ_PPE_ETOP_CFG_TCKINV1 (1 << 11)
++#define LTQ_PPE_ETOP_CFG_TCKINV0 (1 << 10)
++#define LTQ_PPE_ETOP_CFG_FEN1 (1 << 9)
++#define LTQ_PPE_ETOP_CFG_FEN0 (1 << 8)
++#define LTQ_PPE_ETOP_CFG_SEN1 (1 << 7)
++#define LTQ_PPE_ETOP_CFG_SEN0 (1 << 6)
++#define LTQ_PPE_ETOP_CFG_TURBO1 (1 << 5)
++#define LTQ_PPE_ETOP_CFG_REMII1 (1 << 4)
++#define LTQ_PPE_ETOP_CFG_OFF1 (1 << 3)
++#define LTQ_PPE_ETOP_CFG_TURBO0 (1 << 2)
++#define LTQ_PPE_ETOP_CFG_REMII0 (1 << 1)
++#define LTQ_PPE_ETOP_CFG_OFF0 (1 << 0)
++
++#define LTQ_PPE_ENET0_MAC_CFG_CGEN (1 << 11)
++#define LTQ_PPE_ENET0_MAC_CFG_DUPLEX (1 << 2)
++#define LTQ_PPE_ENET0_MAC_CFG_SPEED (1 << 1)
++#define LTQ_PPE_ENET0_MAC_CFG_LINK (1 << 0)
++
++#define LTQ_PPE_ENETS0_CFG_FTUC (1 << 28)
++
++#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX
++#define LTQ_ETH_TX_BUFFER_CNT 8
++#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN
++#define LTQ_ETH_IP_ALIGN 2
++
++#define LTQ_MDIO_DRV_NAME "ltq-mdio"
++#define LTQ_ETH_DRV_NAME "ltq-eth"
++
++struct ltq_ppe_etop_regs {
++ u32 mdio_cfg; /* MDIO configuration */
++ u32 mdio_acc; /* MDIO access */
++ u32 cfg; /* ETOP configuration */
++ u32 ig_vlan_cos; /* IG VLAN priority CoS mapping */
++ u32 ig_dscp_cos3; /* IG DSCP CoS mapping 3 */
++ u32 ig_dscp_cos2; /* IG DSCP CoS mapping 2 */
++ u32 ig_dscp_cos1; /* IG DSCP CoS mapping 1 */
++ u32 ig_dscp_cos0; /* IG DSCP CoS mapping 0 */
++ u32 ig_plen_ctrl; /* IG frame length control */
++ u32 rsvd0[3];
++ u32 vpid; /* VLAN protocol ID */
++};
++
++struct ltq_ppe_enet_regs {
++ u32 mac_cfg; /* MAC configuration */
++ u32 rsvd0[3];
++ u32 ig_cfg; /* Ingress configuration */
++ u32 ig_pgcnt; /* Ingress buffer used page count */
++ u32 rsvd1;
++ u32 ig_buf_ctrl; /* Ingress buffer backpressure ctrl */
++ u32 cos_cfg; /* Classification configuration */
++ u32 ig_drop; /* Total ingress drop frames */
++ u32 ig_err; /* Total ingress error frames */
++ u32 mac_da0; /* Ingress MAC address 0 */
++ u32 mac_da1; /* Ingress MAC address 1 */
++ u32 rsvd2[22];
++ u32 pgcnt; /* Page counter */
++ u32 rsvd3;
++ u32 hf_ctrl; /* Half duplex control */
++ u32 tx_ctrl; /* Transmit control */
++ u32 rsvd4;
++ u32 vlcos0; /* VLAN insertion config CoS 0 */
++ u32 vlcos1; /* VLAN insertion config CoS 1 */
++ u32 vlcos2; /* VLAN insertion config CoS 2 */
++ u32 vlcos3; /* VLAN insertion config CoS 3 */
++ u32 eg_col; /* Total egress collision frames */
++ u32 eg_drop; /* Total egress drop frames */
++};
++
++struct ltq_eth_priv {
++ struct ltq_dma_device dma_dev;
++ struct mii_dev *bus;
++ struct eth_device *dev;
++ int rx_num;
++ int tx_num;
++};
++
++struct ltq_mdio_access {
++ union {
++ struct {
++ unsigned ra:1;
++ unsigned rw:1;
++ unsigned rsvd:4;
++ unsigned phya:5;
++ unsigned rega:5;
++ unsigned phyd:16;
++ } reg;
++ u32 val;
++ };
++};
++
++static struct ltq_ppe_etop_regs *ltq_ppe_etop_regs =
++ (struct ltq_ppe_etop_regs *) CKSEG1ADDR(LTQ_PPE_ETOP_BASE);
++
++static struct ltq_ppe_enet_regs *ltq_ppe_enet0_regs =
++ (struct ltq_ppe_enet_regs *) CKSEG1ADDR(LTQ_PPE_ENET0_BASE);
++
++static inline int ltq_mdio_poll(void)
++{
++ struct ltq_mdio_access acc;
++ unsigned cnt = 10000;
++
++ while (likely(cnt--)) {
++ acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
++ if (!acc.reg.ra)
++ return 0;
++ }
++
++ return 1;
++}
++
++static int ltq_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
++ int regnum)
++{
++ struct ltq_mdio_access acc;
++ int ret;
++
++ acc.val = 0;
++ acc.reg.ra = 1;
++ acc.reg.rw = 1;
++ acc.reg.phya = addr;
++ acc.reg.rega = regnum;
++
++ ret = ltq_mdio_poll();
++ if (ret)
++ return ret;
++
++ ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
++
++ ret = ltq_mdio_poll();
++ if (ret)
++ return ret;
++
++ acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
++
++ return acc.reg.phyd;
++}
++
++static int ltq_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
++ int regnum, u16 val)
++{
++ struct ltq_mdio_access acc;
++ int ret;
++
++ acc.val = 0;
++ acc.reg.ra = 1;
++ acc.reg.rw = 0;
++ acc.reg.phya = addr;
++ acc.reg.rega = regnum;
++ acc.reg.phyd = val;
++
++ ret = ltq_mdio_poll();
++ if (ret)
++ return ret;
++
++ ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
++
++ return 0;
++}
++
++static inline void ltq_eth_write_hwaddr(const struct eth_device *dev)
++{
++ u32 da0, da1;
++
++ da0 = (dev->enetaddr[0] << 24) + (dev->enetaddr[1] << 16) +
++ (dev->enetaddr[2] << 8) + dev->enetaddr[3];
++ da1 = (dev->enetaddr[4] << 24) + (dev->enetaddr[5] << 16);
++
++ ltq_writel(&ltq_ppe_enet0_regs->mac_da0, da0);
++ ltq_writel(&ltq_ppe_enet0_regs->mac_da1, da1);
++}
++
++static inline u8 *ltq_eth_rx_packet_align(int rx_num)
++{
++ u8 *packet = (u8 *) NetRxPackets[rx_num];
++
++ /*
++ * IP header needs
++ */
++ return packet + LTQ_ETH_IP_ALIGN;
++}
++
++static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ int i;
++
++ ltq_eth_write_hwaddr(dev);
++
++ for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
++ ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
++ LTQ_ETH_RX_DATA_SIZE);
++
++ ltq_dma_enable(dma_dev);
++
++ priv->rx_num = 0;
++ priv->tx_num = 0;
++
++ return 0;
++}
++
++static void ltq_eth_halt(struct eth_device *dev)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++
++ ltq_dma_reset(dma_dev);
++}
++
++static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ int err;
++
++ /* Minimum payload length w/ CRC is 60 bytes */
++ if (length < 60)
++ length = 60;
++
++ err = ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
++ if (err) {
++ puts("NET: timeout on waiting for TX descriptor\n");
++ return -1;
++ }
++
++ priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
++
++ return err;
++}
++
++static int ltq_eth_recv(struct eth_device *dev)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ u8 *packet;
++ int len;
++
++ if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
++ return 0;
++
++#if 0
++ printf("%s: rx_num %d\n", __func__, priv->rx_num);
++#endif
++
++ len = ltq_dma_rx_length(dma_dev, priv->rx_num);
++ packet = ltq_eth_rx_packet_align(priv->rx_num);
++
++#if 0
++ printf("%s: received: packet %p, len %u, rx_num %d\n",
++ __func__, packet, len, priv->rx_num);
++#endif
++
++ if (len)
++ NetReceive(packet, len);
++
++ ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
++ LTQ_ETH_RX_DATA_SIZE);
++
++ priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
++
++ return 0;
++}
++
++static void ltq_eth_hw_init(const struct ltq_eth_port_config *port)
++{
++ u32 data;
++
++ /* Power up ethernet subsystems */
++ ltq_pm_enable(LTQ_PM_ETH);
++
++ /* Reset ethernet subsystems */
++ ltq_reset_once(LTQ_RESET_ETH, 1);
++
++ /* Disable MDIO auto-detection */
++ ltq_clrbits(&ltq_ppe_etop_regs->mdio_cfg, LTQ_PPE_ETOP_MDIO_CFG_UMM1 |
++ LTQ_PPE_ETOP_MDIO_CFG_UMM0);
++
++ /* Enable CRC generation, Full Duplex, 100Mbps, Link up */
++ ltq_writel(&ltq_ppe_enet0_regs->mac_cfg, LTQ_PPE_ENET0_MAC_CFG_CGEN |
++ LTQ_PPE_ENET0_MAC_CFG_DUPLEX |
++ LTQ_PPE_ENET0_MAC_CFG_SPEED |
++ LTQ_PPE_ENET0_MAC_CFG_LINK);
++
++ /* Reset ETOP cfg and disable all */
++ data = LTQ_PPE_ETOP_CFG_OFF0 | LTQ_PPE_ETOP_CFG_OFF1;
++
++ /* Enable ENET0, enable store and fetch */
++ data &= ~LTQ_PPE_ETOP_CFG_OFF0;
++ data |= LTQ_PPE_ETOP_CFG_SEN0 | LTQ_PPE_ETOP_CFG_FEN0;
++
++ if (port->phy_if == PHY_INTERFACE_MODE_RMII)
++ data |= LTQ_PPE_ETOP_CFG_REMII0;
++ else
++ data &= ~LTQ_PPE_ETOP_CFG_REMII0;
++
++ ltq_writel(&ltq_ppe_etop_regs->cfg, data);
++
++ /* Set allowed packet length from 64 bytes to 1518 bytes */
++ ltq_writel(&ltq_ppe_etop_regs->ig_plen_ctrl, (64 << 16) | 1518);
++
++ /* Enable filter for unicast packets */
++ ltq_setbits(&ltq_ppe_enet0_regs->ig_cfg, LTQ_PPE_ENETS0_CFG_FTUC);
++}
++
++int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
++{
++ struct eth_device *dev;
++ struct mii_dev *bus;
++ struct ltq_eth_priv *priv;
++ struct ltq_dma_device *dma_dev;
++ const struct ltq_eth_port_config *port = &board_config->ports[0];
++ struct phy_device *phy;
++ struct switch_device *sw;
++ int ret;
++
++ ltq_dma_init();
++ ltq_eth_hw_init(port);
++
++ dev = calloc(1, sizeof(*dev));
++ if (!dev)
++ return -1;
++
++ priv = calloc(1, sizeof(*priv));
++ if (!priv)
++ return -1;
++
++ bus = mdio_alloc();
++ if (!bus)
++ return -1;
++
++ sprintf(dev->name, LTQ_ETH_DRV_NAME);
++ dev->priv = priv;
++ dev->init = ltq_eth_init;
++ dev->halt = ltq_eth_halt;
++ dev->recv = ltq_eth_recv;
++ dev->send = ltq_eth_send;
++
++ sprintf(bus->name, LTQ_MDIO_DRV_NAME);
++ bus->read = ltq_mdio_read;
++ bus->write = ltq_mdio_write;
++ bus->priv = priv;
++
++ dma_dev = &priv->dma_dev;
++ dma_dev->port = 0;
++ dma_dev->rx_chan.chan_no = 6;
++ dma_dev->rx_chan.class = 3;
++ dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
++ dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++ dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
++ dma_dev->tx_chan.chan_no = 7;
++ dma_dev->tx_chan.class = 3;
++ dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
++ dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++ dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
++
++ priv->bus = bus;
++ priv->dev = dev;
++
++ ret = ltq_dma_register(dma_dev);
++ if (ret)
++ return ret;
++
++ ret = mdio_register(bus);
++ if (ret)
++ return ret;
++
++ ret = eth_register(dev);
++ if (ret)
++ return ret;
++
++ if (port->flags & LTQ_ETH_PORT_SWITCH) {
++ sw = switch_connect(bus);
++ if (!sw)
++ return -1;
++
++ switch_setup(sw);
++ }
++
++ if (port->flags & LTQ_ETH_PORT_PHY) {
++ phy = phy_connect(bus, port->phy_addr, dev, port->phy_if);
++ if (!phy)
++ return -1;
++
++ phy_config(phy);
++ }
++
++ return 0;
++}
+--- /dev/null
++++ b/drivers/net/lantiq_vrx200_switch.c
+@@ -0,0 +1,676 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010-2011 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define DEBUG
++
++#include <common.h>
++#include <malloc.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <linux/compiler.h>
++#include <asm/gpio.h>
++#include <asm/processor.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/dma.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/switch.h>
++
++#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX
++#define LTQ_ETH_TX_BUFFER_CNT 8
++#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN
++#define LTQ_ETH_IP_ALIGN 2
++
++#define LTQ_MDIO_DRV_NAME "ltq-mdio"
++#define LTQ_ETH_DRV_NAME "ltq-eth"
++
++#define LTQ_ETHSW_MAX_GMAC 6
++#define LTQ_ETHSW_PMAC 6
++
++struct ltq_mdio_phy_addr_reg {
++ union {
++ struct {
++ unsigned rsvd:1;
++ unsigned lnkst:2; /* Link status control */
++ unsigned speed:2; /* Speed control */
++ unsigned fdup:2; /* Full duplex control */
++ unsigned fcontx:2; /* Flow control mode TX */
++ unsigned fconrx:2; /* Flow control mode RX */
++ unsigned addr:5; /* PHY address */
++ } bits;
++ u16 val;
++ };
++};
++
++enum ltq_mdio_phy_addr_lnkst {
++ LTQ_MDIO_PHY_ADDR_LNKST_AUTO = 0,
++ LTQ_MDIO_PHY_ADDR_LNKST_UP = 1,
++ LTQ_MDIO_PHY_ADDR_LNKST_DOWN = 2,
++};
++
++enum ltq_mdio_phy_addr_speed {
++ LTQ_MDIO_PHY_ADDR_SPEED_M10 = 0,
++ LTQ_MDIO_PHY_ADDR_SPEED_M100 = 1,
++ LTQ_MDIO_PHY_ADDR_SPEED_G1 = 2,
++ LTQ_MDIO_PHY_ADDR_SPEED_AUTO = 3,
++};
++
++enum ltq_mdio_phy_addr_fdup {
++ LTQ_MDIO_PHY_ADDR_FDUP_AUTO = 0,
++ LTQ_MDIO_PHY_ADDR_FDUP_ENABLE = 1,
++ LTQ_MDIO_PHY_ADDR_FDUP_DISABLE = 3,
++};
++
++enum ltq_mdio_phy_addr_fcon {
++ LTQ_MDIO_PHY_ADDR_FCON_AUTO = 0,
++ LTQ_MDIO_PHY_ADDR_FCON_ENABLE = 1,
++ LTQ_MDIO_PHY_ADDR_FCON_DISABLE = 3,
++};
++
++struct ltq_mii_mii_cfg_reg {
++ union {
++ struct {
++ unsigned res:1; /* Hardware reset */
++ unsigned en:1; /* xMII interface enable */
++ unsigned isol:1; /* xMII interface isolate */
++ unsigned ldclkdis:1; /* Link down clock disable */
++ unsigned rsvd:1;
++ unsigned crs:2; /* CRS sensitivity config */
++ unsigned rgmii_ibs:1; /* RGMII In Band status */
++ unsigned rmii:1; /* RMII ref clock direction */
++ unsigned miirate:3; /* xMII interface clock rate */
++ unsigned miimode:4; /* xMII interface mode */
++ } bits;
++ u16 val;
++ };
++};
++
++enum ltq_mii_mii_cfg_miirate {
++ LTQ_MII_MII_CFG_MIIRATE_M2P5 = 0,
++ LTQ_MII_MII_CFG_MIIRATE_M25 = 1,
++ LTQ_MII_MII_CFG_MIIRATE_M125 = 2,
++ LTQ_MII_MII_CFG_MIIRATE_M50 = 3,
++ LTQ_MII_MII_CFG_MIIRATE_AUTO = 4,
++};
++
++enum ltq_mii_mii_cfg_miimode {
++ LTQ_MII_MII_CFG_MIIMODE_MIIP = 0,
++ LTQ_MII_MII_CFG_MIIMODE_MIIM = 1,
++ LTQ_MII_MII_CFG_MIIMODE_RMIIP = 2,
++ LTQ_MII_MII_CFG_MIIMODE_RMIIM = 3,
++ LTQ_MII_MII_CFG_MIIMODE_RGMII = 4,
++};
++
++struct ltq_eth_priv {
++ struct ltq_dma_device dma_dev;
++ struct mii_dev *bus;
++ struct eth_device *dev;
++ struct phy_device *phymap[LTQ_ETHSW_MAX_GMAC];
++ int rx_num;
++ int tx_num;
++};
++
++static struct vr9_switch_regs *switch_regs =
++ (struct vr9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE);
++
++static inline void vr9_switch_sync(void)
++{
++ __asm__("sync");
++}
++
++static inline int vr9_switch_mdio_is_busy(void)
++{
++ u32 mdio_ctrl = ltq_readl(&switch_regs->mdio.mdio_ctrl);
++
++ return mdio_ctrl & MDIO_CTRL_MBUSY;
++}
++
++static inline void vr9_switch_mdio_poll(void)
++{
++ while (vr9_switch_mdio_is_busy())
++ cpu_relax();
++}
++
++static int vr9_switch_mdio_read(struct mii_dev *bus, int phyad, int devad,
++ int regad)
++{
++ u32 mdio_ctrl;
++ int retval;
++
++ mdio_ctrl = MDIO_CTRL_OP_READ |
++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
++ (regad & MDIO_CTRL_REGAD_MASK);
++
++ vr9_switch_mdio_poll();
++ ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
++ vr9_switch_mdio_poll();
++ retval = ltq_readl(&switch_regs->mdio.mdio_read);
++
++ return retval;
++}
++
++static int vr9_switch_mdio_write(struct mii_dev *bus, int phyad, int devad,
++ int regad, u16 val)
++{
++ u32 mdio_ctrl;
++
++ mdio_ctrl = MDIO_CTRL_OP_WRITE |
++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
++ (regad & MDIO_CTRL_REGAD_MASK);
++
++ vr9_switch_mdio_poll();
++ ltq_writel(&switch_regs->mdio.mdio_write, val);
++ ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
++
++ return 0;
++}
++
++static void ltq_eth_gmac_update(struct phy_device *phydev, int num)
++{
++ struct ltq_mdio_phy_addr_reg phy_addr_reg;
++ struct ltq_mii_mii_cfg_reg mii_cfg_reg;
++
++ phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
++
++ switch (num) {
++ case 0:
++ case 1:
++ case 5:
++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
++ break;
++ default:
++ mii_cfg_reg.val = 0;
++ break;
++ }
++
++ phy_addr_reg.bits.addr = phydev->addr;
++
++ if (phydev->link)
++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_UP;
++ else
++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
++
++ switch (phydev->speed) {
++ case SPEED_1000:
++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_G1;
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M125;
++ break;
++ case SPEED_100:
++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M100;
++ switch (mii_cfg_reg.bits.miimode) {
++ case LTQ_MII_MII_CFG_MIIMODE_RMIIM:
++ case LTQ_MII_MII_CFG_MIIMODE_RMIIP:
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M50;
++ break;
++ default:
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M25;
++ break;
++ }
++ break;
++ default:
++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
++ break;
++ }
++
++ if (phydev->duplex == DUPLEX_FULL)
++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_ENABLE;
++ else
++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
++
++ ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
++
++ switch (num) {
++ case 0:
++ case 1:
++ case 5:
++ ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
++ break;
++ default:
++ break;
++ }
++}
++
++static inline u8 *ltq_eth_rx_packet_align(int rx_num)
++{
++ u8 *packet = (u8 *) NetRxPackets[rx_num];
++
++ /*
++ * IP header needs
++ */
++ return packet + LTQ_ETH_IP_ALIGN;
++}
++
++static int ltq_eth_init(struct eth_device *dev, bd_t * bis)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ struct phy_device *phydev;
++ int i;
++
++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
++ phydev = priv->phymap[i];
++ if (!phydev)
++ continue;
++
++ phy_startup(phydev);
++ ltq_eth_gmac_update(phydev, i);
++ }
++
++ for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
++ ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
++ LTQ_ETH_RX_DATA_SIZE);
++
++ ltq_dma_enable(dma_dev);
++
++ priv->rx_num = 0;
++ priv->tx_num = 0;
++
++ return 0;
++}
++
++static void ltq_eth_halt(struct eth_device *dev)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ struct phy_device *phydev;
++ int i;
++
++ ltq_dma_reset(dma_dev);
++
++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
++ phydev = priv->phymap[i];
++ if (!phydev)
++ continue;
++
++ phy_shutdown(phydev);
++ phydev->link = 0;
++ ltq_eth_gmac_update(phydev, i);
++ }
++}
++
++static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++
++#if 0
++ printf("%s: packet %p, len %d\n", __func__, packet, length);
++#endif
++
++ ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
++ priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
++
++ return 0;
++}
++
++static int ltq_eth_recv(struct eth_device *dev)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ u8 *packet;
++ int len;
++
++ if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
++ return 0;
++
++#if 0
++ printf("%s: rx_num %d\n", __func__, priv->rx_num);
++#endif
++
++ len = ltq_dma_rx_length(dma_dev, priv->rx_num);
++ packet = ltq_eth_rx_packet_align(priv->rx_num);
++
++#if 0
++ printf("%s: received: packet %p, len %u, rx_num %d\n",
++ __func__, packet, len, priv->rx_num);
++#endif
++
++ if (len)
++ NetReceive(packet, len);
++
++ ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
++ LTQ_ETH_RX_DATA_SIZE);
++
++ priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
++
++ return 0;
++}
++
++static void ltq_eth_gmac_init(int num)
++{
++ struct ltq_mdio_phy_addr_reg phy_addr_reg;
++ struct ltq_mii_mii_cfg_reg mii_cfg_reg;
++
++ /* Reset PHY status to link down */
++ phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
++ phy_addr_reg.bits.addr = num;
++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
++ ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
++
++ /* Reset and disable MII interface */
++ switch (num) {
++ case 0:
++ case 1:
++ case 5:
++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
++ mii_cfg_reg.bits.en = 0;
++ mii_cfg_reg.bits.res = 1;
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
++ ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
++ break;
++ default:
++ break;
++ }
++
++ /*
++ * - enable frame checksum generation
++ * - enable padding of short frames
++ * - disable flow control
++ */
++ ltq_writel(to_mac_ctrl(switch_regs, num, 0),
++ MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
++
++ vr9_switch_sync();
++}
++
++static void ltq_eth_pmac_init(void)
++{
++ /*
++ * WAR: buffer congestion:
++ * - shorten preambel to 1 byte
++ * - set TX IPG to 7 bytes
++ */
++#if 1
++ ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 1),
++ MAC_CTRL1_SHORTPRE | 7);
++#endif
++
++ /*
++ * WAR: systematical concept weakness ACM bug
++ * - set maximum number of used buffer segments to 254
++ * - soft-reset BM FSQM
++ */
++#if 1
++ ltq_writel(&switch_regs->bm.core.fsqm_gctrl, 253);
++ ltq_setbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
++ ltq_clrbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
++#endif
++
++ /*
++ * WAR: switch MAC drop bug
++ */
++#if 1
++ ltq_writel(to_pce_tbl_key(switch_regs, 0), 0xf);
++ ltq_writel(to_pce_tbl_value(switch_regs, 0), 0x40);
++ ltq_writel(&switch_regs->pce.core.tbl_addr, 0x3);
++ ltq_writel(&switch_regs->pce.core.tbl_ctrl, 0x902f);
++#endif
++
++ /*
++ * Configure frame header control:
++ * - enable flow control
++ * - enable CRC check for packets from DMA to PMAC
++ * - remove special tag from packets from PMAC to DMA
++ * - add CRC for packets from DMA to PMAC
++ */
++ ltq_writel(&switch_regs->pmac.hd_ctl, /*PMAC_HD_CTL_FC |*/
++ PMAC_HD_CTL_CCRC | PMAC_HD_CTL_RST | PMAC_HD_CTL_AC |
++ PMAC_HD_CTL_RC);
++
++#if 1
++ ltq_writel(&switch_regs->pmac.rx_ipg, 0x8b);
++#endif
++
++ /*
++ * - enable frame checksum generation
++ * - enable padding of short frames
++ * - disable flow control
++ */
++ ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 0),
++ MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
++
++ vr9_switch_sync();
++}
++
++static void ltq_eth_hw_init(void)
++{
++ int i;
++
++ /* Power up ethernet and switch subsystems */
++ ltq_pm_enable(LTQ_PM_ETH);
++
++ /* Reset ethernet and switch subsystems */
++#if 0
++ ltq_reset_once(LTQ_RESET_ETH, 10);
++#endif
++
++ /* Enable switch macro */
++ ltq_setbits(&switch_regs->mdio.glob_ctrl, MDIO_GLOB_CTRL_SE);
++
++ /* Disable MDIO auto-polling for all ports */
++ ltq_writel(&switch_regs->mdio.mdc_cfg_0, 0);
++
++ /*
++ * Enable and set MDIO management clock to 2.5 MHz. This is the
++ * maximum clock for FE PHYs.
++ * Formula for clock is:
++ *
++ * 50 MHz
++ * x = ----------- - 1
++ * 2 * f_MDC
++ */
++ ltq_writel(&switch_regs->mdio.mdc_cfg_1, MDIO_MDC_CFG1_RES |
++ MDIO_MDC_CFG1_MCEN | 5);
++
++ vr9_switch_sync();
++
++ /* Init MAC connected to CPU */
++ ltq_eth_pmac_init();
++
++ /* Init MACs connected to external MII interfaces */
++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++)
++ ltq_eth_gmac_init(i);
++}
++
++static void ltq_eth_port_config(struct ltq_eth_priv *priv,
++ const struct ltq_eth_port_config *port)
++{
++ struct ltq_mii_mii_cfg_reg mii_cfg_reg;
++ struct phy_device *phydev;
++ int setup_gpio = 0;
++
++ switch (port->num) {
++ case 0: /* xMII0 */
++ case 1: /* xMII1 */
++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
++ port->num));
++ mii_cfg_reg.bits.en = port->flags ? 1 : 0;
++
++ switch (port->phy_if) {
++ case PHY_INTERFACE_MODE_MII:
++ if (port->flags & LTQ_ETH_PORT_PHY)
++ /* MII MAC mode, connected to external PHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_MIIM;
++ else
++ /* MII PHY mode, connected to external MAC */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_MIIP;
++ setup_gpio = 1;
++ break;
++ case PHY_INTERFACE_MODE_RMII:
++ if (port->flags & LTQ_ETH_PORT_PHY)
++ /* RMII MAC mode, connected to external PHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_RMIIM;
++ else
++ /* RMII PHY mode, connected to external MAC */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_RMIIP;
++ setup_gpio = 1;
++ break;
++ case PHY_INTERFACE_MODE_RGMII:
++ /* RGMII MAC mode, connected to external PHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_RGMII;
++ setup_gpio = 1;
++
++ /* RGMII clock delays */
++ ltq_writel(to_mii_pcdu(switch_regs, port->num),
++ port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
++ port->rgmii_tx_delay);
++ break;
++ default:
++ break;
++ }
++
++ ltq_writel(to_mii_miicfg(switch_regs, port->num),
++ mii_cfg_reg.val);
++ break;
++ case 2: /* internal GPHY0 */
++ case 3: /* internal GPHY0 */
++ case 4: /* internal GPHY1 */
++ switch (port->phy_if) {
++ case PHY_INTERFACE_MODE_MII:
++ case PHY_INTERFACE_MODE_GMII:
++ setup_gpio = 1;
++ break;
++ default:
++ break;
++ }
++ break;
++ case 5: /* internal GPHY1 or xMII2 */
++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
++ port->num));
++ mii_cfg_reg.bits.en = port->flags ? 1 : 0;
++
++ switch (port->phy_if) {
++ case PHY_INTERFACE_MODE_MII:
++ /* MII MAC mode, connected to internal GPHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_MIIM;
++ setup_gpio = 1;
++ break;
++ case PHY_INTERFACE_MODE_RGMII:
++ /* RGMII MAC mode, connected to external PHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_RGMII;
++ setup_gpio = 1;
++
++ /* RGMII clock delays */
++ ltq_writel(to_mii_pcdu(switch_regs, port->num),
++ port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
++ port->rgmii_tx_delay);
++ break;
++ default:
++ break;
++ }
++
++ ltq_writel(to_mii_miicfg(switch_regs, port->num),
++ mii_cfg_reg.val);
++ break;
++ default:
++ break;
++ }
++
++ /* Setup GPIOs for MII with external PHYs/MACs */
++ if (setup_gpio) {
++ /* MII/MDIO */
++ gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
++ GPIO_DIR_OUT);
++ /* MII/MDC */
++ gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
++ GPIO_DIR_OUT);
++ }
++
++ /* Connect to internal/external PHYs */
++ if (port->flags & LTQ_ETH_PORT_PHY) {
++ phydev = phy_connect(priv->bus, port->phy_addr, priv->dev,
++ port->phy_if);
++ if (phydev)
++ phy_config(phydev);
++
++ priv->phymap[port->num] = phydev;
++ }
++}
++
++int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
++{
++ struct eth_device *dev;
++ struct mii_dev *bus;
++ struct ltq_eth_priv *priv;
++ struct ltq_dma_device *dma_dev;
++ int i, ret;
++
++ build_check_vr9_registers();
++
++ ltq_dma_init();
++ ltq_eth_hw_init();
++
++ dev = calloc(1, sizeof(struct eth_device));
++ if (!dev)
++ return -1;
++
++ priv = calloc(1, sizeof(struct ltq_eth_priv));
++ if (!priv)
++ return -1;
++
++ bus = mdio_alloc();
++ if (!bus)
++ return -1;
++
++ sprintf(dev->name, LTQ_ETH_DRV_NAME);
++ dev->priv = priv;
++ dev->init = ltq_eth_init;
++ dev->halt = ltq_eth_halt;
++ dev->recv = ltq_eth_recv;
++ dev->send = ltq_eth_send;
++
++ sprintf(bus->name, LTQ_MDIO_DRV_NAME);
++ bus->read = vr9_switch_mdio_read;
++ bus->write = vr9_switch_mdio_write;
++ bus->priv = priv;
++
++ dma_dev = &priv->dma_dev;
++ dma_dev->port = 0;
++ dma_dev->rx_chan.chan_no = 0;
++ dma_dev->rx_chan.class = 0;
++ dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
++ dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++ dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
++ dma_dev->tx_chan.chan_no = 1;
++ dma_dev->tx_chan.class = 0;
++ dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
++ dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++ dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
++
++ priv->bus = bus;
++ priv->dev = dev;
++
++ ret = ltq_dma_register(dma_dev);
++ if (ret)
++ return -1;
++
++ ret = mdio_register(bus);
++ if (ret)
++ return -1;
++
++ ret = eth_register(dev);
++ if (ret)
++ return -1;
++
++ for (i = 0; i < board_config->num_ports; i++)
++ ltq_eth_port_config(priv, &board_config->ports[i]);
++
++ return 0;
++}
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -34,6 +34,7 @@ COBJS-$(CONFIG_PHYLIB_10G) += generic_10
+ COBJS-$(CONFIG_PHY_ATHEROS) += atheros.o
+ COBJS-$(CONFIG_PHY_BROADCOM) += broadcom.o
+ COBJS-$(CONFIG_PHY_DAVICOM) += davicom.o
++COBJS-$(CONFIG_PHY_LANTIQ) += lantiq.o
+ COBJS-$(CONFIG_PHY_LXT) += lxt.o
+ COBJS-$(CONFIG_PHY_MARVELL) += marvell.o
+ COBJS-$(CONFIG_PHY_MICREL) += micrel.o
+--- /dev/null
++++ b/drivers/net/phy/lantiq.c
+@@ -0,0 +1,239 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define DEBUG
++
++#include <common.h>
++#include <miiphy.h>
++
++#define ADVERTIZE_MPD (1 << 10)
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/*
++ * Update link status.
++ *
++ * Based on genphy_update_link in phylib.c
++ */
++static int ltq_phy_update_link(struct phy_device *phydev)
++{
++ unsigned int mii_reg;
++
++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
++
++ /*
++ * If we already saw the link up, and it hasn't gone down, then
++ * we don't need to wait for autoneg again
++ */
++ if (phydev->link && mii_reg & BMSR_LSTATUS)
++ return 0;
++
++ if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
++ phydev->link = 0;
++ return 0;
++ } else {
++ /* Read the link a second time to clear the latched state */
++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
++
++ if (mii_reg & BMSR_LSTATUS)
++ phydev->link = 1;
++ else
++ phydev->link = 0;
++ }
++
++ return 0;
++}
++
++/*
++ * Update speed and duplex.
++ *
++ * Based on genphy_parse_link in phylib.c
++ */
++static int ltq_phy_parse_link(struct phy_device *phydev)
++{
++ unsigned int mii_reg;
++
++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
++
++ /* We're using autonegotiation */
++ if (mii_reg & BMSR_ANEGCAPABLE) {
++ u32 lpa = 0;
++ u32 gblpa = 0;
++
++ /* Check for gigabit capability */
++ if (mii_reg & BMSR_ERCAP) {
++ /* We want a list of states supported by
++ * both PHYs in the link
++ */
++ gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
++ gblpa &= phy_read(phydev,
++ MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
++ }
++
++ /* Set the baseline so we only have to set them
++ * if they're different
++ */
++ phydev->speed = SPEED_10;
++ phydev->duplex = DUPLEX_HALF;
++
++ /* Check the gigabit fields */
++ if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
++ phydev->speed = SPEED_1000;
++
++ if (gblpa & PHY_1000BTSR_1000FD)
++ phydev->duplex = DUPLEX_FULL;
++
++ /* We're done! */
++ return 0;
++ }
++
++ lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
++ lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
++
++ if (lpa & (LPA_100FULL | LPA_100HALF)) {
++ phydev->speed = SPEED_100;
++
++ if (lpa & LPA_100FULL)
++ phydev->duplex = DUPLEX_FULL;
++
++ } else if (lpa & LPA_10FULL)
++ phydev->duplex = DUPLEX_FULL;
++ } else {
++ u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
++
++ phydev->speed = SPEED_10;
++ phydev->duplex = DUPLEX_HALF;
++
++ if (bmcr & BMCR_FULLDPLX)
++ phydev->duplex = DUPLEX_FULL;
++
++ if (bmcr & BMCR_SPEED1000)
++ phydev->speed = SPEED_1000;
++ else if (bmcr & BMCR_SPEED100)
++ phydev->speed = SPEED_100;
++ }
++
++ return 0;
++}
++
++static int ltq_phy_config(struct phy_device *phydev)
++{
++ u16 val;
++
++ /* Advertise as Multi-port device */
++ val = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
++ val |= ADVERTIZE_MPD;
++ phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, val);
++
++ genphy_config_aneg(phydev);
++
++ return 0;
++}
++
++static int ltq_phy_startup(struct phy_device *phydev)
++{
++ /*
++ * Update PHY status immediately without any delays as genphy_startup
++ * does because VRX200 switch needs to be configured dependent
++ * on this information.
++ */
++ ltq_phy_update_link(phydev);
++ ltq_phy_parse_link(phydev);
++
++ debug("ltq_phy: addr %d, link %d, speed %d, duplex %d\n",
++ phydev->addr, phydev->link, phydev->speed, phydev->duplex);
++
++ return 0;
++}
++
++static struct phy_driver xrx_11g_13_driver = {
++ .name = "Lantiq XWAY XRX PHY11G v1.3 and earlier",
++ .uid = 0x030260D0,
++ .mask = 0xFFFFFFF0,
++ .features = PHY_GBIT_FEATURES,
++ .config = ltq_phy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++static struct phy_driver xrx_11g_14_driver = {
++ .name = "Lantiq XWAY XRX PHY11G v1.4 and later",
++ .uid = 0xd565a408,
++ .mask = 0xFFFFFFF8,
++ .features = PHY_GBIT_FEATURES,
++ .config = ltq_phy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++static struct phy_driver xrx_22f_14_driver = {
++ .name = "Lantiq XWAY XRX PHY22F v1.4 and later",
++ .uid = 0xd565a418,
++ .mask = 0xFFFFFFF8,
++ .features = PHY_BASIC_FEATURES,
++ .config = ltq_phy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++static struct phy_driver pef7071_driver = {
++ .name = "Lantiq XWAY PEF7071",
++ .uid = 0xd565a400,
++ .mask = 0xFFFFFFFF,
++ .features = PHY_GBIT_FEATURES,
++ .config = ltq_phy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++static struct phy_driver xrx_genphy_driver = {
++ .name = "Generic PHY at Lantiq XWAY XRX switch",
++ .uid = 0,
++ .mask = 0,
++ .features = 0,
++ .config = genphy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++int phy_lantiq_init(void)
++{
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++ xrx_11g_13_driver.config = ltq_phy_config;
++ xrx_11g_13_driver.startup = ltq_phy_startup;
++ xrx_11g_13_driver.shutdown = genphy_shutdown;
++ xrx_11g_13_driver.name += gd->reloc_off;
++
++ xrx_11g_14_driver.config = ltq_phy_config;
++ xrx_11g_14_driver.startup = ltq_phy_startup;
++ xrx_11g_14_driver.shutdown = genphy_shutdown;
++ xrx_11g_14_driver.name += gd->reloc_off;
++
++ xrx_22f_14_driver.config = ltq_phy_config;
++ xrx_22f_14_driver.startup = ltq_phy_startup;
++ xrx_22f_14_driver.shutdown = genphy_shutdown;
++ xrx_22f_14_driver.name += gd->reloc_off;
++
++ pef7071_driver.config = ltq_phy_config;
++ pef7071_driver.startup = ltq_phy_startup;
++ pef7071_driver.shutdown = genphy_shutdown;
++ pef7071_driver.name += gd->reloc_off;
++
++ xrx_genphy_driver.config = genphy_config;
++ xrx_genphy_driver.startup = ltq_phy_startup;
++ xrx_genphy_driver.shutdown = genphy_shutdown;
++ xrx_genphy_driver.name += gd->reloc_off;
++#endif
++
++ phy_register(&xrx_11g_13_driver);
++ phy_register(&xrx_11g_14_driver);
++ phy_register(&xrx_22f_14_driver);
++ phy_register(&pef7071_driver);
++ phy_register(&xrx_genphy_driver);
++
++ return 0;
++}
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -32,6 +32,8 @@
+ #include <phy.h>
+ #include <errno.h>
+
++DECLARE_GLOBAL_DATA_PTR;
++
+ /* Generic PHY support and helper functions */
+
+ /**
+@@ -420,6 +422,16 @@ static LIST_HEAD(phy_drivers);
+
+ int phy_init(void)
+ {
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++ INIT_LIST_HEAD(&phy_drivers);
++
++ genphy_driver.config = genphy_config;
++ genphy_driver.startup = genphy_startup;
++ genphy_driver.shutdown = genphy_shutdown;
++
++ genphy_driver.name += gd->reloc_off;
++#endif
++
+ #ifdef CONFIG_PHY_ATHEROS
+ phy_atheros_init();
+ #endif
+@@ -429,6 +441,9 @@ int phy_init(void)
+ #ifdef CONFIG_PHY_DAVICOM
+ phy_davicom_init();
+ #endif
++#ifdef CONFIG_PHY_LANTIQ
++ phy_lantiq_init();
++#endif
+ #ifdef CONFIG_PHY_LXT
+ phy_lxt_init();
+ #endif
+--- a/drivers/serial/Makefile
++++ b/drivers/serial/Makefile
+@@ -42,6 +42,7 @@ COBJS-$(CONFIG_SYS_NS16550_SERIAL) += se
+ COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
+ COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
+ COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
++COBJS-$(CONFIG_LANTIQ_SERIAL) += serial_lantiq.o
+ COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
+ COBJS-$(CONFIG_MXC_UART) += serial_mxc.o
+ COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
+--- /dev/null
++++ b/drivers/serial/serial_lantiq.c
+@@ -0,0 +1,264 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <serial.h>
++#include <asm/errno.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#if CONFIG_CONSOLE_ASC == 0
++#define LTQ_ASC_BASE LTQ_ASC0_BASE
++#else
++#define LTQ_ASC_BASE LTQ_ASC1_BASE
++#endif
++
++#define LTQ_ASC_ID_TXFS_SHIFT 24
++#define LTQ_ASC_ID_TXFS_MASK (0x3F << LTQ_ASC_ID_TXFS_SHIFT)
++#define LTQ_ASC_ID_RXFS_SHIFT 16
++#define LTQ_ASC_ID_RXFS_MASK (0x3F << LTQ_ASC_ID_RXFS_SHIFT)
++
++#define LTQ_ASC_MCON_R (1 << 15)
++#define LTQ_ASC_MCON_FDE (1 << 9)
++
++#define LTQ_ASC_WHBSTATE_SETREN (1 << 1)
++#define LTQ_ASC_WHBSTATE_CLRREN (1 << 0)
++
++#define LTQ_ASC_RXFCON_RXFITL_SHIFT 8
++#define LTQ_ASC_RXFCON_RXFITL_MASK (0x3F << LTQ_ASC_RXFCON_RXFITL_SHIFT)
++#define LTQ_ASC_RXFCON_RXFITL_RXFFLU (1 << 1)
++#define LTQ_ASC_RXFCON_RXFITL_RXFEN (1 << 0)
++
++#define LTQ_ASC_TXFCON_TXFITL_SHIFT 8
++#define LTQ_ASC_TXFCON_TXFITL_MASK (0x3F << LTQ_ASC_TXFCON_TXFITL_SHIFT)
++#define LTQ_ASC_TXFCON_TXFITL_TXFFLU (1 << 1)
++#define LTQ_ASC_TXFCON_TXFITL_TXFEN (1 << 0)
++
++#define LTQ_ASC_FSTAT_TXFREE_SHIFT 24
++#define LTQ_ASC_FSTAT_TXFREE_MASK (0x3F << LTQ_ASC_FSTAT_TXFREE_SHIFT)
++#define LTQ_ASC_FSTAT_RXFREE_SHIFT 16
++#define LTQ_ASC_FSTAT_RXFREE_MASK (0x3F << LTQ_ASC_FSTAT_RXFREE_SHIFT)
++#define LTQ_ASC_FSTAT_TXFFL_SHIFT 8
++#define LTQ_ASC_FSTAT_TXFFL_MASK (0x3F << LTQ_ASC_FSTAT_TXFFL_SHIFT)
++#define LTQ_ASC_FSTAT_RXFFL_MASK 0x3F
++
++#ifdef __BIG_ENDIAN
++#define LTQ_ASC_RBUF_OFFSET 3
++#define LTQ_ASC_TBUF_OFFSET 3
++#else
++#define LTQ_ASC_RBUF_OFFSET 0
++#define LTQ_ASC_TBUF_OFFSET 0
++#endif
++
++struct ltq_asc_regs {
++ u32 clc;
++ u32 pisel;
++ u32 id;
++ u32 rsvd0;
++ u32 mcon;
++ u32 state;
++ u32 whbstate;
++ u32 rsvd1;
++ u8 tbuf[4];
++ u8 rbuf[4];
++ u32 rsvd2[2];
++ u32 abcon;
++ u32 abstat;
++ u32 whbabcon;
++ u32 whbabstat;
++ u32 rxfcon;
++ u32 txfcon;
++ u32 fstat;
++ u32 rsvd3;
++ u32 bg;
++ u32 bg_timer;
++ u32 fdv;
++ u32 pmw;
++ u32 modcon;
++ u32 modstat;
++};
++
++DECLARE_GLOBAL_DATA_PTR;
++
++static struct ltq_asc_regs *ltq_asc_regs =
++ (struct ltq_asc_regs *) CKSEG1ADDR(LTQ_ASC_BASE);
++
++static int ltq_serial_init(void)
++{
++ /* Set clock divider for normal run mode to 1 and enable module */
++ ltq_writel(&ltq_asc_regs->clc, 0x100);
++
++ /* Reset MCON register */
++ ltq_writel(&ltq_asc_regs->mcon, 0);
++
++ /* Use Port A as receiver input */
++ ltq_writel(&ltq_asc_regs->pisel, 0);
++
++ /* Enable and flush RX/TX FIFOs */
++ ltq_setbits(&ltq_asc_regs->rxfcon,
++ LTQ_ASC_RXFCON_RXFITL_RXFFLU | LTQ_ASC_RXFCON_RXFITL_RXFEN);
++ ltq_setbits(&ltq_asc_regs->txfcon,
++ LTQ_ASC_TXFCON_TXFITL_TXFFLU | LTQ_ASC_TXFCON_TXFITL_TXFEN);
++
++ serial_setbrg();
++
++ /* Disable error flags, enable receiver */
++ ltq_writel(&ltq_asc_regs->whbstate, LTQ_ASC_WHBSTATE_SETREN);
++
++ return 0;
++}
++
++/*
++ * fdv asc_clk
++ * Baudrate = ----- * -------------
++ * 512 16 * (bg + 1)
++ */
++static void ltq_serial_calc_br_fdv(unsigned long asc_clk,
++ unsigned long baudrate, u16 *fdv,
++ u16 *bg)
++{
++ const u32 c = asc_clk / (16 * 512);
++ u32 diff1, diff2;
++ u32 bg_calc, br_calc, i;
++
++ diff1 = baudrate;
++ for (i = 512; i > 0; i--) {
++ /* Calc bg for current fdv value */
++ bg_calc = i * c / baudrate;
++
++ /* Impossible baudrate */
++ if (!bg_calc)
++ return;
++
++ /*
++ * Calc diff to target baudrate dependent on current
++ * bg and fdv values
++ */
++ br_calc = i * c / bg_calc;
++ if (br_calc > baudrate)
++ diff2 = br_calc - baudrate;
++ else
++ diff2 = baudrate - br_calc;
++
++ /* Perfect values found */
++ if (diff2 == 0) {
++ *fdv = i;
++ *bg = bg_calc - 1;
++ return;
++ }
++
++ if (diff2 < diff1) {
++ *fdv = i;
++ *bg = bg_calc - 1;
++ diff1 = diff2;
++ }
++ }
++}
++
++static void ltq_serial_setbrg(void)
++{
++ unsigned long asc_clk, baudrate;
++ u16 bg = 0;
++ u16 fdv = 511;
++
++ /* ASC clock is same as FPI clock with CLC.RMS = 1 */
++ asc_clk = ltq_get_bus_clock();
++ baudrate = gd->baudrate;
++
++ /* Calculate FDV and BG values */
++ ltq_serial_calc_br_fdv(asc_clk, baudrate, &fdv, &bg);
++
++ /* Disable baudrate generator */
++ ltq_clrbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
++
++ /* Enable fractional divider */
++ ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_FDE);
++
++ /* Set fdv and bg values */
++ ltq_writel(&ltq_asc_regs->fdv, fdv);
++ ltq_writel(&ltq_asc_regs->bg, bg);
++
++ /* Enable baudrate generator */
++ ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
++}
++
++static unsigned int ltq_serial_tx_free(void)
++{
++ unsigned int txfree;
++
++ txfree = (ltq_readl(&ltq_asc_regs->fstat) &
++ LTQ_ASC_FSTAT_TXFREE_MASK) >>
++ LTQ_ASC_FSTAT_TXFREE_SHIFT;
++
++ return txfree;
++}
++
++static unsigned int ltq_serial_rx_fill(void)
++{
++ unsigned int rxffl;
++
++ rxffl = ltq_readl(&ltq_asc_regs->fstat) & LTQ_ASC_FSTAT_RXFFL_MASK;
++
++ return rxffl;
++}
++
++static void ltq_serial_tx(const char c)
++{
++ ltq_writeb(&ltq_asc_regs->tbuf[LTQ_ASC_TBUF_OFFSET], c);
++}
++
++static u8 ltq_serial_rx(void)
++{
++ return ltq_readb(&ltq_asc_regs->rbuf[LTQ_ASC_RBUF_OFFSET]);
++}
++
++static void ltq_serial_putc(const char c)
++{
++ if (c == '\n')
++ ltq_serial_putc('\r');
++
++ while (!ltq_serial_tx_free())
++ ;
++
++ ltq_serial_tx(c);
++}
++
++static int ltq_serial_getc(void)
++{
++ while (!ltq_serial_rx_fill())
++ ;
++
++ return ltq_serial_rx();
++}
++
++static int ltq_serial_tstc(void)
++{
++ return (0 != ltq_serial_rx_fill());
++}
++
++static struct serial_device ltq_serial_drv = {
++ .name = "ixp_serial",
++ .start = ltq_serial_init,
++ .stop = NULL,
++ .setbrg = ltq_serial_setbrg,
++ .putc = ltq_serial_putc,
++ .puts = default_serial_puts,
++ .getc = ltq_serial_getc,
++ .tstc = ltq_serial_tstc,
++};
++
++void ixp_serial_initialize(void)
++{
++ serial_register(&ltq_serial_drv);
++}
++
++__weak struct serial_device *default_serial_console(void)
++{
++ return &ltq_serial_drv;
++}
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -36,6 +36,7 @@ COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
+ COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
+ COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
+ COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
++COBJS-$(CONFIG_LANTIQ_SPI) += lantiq_spi.o
+ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
+ COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
+ COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
+--- /dev/null
++++ b/drivers/spi/lantiq_spi.c
+@@ -0,0 +1,476 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <spi.h>
++#include <malloc.h>
++#include <watchdog.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_SPI_CLC_RMC_SHIFT 8
++#define LTQ_SPI_CLC_RMC_MASK (0xFF << LTQ_SPI_CLC_RMC_SHIFT)
++#define LTQ_SPI_CLC_DISS (1 << 1)
++#define LTQ_SPI_CLC_DISR 1
++
++#define LTQ_SPI_ID_TXFS_SHIFT 24
++#define LTQ_SPI_ID_TXFS_MASK (0x3F << LTQ_SPI_ID_TXFS_SHIFT)
++#define LTQ_SPI_ID_RXFS_SHIFT 16
++#define LTQ_SPI_ID_RXFS_MASK (0x3F << LTQ_SPI_ID_RXFS_SHIFT)
++
++#define LTQ_SPI_CON_ENBV (1 << 22)
++#define LTQ_SPI_CON_BM_SHIFT 16
++#define LTQ_SPI_CON_BM_MASK (0x1F << LTQ_SPI_CON_BM_SHIFT)
++#define LTQ_SPI_CON_LB (1 << 7)
++#define LTQ_SPI_CON_PO (1 << 6)
++#define LTQ_SPI_CON_PH (1 << 5)
++#define LTQ_SPI_CON_HB (1 << 4)
++#define LTQ_SPI_CON_RXOFF (1 << 1)
++#define LTQ_SPI_CON_TXOFF 1
++
++#define LTQ_SPI_STAT_RXBV_SHIFT 28
++#define LTQ_SPI_STAT_RXBV_MASK (0x7 << LTQ_SPI_STAT_RXBV_SHIFT)
++#define LTQ_SPI_STAT_BSY (1 << 13)
++
++#define LTQ_SPI_WHBSTATE_SETMS (1 << 3)
++#define LTQ_SPI_WHBSTATE_CLRMS (1 << 2)
++#define LTQ_SPI_WHBSTATE_SETEN (1 << 1)
++#define LTQ_SPI_WHBSTATE_CLREN 1
++
++#define LTQ_SPI_TXFCON_TXFLU (1 << 1)
++#define LTQ_SPI_TXFCON_TXFEN 1
++
++#define LTQ_SPI_RXFCON_RXFLU (1 << 1)
++#define LTQ_SPI_RXFCON_RXFEN 1
++
++#define LTQ_SPI_FSTAT_RXFFL_MASK 0x3f
++#define LTQ_SPI_FSTAT_TXFFL_SHIFT 8
++#define LTQ_SPI_FSTAT_TXFFL_MASK (0x3f << LTQ_SPI_FSTAT_TXFFL_SHIFT)
++
++#define LTQ_SPI_RXREQ_RXCNT_MASK 0xFFFF
++#define LTQ_SPI_RXCNT_TODO_MASK 0xFFFF
++
++#define LTQ_SPI_GPIO_DIN 16
++#define LTQ_SPI_GPIO_DOUT 17
++#define LTQ_SPI_GPIO_CLK 18
++
++struct ltq_spi_regs {
++ u32 clc; /* Clock control */
++ u32 pisel; /* Port input select */
++ u32 id; /* Identification */
++ u32 rsvd0;
++ u32 con; /* Control */
++ u32 stat; /* Status */
++ u32 whbstate; /* Write HW modified state */
++ u32 rsvd1;
++ u32 tb; /* Transmit buffer */
++ u32 rb; /* Receive buffer */
++ u32 rsvd2[2];
++ u32 rxfcon; /* Recevie FIFO control */
++ u32 txfcon; /* Transmit FIFO control */
++ u32 fstat; /* FIFO status */
++ u32 rsvd3;
++ u32 brt; /* Baudrate timer */
++ u32 brstat; /* Baudrate timer status */
++ u32 rsvd4[6];
++ u32 sfcon; /* Serial frame control */
++ u32 sfstat; /* Serial frame status */
++ u32 rsvd5[2];
++ u32 gpocon; /* General purpose output control */
++ u32 gpostat; /* General purpose output status */
++ u32 fgpo; /* Force general purpose output */
++ u32 rsvd6;
++ u32 rxreq; /* Receive request */
++ u32 rxcnt; /* Receive count */
++ u32 rsvd7[25];
++ u32 dmacon; /* DMA control */
++};
++
++struct ltq_spi_slave {
++ struct spi_slave slave;
++ unsigned int max_hz;
++ unsigned int mode;
++ unsigned int len;
++ unsigned int brt;
++ unsigned int tx_cnt;
++ unsigned int rx_cnt;
++ unsigned int rx_req;
++ const u8 *tx;
++ u8 *rx;
++ u8 txfs;
++ u8 rxfs;
++};
++
++static inline struct ltq_spi_slave *to_ltq_spi_slave(struct spi_slave *slave)
++{
++ return container_of(slave, struct ltq_spi_slave, slave);
++}
++
++#ifdef CONFIG_SPL_BUILD
++/*
++ * We do not have or want malloc in a SPI flash SPL.
++ * Neither we have to support multiple SPI slaves. Thus we put the
++ * SPI slave context in BSS for SPL builds.
++ */
++static struct ltq_spi_slave ltq_spi_slave;
++
++static inline struct ltq_spi_slave *ltq_spi_slave_alloc(void)
++{
++ return &ltq_spi_slave;
++}
++
++static inline void ltq_spi_slave_free(struct spi_slave *slave)
++{
++}
++#else
++static inline struct ltq_spi_slave *ltq_spi_slave_alloc(void)
++{
++ return malloc(sizeof(struct ltq_spi_slave));
++}
++
++static inline void ltq_spi_slave_free(struct spi_slave *slave)
++{
++ struct ltq_spi_slave *sl;
++
++ if (slave) {
++ sl = to_ltq_spi_slave(slave);
++ free(sl);
++ }
++}
++#endif
++
++static struct ltq_spi_regs *ltq_spi_regs =
++ (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE);
++
++void spi_init(void)
++{
++ /* Power up SPI subsystem */
++ ltq_pm_enable(LTQ_PM_SPI);
++
++ /* Enable module and set clock divider to 1 */
++ ltq_writel(&ltq_spi_regs->clc, 1 << LTQ_SPI_CLC_RMC_SHIFT);
++
++ /* SPI/DIN input */
++ gpio_set_altfunc(16, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++ /* SPI/DOUT output */
++ gpio_set_altfunc(17, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* SPI/CLK output */
++ gpio_set_altfunc(18, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++static inline u32 ltq_spi_calc_br(unsigned int max_hz)
++{
++ u32 speed_hz, spi_hz;
++ u16 brt;
++
++ /* SPI module clock is same as FPI bus clock */
++ spi_hz = ltq_get_bus_clock();
++
++ /*
++ * f_SPI
++ * baudrate = --------------
++ * 2 * (BR + 1)
++ */
++ spi_hz /= 2;
++
++ for (brt = 0; brt < 0xFFFF; brt++) {
++ speed_hz = spi_hz / (brt + 1);
++ if (speed_hz <= max_hz)
++ break;
++ }
++
++ return brt;
++}
++
++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
++ unsigned int max_hz, unsigned int mode)
++{
++ u32 id;
++ struct ltq_spi_slave *sl;
++
++ if (!spi_cs_is_valid(bus, cs))
++ return NULL;
++
++ sl = ltq_spi_slave_alloc();
++ if (!sl)
++ return NULL;
++
++ /* Read HW capabilities */
++ id = ltq_readl(&ltq_spi_regs->id);
++ sl->txfs = (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT;
++ sl->rxfs = (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT;
++
++ sl->slave.bus = bus;
++ sl->slave.cs = cs;
++ sl->max_hz = max_hz;
++ sl->mode = mode;
++
++ sl->brt = ltq_spi_calc_br(max_hz);
++
++ return &sl->slave;
++}
++
++void spi_free_slave(struct spi_slave *slave)
++{
++ ltq_spi_slave_free(slave);
++}
++
++static int ltq_spi_wait_ready(struct ltq_spi_slave *sl)
++{
++ u32 stat;
++ const unsigned long timeout = 20000;
++ unsigned long timebase;
++
++ timebase = get_timer(0);
++
++ do {
++ WATCHDOG_RESET();
++
++ stat = ltq_readl(&ltq_spi_regs->stat);
++
++ if (!(stat & LTQ_SPI_STAT_BSY))
++ return 0;
++ } while (get_timer(timebase) < timeout);
++
++ return 1;
++}
++
++int spi_claim_bus(struct spi_slave *slave)
++{
++ struct ltq_spi_slave *sl = to_ltq_spi_slave(slave);
++ u32 con;
++ int ret;
++
++ /* Put module in configuration mode */
++ ltq_setbits(&ltq_spi_regs->whbstate, LTQ_SPI_WHBSTATE_CLREN);
++
++ /* Enable and flush RX and TX FIFOs */
++ ltq_setbits(&ltq_spi_regs->txfcon,
++ LTQ_SPI_TXFCON_TXFLU | LTQ_SPI_TXFCON_TXFEN);
++ ltq_setbits(&ltq_spi_regs->rxfcon,
++ LTQ_SPI_RXFCON_RXFLU | LTQ_SPI_RXFCON_RXFEN);
++
++ ret = ltq_spi_wait_ready(sl);
++ if (ret)
++ return ret;
++
++ /* Set baudrate */
++ ltq_writel(&ltq_spi_regs->brt, sl->brt);
++
++ /*
++ * Disable byte valid control (ENBV = 0) and
++ * set data width to 8 bit (BM = 7)
++ */
++ con = (7 << LTQ_SPI_CON_BM_SHIFT);
++
++ /* Disable transmitter and receiver */
++ con |= (LTQ_SPI_CON_RXOFF | LTQ_SPI_CON_TXOFF);
++
++ /* Set SPI mode
++ * Mapping: Mode CPOL CPHA CON.PO CON.PH
++ * 0 0 0 0 1
++ * 1 0 1 0 0
++ * 2 1 0 1 1
++ * 3 1 1 1 0
++ */
++ if (sl->mode & SPI_CPHA)
++ con &= ~LTQ_SPI_CON_PH;
++ else
++ con |= LTQ_SPI_CON_PH;
++
++ if (sl->mode & SPI_CPOL)
++ con |= LTQ_SPI_CON_PO;
++ else
++ con &= ~LTQ_SPI_CON_PO;
++
++ /* Set heading control */
++ if (sl->mode & SPI_LSB_FIRST)
++ con &= ~LTQ_SPI_CON_HB;
++ else
++ con |= LTQ_SPI_CON_HB;
++
++ /* Set loopback control */
++ if (sl->mode & SPI_LOOP)
++ con |= LTQ_SPI_CON_LB;
++ else
++ con &= ~LTQ_SPI_CON_LB;
++
++ ltq_writel(&ltq_spi_regs->con, con);
++
++ /* Set SPI master mode and enable SPI */
++ ltq_setbits(&ltq_spi_regs->whbstate,
++ LTQ_SPI_WHBSTATE_SETEN | LTQ_SPI_WHBSTATE_SETMS);
++
++ return 0;
++}
++
++void spi_release_bus(struct spi_slave *slave)
++{
++ /* Put module in configuration mode */
++ ltq_setbits(&ltq_spi_regs->whbstate, LTQ_SPI_WHBSTATE_CLREN);
++
++ /* Flush RX and TX FIFOs */
++ ltq_setbits(&ltq_spi_regs->txfcon, LTQ_SPI_TXFCON_TXFLU);
++ ltq_setbits(&ltq_spi_regs->rxfcon, LTQ_SPI_RXFCON_RXFLU);
++}
++
++static inline void ltq_spi_txfifo_write(struct ltq_spi_slave *sl)
++{
++ u32 fstat, tb;
++ u16 fifo_space;
++
++ fstat = ltq_readl(&ltq_spi_regs->fstat);
++ fifo_space = sl->txfs - ((fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >>
++ LTQ_SPI_FSTAT_TXFFL_SHIFT);
++
++ while (sl->tx_cnt < sl->len && fifo_space) {
++ tb = *sl->tx++;
++ ltq_writel(&ltq_spi_regs->tb, tb);
++ fifo_space--;
++ sl->tx_cnt++;
++ }
++}
++
++static inline void ltq_spi_rx_request(struct ltq_spi_slave *sl)
++{
++ u32 rxreq, rxreq_max;
++
++ /*
++ * In RX-only mode the serial clock is activated only after writing
++ * the expected amount of RX bytes into RXREQ register.
++ * To avoid receive overflows at high clocks it is better to request
++ * only the amount of bytes that fits into all FIFOs. This value
++ * depends on the FIFO size implemented in hardware.
++ */
++ rxreq = sl->len - sl->rx_cnt;
++ rxreq_max = sl->rxfs << 2;
++ rxreq = min(rxreq_max, rxreq);
++
++ if (!sl->rx_req && rxreq && sl->rx_cnt < sl->len) {
++ ltq_writel(&ltq_spi_regs->rxreq, rxreq);
++ sl->rx_req = rxreq;
++ }
++}
++
++static void ltq_spi_rxfifo_read(struct ltq_spi_slave *sl)
++{
++ u32 fstat, data, *rx32;
++ u16 fifo_fill;
++ u8 rxbv, shift, *rx8;
++
++ /* Determine how much FIFOs are filled with RX data */
++ fstat = ltq_readl(&ltq_spi_regs->fstat);
++ fifo_fill = fstat & LTQ_SPI_FSTAT_RXFFL_MASK;
++
++ /*
++ * The 32 bit FIFO is always used completely independent from the
++ * bits_per_word value. Thus four bytes have to be read at once
++ * per FIFO.
++ */
++ rx32 = (u32 *) sl->rx;
++ while (sl->len - sl->rx_cnt >= 4 && fifo_fill) {
++ data = ltq_readl(&ltq_spi_regs->rb);
++ *rx32++ = data;
++ sl->rx_cnt += 4;
++ sl->rx_req -= 4;
++ sl->rx += 4;
++ fifo_fill--;
++ }
++
++ /*
++ * If there are remaining bytes, read byte count from STAT.RXBV
++ * register and read the data byte-wise.
++ */
++ while (fifo_fill && sl->rx_cnt < sl->len) {
++ fstat = ltq_readl(&ltq_spi_regs->stat);
++ rxbv = (fstat & LTQ_SPI_STAT_RXBV_MASK) >>
++ LTQ_SPI_STAT_RXBV_SHIFT;
++
++ if (!rxbv)
++ break;
++
++ data = ltq_readl(&ltq_spi_regs->rb);
++
++ shift = (rxbv - 1) * 8;
++ rx8 = sl->rx;
++
++ while (rxbv) {
++ *rx8++ = (data >> shift) & 0xFF;
++ rxbv--;
++ shift -= 8;
++ sl->rx_cnt++;
++ sl->rx_req--;
++ sl->rx++;
++ }
++
++ fifo_fill--;
++ }
++}
++
++int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
++ const void *dout, void *din, unsigned long flags)
++{
++ struct ltq_spi_slave *sl = to_ltq_spi_slave(slave);
++ int ret;
++
++ if (bitlen % 8)
++ return 1;
++
++ if (!bitlen) {
++ ret = 0;
++ goto done;
++ }
++
++ sl->len = bitlen / 8;
++ sl->tx = dout;
++ sl->rx = din;
++ sl->tx_cnt = 0;
++ sl->rx_cnt = 0;
++ sl->rx_req = 0;
++
++ if (flags & SPI_XFER_BEGIN)
++ spi_cs_activate(slave);
++
++ /* Enable transmitter */
++ if (sl->tx)
++ ltq_clrbits(&ltq_spi_regs->con, LTQ_SPI_CON_TXOFF);
++
++ /* Enable receiver */
++ if (sl->rx)
++ ltq_clrbits(&ltq_spi_regs->con, LTQ_SPI_CON_RXOFF);
++
++ if (sl->tx)
++ ltq_spi_txfifo_write(sl);
++ else if (sl->rx)
++ ltq_spi_rx_request(sl);
++
++ while (sl->tx_cnt != sl->len && sl->rx_cnt != sl->len) {
++ if (sl->rx) {
++ ltq_spi_rxfifo_read(sl);
++
++ if (sl->tx)
++ ltq_spi_txfifo_write(sl);
++ else
++ ltq_spi_rx_request(sl);
++ } else if (sl->tx)
++ ltq_spi_txfifo_write(sl);
++ }
++
++ ret = ltq_spi_wait_ready(sl);
++
++done:
++ /* Disable transmitter and receiver */
++ ltq_setbits(&ltq_spi_regs->con, LTQ_SPI_CON_TXOFF | LTQ_SPI_CON_RXOFF);
++
++ if (flags & SPI_XFER_END)
++ spi_cs_deactivate(slave);
++
++ return ret;
++}
+--- /dev/null
++++ b/include/configs/easy50712.h
+@@ -0,0 +1,78 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "EASY50712"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "Lantiq EASY50712 Danube Reference Board"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++#define CONFIG_LTQ_SUPPORT_SPI_FLASH
++#define CONFIG_SPI_FLASH_ATMEL /* Have an AT45DB321D serial flash */
++
++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */
++
++#define CONFIG_LTQ_SPL_COMP_LZO
++#define CONFIG_LTQ_SPL_CONSOLE
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_ADM6996I
++
++/* Environment */
++#define CONFIG_ENV_SPI_BUS 0
++#define CONFIG_ENV_SPI_CS 2
++#define CONFIG_ENV_SPI_MAX_HZ 20000000
++#define CONFIG_ENV_SPI_MODE 0
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (256 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (128 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE (8 * 1024)
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR
++
++#endif /* __CONFIG_H */
+--- /dev/null
++++ b/include/configs/easy80920.h
+@@ -0,0 +1,93 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "EASY80920"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "Lantiq EASY80920 VRX200 Family Board"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++#define CONFIG_LTQ_SUPPORT_SPI_FLASH
++#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29LV620 serial flash */
++
++#define CONFIG_LTQ_SUPPORT_NAND_FLASH
++
++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */
++#define CONFIG_SPL_SPI_BUS 0
++#define CONFIG_SPL_SPI_CS 4
++#define CONFIG_SPL_SPI_MAX_HZ 25000000
++#define CONFIG_SPL_SPI_MODE 0
++
++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */
++
++#define CONFIG_LTQ_SPL_COMP_LZO
++#define CONFIG_LTQ_SPL_CONSOLE
++
++#define CONFIG_SYS_DRAM_PROBE
++
++/* Environment */
++#define CONFIG_ENV_SPI_BUS CONFIG_SPL_SPI_BUS
++#define CONFIG_ENV_SPI_CS CONFIG_SPL_SPI_CS
++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SPL_SPI_MAX_HZ
++#define CONFIG_ENV_SPI_MODE CONFIG_SPL_SPI_MODE
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (384 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_ENV_IS_IN_SPI_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE (8 * 1024)
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
++
++#define CONFIG_ENV_UPDATE_UBOOT_SF \
++ "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR \
++ CONFIG_ENV_UPDATE_UBOOT_SF
++
++#endif /* __CONFIG_H */
+--- a/include/phy.h
++++ b/include/phy.h
+@@ -220,6 +220,7 @@ int gen10g_discover_mmds(struct phy_devi
+ int phy_atheros_init(void);
+ int phy_broadcom_init(void);
+ int phy_davicom_init(void);
++int phy_lantiq_init(void);
+ int phy_lxt_init(void);
+ int phy_marvell_init(void);
+ int phy_micrel_init(void);
+--- a/spl/Makefile
++++ b/spl/Makefile
+@@ -81,6 +81,8 @@ LIBS-$(CONFIG_SPL_POST_MEM_SUPPORT) += p
+ LIBS-$(CONFIG_SPL_NET_SUPPORT) += net/libnet.o
+ LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/libnet.o
+ LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/libphy.o
++LIBS-$(CONFIG_SPL_LZMA_SUPPORT) += lib/lzma/liblzma.o
++LIBS-$(CONFIG_SPL_LZO_SUPPORT) += lib/lzo/liblzo.o
+
+ ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+ LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
+--- a/tools/.gitignore
++++ b/tools/.gitignore
+@@ -2,6 +2,7 @@
+ /envcrc
+ /gen_eth_addr
+ /img2srec
++/ltq-boot-image
+ /kwboot
+ /mkenvimage
+ /mkimage
+--- a/tools/Makefile
++++ b/tools/Makefile
+@@ -65,6 +65,7 @@ BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_lo
+ BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
+ BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX)
+ BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
++BIN_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image$(SFX)
+ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
+ BIN_FILES-y += mkenvimage$(SFX)
+ BIN_FILES-y += mkimage$(SFX)
+@@ -89,6 +90,7 @@ OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envc
+ NOPED_OBJ_FILES-y += fit_image.o
+ OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
+ OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
++OBJ_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image.o
+ OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
+ NOPED_OBJ_FILES-y += aisimage.o
+ NOPED_OBJ_FILES-y += kwbimage.o
+@@ -193,6 +195,10 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o
+ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+ $(HOSTSTRIP) $@
+
++$(obj)ltq-boot-image$(SFX): $(obj)ltq-boot-image.o
++ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
++ $(HOSTSTRIP) $@
++
+ $(obj)xway-swap-bytes$(SFX): $(obj)xway-swap-bytes.o
+ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+ $(HOSTSTRIP) $@
+--- /dev/null
++++ b/tools/ltq-boot-image.c
+@@ -0,0 +1,316 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <getopt.h>
++#include <compiler.h>
++#include <sys/stat.h>
++
++enum image_types {
++ IMAGE_NONE,
++ IMAGE_SFSPL
++};
++
++/* Lantiq non-volatile bootstrap command IDs */
++enum nvb_cmd_ids {
++ NVB_CMD_DEBUG = 0x11,
++ NVB_CMD_REGCFG = 0x22,
++ NVB_CMD_IDWNLD = 0x33,
++ NVB_CMD_CDWNLD = 0x44,
++ NVB_CMD_DWNLD = 0x55,
++ NVB_CMD_IFCFG = 0x66,
++ NVB_CMD_START = 0x77
++};
++
++/* Lantiq non-volatile bootstrap command flags */
++enum nvb_cmd_flags {
++ NVB_FLAG_START = 1,
++ NVB_FLAG_DEC = (1 << 1),
++ NVB_FLAG_DBG = (1 << 2),
++ NVB_FLAG_SDBG = (1 << 3),
++ NVB_FLAG_CFG0 = (1 << 4),
++ NVB_FLAG_CFG1 = (1 << 5),
++ NVB_FLAG_CFG2 = (1 << 6),
++ NVB_FLAG_RST = (1 << 7)
++};
++
++struct args {
++ enum image_types type;
++ __u32 entry_addr;
++ const char *uboot_bin;
++ const char *spl_bin;
++ const char *out_bin;
++};
++
++static void usage_msg(const char *name)
++{
++ fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n",
++ name);
++ fprintf(stderr, " Image types:\n"
++ " sfspl - SPL + [compressed] U-Boot for SPI flash\n");
++}
++
++static enum image_types parse_image_type(const char *type)
++{
++ if (!type)
++ return IMAGE_NONE;
++
++ if (!strncmp(type, "sfspl", 6))
++ return IMAGE_SFSPL;
++
++ return IMAGE_NONE;
++}
++
++static int parse_args(int argc, char *argv[], struct args *arg)
++{
++ int opt;
++
++ memset(arg, 0, sizeof(*arg));
++
++ while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) {
++ switch (opt) {
++ case 'h':
++ usage_msg(argv[0]);
++ return 1;
++ case 't':
++ arg->type = parse_image_type(optarg);
++ break;
++ case 'e':
++ arg->entry_addr = strtoul(optarg, NULL, 16);
++ break;
++ case 'u':
++ arg->uboot_bin = optarg;
++ break;
++ case 's':
++ arg->spl_bin = optarg;
++ break;
++ case 'o':
++ arg->out_bin = optarg;
++ break;
++ default:
++ fprintf(stderr, "Invalid option -%c\n", opt);
++ goto parse_error;
++ }
++ }
++
++ if (arg->type == IMAGE_NONE) {
++ fprintf(stderr, "Invalid image type\n");
++ goto parse_error;
++ }
++
++ if (!arg->uboot_bin) {
++ fprintf(stderr, "Missing U-Boot binary\n");
++ goto parse_error;
++ }
++
++ if (!arg->out_bin) {
++ fprintf(stderr, "Missing output binary\n");
++ goto parse_error;
++ }
++
++ if (arg->type == IMAGE_SFSPL && !arg->spl_bin) {
++ fprintf(stderr, "Missing SPL binary\n");
++ goto parse_error;
++ }
++
++ return 0;
++
++parse_error:
++ usage_msg(argv[0]);
++ return -1;
++}
++
++static __u32 build_nvb_command(unsigned cmdid, unsigned cmdflags)
++{
++ __u32 cmd;
++ __u16 tag;
++
++ tag = (cmdid << 8) | cmdflags;
++ cmd = (tag << 16) | (0xFFFF - tag);
++
++ return cpu_to_be32(cmd);
++}
++
++static int write_header(int fd, const void *hdr, size_t size)
++{
++ ssize_t n;
++
++ n = write(fd, hdr, size);
++ if (n != size) {
++ fprintf(stderr, "Cannot write header: %s\n",
++ strerror(errno));
++ return -1;
++ }
++
++ return 0;
++}
++
++static int write_nvb_dwnld_header(int fd, size_t size, __u32 addr)
++{
++ __u32 hdr[3];
++
++ hdr[0] = build_nvb_command(NVB_CMD_DWNLD, NVB_FLAG_START |
++ NVB_FLAG_SDBG);
++ hdr[1] = cpu_to_be32(size + 4);
++ hdr[2] = cpu_to_be32(addr);
++
++ return write_header(fd, hdr, sizeof(hdr));
++}
++
++static int write_nvb_start_header(int fd, __u32 addr)
++{
++ __u32 hdr[3];
++
++ hdr[0] = build_nvb_command(NVB_CMD_START, NVB_FLAG_SDBG);
++ hdr[1] = cpu_to_be32(4);
++ hdr[2] = cpu_to_be32(addr);
++
++ return write_header(fd, hdr, sizeof(hdr));
++}
++
++static int open_input_bin(const char *name, void **ptr, size_t *size)
++{
++ struct stat sbuf;
++ int ret, fd;
++
++ fd = open(name, O_RDONLY | O_BINARY);
++ if (0 > fd) {
++ fprintf(stderr, "Cannot open %s: %s\n", name,
++ strerror(errno));
++ return -1;
++ }
++
++ ret = fstat(fd, &sbuf);
++ if (0 > ret) {
++ fprintf(stderr, "Cannot fstat %s: %s\n", name,
++ strerror(errno));
++ return -1;
++ }
++
++ *ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
++ if (*ptr == MAP_FAILED) {
++ fprintf(stderr, "Cannot mmap %s: %s\n", name,
++ strerror(errno));
++ return -1;
++ }
++
++ *size = sbuf.st_size;
++
++ return fd;
++}
++
++static void close_input_bin(int fd, void *ptr, size_t size)
++{
++ munmap(ptr, size);
++ close(fd);
++}
++
++static int copy_bin(int fd, void *ptr, size_t size)
++{
++ ssize_t n;
++
++ n = write(fd, ptr, size);
++ if (n != size) {
++ fprintf(stderr, "Cannot copy binary: %s\n", strerror(errno));
++ return -1;
++ }
++
++ return 0;
++}
++
++static int open_output_bin(const char *name)
++{
++ int fd;
++
++ fd = open(name, O_RDWR | O_CREAT | O_TRUNC | O_SYNC | O_BINARY, 0666);
++ if (0 > fd) {
++ fprintf(stderr, "Cannot open %s: %s\n", name,
++ strerror(errno));
++ return -1;
++ }
++
++ return fd;
++}
++
++static int create_sfspl(const struct args *arg)
++{
++ int out_fd, uboot_fd, spl_fd, ret;
++ void *uboot_ptr, *spl_ptr;
++ size_t uboot_size, spl_size;
++
++ out_fd = open_output_bin(arg->out_bin);
++ if (0 > out_fd)
++ goto err;
++
++ spl_fd = open_input_bin(arg->spl_bin, &spl_ptr, &spl_size);
++ if (0 > spl_fd)
++ goto err_spl;
++
++ uboot_fd = open_input_bin(arg->uboot_bin, &uboot_ptr, &uboot_size);
++ if (0 > uboot_fd)
++ goto err_uboot;
++
++ ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr);
++ if (ret)
++ goto err_write;
++
++ ret = copy_bin(out_fd, spl_ptr, spl_size);
++ if (ret)
++ goto err_write;
++
++ ret = write_nvb_start_header(out_fd, arg->entry_addr);
++ if (ret)
++ goto err_write;
++
++ ret = copy_bin(out_fd, uboot_ptr, uboot_size);
++ if (ret)
++ goto err_write;
++
++ close_input_bin(uboot_fd, uboot_ptr, uboot_size);
++ close_input_bin(spl_fd, spl_ptr, spl_size);
++ close(out_fd);
++
++ return 0;
++
++err_write:
++ close_input_bin(uboot_fd, uboot_ptr, uboot_size);
++err_uboot:
++ close_input_bin(spl_fd, spl_ptr, spl_size);
++err_spl:
++ close(out_fd);
++err:
++ return -1;
++}
++
++int main(int argc, char *argv[])
++{
++ int ret;
++ struct args arg;
++
++ ret = parse_args(argc, argv, &arg);
++ if (ret)
++ goto done;
++
++ switch (arg.type) {
++ case IMAGE_SFSPL:
++ ret = create_sfspl(&arg);
++ break;
++ default:
++ fprintf(stderr, "Image type not implemented\n");
++ ret = -1;
++ break;
++ }
++
++done:
++ if (ret >= 0)
++ return EXIT_SUCCESS;
++
++ return EXIT_FAILURE;
++}
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch.svn-base
new file mode 100644
index 0000000..ba24bae
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch.svn-base
@@ -0,0 +1,33 @@
+From 2c6115188c7353a601835885a6c544240cfc479e Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Fri, 30 Nov 2012 18:09:25 +0100
+Subject: MIPS: VRX200: add option to boot from AVM EVA loader
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/arch/mips/cpu/mips32/vrx200/config.mk
++++ b/arch/mips/cpu/mips32/vrx200/config.mk
+@@ -17,6 +17,9 @@ endif
+ LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
+
+ ifndef CONFIG_SPL_BUILD
++ifdef CONFIG_SYS_BOOT_EVA
++ALL-y += $(obj)u-boot.bin.lzma
++endif
+ ifdef CONFIG_SYS_BOOT_SFSPL
+ ALL-y += $(obj)u-boot.ltq.sfspl
+ ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
+--- a/arch/mips/include/asm/arch-vrx200/config.h
++++ b/arch/mips/include/asm/arch-vrx200/config.h
+@@ -161,6 +161,11 @@
+ #define CONFIG_SYS_DISABLE_CACHE
+ #endif
+
++#if defined(CONFIG_SYS_BOOT_EVA)
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#endif
++
+ #if defined(CONFIG_SYS_BOOT_NOR)
+ #define CONFIG_SYS_TEXT_BASE 0xB0000000
+ #endif
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch.svn-base
new file mode 100644
index 0000000..b680a97
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch.svn-base
@@ -0,0 +1,355 @@
+From 51f04c00e831b49587f9f766ff1af67d2122feb2 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Fri, 30 Nov 2012 18:09:47 +0100
+Subject: MIPS: add board support for AVM FritzBox 3370
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/avm/fb3370/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/avm/fb3370/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/avm/fb3370/ddr_settings.h
+@@ -0,0 +1,70 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define MC_CCR00_VALUE 0x101
++#define MC_CCR01_VALUE 0x1000100
++#define MC_CCR02_VALUE 0x1010000
++#define MC_CCR03_VALUE 0x101
++#define MC_CCR04_VALUE 0x1000000
++#define MC_CCR05_VALUE 0x1000101
++#define MC_CCR06_VALUE 0x1000100
++#define MC_CCR07_VALUE 0x1010000
++#define MC_CCR08_VALUE 0x1000101
++#define MC_CCR09_VALUE 0x0
++#define MC_CCR10_VALUE 0x2000100
++#define MC_CCR11_VALUE 0x2000300
++#define MC_CCR12_VALUE 0x30000
++#define MC_CCR13_VALUE 0x202
++#define MC_CCR14_VALUE 0x7080A0F
++#define MC_CCR15_VALUE 0x2040F
++#define MC_CCR16_VALUE 0x40000
++#define MC_CCR17_VALUE 0x70102
++#define MC_CCR18_VALUE 0x4020002
++#define MC_CCR19_VALUE 0x30302
++#define MC_CCR20_VALUE 0x8000700
++#define MC_CCR21_VALUE 0x40F020A
++#define MC_CCR22_VALUE 0x0
++#define MC_CCR23_VALUE 0xC020000
++#define MC_CCR24_VALUE 0x4401B04
++#define MC_CCR25_VALUE 0x0
++#define MC_CCR26_VALUE 0x0
++#define MC_CCR27_VALUE 0x6420000
++#define MC_CCR28_VALUE 0x0
++#define MC_CCR29_VALUE 0x0
++#define MC_CCR30_VALUE 0x798
++#define MC_CCR31_VALUE 0x0
++#define MC_CCR32_VALUE 0x0
++#define MC_CCR33_VALUE 0x650000
++#define MC_CCR34_VALUE 0x200C8
++#define MC_CCR35_VALUE 0x1D445D
++#define MC_CCR36_VALUE 0xC8
++#define MC_CCR37_VALUE 0xC351
++#define MC_CCR38_VALUE 0x0
++#define MC_CCR39_VALUE 0x141F04
++#define MC_CCR40_VALUE 0x142704
++#define MC_CCR41_VALUE 0x141b42
++#define MC_CCR42_VALUE 0x141b42
++#define MC_CCR43_VALUE 0x566504
++#define MC_CCR44_VALUE 0x566504
++#define MC_CCR45_VALUE 0x565F17
++#define MC_CCR46_VALUE 0x565F17
++#define MC_CCR47_VALUE 0x0
++#define MC_CCR48_VALUE 0x0
++#define MC_CCR49_VALUE 0x0
++#define MC_CCR50_VALUE 0x0
++#define MC_CCR51_VALUE 0x0
++#define MC_CCR52_VALUE 0x133
++#define MC_CCR53_VALUE 0xF3014B27
++#define MC_CCR54_VALUE 0xF3014B27
++#define MC_CCR55_VALUE 0xF3014B27
++#define MC_CCR56_VALUE 0xF3014B27
++#define MC_CCR57_VALUE 0x7800301
++#define MC_CCR58_VALUE 0x7800301
++#define MC_CCR59_VALUE 0x7800301
++#define MC_CCR60_VALUE 0x7800301
++#define MC_CCR61_VALUE 0x4
+--- /dev/null
++++ b/board/avm/fb3370/fb3370.c
+@@ -0,0 +1,139 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <spi.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SPL_BUILD)
++#define do_gpio_init 1
++#define do_pll_init 1
++#define do_dcdc_init 0
++#elif defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init 1
++#define do_pll_init 0
++#define do_dcdc_init 1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define do_gpio_init 1
++#define do_pll_init 1
++#define do_dcdc_init 1
++#else
++#define do_gpio_init 0
++#define do_pll_init 0
++#define do_dcdc_init 1
++#endif
++
++static void gpio_init(void)
++{
++ /* SPI CS 0.4 to serial flash */
++ gpio_direction_output(10, 1);
++
++ /* EBU.FL_CS1 as output for NAND CE */
++ gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* EBU.FL_A23 as output for NAND CLE */
++ gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* EBU.FL_A24 as output for NAND ALE */
++ gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* GPIO 3.0 as input for NAND Ready Busy */
++ gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++ /* GPIO 3.1 as output for NAND Read */
++ gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++ if (do_gpio_init)
++ gpio_init();
++
++ if (do_pll_init)
++ ltq_pll_init();
++
++ if (do_dcdc_init)
++ ltq_dcdc_init(0x7F);
++
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++ /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
++ { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++ /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++ /* GMAC3: unused */
++ { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++ /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
++ { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++ const ulong fw_addr = 0x80FF0000;
++
++ ltq_gphy_phy11g_a1x_load(fw_addr);
++
++ ltq_cgu_gphy_clk_src(clk);
++
++ ltq_rcu_gphy_boot(0, fw_addr);
++ ltq_rcu_gphy_boot(1, fw_addr);
++
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++ if (bus)
++ return 0;
++
++ if (cs == 4)
++ return 1;
++
++ return 0;
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 4:
++ gpio_set_value(10, 0);
++ break;
++ default:
++ break;
++ }
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 4:
++ gpio_set_value(10, 1);
++ break;
++ default:
++ break;
++ }
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -451,6 +451,9 @@ incaip mips
+ incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000
+ incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000
+ incaip_150MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=150000000
++fb3370_ram mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_RAM
++fb3370_eva mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_EVA
++fb3370_sfspl mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_SFSPL
+ easy80920_nor mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NOR
+ easy80920_norspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NORSPL
+ easy80920_ram mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_RAM
+--- /dev/null
++++ b/include/configs/fb3370.h
+@@ -0,0 +1,75 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "FB3370"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "AVM FritzBox 3370"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_SPI_FLASH
++#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29LV620 serial flash */
++
++#define CONFIG_LTQ_SUPPORT_NAND_FLASH
++
++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */
++#define CONFIG_SPL_SPI_BUS 0
++#define CONFIG_SPL_SPI_CS 4
++#define CONFIG_SPL_SPI_MAX_HZ 25000000
++#define CONFIG_SPL_SPI_MODE 0
++
++#define CONFIG_LTQ_SPL_COMP_LZO
++#define CONFIG_LTQ_SPL_CONSOLE
++
++#define CONFIG_SYS_DRAM_PROBE
++
++/* Environment */
++#define CONFIG_ENV_SPI_BUS CONFIG_SPL_SPI_BUS
++#define CONFIG_ENV_SPI_CS CONFIG_SPL_SPI_CS
++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SPL_SPI_MAX_HZ
++#define CONFIG_ENV_SPI_MODE CONFIG_SPL_SPI_MODE
++
++#if defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_ENV_IS_IN_SPI_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE (8 * 1024)
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++#define CONFIG_ENV_UPDATE_UBOOT_SF \
++ "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_SF
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch.svn-base
new file mode 100644
index 0000000..810770a
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch.svn-base
@@ -0,0 +1,264 @@
+From 66b56aa3a4810f10e0b0c77bb87279a8d64b566b Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Fri, 16 Dec 2011 11:55:45 +0100
+Subject: MIPS: add board support for Gigaset SX76X
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/gigaset/sx76x/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/gigaset/sx76x/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/gigaset/sx76x/ddr_settings.h
+@@ -0,0 +1,56 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * generated with lantiq_ram_extract_magic.awk
++ *
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ */
++
++#define MC_DC00_VALUE 0x1B1B
++#define MC_DC01_VALUE 0x0
++#define MC_DC02_VALUE 0x0
++#define MC_DC03_VALUE 0x0
++#define MC_DC04_VALUE 0x0
++#define MC_DC05_VALUE 0x200
++#define MC_DC06_VALUE 0x605
++#define MC_DC07_VALUE 0x303
++#define MC_DC08_VALUE 0x202
++#define MC_DC09_VALUE 0x70A
++#define MC_DC10_VALUE 0x203
++#define MC_DC11_VALUE 0xC02
++#define MC_DC12_VALUE 0x1C8
++#define MC_DC13_VALUE 0x1
++#define MC_DC14_VALUE 0x0
++#define MC_DC15_VALUE 0xF3E
++#define MC_DC16_VALUE 0xC800
++#define MC_DC17_VALUE 0xD
++#define MC_DC18_VALUE 0x300
++#define MC_DC19_VALUE 0x200
++#define MC_DC20_VALUE 0xA04
++#define MC_DC21_VALUE 0xF00
++#define MC_DC22_VALUE 0xF0F
++#define MC_DC23_VALUE 0x0
++#define MC_DC24_VALUE 0x63
++#define MC_DC25_VALUE 0x0
++#define MC_DC26_VALUE 0x100
++#define MC_DC27_VALUE 0x0
++#define MC_DC28_VALUE 0x514
++#define MC_DC29_VALUE 0x2D89
++#define MC_DC30_VALUE 0x8300
++#define MC_DC31_VALUE 0x2002
++#define MC_DC32_VALUE 0x0
++#define MC_DC33_VALUE 0x0
++#define MC_DC34_VALUE 0x0
++#define MC_DC35_VALUE 0x0
++#define MC_DC36_VALUE 0x0
++#define MC_DC37_VALUE 0x0
++#define MC_DC38_VALUE 0x0
++#define MC_DC39_VALUE 0x0
++#define MC_DC40_VALUE 0x0
++#define MC_DC41_VALUE 0x0
++#define MC_DC42_VALUE 0x0
++#define MC_DC43_VALUE 0x0
++#define MC_DC44_VALUE 0x0
++#define MC_DC45_VALUE 0x500
++#define MC_DC46_VALUE 0x0
+--- /dev/null
++++ b/board/gigaset/sx76x/sx76x.c
+@@ -0,0 +1,66 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++static void gpio_init(void)
++{
++ /* Activate reset line of ADM6996I switch */
++ gpio_direction_output(19, 0);
++}
++
++int board_early_init_f(void)
++{
++ gpio_init();
++
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* MAC0: Lantiq ADM6996I switch */
++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device adm6996i_dev = {
++ .name = "adm6996i",
++ .cpu_port = 5,
++ .port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++ /* Deactivate reset line of ADM6996I switch */
++ gpio_set_value(19, 1);
++
++ /* ADM6996I needs some time to come out of reset */
++ __udelay(50000);
++
++ return switch_device_register(&adm6996i_dev);
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -447,6 +447,8 @@ pb1000 mips
+ easy50712_nor mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NOR
+ easy50712_norspl mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NORSPL
+ easy50712_ram mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_RAM
++gigasx76x_nor mips mips32 sx76x gigaset danube sx76x:SYS_BOOT_NOR
++gigasx76x_ram mips mips32 sx76x gigaset danube sx76x:SYS_BOOT_RAM
+ incaip mips mips32 incaip - incaip
+ incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000
+ incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000
+--- /dev/null
++++ b/include/configs/sx76x.h
+@@ -0,0 +1,71 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "GIGASX76X"
++#define CONFIG_IDENT_STRING " sx76x"
++#define CONFIG_BOARD_NAME "Gigaset sx76x"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_ADM6996I
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (256 * 1024)
++#define CONFIG_ENV_SIZE (8 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_SIZE (2 * 1024)
++#endif
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Compression */
++#define CONFIG_LZMA
++
++/* Auto boot */
++#define CONFIG_BOOTDELAY 2
++
++/* Environment configuration */
++#define CONFIG_BOOTCOMMAND \
++ "run addeth; bootm ${kernel_addr}"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch.svn-base
new file mode 100644
index 0000000..4156089
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch.svn-base
@@ -0,0 +1,248 @@
+From 289f7ed5d725067b4eb4b1a105bb63d55bf20392 Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Wed, 29 Aug 2012 22:08:41 +0200
+Subject: MIPS: add board support for Arcadyan ARV7518
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/arv7518pw.c
+@@ -0,0 +1,52 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* MAC0: Atheros ar8216 switch */
++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device ar8216_dev = {
++ .name = "ar8216",
++ .cpu_port = 0,
++ .port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++ return switch_device_register(&ar8216_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/ddr_settings.h
+@@ -0,0 +1,56 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * generated with lantiq_ram_extract_magic.awk
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#define MC_DC00_VALUE 0x1B1B
++#define MC_DC01_VALUE 0x0
++#define MC_DC02_VALUE 0x0
++#define MC_DC03_VALUE 0x0
++#define MC_DC04_VALUE 0x0
++#define MC_DC05_VALUE 0x200
++#define MC_DC06_VALUE 0x605
++#define MC_DC07_VALUE 0x303
++#define MC_DC08_VALUE 0x102
++#define MC_DC09_VALUE 0x70A
++#define MC_DC10_VALUE 0x203
++#define MC_DC11_VALUE 0xC02
++#define MC_DC12_VALUE 0x1C8
++#define MC_DC13_VALUE 0x1
++#define MC_DC14_VALUE 0x0
++#define MC_DC15_VALUE 0x134
++#define MC_DC16_VALUE 0xC800
++#define MC_DC17_VALUE 0xD
++#define MC_DC18_VALUE 0x301
++#define MC_DC19_VALUE 0x200
++#define MC_DC20_VALUE 0xA03
++#define MC_DC21_VALUE 0x1400
++#define MC_DC22_VALUE 0x1414
++#define MC_DC23_VALUE 0x0
++#define MC_DC24_VALUE 0x5B
++#define MC_DC25_VALUE 0x0
++#define MC_DC26_VALUE 0x0
++#define MC_DC27_VALUE 0x0
++#define MC_DC28_VALUE 0x510
++#define MC_DC29_VALUE 0x4E20
++#define MC_DC30_VALUE 0x8235
++#define MC_DC31_VALUE 0x0
++#define MC_DC32_VALUE 0x0
++#define MC_DC33_VALUE 0x0
++#define MC_DC34_VALUE 0x0
++#define MC_DC35_VALUE 0x0
++#define MC_DC36_VALUE 0x0
++#define MC_DC37_VALUE 0x0
++#define MC_DC38_VALUE 0x0
++#define MC_DC39_VALUE 0x0
++#define MC_DC40_VALUE 0x0
++#define MC_DC41_VALUE 0x0
++#define MC_DC42_VALUE 0x0
++#define MC_DC43_VALUE 0x0
++#define MC_DC44_VALUE 0x0
++#define MC_DC45_VALUE 0x500
++#define MC_DC46_VALUE 0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -438,6 +438,8 @@ vct_premium mips
+ vct_premium_onenand mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND
+ vct_premium_onenand_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE
+ vct_premium_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_SMALL_IMAGE
++arv7518pw_ram mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_RAM
++arv7518pw_nor mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_NOR
+ dbau1000 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1000
+ dbau1100 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1100
+ dbau1500 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1500
+--- /dev/null
++++ b/include/configs/arv7518pw.h
+@@ -0,0 +1,69 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "ARV7518PW"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "Arcadyan ARV7518PW"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_AR8216
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SIZE (64 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_SIZE (2 * 1024)
++#endif
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Compression */
++#define CONFIG_LZMA
++
++/* Auto boot */
++#define CONFIG_BOOTDELAY 2
++
++/* Environment configuration */
++#define CONFIG_BOOTCOMMAND \
++ "run addeth; bootm ${kernel_addr}"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch.svn-base
new file mode 100644
index 0000000..4698e67
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch.svn-base
@@ -0,0 +1,248 @@
+From 4a738c02a7190756e01ba58c93c4b07bc6d6c2aa Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Wed, 29 Aug 2012 22:08:42 +0200
+Subject: MIPS: add board support for Arcadyan ARV4519
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/arv4519pw.c
+@@ -0,0 +1,52 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* MAC0: Atheros ar8216 switch */
++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device ar8216_dev = {
++ .name = "ar8216",
++ .cpu_port = 0,
++ .port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++ return switch_device_register(&ar8216_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/ddr_settings.h
+@@ -0,0 +1,56 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * generated with lantiq_ram_extract_magic.awk
++ *
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ */
++
++#define MC_DC00_VALUE 0x1B1B
++#define MC_DC01_VALUE 0x0
++#define MC_DC02_VALUE 0x0
++#define MC_DC03_VALUE 0x0
++#define MC_DC04_VALUE 0x0
++#define MC_DC05_VALUE 0x200
++#define MC_DC06_VALUE 0x605
++#define MC_DC07_VALUE 0x303
++#define MC_DC08_VALUE 0x102
++#define MC_DC09_VALUE 0x70A
++#define MC_DC10_VALUE 0x203
++#define MC_DC11_VALUE 0xC02
++#define MC_DC12_VALUE 0x1C8
++#define MC_DC13_VALUE 0x1
++#define MC_DC14_VALUE 0x0
++#define MC_DC15_VALUE 0x131
++#define MC_DC16_VALUE 0xC800
++#define MC_DC17_VALUE 0xD
++#define MC_DC18_VALUE 0x301
++#define MC_DC19_VALUE 0x200
++#define MC_DC20_VALUE 0xA04
++#define MC_DC21_VALUE 0x1700
++#define MC_DC22_VALUE 0x1717
++#define MC_DC23_VALUE 0x0
++#define MC_DC24_VALUE 0x5A
++#define MC_DC25_VALUE 0x0
++#define MC_DC26_VALUE 0x0
++#define MC_DC27_VALUE 0x0
++#define MC_DC28_VALUE 0x510
++#define MC_DC29_VALUE 0x4E20
++#define MC_DC30_VALUE 0x8235
++#define MC_DC31_VALUE 0x0
++#define MC_DC32_VALUE 0x0
++#define MC_DC33_VALUE 0x0
++#define MC_DC34_VALUE 0x0
++#define MC_DC35_VALUE 0x0
++#define MC_DC36_VALUE 0x0
++#define MC_DC37_VALUE 0x0
++#define MC_DC38_VALUE 0x0
++#define MC_DC39_VALUE 0x0
++#define MC_DC40_VALUE 0x0
++#define MC_DC41_VALUE 0x0
++#define MC_DC42_VALUE 0x0
++#define MC_DC43_VALUE 0x0
++#define MC_DC44_VALUE 0x0
++#define MC_DC45_VALUE 0x500
++#define MC_DC46_VALUE 0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -438,6 +438,8 @@ vct_premium mips
+ vct_premium_onenand mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND
+ vct_premium_onenand_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE
+ vct_premium_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_SMALL_IMAGE
++arv4519pw_ram mips mips32 arv4519pw arcadyan danube arv4519pw:SYS_BOOT_RAM
++arv4519pw_nor mips mips32 arv4519pw arcadyan danube arv4519pw:SYS_BOOT_NOR
+ arv7518pw_ram mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_RAM
+ arv7518pw_nor mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_NOR
+ dbau1000 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1000
+--- /dev/null
++++ b/include/configs/arv4519pw.h
+@@ -0,0 +1,69 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "ARV4519PW"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "Arcadyan ARV4519PW"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_AR8216
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SIZE (64 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_SIZE (2 * 1024)
++#endif
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Compression */
++#define CONFIG_LZMA
++
++/* Auto boot */
++#define CONFIG_BOOTDELAY 2
++
++/* Environment configuration */
++#define CONFIG_BOOTCOMMAND \
++ "run addeth; bootm ${kernel_addr}"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch.svn-base
new file mode 100644
index 0000000..77d48d1
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch.svn-base
@@ -0,0 +1,361 @@
+From 1b77d4249b5addbf3b0848db6992a445019a1865 Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Wed, 29 Aug 2012 22:08:42 +0200
+Subject: tools: add some helper tools for Lantiq SoCs
+
+Signed-off-by: Luka Perkov Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/tools/gct.pl
+@@ -0,0 +1,155 @@
++#!/usr/bin/perl
++
++#use strict;
++#use Cwd;
++#use Env;
++
++my $aline;
++my $lineid;
++my $length;
++my $address;
++my @bytes;
++my $addstr;
++my $chsum=0;
++my $count=0;
++my $firstime=1;
++my $i;
++my $currentaddr;
++my $tmp;
++my $holder="";
++my $loadaddr;
++
++if(@ARGV < 2){
++ die("\n Syntax: perl gct.pl uart_ddr_settings.conf u-boot.srec u-boot.asc\n");
++}
++
++open(IN_UART_DDR_SETTINGS, "<$ARGV[0]") || die("failed to open uart_ddr_settings.conf\n");
++open(IN_UART_SREC, "<$ARGV[1]") || die("failed to open u-boot.srec\n");
++open(OUT_UBOOT_ASC, ">$ARGV[2]") || die("failed to open u-boot.asc\n");
++
++$i=0;
++while ($line = <IN_UART_DDR_SETTINGS>){
++ if($line=~/\w/){
++ if($line!~/[;#\*]/){
++ if($i eq 0){
++ printf OUT_UBOOT_ASC ("33333333");
++ }
++ chomp($line);
++ $line=~s/\t//;
++ @array=split(/ +/,$line);
++ $j=0;
++ while(@array[$j]!~/\w/){
++ $j=$j+1;
++ }
++ $addr=@array[$j];
++ $regval=@array[$j+1];
++ $addr=~s/0x//;
++ $regval=~s/0x//;
++ printf OUT_UBOOT_ASC ("%08x%08x",hex($addr),hex($regval));
++ $i=$i+1;
++ if($i eq 8){
++ $i=0;
++ printf OUT_UBOOT_ASC ("\n");
++ }
++ }
++ }
++}
++
++while($i lt 8 && $i gt 0){
++ printf OUT_UBOOT_ASC "00"x8;
++ $i=$i+1;
++}
++
++if($i eq 8){
++ printf OUT_UBOOT_ASC ("\n");
++}
++
++while($aline=<IN_UART_SREC>){
++ $aline=uc($aline);
++ chomp($aline);
++ next if(($aline=~/^S0/) || ($aline=~/^S7/));
++ ($lineid, $length, $address, @bytes) = unpack"A2A2A8"."A2"x300, $aline;
++ $length = hex($length);
++ $address = hex($address);
++ $length -=5;
++ $i=0;
++
++ while($length>0){
++ if($firstime==1){
++ $addstr = sprintf("%x", $address);
++ $addstr = "0"x(8-length($addstr)).$addstr;
++ print OUT_UBOOT_ASC $addstr;
++ addchsum($addstr);
++ $firstime=0;
++ $currentaddr=$address;
++ $loadaddr = $addstr;
++ }
++ else{
++ if($count==64){
++ $addstr = sprintf("%x", $currentaddr);
++ $addstr = "0"x(8-length($addstr)).$addstr;
++ print OUT_UBOOT_ASC $addstr;
++ addchsum($addstr);
++ $count=0;
++ }
++#printf("*** %x != %x\n", $address, $currentaddr) if $address != $currentaddr;
++ }
++ if($currentaddr < $address) {
++ print OUT_UBOOT_ASC "00";
++ addchsum("00");
++ $count++;
++ $currentaddr++;
++ }
++ else {
++ while($count<64){
++ $bytes[$i]=~tr/ABCDEF/abcdef/;
++ print OUT_UBOOT_ASC "$bytes[$i]";
++ addchsum($bytes[$i]);
++ $i++;
++ $count++;
++ $currentaddr++;
++ $length--;
++ last if($length==0);
++ }
++ }
++ if($count==64){
++ print OUT_UBOOT_ASC "\n";
++ }
++ }
++}
++if($count != 64){
++ $tmp = "00";
++ for($i=0;$i<(64-$count);$i++){
++ print OUT_UBOOT_ASC "00";
++ addchsum($tmp);
++ }
++ print OUT_UBOOT_ASC "\n";
++}
++
++
++print OUT_UBOOT_ASC "11"x4;
++use integer;
++$chsum=$chsum & 0xffffffff;
++$chsum = sprintf("%X", $chsum);
++$chsum = "0"x(8-length($chsum)).$chsum;
++$chsum =~tr/ABCDEF/abcdef/;
++print OUT_UBOOT_ASC $chsum;
++print OUT_UBOOT_ASC "00"x60;
++print OUT_UBOOT_ASC "\n";
++
++print OUT_UBOOT_ASC "99"x4;
++print OUT_UBOOT_ASC $loadaddr;
++print OUT_UBOOT_ASC "00"x60;
++print OUT_UBOOT_ASC "\n";
++
++close OUT_UBOOT_ASC;
++
++sub addchsum{
++ my $cc=$_[0];
++ $holder=$holder.$cc;
++ if(length($holder)==8){
++ $holder = hex($holder);
++ $chsum+=$holder;
++ $holder="";
++ }
++}
+--- /dev/null
++++ b/tools/lantiq_extract_openwrt_patches.sh
+@@ -0,0 +1,15 @@
++#!/bin/bash
++
++set -e
++set -x
++
++test $# -eq 1
++
++openwrt_root=$(readlink -f $1)
++test -d $openwrt_root
++
++uboot_lantiq_dir=$openwrt_root/package/boot/uboot-lantiq/patches
++test -d $uboot_lantiq_dir
++
++rm -vf $uboot_lantiq_dir/*
++git format-patch -k -p --no-renames --text --full-index -o $uboot_lantiq_dir v2012.10..openwrt/v2013.01
+--- /dev/null
++++ b/tools/lantiq_ram_extract_magic.awk
+@@ -0,0 +1,70 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++#
++# usage: mips-openwrt-linux-objdump -EB -b binary -m mips:isa32r2 -D YOUR_IMAGE_DUMP | awk -f lantiq_ram_extract_magic.awk
++#
++
++BEGIN {
++ print "/* "
++ print " * This file is released under the terms of GPL v2 and any later version. "
++ print " * See the file COPYING in the root directory of the source tree for details. "
++ print " * "
++ print " * generated with lantiq_ram_extract_magic.awk "
++ print " * "
++ print " * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> "
++ print " */ "
++ print ""
++
++ mc_dc_value=0
++ mc_dc_number=0
++ right_section=0
++ mc_dc_value_print=0
++ mc_dc_number_print=0
++}
++
++/t2,[0-9]+$/ {
++ if (right_section) {
++ split($4, tmp, ",")
++ mc_dc_value=sprintf("%X", tmp[2])
++ mc_dc_value_print=1
++ }
++}
++
++/t2,0x[0-9a-f]+$/ {
++ if (right_section) {
++ split($4, tmp, ",0x")
++ mc_dc_value=sprintf("%s", tmp[2])
++ mc_dc_value=toupper(mc_dc_value)
++ mc_dc_value_print=1
++ }
++}
++
++/t2,[0-9]+\(t1\)$/ {
++ if (right_section) {
++ split($4, tmp, ",")
++ split(tmp[2], tmp, "(")
++ mc_dc_number=tmp[1]/16
++ mc_dc_number_print=1
++ }
++}
++
++{
++ if (right_section && mc_dc_number_print && mc_dc_value_print) {
++ if (mc_dc_number < 10)
++ print "#define MC_DC0" mc_dc_number "_VALUE\t0x" mc_dc_value
++ else
++ print "#define MC_DC" mc_dc_number "_VALUE\t0x" mc_dc_value
++ mc_dc_value_print=0
++ mc_dc_number_print=0
++ }
++
++ if ($4 == "t1,t1,0x1000")
++ right_section=1
++
++
++ if ($4 == "t2,736(t1)")
++ right_section=0
++}
+--- /dev/null
++++ b/tools/lantiq_ram_init_uart.awk
+@@ -0,0 +1,101 @@
++#!/usr/bin/awk -f
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011-2012 Luka Perkov <luka@openwrt.org>
++# Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++#
++# usage: awk -f lantiq_ram_init_uart.awk -v soc=<danube|ar9|vr9> PATH_TO_BOARD/ddr_settings.h
++#
++
++function print_header()
++{
++ print "; "
++ print "; This file is released under the terms of GPL v2 and any later version. "
++ print "; See the file COPYING in the root directory of the source tree for details. "
++ print "; "
++ print "; generated with lantiq_ram_init_uart.awk "
++ print "; "
++ print "; Copyright (C) 2011-2012 Luka Perkov <luka@openwrt.org> "
++ print "; Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@gmail.com> "
++ print "; "
++ print ""
++}
++
++function mc_ddr1_prologue()
++{
++ /* Clear access error log registers */
++ print "0xbf800010", "0x0"
++ print "0xbf800020", "0x0"
++
++ /* Enable DDR and SRAM module in memory controller */
++ print "0xbf800060", "0x5"
++
++ /* Clear start bit of DDR memory controller */
++ print "0xbf801030", "0x0"
++}
++
++function mc_ddr1_epilogue()
++{
++ /* Set start bit of DDR memory controller */
++ print "0xbf801030", "0x100"
++}
++
++function mc_ddr2_prologue()
++{
++ /* Put memory controller in inactive mode */
++ print "0xbf401070", "0x0"
++}
++
++function mc_ddr2_epilogue(mc_ccr07_value)
++{
++ /* Put memory controller in active mode */
++ mc_ccr07_value = or(mc_ccr07_value, 0x100)
++ printf("0xbf401070 0x%x\n", mc_ccr07_value)
++}
++
++BEGIN {
++ switch (soc) {
++ case "danube":
++ case "ar9":
++ reg_base = 0xbf801000
++ print_header()
++ mc_ddr1_prologue()
++ break
++ case "vr9":
++ reg_base = 0xbf401000
++ print_header()
++ mc_ddr2_prologue()
++ break
++ default:
++ print "Invalid or no value for soc specified!"
++ exit 1
++ }
++
++ mc_ccr07_value = 0
++}
++
++/^#define/ {
++ printf("0x%x %s\n", reg_base, tolower($3))
++ reg_base += 0x10
++}
++
++/^#define(.*)MC_CCR07_VALUE/ {
++ printf("0x%x %s\n", reg_base, tolower($3))
++ reg_base += 0x10
++ mc_ccr07_value = strtonum($3)
++}
++
++END {
++ switch (soc) {
++ case "danube":
++ case "ar9":
++ mc_ddr1_epilogue()
++ break
++ case "vr9":
++ mc_ddr2_epilogue(mc_ccr07_value)
++ break
++ default:
++ }
++}
diff --git a/package/boot/uboot-lantiq/patches/0002-sf-handle-CONFIG_MANUAL_RELOC.patch b/package/boot/uboot-lantiq/patches/0002-sf-handle-CONFIG_MANUAL_RELOC.patch
new file mode 100644
index 0000000..63a21af
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0002-sf-handle-CONFIG_MANUAL_RELOC.patch
@@ -0,0 +1,46 @@
+From 60e8a35f0efa5a7e5d797a3f239971c84061ef11 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 21:39:47 +0100
+Subject: sf: handle CONFIG_MANUAL_RELOC
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -293,7 +293,7 @@ int spi_flash_cmd_write_status(struct sp
+ */
+ #define IDCODE_CONT_LEN 0
+ #define IDCODE_PART_LEN 5
+-static const struct {
++static struct {
+ const u8 shift;
+ const u8 idcode;
+ struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
+@@ -335,6 +335,10 @@ static const struct {
+ };
+ #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
+
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++DECLARE_GLOBAL_DATA_PTR;
++#endif
++
+ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int spi_mode)
+ {
+@@ -342,6 +346,16 @@ struct spi_flash *spi_flash_probe(unsign
+ struct spi_flash *flash = NULL;
+ int ret, i, shift;
+ u8 idcode[IDCODE_LEN], *idp;
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++ static int relocated;
++
++ if (!relocated) {
++ for (i = 0; i < ARRAY_SIZE(flashes); i++)
++ flashes[i].probe += gd->reloc_off;
++
++ relocated = 1;
++ }
++#endif
+
+ spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+ if (!spi) {
diff --git a/package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch b/package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch
new file mode 100644
index 0000000..7f44675
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch
@@ -0,0 +1,719 @@
+From 73d127565b5a4b19bcaacabc505689ee039f16fd Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sun, 11 Nov 2012 03:11:38 +0100
+Subject: sf: factor out malloc from SPI flash drivers
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/atmel.c
++++ b/drivers/mtd/spi/atmel.c
+@@ -40,18 +40,6 @@ struct atmel_spi_flash_params {
+ const char *name;
+ };
+
+-/* spi_flash needs to be first so upper layers can free() it */
+-struct atmel_spi_flash {
+- struct spi_flash flash;
+- const struct atmel_spi_flash_params *params;
+-};
+-
+-static inline struct atmel_spi_flash *
+-to_atmel_spi_flash(struct spi_flash *flash)
+-{
+- return container_of(flash, struct atmel_spi_flash, flash);
+-}
+-
+ static const struct atmel_spi_flash_params atmel_spi_flash_table[] = {
+ {
+ .idcode1 = 0x22,
+@@ -156,7 +144,8 @@ static int at45_wait_ready(struct spi_fl
+ * Assemble the address part of a command for AT45 devices in
+ * non-power-of-two page size mode.
+ */
+-static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset)
++static void at45_build_address(const struct atmel_spi_flash_params *params,
++ u8 *cmd, u32 offset)
+ {
+ unsigned long page_addr;
+ unsigned long byte_addr;
+@@ -167,7 +156,7 @@ static void at45_build_address(struct at
+ * The "extra" space per page is the power-of-two page size
+ * divided by 32.
+ */
+- page_shift = asf->params->l2_page_size;
++ page_shift = params->l2_page_size;
+ page_size = (1 << page_shift) + (1 << (page_shift - 5));
+ page_shift++;
+ page_addr = offset / page_size;
+@@ -181,11 +170,11 @@ static void at45_build_address(struct at
+ static int dataflash_read_fast_at45(struct spi_flash *flash,
+ u32 offset, size_t len, void *buf)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ u8 cmd[5];
+
+ cmd[0] = CMD_READ_ARRAY_FAST;
+- at45_build_address(asf, cmd + 1, offset);
++ at45_build_address(params, cmd + 1, offset);
+ cmd[4] = 0x00;
+
+ return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
+@@ -197,7 +186,7 @@ static int dataflash_read_fast_at45(stru
+ static int dataflash_write_p2(struct spi_flash *flash,
+ u32 offset, size_t len, const void *buf)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ unsigned long page_size;
+ u32 addr = offset;
+ size_t chunk_len;
+@@ -211,7 +200,7 @@ static int dataflash_write_p2(struct spi
+ * the other is being programmed into main memory.
+ */
+
+- page_size = (1 << asf->params->l2_page_size);
++ page_size = (1 << params->l2_page_size);
+
+ ret = spi_claim_bus(flash->spi);
+ if (ret) {
+@@ -263,7 +252,7 @@ out:
+ static int dataflash_write_at45(struct spi_flash *flash,
+ u32 offset, size_t len, const void *buf)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ unsigned long page_addr;
+ unsigned long byte_addr;
+ unsigned long page_size;
+@@ -279,7 +268,7 @@ static int dataflash_write_at45(struct s
+ * the other is being programmed into main memory.
+ */
+
+- page_shift = asf->params->l2_page_size;
++ page_shift = params->l2_page_size;
+ page_size = (1 << page_shift) + (1 << (page_shift - 5));
+ page_shift++;
+ page_addr = offset / page_size;
+@@ -338,7 +327,7 @@ out:
+ */
+ static int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ unsigned long page_size;
+
+ size_t actual;
+@@ -351,7 +340,7 @@ static int dataflash_erase_p2(struct spi
+ * when possible.
+ */
+
+- page_size = (1 << asf->params->l2_page_size);
++ page_size = (1 << params->l2_page_size);
+
+ if (offset % page_size || len % page_size) {
+ debug("SF: Erase offset/length not multiple of page size\n");
+@@ -397,7 +386,7 @@ out:
+
+ static int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len)
+ {
+- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
++ const struct atmel_spi_flash_params *params = flash->priv;
+ unsigned long page_addr;
+ unsigned long page_size;
+ unsigned int page_shift;
+@@ -411,7 +400,7 @@ static int dataflash_erase_at45(struct s
+ * when possible.
+ */
+
+- page_shift = asf->params->l2_page_size;
++ page_shift = params->l2_page_size;
+ page_size = (1 << page_shift) + (1 << (page_shift - 5));
+ page_shift++;
+ page_addr = offset / page_size;
+@@ -458,12 +447,12 @@ out:
+ return ret;
+ }
+
+-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct atmel_spi_flash_params *params;
++ struct spi_slave *spi = flash->spi;
+ unsigned page_size;
+ unsigned int family;
+- struct atmel_spi_flash *asf;
+ unsigned int i;
+ int ret;
+ u8 status;
+@@ -477,18 +466,11 @@ struct spi_flash *spi_flash_probe_atmel(
+ if (i == ARRAY_SIZE(atmel_spi_flash_table)) {
+ debug("SF: Unsupported DataFlash ID %02x\n",
+ idcode[1]);
+- return NULL;
+- }
+-
+- asf = malloc(sizeof(struct atmel_spi_flash));
+- if (!asf) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
++ return 0;
+ }
+
+- asf->params = params;
+- asf->flash.spi = spi;
+- asf->flash.name = params->name;
++ flash->priv = (void *)params;
++ flash->name = params->name;
+
+ /* Assuming power-of-two page size initially. */
+ page_size = 1 << params->l2_page_size;
+@@ -503,48 +485,44 @@ struct spi_flash *spi_flash_probe_atmel(
+ */
+ ret = spi_flash_cmd(spi, CMD_AT45_READ_STATUS, &status, 1);
+ if (ret)
+- goto err;
++ return -1;
+
+ debug("SF: AT45 status register: %02x\n", status);
+
+ if (!(status & AT45_STATUS_P2_PAGE_SIZE)) {
+- asf->flash.read = dataflash_read_fast_at45;
+- asf->flash.write = dataflash_write_at45;
+- asf->flash.erase = dataflash_erase_at45;
++ flash->read = dataflash_read_fast_at45;
++ flash->write = dataflash_write_at45;
++ flash->erase = dataflash_erase_at45;
+ page_size += 1 << (params->l2_page_size - 5);
+ } else {
+- asf->flash.read = spi_flash_cmd_read_fast;
+- asf->flash.write = dataflash_write_p2;
+- asf->flash.erase = dataflash_erase_p2;
++ flash->read = spi_flash_cmd_read_fast;
++ flash->write = dataflash_write_p2;
++ flash->erase = dataflash_erase_p2;
+ }
+
+- asf->flash.page_size = page_size;
+- asf->flash.sector_size = page_size;
++ flash->page_size = page_size;
++ flash->sector_size = page_size;
+ break;
+
+ case DF_FAMILY_AT26F:
+ case DF_FAMILY_AT26DF:
+- asf->flash.read = spi_flash_cmd_read_fast;
+- asf->flash.write = spi_flash_cmd_write_multi;
+- asf->flash.erase = spi_flash_cmd_erase;
+- asf->flash.page_size = page_size;
+- asf->flash.sector_size = 4096;
++ flash->read = spi_flash_cmd_read_fast;
++ flash->write = spi_flash_cmd_write_multi;
++ flash->erase = spi_flash_cmd_erase;
++ flash->page_size = page_size;
++ flash->sector_size = 4096;
+ /* clear SPRL# bit for locked flash */
+- spi_flash_cmd_write_status(&asf->flash, 0);
++ spi_flash_cmd_write_status(flash, 0);
+ break;
+
+ default:
+ debug("SF: Unsupported DataFlash family %u\n", family);
+- goto err;
++ return -1;
+ }
+
+- asf->flash.size = page_size * params->pages_per_block
++ flash->size = page_size * params->pages_per_block
+ * params->blocks_per_sector
+ * params->nr_sectors;
+
+- return &asf->flash;
+-
+-err:
+- free(asf);
+- return NULL;
++ return 1;
+ }
+--- a/drivers/mtd/spi/eon.c
++++ b/drivers/mtd/spi/eon.c
+@@ -29,10 +29,9 @@ static const struct eon_spi_flash_params
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct eon_spi_flash_params *params;
+- struct spi_flash *flash;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) {
+@@ -43,16 +42,10 @@ struct spi_flash *spi_flash_probe_eon(st
+
+ if (i == ARRAY_SIZE(eon_spi_flash_table)) {
+ debug("SF: Unsupported EON ID %02x\n", idcode[1]);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -63,5 +56,5 @@ struct spi_flash *spi_flash_probe_eon(st
+ flash->size = 256 * 16
+ * params->nr_sectors;
+
+- return flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/macronix.c
++++ b/drivers/mtd/spi/macronix.c
+@@ -79,10 +79,9 @@ static const struct macronix_spi_flash_p
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct macronix_spi_flash_params *params;
+- struct spi_flash *flash;
+ unsigned int i;
+ u16 id = idcode[2] | idcode[1] << 8;
+
+@@ -94,16 +93,10 @@ struct spi_flash *spi_flash_probe_macron
+
+ if (i == ARRAY_SIZE(macronix_spi_flash_table)) {
+ debug("SF: Unsupported Macronix ID %04x\n", id);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -116,5 +109,5 @@ struct spi_flash *spi_flash_probe_macron
+ /* Clear BP# bits for read-only flash */
+ spi_flash_cmd_write_status(flash, 0);
+
+- return flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/ramtron.c
++++ b/drivers/mtd/spi/ramtron.c
+@@ -69,17 +69,6 @@ struct ramtron_spi_fram_params {
+ const char *name; /* name for display and/or matching */
+ };
+
+-struct ramtron_spi_fram {
+- struct spi_flash flash;
+- const struct ramtron_spi_fram_params *params;
+-};
+-
+-static inline struct ramtron_spi_fram *to_ramtron_spi_fram(struct spi_flash
+- *flash)
+-{
+- return container_of(flash, struct ramtron_spi_fram, flash);
+-}
+-
+ /*
+ * table describing supported FRAM chips:
+ * chips without RDID command must have the values 0xff for id1 and id2
+@@ -155,18 +144,18 @@ static const struct ramtron_spi_fram_par
+ static int ramtron_common(struct spi_flash *flash,
+ u32 offset, size_t len, void *buf, u8 command)
+ {
+- struct ramtron_spi_fram *sn = to_ramtron_spi_fram(flash);
++ const struct ramtron_spi_fram_params *params = flash->priv;
+ u8 cmd[4];
+ int cmd_len;
+ int ret;
+
+- if (sn->params->addr_len == 3 && sn->params->merge_cmd == 0) {
++ if (params->addr_len == 3 && params->merge_cmd == 0) {
+ cmd[0] = command;
+ cmd[1] = offset >> 16;
+ cmd[2] = offset >> 8;
+ cmd[3] = offset;
+ cmd_len = 4;
+- } else if (sn->params->addr_len == 2 && sn->params->merge_cmd == 0) {
++ } else if (params->addr_len == 2 && params->merge_cmd == 0) {
+ cmd[0] = command;
+ cmd[1] = offset >> 8;
+ cmd[2] = offset;
+@@ -230,10 +219,9 @@ static int ramtron_erase(struct spi_flas
+ * nore: we are called here with idcode pointing to the first non-0x7f byte
+ * already!
+ */
+-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
++int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct ramtron_spi_fram_params *params;
+- struct ramtron_spi_fram *sn;
+ unsigned int i;
+ #ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
+ int ret;
+@@ -259,11 +247,11 @@ struct spi_flash *spi_fram_probe_ramtron
+ */
+ ret = spi_flash_cmd(spi, CMD_READ_STATUS, &sr, 1);
+ if (ret)
+- return NULL;
++ return 0;
+
+ /* Bits 5,4,0 are fixed 0 for all devices */
+ if ((sr & 0x31) != 0x00)
+- return NULL;
++ return 0;
+ /* now find the device */
+ for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) {
+ params = &ramtron_spi_fram_table[i];
+@@ -281,23 +269,16 @@ struct spi_flash *spi_fram_probe_ramtron
+ /* arriving here means no method has found a device we can handle */
+ debug("SF/ramtron: unsupported device id0=%02x id1=%02x id2=%02x\n",
+ idcode[0], idcode[1], idcode[2]);
+- return NULL;
++ return 0;
+
+ found:
+- sn = malloc(sizeof(*sn));
+- if (!sn) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
++ flash->priv = (void *)params;
++ flash->name = params->name;
+
+- sn->params = params;
+- sn->flash.spi = spi;
+- sn->flash.name = params->name;
+-
+- sn->flash.write = ramtron_write;
+- sn->flash.read = ramtron_read;
+- sn->flash.erase = ramtron_erase;
+- sn->flash.size = params->size;
++ flash->write = ramtron_write;
++ flash->read = ramtron_read;
++ flash->erase = ramtron_erase;
++ flash->size = params->size;
+
+- return &sn->flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/spansion.c
++++ b/drivers/mtd/spi/spansion.c
+@@ -105,10 +105,9 @@ static const struct spansion_spi_flash_p
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct spansion_spi_flash_params *params;
+- struct spi_flash *flash;
+ unsigned int i;
+ unsigned short jedec, ext_jedec;
+
+@@ -125,16 +124,10 @@ struct spi_flash *spi_flash_probe_spansi
+
+ if (i == ARRAY_SIZE(spansion_spi_flash_table)) {
+ debug("SF: Unsupported SPANSION ID %04x %04x\n", jedec, ext_jedec);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -144,5 +137,5 @@ struct spi_flash *spi_flash_probe_spansi
+ flash->sector_size = 256 * params->pages_per_sector;
+ flash->size = flash->sector_size * params->nr_sectors;
+
+- return flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -296,7 +296,7 @@ int spi_flash_cmd_write_status(struct sp
+ static struct {
+ const u8 shift;
+ const u8 idcode;
+- struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode);
++ int (*probe) (struct spi_flash *flash, u8 *idcode);
+ } flashes[] = {
+ /* Keep it sorted by define name */
+ #ifdef CONFIG_SPI_FLASH_ATMEL
+@@ -343,7 +343,7 @@ struct spi_flash *spi_flash_probe(unsign
+ unsigned int max_hz, unsigned int spi_mode)
+ {
+ struct spi_slave *spi;
+- struct spi_flash *flash = NULL;
++ struct spi_flash *flash;
+ int ret, i, shift;
+ u8 idcode[IDCODE_LEN], *idp;
+ #ifdef CONFIG_NEEDS_MANUAL_RELOC
+@@ -379,6 +379,15 @@ struct spi_flash *spi_flash_probe(unsign
+ print_buffer(0, idcode, 1, sizeof(idcode), 0);
+ #endif
+
++ flash = malloc(sizeof(*flash));
++ if (!flash) {
++ debug("SF: failed to alloc memory\n");
++ goto err_malloc;
++ }
++
++ memset(flash, 0, sizeof(*flash));
++ flash->spi = spi;
++
+ /* count the number of continuation bytes */
+ for (shift = 0, idp = idcode;
+ shift < IDCODE_CONT_LEN && *idp == 0x7f;
+@@ -389,12 +398,12 @@ struct spi_flash *spi_flash_probe(unsign
+ for (i = 0; i < ARRAY_SIZE(flashes); ++i)
+ if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
+ /* we have a match, call probe */
+- flash = flashes[i].probe(spi, idp);
+- if (flash)
++ ret = flashes[i].probe(flash, idp);
++ if (ret)
+ break;
+ }
+
+- if (!flash) {
++ if (ret <= 0) {
+ printf("SF: Unsupported manufacturer %02x\n", *idp);
+ goto err_manufacturer_probe;
+ }
+@@ -408,6 +417,8 @@ struct spi_flash *spi_flash_probe(unsign
+ return flash;
+
+ err_manufacturer_probe:
++ free(flash);
++err_malloc:
+ err_read_id:
+ spi_release_bus(spi);
+ err_claim_bus:
+--- a/drivers/mtd/spi/spi_flash_internal.h
++++ b/drivers/mtd/spi/spi_flash_internal.h
+@@ -98,11 +98,11 @@ int spi_flash_cmd_wait_ready(struct spi_
+ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len);
+
+ /* Manufacturer-specific probe functions */
+-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode);
+-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode);
++int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_stmicro(struct spi_flash *flash, u8 *idcode);
++int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode);
++int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode);
+--- a/drivers/mtd/spi/sst.c
++++ b/drivers/mtd/spi/sst.c
+@@ -39,11 +39,6 @@ struct sst_spi_flash_params {
+ const char *name;
+ };
+
+-struct sst_spi_flash {
+- struct spi_flash flash;
+- const struct sst_spi_flash_params *params;
+-};
+-
+ static const struct sst_spi_flash_params sst_spi_flash_table[] = {
+ {
+ .idcode1 = 0x8d,
+@@ -185,11 +180,9 @@ sst_write_wp(struct spi_flash *flash, u3
+ return ret;
+ }
+
+-struct spi_flash *
+-spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct sst_spi_flash_params *params;
+- struct sst_spi_flash *stm;
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(sst_spi_flash_table); ++i) {
+@@ -200,31 +193,24 @@ spi_flash_probe_sst(struct spi_slave *sp
+
+ if (i == ARRAY_SIZE(sst_spi_flash_table)) {
+ debug("SF: Unsupported SST ID %02x\n", idcode[1]);
+- return NULL;
+- }
+-
+- stm = malloc(sizeof(*stm));
+- if (!stm) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
++ return 0;
+ }
+
+- stm->params = params;
+- stm->flash.spi = spi;
+- stm->flash.name = params->name;
++ flash->priv = (void *)params;
++ flash->name = params->name;
+
+- if (stm->params->flags & SST_FEAT_WP)
+- stm->flash.write = sst_write_wp;
++ if (params->flags & SST_FEAT_WP)
++ flash->write = sst_write_wp;
+ else
+- stm->flash.write = spi_flash_cmd_write_multi;
+- stm->flash.erase = spi_flash_cmd_erase;
+- stm->flash.read = spi_flash_cmd_read_fast;
+- stm->flash.page_size = 256;
+- stm->flash.sector_size = 4096;
+- stm->flash.size = stm->flash.sector_size * params->nr_sectors;
++ flash->write = spi_flash_cmd_write_multi;
++ flash->erase = spi_flash_cmd_erase;
++ flash->read = spi_flash_cmd_read_fast;
++ flash->page_size = 256;
++ flash->sector_size = 4096;
++ flash->size = flash->sector_size * params->nr_sectors;
+
+ /* Flash powers up read-only, so clear BP# bits */
+- spi_flash_cmd_write_status(&stm->flash, 0);
++ spi_flash_cmd_write_status(flash, 0);
+
+- return &stm->flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/stmicro.c
++++ b/drivers/mtd/spi/stmicro.c
+@@ -112,10 +112,10 @@ static const struct stmicro_spi_flash_pa
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
++int spi_flash_probe_stmicro(struct spi_flash *flash, u8 * idcode)
+ {
+ const struct stmicro_spi_flash_params *params;
+- struct spi_flash *flash;
++ struct spi_slave *spi = flash->spi;
+ unsigned int i;
+ u16 id;
+
+@@ -123,13 +123,13 @@ struct spi_flash *spi_flash_probe_stmicr
+ i = spi_flash_cmd(spi, CMD_M25PXX_RES,
+ idcode, 4);
+ if (i)
+- return NULL;
++ return 0;
+ if ((idcode[3] & 0xf0) == 0x10) {
+ idcode[0] = 0x20;
+ idcode[1] = 0x20;
+ idcode[2] = idcode[3] + 1;
+ } else
+- return NULL;
++ return 0;
+ }
+
+ id = ((idcode[1] << 8) | idcode[2]);
+@@ -143,16 +143,10 @@ struct spi_flash *spi_flash_probe_stmicr
+
+ if (i == ARRAY_SIZE(stmicro_spi_flash_table)) {
+ debug("SF: Unsupported STMicro ID %04x\n", id);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -162,5 +156,5 @@ struct spi_flash *spi_flash_probe_stmicr
+ flash->sector_size = 256 * params->pages_per_sector;
+ flash->size = flash->sector_size * params->nr_sectors;
+
+- return flash;
++ return 1;
+ }
+--- a/drivers/mtd/spi/winbond.c
++++ b/drivers/mtd/spi/winbond.c
+@@ -69,10 +69,9 @@ static const struct winbond_spi_flash_pa
+ },
+ };
+
+-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
++int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct winbond_spi_flash_params *params;
+- struct spi_flash *flash;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
+@@ -84,16 +83,10 @@ struct spi_flash *spi_flash_probe_winbon
+ if (i == ARRAY_SIZE(winbond_spi_flash_table)) {
+ debug("SF: Unsupported Winbond ID %02x%02x\n",
+ idcode[1], idcode[2]);
+- return NULL;
++ return 0;
+ }
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: Failed to allocate memory\n");
+- return NULL;
+- }
+-
+- flash->spi = spi;
++ flash->priv = (void *)params;
+ flash->name = params->name;
+
+ flash->write = spi_flash_cmd_write_multi;
+@@ -103,5 +96,5 @@ struct spi_flash *spi_flash_probe_winbon
+ flash->sector_size = 4096;
+ flash->size = 4096 * 16 * params->nr_blocks;
+
+- return flash;
++ return 1;
+ }
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -31,6 +31,7 @@ struct spi_flash {
+ struct spi_slave *spi;
+
+ const char *name;
++ void *priv;
+
+ /* Total flash size */
+ u32 size;
diff --git a/package/boot/uboot-lantiq/patches/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch b/package/boot/uboot-lantiq/patches/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch
new file mode 100644
index 0000000..7a1ef3b
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch
@@ -0,0 +1,131 @@
+From f9ab44c271fbd82a5702b6ba067fa90e33a30089 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:29:27 +0100
+Subject: sf: add malloc-free probe functions dedicated for SPL
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -339,11 +339,11 @@ static struct {
+ DECLARE_GLOBAL_DATA_PTR;
+ #endif
+
+-struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+- unsigned int max_hz, unsigned int spi_mode)
++int spi_flash_probe_spl(struct spi_flash *flash, unsigned int bus,
++ unsigned int cs, unsigned int max_hz,
++ unsigned int spi_mode)
+ {
+ struct spi_slave *spi;
+- struct spi_flash *flash;
+ int ret, i, shift;
+ u8 idcode[IDCODE_LEN], *idp;
+ #ifdef CONFIG_NEEDS_MANUAL_RELOC
+@@ -359,8 +359,8 @@ struct spi_flash *spi_flash_probe(unsign
+
+ spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+ if (!spi) {
+- printf("SF: Failed to set up slave\n");
+- return NULL;
++ debug("SF: Failed to set up slave\n");
++ return -1;
+ }
+
+ ret = spi_claim_bus(spi);
+@@ -379,13 +379,6 @@ struct spi_flash *spi_flash_probe(unsign
+ print_buffer(0, idcode, 1, sizeof(idcode), 0);
+ #endif
+
+- flash = malloc(sizeof(*flash));
+- if (!flash) {
+- debug("SF: failed to alloc memory\n");
+- goto err_malloc;
+- }
+-
+- memset(flash, 0, sizeof(*flash));
+ flash->spi = spi;
+
+ /* count the number of continuation bytes */
+@@ -404,30 +397,58 @@ struct spi_flash *spi_flash_probe(unsign
+ }
+
+ if (ret <= 0) {
+- printf("SF: Unsupported manufacturer %02x\n", *idp);
++ debug("SF: Unsupported manufacturer %02x\n", *idp);
+ goto err_manufacturer_probe;
+ }
+
+- printf("SF: Detected %s with page size ", flash->name);
+- print_size(flash->sector_size, ", total ");
+- print_size(flash->size, "\n");
+-
+ spi_release_bus(spi);
+
+- return flash;
++ return 0;
+
+ err_manufacturer_probe:
+- free(flash);
+-err_malloc:
+ err_read_id:
+ spi_release_bus(spi);
+ err_claim_bus:
+ spi_free_slave(spi);
++
++ return ret;
++}
++
++struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
++ unsigned int max_hz, unsigned int spi_mode)
++{
++ struct spi_flash *flash;
++ int ret;
++
++ flash = malloc(sizeof(*flash));
++ if (!flash) {
++ debug("SF: Failed to malloc spi_flash\n");
++ return NULL;
++ }
++ memset(flash, 0, sizeof(*flash));
++
++ ret = spi_flash_probe_spl(flash, bus, cs, max_hz, spi_mode);
++ if (ret)
++ goto err_probe;
++
++ printf("SF: %s, page size ", flash->name);
++ print_size(flash->sector_size, ", total ");
++ print_size(flash->size, "\n");
++
++ return flash;
++
++err_probe:
++ free(flash);
+ return NULL;
+ }
+
+-void spi_flash_free(struct spi_flash *flash)
++void spi_flash_free_spl(struct spi_flash *flash)
+ {
+ spi_free_slave(flash->spi);
++}
++
++void spi_flash_free(struct spi_flash *flash)
++{
++ spi_flash_free_spl(flash);
+ free(flash);
+ }
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -52,6 +52,11 @@ struct spi_flash *spi_flash_probe(unsign
+ unsigned int max_hz, unsigned int spi_mode);
+ void spi_flash_free(struct spi_flash *flash);
+
++int spi_flash_probe_spl(struct spi_flash *flash, unsigned int bus,
++ unsigned int cs, unsigned int max_hz,
++ unsigned int spi_mode);
++void spi_flash_free_spl(struct spi_flash *flash);
++
+ static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
+ size_t len, void *buf)
+ {
diff --git a/package/boot/uboot-lantiq/patches/0005-sf-factor-out-the-flash-address-calculation.patch b/package/boot/uboot-lantiq/patches/0005-sf-factor-out-the-flash-address-calculation.patch
new file mode 100644
index 0000000..356db59
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0005-sf-factor-out-the-flash-address-calculation.patch
@@ -0,0 +1,107 @@
+From acb2721e1cd2e7488a7b08a4ed590177369a1689 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 19:10:40 +0100
+Subject: sf: factor out the flash address calculation
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -15,12 +15,22 @@
+
+ #include "spi_flash_internal.h"
+
+-static void spi_flash_addr(u32 addr, u8 *cmd)
++static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd, u8 *cmd_len)
+ {
+ /* cmd[0] is actual command */
+ cmd[1] = addr >> 16;
+ cmd[2] = addr >> 8;
+ cmd[3] = addr >> 0;
++ *cmd_len = 4;
++}
++
++static void spi_flash_page_addr(struct spi_flash *flash, u32 page_addr, u32 byte_addr, u8 *cmd, u8 *cmd_len)
++{
++ /* cmd[0] is actual command */
++ cmd[1] = page_addr >> 8;
++ cmd[2] = page_addr >> 0;
++ cmd[3] = byte_addr;
++ *cmd_len = 4;
+ }
+
+ static int spi_flash_read_write(struct spi_slave *spi,
+@@ -71,7 +81,7 @@ int spi_flash_cmd_write_multi(struct spi
+ unsigned long page_addr, byte_addr, page_size;
+ size_t chunk_len, actual;
+ int ret;
+- u8 cmd[4];
++ u8 cmd[4], cmd_len;
+
+ page_size = flash->page_size;
+ page_addr = offset / page_size;
+@@ -87,9 +97,7 @@ int spi_flash_cmd_write_multi(struct spi
+ for (actual = 0; actual < len; actual += chunk_len) {
+ chunk_len = min(len - actual, page_size - byte_addr);
+
+- cmd[1] = page_addr >> 8;
+- cmd[2] = page_addr;
+- cmd[3] = byte_addr;
++ spi_flash_page_addr(flash, page_addr, byte_addr, cmd, &cmd_len);
+
+ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+ buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+@@ -100,7 +108,7 @@ int spi_flash_cmd_write_multi(struct spi
+ break;
+ }
+
+- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
++ ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len,
+ buf + actual, chunk_len);
+ if (ret < 0) {
+ debug("SF: write failed\n");
+@@ -138,13 +146,13 @@ int spi_flash_read_common(struct spi_fla
+ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
+ size_t len, void *data)
+ {
+- u8 cmd[5];
++ u8 cmd[5], cmd_len;
+
+ cmd[0] = CMD_READ_ARRAY_FAST;
+- spi_flash_addr(offset, cmd);
+- cmd[4] = 0x00;
++ spi_flash_addr(flash, offset, cmd, &cmd_len);
++ cmd[cmd_len] = 0x00;
+
+- return spi_flash_read_common(flash, cmd, sizeof(cmd), data, len);
++ return spi_flash_read_common(flash, cmd, cmd_len + 1, data, len);
+ }
+
+ int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
+@@ -194,7 +202,7 @@ int spi_flash_cmd_erase(struct spi_flash
+ {
+ u32 start, end, erase_size;
+ int ret;
+- u8 cmd[4];
++ u8 cmd[4], cmd_len;
+
+ erase_size = flash->sector_size;
+ if (offset % erase_size || len % erase_size) {
+@@ -216,7 +224,7 @@ int spi_flash_cmd_erase(struct spi_flash
+ end = start + len;
+
+ while (offset < end) {
+- spi_flash_addr(offset, cmd);
++ spi_flash_addr(flash, offset, cmd, &cmd_len);
+ offset += erase_size;
+
+ debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+@@ -226,7 +234,7 @@ int spi_flash_cmd_erase(struct spi_flash
+ if (ret)
+ goto out;
+
+- ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0);
++ ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, NULL, 0);
+ if (ret)
+ goto out;
+
diff --git a/package/boot/uboot-lantiq/patches/0006-sf-add-generic-support-for-4-byte-address-mode.patch b/package/boot/uboot-lantiq/patches/0006-sf-add-generic-support-for-4-byte-address-mode.patch
new file mode 100644
index 0000000..1623b15
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0006-sf-add-generic-support-for-4-byte-address-mode.patch
@@ -0,0 +1,161 @@
+From fb9ed0ef6f0ba6b6535c64dcfcf45c161723e56f Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 19:31:38 +0100
+Subject: sf: add generic support for 4-byte address mode
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -18,19 +18,35 @@
+ static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd, u8 *cmd_len)
+ {
+ /* cmd[0] is actual command */
+- cmd[1] = addr >> 16;
+- cmd[2] = addr >> 8;
+- cmd[3] = addr >> 0;
+- *cmd_len = 4;
++ if (spi_flash_use_4byte_mode(flash)) {
++ cmd[1] = addr >> 24;
++ cmd[2] = addr >> 16;
++ cmd[3] = addr >> 8;
++ cmd[4] = addr >> 0;
++ *cmd_len = 5;
++ } else {
++ cmd[1] = addr >> 16;
++ cmd[2] = addr >> 8;
++ cmd[3] = addr >> 0;
++ *cmd_len = 4;
++ }
+ }
+
+ static void spi_flash_page_addr(struct spi_flash *flash, u32 page_addr, u32 byte_addr, u8 *cmd, u8 *cmd_len)
+ {
+ /* cmd[0] is actual command */
+- cmd[1] = page_addr >> 8;
+- cmd[2] = page_addr >> 0;
+- cmd[3] = byte_addr;
+- *cmd_len = 4;
++ if (spi_flash_use_4byte_mode(flash)) {
++ cmd[1] = page_addr >> 16;
++ cmd[2] = page_addr >> 8;
++ cmd[3] = page_addr >> 0;
++ cmd[4] = byte_addr;
++ *cmd_len = 5;
++ } else {
++ cmd[1] = page_addr >> 8;
++ cmd[2] = page_addr >> 0;
++ cmd[3] = byte_addr;
++ *cmd_len = 4;
++ }
+ }
+
+ static int spi_flash_read_write(struct spi_slave *spi,
+@@ -81,7 +97,7 @@ int spi_flash_cmd_write_multi(struct spi
+ unsigned long page_addr, byte_addr, page_size;
+ size_t chunk_len, actual;
+ int ret;
+- u8 cmd[4], cmd_len;
++ u8 cmd[5], cmd_len;
+
+ page_size = flash->page_size;
+ page_addr = offset / page_size;
+@@ -99,8 +115,8 @@ int spi_flash_cmd_write_multi(struct spi
+
+ spi_flash_page_addr(flash, page_addr, byte_addr, cmd, &cmd_len);
+
+- debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+- buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
++ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x%02x } chunk_len = %zu\n",
++ buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], chunk_len);
+
+ ret = spi_flash_cmd_write_enable(flash);
+ if (ret < 0) {
+@@ -146,7 +162,7 @@ int spi_flash_read_common(struct spi_fla
+ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
+ size_t len, void *data)
+ {
+- u8 cmd[5], cmd_len;
++ u8 cmd[6], cmd_len;
+
+ cmd[0] = CMD_READ_ARRAY_FAST;
+ spi_flash_addr(flash, offset, cmd, &cmd_len);
+@@ -202,7 +218,7 @@ int spi_flash_cmd_erase(struct spi_flash
+ {
+ u32 start, end, erase_size;
+ int ret;
+- u8 cmd[4], cmd_len;
++ u8 cmd[5], cmd_len;
+
+ erase_size = flash->sector_size;
+ if (offset % erase_size || len % erase_size) {
+@@ -227,8 +243,8 @@ int spi_flash_cmd_erase(struct spi_flash
+ spi_flash_addr(flash, offset, cmd, &cmd_len);
+ offset += erase_size;
+
+- debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+- cmd[2], cmd[3], offset);
++ debug("SF: erase %2x %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
++ cmd[2], cmd[3], cmd[4], offset);
+
+ ret = spi_flash_cmd_write_enable(flash);
+ if (ret)
+@@ -409,6 +425,12 @@ int spi_flash_probe_spl(struct spi_flash
+ goto err_manufacturer_probe;
+ }
+
++ ret = spi_flash_set_4byte_mode(flash);
++ if (ret) {
++ debug("SF: Failed to enable 4 byte mode: %d\n", ret);
++ goto err_manufacturer_probe;
++ }
++
+ spi_release_bus(spi);
+
+ return 0;
+--- a/drivers/mtd/spi/spi_flash_internal.h
++++ b/drivers/mtd/spi/spi_flash_internal.h
+@@ -97,6 +97,31 @@ int spi_flash_cmd_wait_ready(struct spi_
+ /* Erase sectors. */
+ int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len);
+
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++static inline int spi_flash_use_4byte_mode(struct spi_flash *flash)
++{
++ return NULL != flash->set_4byte_mode;
++}
++
++static inline int spi_flash_set_4byte_mode(struct spi_flash *flash)
++{
++ if (spi_flash_use_4byte_mode(flash))
++ return flash->set_4byte_mode(flash);
++
++ return 0;
++}
++#else
++static inline int spi_flash_use_4byte_mode(struct spi_flash *flash)
++{
++ return 0;
++}
++
++static inline int spi_flash_set_4byte_mode(struct spi_flash *flash)
++{
++ return 0;
++}
++#endif
++
+ /* Manufacturer-specific probe functions */
+ int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode);
+ int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode);
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -46,6 +46,9 @@ struct spi_flash {
+ size_t len, const void *buf);
+ int (*erase)(struct spi_flash *flash, u32 offset,
+ size_t len);
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++ int (*set_4byte_mode)(struct spi_flash *flash);
++#endif
+ };
+
+ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
diff --git a/package/boot/uboot-lantiq/patches/0007-sf-eon-use-16-bit-ID-for-comparison.patch b/package/boot/uboot-lantiq/patches/0007-sf-eon-use-16-bit-ID-for-comparison.patch
new file mode 100644
index 0000000..6836674
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0007-sf-eon-use-16-bit-ID-for-comparison.patch
@@ -0,0 +1,45 @@
+From d32f45357f0475a2f810752eeb9412fe692e1c0a Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:09:21 +0100
+Subject: sf: eon: use 16 bit ID for comparison
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/eon.c
++++ b/drivers/mtd/spi/eon.c
+@@ -11,19 +11,19 @@
+ #include "spi_flash_internal.h"
+
+ struct eon_spi_flash_params {
+- u8 idcode1;
++ u16 idcode;
+ u16 nr_sectors;
+ const char *name;
+ };
+
+ static const struct eon_spi_flash_params eon_spi_flash_table[] = {
+ {
+- .idcode1 = 0x16,
++ .idcode = 0x3016,
+ .nr_sectors = 1024,
+ .name = "EN25Q32B",
+ },
+ {
+- .idcode1 = 0x18,
++ .idcode = 0x3018,
+ .nr_sectors = 4096,
+ .name = "EN25Q128",
+ },
+@@ -33,10 +33,11 @@ int spi_flash_probe_eon(struct spi_flash
+ {
+ const struct eon_spi_flash_params *params;
+ unsigned int i;
++ u16 id = idcode[2] | idcode[1] << 8;
+
+ for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) {
+ params = &eon_spi_flash_table[i];
+- if (params->idcode1 == idcode[2])
++ if (params->idcode == id)
+ break;
+ }
+
diff --git a/package/boot/uboot-lantiq/patches/0008-sf-eon-add-support-for-4-byte-address-mode.patch b/package/boot/uboot-lantiq/patches/0008-sf-eon-add-support-for-4-byte-address-mode.patch
new file mode 100644
index 0000000..c037a86
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0008-sf-eon-add-support-for-4-byte-address-mode.patch
@@ -0,0 +1,43 @@
+From 37254e3284f61ea495f73a78b7c8efae983781e2 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:10:07 +0100
+Subject: sf: eon: add support for 4-byte address mode
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/eon.c
++++ b/drivers/mtd/spi/eon.c
+@@ -10,6 +10,8 @@
+
+ #include "spi_flash_internal.h"
+
++#define EN25XX_EN4B 0xb7 /* Enter 4-byte mode */
++
+ struct eon_spi_flash_params {
+ u16 idcode;
+ u16 nr_sectors;
+@@ -29,6 +31,13 @@ static const struct eon_spi_flash_params
+ },
+ };
+
++static __maybe_unused int eon_set_4byte_mode(struct spi_flash *flash)
++{
++ struct spi_slave *spi = flash->spi;
++
++ return spi_flash_cmd(spi, EN25XX_EN4B, NULL, 0);
++}
++
+ int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct eon_spi_flash_params *params;
+@@ -57,5 +66,10 @@ int spi_flash_probe_eon(struct spi_flash
+ flash->size = 256 * 16
+ * params->nr_sectors;
+
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++ if (flash->size > (1 << 24))
++ flash->set_4byte_mode = eon_set_4byte_mode;
++#endif
++
+ return 1;
+ }
diff --git a/package/boot/uboot-lantiq/patches/0009-sf-eon-add-support-for-EN25QH256.patch b/package/boot/uboot-lantiq/patches/0009-sf-eon-add-support-for-EN25QH256.patch
new file mode 100644
index 0000000..18f5823
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0009-sf-eon-add-support-for-EN25QH256.patch
@@ -0,0 +1,21 @@
+From e510be1145796cd44cf5800e187a94ad7c19e764 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:10:34 +0100
+Subject: sf: eon: add support for EN25QH256
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/eon.c
++++ b/drivers/mtd/spi/eon.c
+@@ -29,6 +29,11 @@ static const struct eon_spi_flash_params
+ .nr_sectors = 4096,
+ .name = "EN25Q128",
+ },
++ {
++ .idcode = 0x7019,
++ .nr_sectors = 8192,
++ .name = "EN25QH256",
++ },
+ };
+
+ static __maybe_unused int eon_set_4byte_mode(struct spi_flash *flash)
diff --git a/package/boot/uboot-lantiq/patches/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch b/package/boot/uboot-lantiq/patches/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch
new file mode 100644
index 0000000..af8c7a1
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch
@@ -0,0 +1,30 @@
+From 81a8e9e192d53ce8b5cafd47190d6c6826519d09 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:58:59 +0100
+Subject: sf: spansion: fix device IDs and sector architecture for S25FL256S
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spansion.c
++++ b/drivers/mtd/spi/spansion.c
+@@ -97,11 +97,18 @@ static const struct spansion_spi_flash_p
+ .name = "S25FL129P_64K",
+ },
+ {
+- .idcode1 = 0x2019,
++ .idcode1 = 0x0219,
+ .idcode2 = 0x4d01,
+ .pages_per_sector = 256,
+ .nr_sectors = 512,
+- .name = "S25FL256S",
++ .name = "S25FL256S_64K",
++ },
++ {
++ .idcode1 = 0x0219,
++ .idcode2 = 0x4d00,
++ .pages_per_sector = 1024,
++ .nr_sectors = 128,
++ .name = "S25FL256S_256K",
+ },
+ };
+
diff --git a/package/boot/uboot-lantiq/patches/0011-sf-spansion-add-support-for-4-byte-address-mode.patch b/package/boot/uboot-lantiq/patches/0011-sf-spansion-add-support-for-4-byte-address-mode.patch
new file mode 100644
index 0000000..9471d47
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0011-sf-spansion-add-support-for-4-byte-address-mode.patch
@@ -0,0 +1,55 @@
+From 0add8e5c60961d2b99174610df8d3d9d6d192b74 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 14:16:11 +0100
+Subject: sf: spansion: add support for 4-byte address mode
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spansion.c
++++ b/drivers/mtd/spi/spansion.c
+@@ -31,6 +31,10 @@
+
+ #include "spi_flash_internal.h"
+
++#define S25FLXX_BRRD 0x16 /* Read Bank Register */
++#define S25FLXX_BRWR 0x17 /* Write Bank Register */
++#define S25FLXX_BAR_EXTADD (1 << 7) /* Extended address enable */
++
+ struct spansion_spi_flash_params {
+ u16 idcode1;
+ u16 idcode2;
+@@ -112,6 +116,23 @@ static const struct spansion_spi_flash_p
+ },
+ };
+
++static __maybe_unused int spansion_set_4byte_mode(struct spi_flash *flash)
++{
++ struct spi_slave *spi = flash->spi;
++ u8 bar, cmd;
++ int err;
++
++ cmd = S25FLXX_BRRD;
++ err = spi_flash_cmd(spi, cmd, &bar, 1);
++ if (err)
++ return err;
++
++ bar |= S25FLXX_BAR_EXTADD;
++ cmd = S25FLXX_BRWR;
++
++ return spi_flash_cmd_write(spi, &cmd, 1, &bar, 1);
++}
++
+ int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct spansion_spi_flash_params *params;
+@@ -144,5 +165,10 @@ int spi_flash_probe_spansion(struct spi_
+ flash->sector_size = 256 * params->pages_per_sector;
+ flash->size = flash->sector_size * params->nr_sectors;
+
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++ if (flash->size > (1 << 24))
++ flash->set_4byte_mode = spansion_set_4byte_mode;
++#endif
++
+ return 1;
+ }
diff --git a/package/boot/uboot-lantiq/patches/0012-sf-spansion-add-support-for-S25FL512S.patch b/package/boot/uboot-lantiq/patches/0012-sf-spansion-add-support-for-S25FL512S.patch
new file mode 100644
index 0000000..5f415a9
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0012-sf-spansion-add-support-for-S25FL512S.patch
@@ -0,0 +1,23 @@
+From bff335ac524843bc90163c3b231091a5016f8670 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:07:54 +0100
+Subject: sf: spansion: add support for S25FL512S
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spansion.c
++++ b/drivers/mtd/spi/spansion.c
+@@ -114,6 +114,13 @@ static const struct spansion_spi_flash_p
+ .nr_sectors = 128,
+ .name = "S25FL256S_256K",
+ },
++ {
++ .idcode1 = 0x0220,
++ .idcode2 = 0x4d00,
++ .pages_per_sector = 1024,
++ .nr_sectors = 256,
++ .name = "S25FL512S_256K",
++ },
+ };
+
+ static __maybe_unused int spansion_set_4byte_mode(struct spi_flash *flash)
diff --git a/package/boot/uboot-lantiq/patches/0013-sf-macronix-add-support-for-4-byte-address-mode.patch b/package/boot/uboot-lantiq/patches/0013-sf-macronix-add-support-for-4-byte-address-mode.patch
new file mode 100644
index 0000000..70015c9
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0013-sf-macronix-add-support-for-4-byte-address-mode.patch
@@ -0,0 +1,44 @@
+From 207662a9270cc542709fbab0d25fbc361b39748c Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:13:49 +0100
+Subject: sf: macronix: add support for 4-byte address mode
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/macronix.c
++++ b/drivers/mtd/spi/macronix.c
+@@ -35,6 +35,8 @@
+
+ #include "spi_flash_internal.h"
+
++#define MX25XX_EN4B 0xb7 /* Enter 4-byte mode */
++
+ struct macronix_spi_flash_params {
+ u16 idcode;
+ u16 nr_blocks;
+@@ -79,6 +81,13 @@ static const struct macronix_spi_flash_p
+ },
+ };
+
++static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash)
++{
++ struct spi_slave *spi = flash->spi;
++
++ return spi_flash_cmd(spi, MX25XX_EN4B, NULL, 0);
++}
++
+ int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode)
+ {
+ const struct macronix_spi_flash_params *params;
+@@ -106,6 +115,11 @@ int spi_flash_probe_macronix(struct spi_
+ flash->sector_size = 256 * 16 * 16;
+ flash->size = flash->sector_size * params->nr_blocks;
+
++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE
++ if (flash->size > (1 << 24))
++ flash->set_4byte_mode = macronix_set_4byte_mode;
++#endif
++
+ /* Clear BP# bits for read-only flash */
+ spi_flash_cmd_write_status(flash, 0);
+
diff --git a/package/boot/uboot-lantiq/patches/0014-sf-macronix-add-support-for-MX25L25635E.patch b/package/boot/uboot-lantiq/patches/0014-sf-macronix-add-support-for-MX25L25635E.patch
new file mode 100644
index 0000000..8e33836
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0014-sf-macronix-add-support-for-MX25L25635E.patch
@@ -0,0 +1,21 @@
+From 0f31fef3d6a5110684ea31c5064c45fc448013d6 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:14:24 +0100
+Subject: sf: macronix: add support for MX25L25635E
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/macronix.c
++++ b/drivers/mtd/spi/macronix.c
+@@ -79,6 +79,11 @@ static const struct macronix_spi_flash_p
+ .nr_blocks = 256,
+ .name = "MX25L12855E",
+ },
++ {
++ .idcode = 0x2019,
++ .nr_blocks = 512,
++ .name = "MX25L25635E",
++ },
+ };
+
+ static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash)
diff --git a/package/boot/uboot-lantiq/patches/0015-sf-macronix-add-support-for-MX66L51235L.patch b/package/boot/uboot-lantiq/patches/0015-sf-macronix-add-support-for-MX66L51235L.patch
new file mode 100644
index 0000000..fbc22e4
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0015-sf-macronix-add-support-for-MX66L51235L.patch
@@ -0,0 +1,21 @@
+From a2d80b6b91ac63beea31455ce8d136230c030500 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 7 Nov 2012 15:14:40 +0100
+Subject: sf: macronix: add support for MX66L51235L
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/macronix.c
++++ b/drivers/mtd/spi/macronix.c
+@@ -84,6 +84,11 @@ static const struct macronix_spi_flash_p
+ .nr_blocks = 512,
+ .name = "MX25L25635E",
+ },
++ {
++ .idcode = 0x201A,
++ .nr_blocks = 1024,
++ .name = "MX66L51235L",
++ },
+ };
+
+ static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash)
diff --git a/package/boot/uboot-lantiq/patches/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch b/package/boot/uboot-lantiq/patches/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch
new file mode 100644
index 0000000..a9ee560
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch
@@ -0,0 +1,133 @@
+From 7f6ded11965b09daf6da44d4fa98da17b9fba36c Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 19:41:26 +0100
+Subject: sf: add MTD layer driver for SPI flash devices
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/Makefile
++++ b/drivers/mtd/spi/Makefile
+@@ -30,6 +30,7 @@ COBJS-$(CONFIG_SPL_SPI_LOAD) += spi_spl_
+ endif
+
+ COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o
++COBJS-$(CONFIG_SPI_FLASH_MTD) += spi_flash_mtd.o
+ COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o
+ COBJS-$(CONFIG_SPI_FLASH_EON) += eon.o
+ COBJS-$(CONFIG_SPI_FLASH_MACRONIX) += macronix.o
+--- a/drivers/mtd/spi/spi_flash_internal.h
++++ b/drivers/mtd/spi/spi_flash_internal.h
+@@ -122,6 +122,9 @@ static inline int spi_flash_set_4byte_mo
+ }
+ #endif
+
++/* SPI flash MTD adapter init */
++int spi_flash_mtd_init(struct spi_flash *flash);
++
+ /* Manufacturer-specific probe functions */
+ int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode);
+ int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode);
+--- /dev/null
++++ b/drivers/mtd/spi/spi_flash_mtd.c
+@@ -0,0 +1,101 @@
++/*
++ * (C) Copyright 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * MTD layer driver for SPI flash devices
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <asm/errno.h>
++#include <linux/mtd/mtd.h>
++#include <spi_flash.h>
++
++static struct mtd_info sf_mtd_info;
++static char sf_mtd_name[8];
++
++static int spi_flash_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
++{
++ struct spi_flash *flash = mtd->priv;
++ int err;
++
++ instr->state = MTD_ERASING;
++
++ err = spi_flash_erase(flash, instr->addr, instr->len);
++ if (err) {
++ instr->state = MTD_ERASE_FAILED;
++ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
++ return -EIO;
++ }
++
++ instr->state = MTD_ERASE_DONE;
++ mtd_erase_callback(instr);
++
++ return 0;
++}
++
++static int spi_flash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
++ size_t *retlen, u_char *buf)
++{
++ struct spi_flash *flash = mtd->priv;
++ int err;
++
++ err = spi_flash_read(flash, from, len, buf);
++ if (!err)
++ *retlen = len;
++
++ return err;
++}
++
++static int spi_flash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
++ size_t *retlen, const u_char *buf)
++{
++ struct spi_flash *flash = mtd->priv;
++ int err;
++
++ err = spi_flash_write(flash, to, len, buf);
++ if (!err)
++ *retlen = len;
++
++ return err;
++}
++
++static void spi_flash_mtd_sync(struct mtd_info *mtd)
++{
++}
++
++static int spi_flash_mtd_number(void)
++{
++#ifdef CONFIG_SYS_MAX_FLASH_BANKS
++ return CONFIG_SYS_MAX_FLASH_BANKS;
++#else
++ return 0;
++#endif
++}
++
++int spi_flash_mtd_init(struct spi_flash *flash)
++{
++ memset(&sf_mtd_info, 0, sizeof(sf_mtd_info));
++ sprintf(sf_mtd_name, "nor%d", spi_flash_mtd_number());
++
++ sf_mtd_info.name = sf_mtd_name;
++ sf_mtd_info.type = MTD_NORFLASH;
++ sf_mtd_info.flags = MTD_CAP_NORFLASH;
++ sf_mtd_info.writesize = 1;
++
++ sf_mtd_info.erase = spi_flash_mtd_erase;
++ sf_mtd_info.read = spi_flash_mtd_read;
++ sf_mtd_info.write = spi_flash_mtd_write;
++ sf_mtd_info.sync = spi_flash_mtd_sync;
++
++ sf_mtd_info.size = flash->size;
++ sf_mtd_info.priv = flash;
++
++ /* Only uniform flash devices for now */
++ sf_mtd_info.numeraseregions = 0;
++ sf_mtd_info.erasesize = flash->sector_size;
++
++ return add_mtd_device(&sf_mtd_info);
++}
diff --git a/package/boot/uboot-lantiq/patches/0017-sf-add-init-function.patch b/package/boot/uboot-lantiq/patches/0017-sf-add-init-function.patch
new file mode 100644
index 0000000..2d29051
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0017-sf-add-init-function.patch
@@ -0,0 +1,57 @@
+From aa9d5d64ca6441cb24e22dc3c1f707da62da2887 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 19:35:17 +0100
+Subject: sf: add init function
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/spi_flash.c
++++ b/drivers/mtd/spi/spi_flash.c
+@@ -482,3 +482,36 @@ void spi_flash_free(struct spi_flash *fl
+ spi_flash_free_spl(flash);
+ free(flash);
+ }
++
++#ifdef CONFIG_SPI_FLASH_MTD
++static int spi_flash_mtd_register(void)
++{
++ struct spi_flash *flash;
++ int err;
++
++ flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
++ CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
++ if (!flash)
++ return -1;
++
++ err = spi_flash_mtd_init(flash);
++ if (err)
++ spi_flash_free(flash);
++
++ return err;
++}
++#else
++static int spi_flash_mtd_register(void)
++{
++ return 0;
++}
++#endif
++
++int spi_flash_init(void)
++{
++ int err;
++
++ err = spi_flash_mtd_register();
++
++ return err;
++}
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -51,6 +51,8 @@ struct spi_flash {
+ #endif
+ };
+
++int spi_flash_init(void);
++
+ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int spi_mode);
+ void spi_flash_free(struct spi_flash *flash);
diff --git a/package/boot/uboot-lantiq/patches/0018-MIPS-add-SPI-flash-init-hook.patch b/package/boot/uboot-lantiq/patches/0018-MIPS-add-SPI-flash-init-hook.patch
new file mode 100644
index 0000000..71f094b
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0018-MIPS-add-SPI-flash-init-hook.patch
@@ -0,0 +1,47 @@
+From 888b33e84082fe72d60d528c05c885c0c9d70bc4 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Tue, 6 Nov 2012 21:19:43 +0100
+Subject: MIPS: add SPI flash init hook
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/arch/mips/lib/board.c
++++ b/arch/mips/lib/board.c
+@@ -32,6 +32,7 @@
+ #include <nand.h>
+ #include <onenand_uboot.h>
+ #include <spi.h>
++#include <spi_flash.h>
+
+ #ifdef CONFIG_BITBANGMII
+ #include <miiphy.h>
+@@ -312,6 +313,16 @@ void board_init_r(gd_t *id, ulong dest_a
+ onenand_init();
+ #endif
+
++#ifdef CONFIG_CMD_SPI
++ puts("SPI: ");
++ spi_init(); /* go init the SPI */
++ puts("ready\n");
++#endif
++
++#if defined(CONFIG_SPI_FLASH)
++ spi_flash_init();
++#endif
++
+ /* relocate environment function pointers etc. */
+ env_relocate();
+
+@@ -335,12 +346,6 @@ void board_init_r(gd_t *id, ulong dest_a
+ /* Initialize from environment */
+ load_addr = getenv_ulong("loadaddr", 16, load_addr);
+
+-#ifdef CONFIG_CMD_SPI
+- puts("SPI: ");
+- spi_init(); /* go init the SPI */
+- puts("ready\n");
+-#endif
+-
+ #if defined(CONFIG_MISC_INIT_R)
+ /* miscellaneous platform dependent initialisations */
+ misc_init_r();
diff --git a/package/boot/uboot-lantiq/patches/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch b/package/boot/uboot-lantiq/patches/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch
new file mode 100644
index 0000000..a215d1a
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch
@@ -0,0 +1,239 @@
+From d8b1597130d228bc7e2bafd0c8d097529018c833 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 29 Aug 2012 22:08:15 +0200
+Subject: net: switchlib: add framework for ethernet switch drivers
+
+Add a generic framework similar to phylib for ethernet switch
+drivers and devices. This is useful to share the init and
+setup code for switch devices across different boards.
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Cc: Joe Hershberger <joe.hershberger@gmail.com>
+
+--- a/Makefile
++++ b/Makefile
+@@ -291,6 +291,7 @@ LIBS-y += drivers/mtd/ubi/libubi.o
+ LIBS-y += drivers/mtd/spi/libspi_flash.o
+ LIBS-y += drivers/net/libnet.o
+ LIBS-y += drivers/net/phy/libphy.o
++LIBS-y += drivers/net/switch/libswitch.o
+ LIBS-y += drivers/pci/libpci.o
+ LIBS-y += drivers/pcmcia/libpcmcia.o
+ LIBS-y += drivers/power/libpower.o \
+--- /dev/null
++++ b/drivers/net/switch/Makefile
+@@ -0,0 +1,31 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB := $(obj)libswitch.o
++
++COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
++
++COBJS := $(COBJS-y)
++SRCS := $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++
++all: $(LIB)
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/drivers/net/switch/switch.c
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <switch.h>
++
++static struct list_head switch_drivers;
++static struct list_head switch_devices;
++
++void switch_init(void)
++{
++ INIT_LIST_HEAD(&switch_drivers);
++ INIT_LIST_HEAD(&switch_devices);
++
++ board_switch_init();
++}
++
++void switch_driver_register(struct switch_driver *drv)
++{
++ INIT_LIST_HEAD(&drv->list);
++ list_add_tail(&drv->list, &switch_drivers);
++}
++
++int switch_device_register(struct switch_device *dev)
++{
++ struct switch_driver *drv;
++
++ /* Add switch device only, if an adequate driver is registered */
++ list_for_each_entry(drv, &switch_drivers, list) {
++ if (!strcmp(drv->name, dev->name)) {
++ dev->drv = drv;
++
++ INIT_LIST_HEAD(&dev->list);
++ list_add_tail(&dev->list, &switch_devices);
++
++ return 0;
++ }
++ }
++
++ return -1;
++}
++
++struct switch_device *switch_connect(struct mii_dev *bus)
++{
++ struct switch_device *sw;
++ int err;
++
++ list_for_each_entry(sw, &switch_devices, list) {
++ sw->bus = bus;
++
++ err = sw->drv->probe(sw);
++ if (!err)
++ return sw;
++ }
++
++ return NULL;
++}
+--- /dev/null
++++ b/include/switch.h
+@@ -0,0 +1,95 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __SWITCH_H
++#define __SWITCH_H
++
++#include <linux/list.h>
++
++#define SWITCH_NAME_SIZE 32
++
++struct switch_device;
++struct mii_dev;
++
++struct switch_driver {
++ struct list_head list;
++
++ /* Switch device name */
++ const char name[SWITCH_NAME_SIZE];
++
++ /*
++ * Called to probe the switch chip. Must return 0 if the switch
++ * chip matches the given switch device/driver combination. Otherwise
++ * 1 must be returned.
++ */
++ int (*probe) (struct switch_device *dev);
++
++ /*
++ * Called to initialize the switch chip.
++ */
++ void (*setup) (struct switch_device *dev);
++};
++
++struct switch_device {
++ struct list_head list;
++ struct switch_driver *drv;
++
++ /* MII bus the switch chip is connected to */
++ struct mii_dev *bus;
++
++ /* Switch device name */
++ const char name[SWITCH_NAME_SIZE];
++
++ /* Bitmask for board specific setup of used switch ports */
++ u16 port_mask;
++
++ /* Number of switch port that is connected to host CPU */
++ u16 cpu_port;
++};
++
++/*
++ * Board specific switch initialization.
++ *
++ * Called from switch_init to register the board specific switch_device
++ * structure.
++ */
++extern int board_switch_init(void);
++
++/* Initialize switch subsystem */
++#ifdef CONFIG_SWITCH_MULTI
++extern void switch_init(void);
++#else
++static inline void switch_init(void)
++{
++}
++#endif
++
++/* Register a switch driver */
++extern void switch_driver_register(struct switch_driver *drv);
++
++/* Register a switch device */
++extern int switch_device_register(struct switch_device *dev);
++
++/*
++ * Probe the available switch chips and connect the found one
++ * with the given MII bus
++ */
++extern struct switch_device *switch_connect(struct mii_dev *bus);
++
++/*
++ * Setup the given switch device
++ */
++static inline void switch_setup(struct switch_device *dev)
++{
++ if (dev->drv->setup)
++ dev->drv->setup(dev);
++}
++
++/* Init functions for supported Switch drivers */
++
++#endif /* __SWITCH_H */
++
+--- a/net/eth.c
++++ b/net/eth.c
+@@ -26,6 +26,7 @@
+ #include <net.h>
+ #include <miiphy.h>
+ #include <phy.h>
++#include <switch.h>
+
+ void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
+ {
+@@ -303,6 +304,8 @@ int eth_initialize(bd_t *bis)
+ phy_init();
+ #endif
+
++ switch_init();
++
+ eth_env_init(bis);
+
+ /*
diff --git a/package/boot/uboot-lantiq/patches/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch b/package/boot/uboot-lantiq/patches/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch
new file mode 100644
index 0000000..c017e0f
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch
@@ -0,0 +1,162 @@
+From b8c666eda693906488637c414db9db35b6760e4a Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 29 Aug 2012 22:08:15 +0200
+Subject: net: switchlib: add driver for Lantiq PSB697X switch family
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -11,6 +11,7 @@ include $(TOPDIR)/config.mk
+ LIB := $(obj)libswitch.o
+
+ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
++COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/psb697x.c
+@@ -0,0 +1,119 @@
++/*
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <switch.h>
++#include <miiphy.h>
++
++#define PSB697X_CHIPID1 0x2599
++#define PSB697X_PORT_COUNT 7
++
++#define PSB697X_PORT_BASE(p) (p * 0x20)
++#define PSB697X_REG_PS(p) (PSB697X_PORT_BASE(p) + 0x00)
++#define PSB697X_REG_PBC(p) (PSB697X_PORT_BASE(p) + 0x01)
++#define PSB697X_REG_PEC(p) (PSB697X_PORT_BASE(p) + 0x02)
++
++#define PSB697X_REG_SGC1 0x0E0 /* Switch Global Control Register 1 */
++#define PSB697X_REG_SGC2 0x0E1 /* Switch Global Control Register 2 */
++#define PSB697X_REG_CMH 0x0E2 /* CPU Port & Mirror Control */
++#define PSB697X_REG_MIICR 0x0F5 /* MII Port Control */
++#define PSB697X_REG_CI0 0x100 /* Chip Identifier 0 */
++#define PSB697X_REG_CI1 0x101 /* Chip Identifier 1 */
++#define PSB697X_REG_MIIAC 0x120 /* MII Indirect Access Control */
++#define PSB697X_REG_MIIWD 0x121 /* MII Indirect Write Data */
++#define PSB697X_REG_MIIRD 0x122 /* MII Indirect Read Data */
++
++#define PSB697X_REG_PORT_FLP (1 << 2) /* Force link up */
++#define PSB697X_REG_PORT_FLD (1 << 1) /* Force link down */
++
++#define PSB697X_REG_SGC2_SE (1 << 15) /* Switch enable */
++
++#define PSB697X_REG_CMH_CPN_MASK 0x7
++#define PSB697X_REG_CMH_CPN_SHIFT 5
++
++
++static inline int psb697x_mii_read(struct mii_dev *bus, u16 reg)
++{
++ int ret;
++
++ ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f);
++
++ return ret;
++}
++
++static inline int psb697x_mii_write(struct mii_dev *bus, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE,
++ reg & 0x1f, val);
++
++ return ret;
++}
++
++static int psb697x_probe(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ int ci1;
++
++ ci1 = psb697x_mii_read(bus, PSB697X_REG_CI1);
++
++ if (ci1 == PSB697X_CHIPID1)
++ return 0;
++
++ return 1;
++}
++
++static void psb697x_setup(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ int i, state;
++
++ /* Enable switch */
++ psb697x_mii_write(bus, PSB697X_REG_SGC2, PSB697X_REG_SGC2_SE);
++
++ /*
++ * Force 100 Mbps as default value for CPU ports 5 and 6 to get
++ * full speed.
++ */
++ psb697x_mii_write(bus, PSB697X_REG_MIICR, 0x0773);
++
++ for (i = 0; i < PSB697X_PORT_COUNT; i++) {
++ state = dev->port_mask & (1 << i);
++
++ /*
++ * Software workaround from Errata Sheet:
++ * Force link down and reset internal PHY, keep that state
++ * for all unconnected ports and disable force link down
++ * for all connected ports
++ */
++ psb697x_mii_write(bus, PSB697X_REG_PBC(i),
++ PSB697X_REG_PORT_FLD);
++
++ if (i == dev->cpu_port)
++ /* Force link up for CPU port */
++ psb697x_mii_write(bus, PSB697X_REG_PBC(i),
++ PSB697X_REG_PORT_FLP);
++ else if (state)
++ /* Disable force link down for active LAN ports */
++ psb697x_mii_write(bus, PSB697X_REG_PBC(i), 0);
++ }
++}
++
++static struct switch_driver psb697x_drv = {
++ .name = "psb697x",
++};
++
++void switch_psb697x_init(void)
++{
++ /* For archs with manual relocation */
++ psb697x_drv.probe = psb697x_probe;
++ psb697x_drv.setup = psb697x_setup;
++
++ switch_driver_register(&psb697x_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -18,6 +18,10 @@ void switch_init(void)
+ INIT_LIST_HEAD(&switch_drivers);
+ INIT_LIST_HEAD(&switch_devices);
+
++#if defined(CONFIG_SWITCH_PSB697X)
++ switch_psb697x_init();
++#endif
++
+ board_switch_init();
+ }
+
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -90,6 +90,7 @@ static inline void switch_setup(struct s
+ }
+
+ /* Init functions for supported Switch drivers */
++extern void switch_psb697x_init(void);
+
+ #endif /* __SWITCH_H */
+
diff --git a/package/boot/uboot-lantiq/patches/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch b/package/boot/uboot-lantiq/patches/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch
new file mode 100644
index 0000000..342fa46
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch
@@ -0,0 +1,158 @@
+From fcbbb1beb2ae862f5c703c5719ed0e155cbbf82f Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 29 Aug 2012 22:08:16 +0200
+Subject: net: switchlib: add driver for Lantiq ADM6996I switch family
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -12,6 +12,7 @@ LIB := $(obj)libswitch.o
+
+ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
+ COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
++COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/adm6996i.c
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <switch.h>
++#include <miiphy.h>
++
++#define ADM6996I_CHIPID0 0x1020
++#define ADM6996I_CHIPID1 0x0007
++#define ADM6996I_PORT_COUNT 6
++
++#define ADM6996I_REG_P0BC 0x001 /* P0 Basic Control */
++#define ADM6996I_REG_P1BC 0x003 /* P1 Basic Control */
++#define ADM6996I_REG_P2BC 0x005 /* P2 Basic Control */
++#define ADM6996I_REG_P3BC 0x007 /* P3 Basic Control */
++#define ADM6996I_REG_P4BC 0x008 /* P4 Basic Control */
++#define ADM6996I_REG_P5BC 0x009 /* P5 Basic Control */
++
++#define ADM6996I_REG_P0EC 0x002 /* P0 Extended Control */
++#define ADM6996I_REG_P1EC 0x002 /* P1 Extended Control */
++#define ADM6996I_REG_P2EC 0x004 /* P2 Extended Control */
++#define ADM6996I_REG_P3EC 0x004 /* P3 Extended Control */
++#define ADM6996I_REG_P4EC 0x006 /* P4 Extended Control */
++#define ADM6996I_REG_P5EC 0x006 /* P5 Extended Control */
++
++#define ADM6996I_REG_SC4 0x012 /* System Control 4 */
++
++#define ADM6996I_REG_CI0 0xA0 /* Chip Identifier 0 */
++#define ADM6996I_REG_CI1 0xA1 /* Chip Identifier 1 */
++
++#define ADM6996I_REG_PXBC_DEFAULT 0x040F
++#define ADM6996I_REG_PXBC_CROSS_EE (1 << 15)
++#define ADM6996I_REG_PXBC_PD (1 << 5)
++
++#define ADM6996I_REG_SC4_DEFAULT 0x3600
++#define ADM6996I_REG_SC4_LED_ENABLE (1 << 1)
++
++#define ADM6996I_REG_CI0_PC_MASK 0xFFF0
++#define ADM6996I_REG_CI0_VN_MASK 0xF
++#define ADM6996I_REG_CI1_PC_MASK 0xF
++
++
++static inline int adm6996i_mii_read(struct mii_dev *bus, u16 reg)
++{
++ int ret;
++
++ ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f);
++
++ return ret;
++}
++
++static inline int adm6996i_mii_write(struct mii_dev *bus, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE,
++ reg & 0x1f, val);
++
++ return ret;
++}
++
++static int adm6996i_probe(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ u16 ci0, ci1;
++
++ ci0 = adm6996i_mii_read(bus, ADM6996I_REG_CI0);
++ ci1 = adm6996i_mii_read(bus, ADM6996I_REG_CI1);
++
++ ci0 &= ADM6996I_REG_CI0_PC_MASK;
++ ci1 &= ADM6996I_REG_CI1_PC_MASK;
++
++ if (ci0 == ADM6996I_CHIPID0 && ci1 == ADM6996I_CHIPID1)
++ return 0;
++
++ return 1;
++}
++
++static void adm6996i_setup(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ u16 val;
++
++ /*
++ * Write default values (Port enable, 100 Mbps, Full Duplex,
++ * Auto negotiation, Flow control) and enable crossover auto-detect
++ */
++ val = ADM6996I_REG_PXBC_DEFAULT | ADM6996I_REG_PXBC_CROSS_EE;
++ adm6996i_mii_write(bus, ADM6996I_REG_P0BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P1BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P2BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P3BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P4BC, val);
++ adm6996i_mii_write(bus, ADM6996I_REG_P5BC, val);
++
++ val = ADM6996I_REG_SC4_DEFAULT | ADM6996I_REG_SC4_LED_ENABLE;
++ adm6996i_mii_write(bus, ADM6996I_REG_SC4, val);
++}
++
++static struct switch_driver adm6996i_drv = {
++ .name = "adm6996i",
++};
++
++void switch_adm6996i_init(void)
++{
++ /* For archs with manual relocation */
++ adm6996i_drv.probe = adm6996i_probe;
++ adm6996i_drv.setup = adm6996i_setup;
++
++ switch_driver_register(&adm6996i_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -21,6 +21,9 @@ void switch_init(void)
+ #if defined(CONFIG_SWITCH_PSB697X)
+ switch_psb697x_init();
+ #endif
++#if defined(CONFIG_SWITCH_ADM6996I)
++ switch_adm6996i_init();
++#endif
+
+ board_switch_init();
+ }
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -91,6 +91,7 @@ static inline void switch_setup(struct s
+
+ /* Init functions for supported Switch drivers */
+ extern void switch_psb697x_init(void);
++extern void switch_adm6996i_init(void);
+
+ #endif /* __SWITCH_H */
+
diff --git a/package/boot/uboot-lantiq/patches/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch b/package/boot/uboot-lantiq/patches/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch
new file mode 100644
index 0000000..127c0d8
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch
@@ -0,0 +1,158 @@
+From 16b8c52f80f20e07866e397ff52ff9658766437b Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Wed, 29 Aug 2012 22:08:16 +0200
+Subject: net: switchlib: add driver for Atheros AR8216
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -13,6 +13,7 @@ LIB := $(obj)libswitch.o
+ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
+ COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
+ COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o
++COBJS-$(CONFIG_SWITCH_AR8216) += ar8216.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/ar8216.c
+@@ -0,0 +1,115 @@
++/*
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ *
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <miiphy.h>
++#include <switch.h>
++#include <netdev.h>
++
++#define BITS(_s, _n) (((1UL << (_n)) - 1) << _s)
++
++#define AR8216_REG_CTRL 0x0000
++#define AR8216_CTRL_REVISION BITS(0, 8)
++#define AR8216_CTRL_VERSION BITS(8, 8)
++
++#define AR8216_PROBE_RETRIES 10
++
++static void split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
++{
++ regaddr >>= 1;
++ *r1 = regaddr & 0x1e;
++
++ regaddr >>= 5;
++ *r2 = regaddr & 0x7;
++
++ regaddr >>= 3;
++ *page = regaddr & 0x1ff;
++}
++
++static int ar8216_mii_read(struct mii_dev *bus, u32 reg)
++{
++ u16 r1, r2, page;
++ u16 lo, hi;
++
++ split_addr(reg, &r1, &r2, &page);
++
++ bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, page);
++ __udelay(1000);
++
++ lo = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1);
++ hi = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1);
++
++ return (hi << 16) | lo;
++}
++
++static void ar8216_mii_write(struct mii_dev *bus, u16 reg, u32 val)
++{
++ u16 r1, r2, r3;
++ u16 lo, hi;
++
++ split_addr((u32) reg, &r1, &r2, &r3);
++
++ bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, r3);
++ __udelay(1000);
++
++ lo = val & 0xffff;
++ hi = (u16) (val >> 16);
++ bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1, hi);
++ bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1, lo);
++}
++
++static int ar8216_probe(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++ u32 val;
++ u16 id;
++
++ val = ar8216_mii_read(bus, AR8216_REG_CTRL);
++ if (val == ~0)
++ return 1;
++
++ id = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION);
++
++ switch (id) {
++ case 0x0101:
++ return 0;
++ default:
++ return 1;
++ }
++}
++
++static void ar8216_setup(struct switch_device *dev)
++{
++ struct mii_dev *bus = dev->bus;
++
++ ar8216_mii_write(bus, 0x200, 0x200);
++ ar8216_mii_write(bus, 0x300, 0x200);
++ ar8216_mii_write(bus, 0x400, 0x200);
++ ar8216_mii_write(bus, 0x500, 0x200);
++ ar8216_mii_write(bus, 0x600, 0x7d);
++ ar8216_mii_write(bus, 0x38, 0xc000050e);
++ ar8216_mii_write(bus, 0x104, 0x4004);
++ ar8216_mii_write(bus, 0x60, 0xffffffff);
++ ar8216_mii_write(bus, 0x64, 0xaaaaaaaa);
++ ar8216_mii_write(bus, 0x68, 0x55555555);
++ ar8216_mii_write(bus, 0x6c, 0x0);
++ ar8216_mii_write(bus, 0x70, 0x41af);
++}
++
++static struct switch_driver ar8216_drv = {
++ .name = "ar8216",
++};
++
++void switch_ar8216_init(void)
++{
++ /* for archs with manual relocation */
++ ar8216_drv.probe = ar8216_probe;
++ ar8216_drv.setup = ar8216_setup;
++
++ switch_driver_register(&ar8216_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -24,6 +24,9 @@ void switch_init(void)
+ #if defined(CONFIG_SWITCH_ADM6996I)
+ switch_adm6996i_init();
+ #endif
++#if defined(CONFIG_SWITCH_AR8216)
++ switch_ar8216_init();
++#endif
+
+ board_switch_init();
+ }
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -92,6 +92,7 @@ static inline void switch_setup(struct s
+ /* Init functions for supported Switch drivers */
+ extern void switch_psb697x_init(void);
+ extern void switch_adm6996i_init(void);
++extern void switch_ar8216_init(void);
+
+ #endif /* __SWITCH_H */
+
diff --git a/package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch b/package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch
new file mode 100644
index 0000000..2582c16
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch
@@ -0,0 +1,9496 @@
+From ed2effe0839929d00f05ec0e1e16fb467f324e1b Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Thu, 20 Dec 2012 19:05:54 +0100
+Subject: MIPS: add support for Lantiq XWAY SoCs
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/.gitignore
++++ b/.gitignore
+@@ -44,6 +44,13 @@
+ /u-boot.sb
+ /u-boot.geany
+ /include/u-boot.lst
++/u-boot.bin.lzma
++/u-boot.bin.lzo
++/u-boot.ltq.lzma.norspl
++/u-boot.ltq.lzo.norspl
++/u-boot.ltq.norspl
++/u-boot.lzma.img
++/u-boot.lzo.img
+
+ #
+ # Generated files
+--- a/Makefile
++++ b/Makefile
+@@ -441,6 +441,12 @@ $(obj)u-boot.bin: $(obj)u-boot
+ $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+ $(BOARD_SIZE_CHECK)
+
++$(obj)u-boot.bin.lzma: $(obj)u-boot.bin
++ cat $< | lzma -9 -f - > $@
++
++$(obj)u-boot.bin.lzo: $(obj)u-boot.bin
++ cat $< | lzop -9 -f - > $@
++
+ $(obj)u-boot.ldr: $(obj)u-boot
+ $(CREATE_LDR_ENV)
+ $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
+@@ -460,13 +466,23 @@ ifndef CONFIG_SYS_UBOOT_START
+ CONFIG_SYS_UBOOT_START := 0
+ endif
+
+-$(obj)u-boot.img: $(obj)u-boot.bin
+- $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
++define GEN_UBOOT_IMAGE
++ $(obj)tools/mkimage -A $(ARCH) -T firmware -C $(1) \
+ -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \
+ -e $(CONFIG_SYS_UBOOT_START) \
+ -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
+ sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
+ -d $< $@
++endef
++
++$(obj)u-boot.img: $(obj)u-boot.bin
++ $(call GEN_UBOOT_IMAGE,none)
++
++$(obj)u-boot.lzma.img: $(obj)u-boot.bin.lzma
++ $(call GEN_UBOOT_IMAGE,lzma)
++
++$(obj)u-boot.lzo.img: $(obj)u-boot.bin.lzo
++ $(call GEN_UBOOT_IMAGE,lzo)
+
+ $(obj)u-boot.imx: $(obj)u-boot.bin
+ $(obj)tools/mkimage -n $(CONFIG_IMX_CONFIG) -T imximage \
+@@ -549,6 +565,27 @@ endif
+ $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
+ cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@
+
++$(obj)u-boot.ltq.sfspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.lzo.sfspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
++ cat $(obj)spl/u-boot-spl.bin $< > $@
++
++$(obj)u-boot.ltq.lzo.norspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
++ cat $(obj)spl/u-boot-spl.bin $< > $@
++
++$(obj)u-boot.ltq.lzma.norspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
++ cat $(obj)spl/u-boot-spl.bin $< > $@
++
+ ifeq ($(CONFIG_SANDBOX),y)
+ GEN_UBOOT = \
+ cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
+--- a/README
++++ b/README
+@@ -460,6 +460,11 @@ The following options need to be configu
+ CONF_CM_CACHABLE_CUW
+ CONF_CM_CACHABLE_ACCELERATED
+
++ CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++ Enable this to use extended cache initialization for recent
++ MIPS CPU cores.
++
+ CONFIG_SYS_XWAY_EBU_BOOTCFG
+
+ Special option for Lantiq XWAY SoCs for booting from NOR flash.
+--- a/arch/mips/config.mk
++++ b/arch/mips/config.mk
+@@ -61,7 +61,10 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__M
+ # On the other hand, we want PIC in the U-Boot code to relocate it from ROM
+ # to RAM. $28 is always used as gp.
+ #
+-PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS)
++PF_ABICALLS ?= -mabicalls
++PF_PIC ?= -fpic
++
++PLATFORM_CPPFLAGS += -G 0 $(PF_ABICALLS) $(PF_PIC) $(ENDIANNESS)
+ PLATFORM_CPPFLAGS += -msoft-float
+ PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS)
+ PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
+--- a/arch/mips/cpu/mips32/cache.S
++++ b/arch/mips/cpu/mips32/cache.S
+@@ -45,7 +45,11 @@
+ */
+ #define MIPS_MAX_CACHE_SIZE 0x10000
+
++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
++#define INDEX_BASE 0x9fc00000
++#else
+ #define INDEX_BASE CKSEG0
++#endif
+
+ .macro cache_op op addr
+ .set push
+@@ -81,7 +85,11 @@
+ */
+ LEAF(mips_init_icache)
+ blez a1, 9f
++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
++ mtc0 zero, CP0_ITAGLO
++#else
+ mtc0 zero, CP0_TAGLO
++#endif
+ /* clear tag to invalidate */
+ PTR_LI t0, INDEX_BASE
+ PTR_ADDU t1, t0, a1
+@@ -106,7 +114,11 @@ LEAF(mips_init_icache)
+ */
+ LEAF(mips_init_dcache)
+ blez a1, 9f
++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
++ mtc0 zero, CP0_DTAGLO
++#else
+ mtc0 zero, CP0_TAGLO
++#endif
+ /* clear all tags */
+ PTR_LI t0, INDEX_BASE
+ PTR_ADDU t1, t0, a1
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/Makefile
+@@ -0,0 +1,33 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(SOC).o
++
++COBJS-y += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
++SOBJS-y += cgu_init.o mem_init.o
++
++COBJS := $(COBJS-y)
++SOBJS := $(SOBJS-y)
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
++
++all: $(LIB)
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/cgu.c
+@@ -0,0 +1,118 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_CGU_SYS_DDR_MASK 0x0003
++#define LTQ_CGU_SYS_DDR_SHIFT 0
++#define LTQ_CGU_SYS_CPU0_MASK 0x000C
++#define LTQ_CGU_SYS_CPU0_SHIFT 2
++#define LTQ_CGU_SYS_FPI_MASK 0x0040
++#define LTQ_CGU_SYS_FPI_SHIFT 6
++
++struct ltq_cgu_regs {
++ u32 rsvd0;
++ u32 pll0_cfg; /* PLL0 config */
++ u32 pll1_cfg; /* PLL1 config */
++ u32 pll2_cfg; /* PLL2 config */
++ u32 sys; /* System clock */
++ u32 update; /* CGU update control */
++ u32 if_clk; /* Interface clock */
++ u32 osc_con; /* Update OSC Control */
++ u32 smd; /* SDRAM Memory Control */
++ u32 rsvd1[3];
++ u32 pcm_cr; /* PCM control */
++ u32 pci_cr; /* PCI clock control */
++};
++
++static struct ltq_cgu_regs *ltq_cgu_regs =
++ (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
++
++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
++{
++ return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
++}
++
++unsigned long ltq_get_io_region_clock(void)
++{
++ u32 ddr_sel;
++ unsigned long clk;
++
++ ddr_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_DDR_MASK,
++ LTQ_CGU_SYS_DDR_SHIFT);
++
++ switch (ddr_sel) {
++ case 0:
++ clk = CLOCK_166_MHZ;
++ break;
++ case 1:
++ clk = CLOCK_133_MHZ;
++ break;
++ case 2:
++ clk = CLOCK_111_MHZ;
++ break;
++ case 3:
++ clk = CLOCK_83_MHZ;
++ break;
++ default:
++ clk = 0;
++ break;
++ }
++
++ return clk;
++}
++
++unsigned long ltq_get_cpu_clock(void)
++{
++ u32 cpu0_sel;
++ unsigned long clk;
++
++ cpu0_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU0_MASK,
++ LTQ_CGU_SYS_CPU0_SHIFT);
++
++ switch (cpu0_sel) {
++ /* Same as PLL0 output (333,33 MHz) */
++ case 0:
++ clk = CLOCK_333_MHZ;
++ break;
++ /* 1/1 fixed ratio to DDR clock */
++ case 1:
++ clk = ltq_get_io_region_clock();
++ break;
++ /* 1/2 fixed ratio to DDR clock */
++ case 2:
++ clk = ltq_get_io_region_clock() << 1;
++ break;
++ default:
++ clk = 0;
++ break;
++ }
++
++ return clk;
++}
++
++unsigned long ltq_get_bus_clock(void)
++{
++ u32 fpi_sel;
++ unsigned long clk;
++
++ fpi_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_FPI_MASK,
++ LTQ_CGU_SYS_FPI_SHIFT);
++
++ if (fpi_sel)
++ /* Half the DDR clock */
++ clk = ltq_get_io_region_clock() >> 1;
++ else
++ /* Same as DDR clock */
++ clk = ltq_get_io_region_clock();
++
++ return clk;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/cgu_init.S
+@@ -0,0 +1,143 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* RCU module register */
++#define LTQ_RCU_RST_REQ 0x0010
++#define LTQ_RCU_RST_STAT 0x0014
++#define LTQ_RCU_RST_REQ_VALUE 0x40000008
++#define LTQ_RCU_RST_STAT_XTAL_F 0x20000
++
++/* CGU module register */
++#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
++#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
++#define LTQ_CGU_PLL2_CFG 0x000C /* PLL2 config */
++#define LTQ_CGU_SYS 0x0010 /* System clock */
++
++/* Valid SYS.CPU0/1 values */
++#define LTQ_CGU_SYS_CPU0_SHIFT 2
++#define LTQ_CGU_SYS_CPU1_SHIFT 4
++#define LTQ_CGU_SYS_CPU_PLL0 0x0
++#define LTQ_CGU_SYS_CPU_DDR_EQUAL 0x1
++#define LTQ_CGU_SYS_CPU_DDR_TWICE 0x2
++
++/* Valid SYS.DDR values */
++#define LTQ_CGU_SYS_DDR_SHIFT 0
++#define LTQ_CGU_SYS_DDR_167_MHZ 0x0
++#define LTQ_CGU_SYS_DDR_133_MHZ 0x1
++#define LTQ_CGU_SYS_DDR_111_MHZ 0x2
++#define LTQ_CGU_SYS_DDR_83_MHZ 0x3
++
++/* Valid SYS.FPI values */
++#define LTQ_CGU_SYS_FPI_SHIFT 6
++#define LTQ_CGU_SYS_FPI_DDR_EQUAL 0x0
++#define LTQ_CGU_SYS_FPI_DDR_HALF 0x1
++
++/* Valid SYS.PPE values */
++#define LTQ_CGU_SYS_PPE_SHIFT 7
++#define LTQ_CGU_SYS_PPE_266_MHZ 0x0
++#define LTQ_CGU_SYS_PPE_240_MHZ 0x1
++#define LTQ_CGU_SYS_PPE_222_MHZ 0x2
++#define LTQ_CGU_SYS_PPE_133_MHZ 0x3
++
++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167)
++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_TWICE
++#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_167_MHZ
++#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
++#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_266_MHZ
++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111)
++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_EQUAL
++#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_111_MHZ
++#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
++#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_133_MHZ
++#else
++#error "Invalid system clock configuration!"
++#endif
++
++/* Build register values */
++#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_PPE_CONFIG << \
++ LTQ_CGU_SYS_PPE_SHIFT) | \
++ (LTQ_CGU_SYS_FPI_CONFIG << \
++ LTQ_CGU_SYS_FPI_SHIFT) | \
++ (LTQ_CGU_SYS_CPU_CONFIG << \
++ LTQ_CGU_SYS_CPU1_SHIFT) | \
++ (LTQ_CGU_SYS_CPU_CONFIG << \
++ LTQ_CGU_SYS_CPU0_SHIFT) | \
++ LTQ_CGU_SYS_DDR_CONFIG)
++
++/* Reset values for PLL registers for usage with 35.328 MHz crystal */
++#define PLL0_35MHZ_CONFIG 0x9D861059
++#define PLL1_35MHZ_CONFIG 0x1A260CD9
++#define PLL2_35MHZ_CONFIG 0x8000f1e5
++
++/* Reset values for PLL registers for usage with 36 MHz crystal */
++#define PLL0_36MHZ_CONFIG 0x1000125D
++#define PLL1_36MHZ_CONFIG 0x1B1E0C99
++#define PLL2_36MHZ_CONFIG 0x8002f2a1
++
++LEAF(ltq_cgu_init)
++ /* Load current CGU register value */
++ li t0, (LTQ_CGU_BASE | KSEG1)
++ lw t1, LTQ_CGU_SYS(t0)
++
++ /* Load target CGU register values */
++ li t3, LTQ_CGU_SYS_VALUE
++
++ /* Only update registers if values differ */
++ beq t1, t3, finished
++
++ /*
++ * Check whether the XTAL_F bit in RST_STAT register is set or not.
++ * This bit is latched in via pin strapping. If bit is set then
++ * clock source is a 36 MHz crystal. Otherwise a 35.328 MHz crystal.
++ */
++ li t1, (LTQ_RCU_BASE | KSEG1)
++ lw t2, LTQ_RCU_RST_STAT(t1)
++ and t2, t2, LTQ_RCU_RST_STAT_XTAL_F
++ beq t2, LTQ_RCU_RST_STAT_XTAL_F, boot_36mhz
++
++boot_35mhz:
++ /* Configure PLL for 35.328 MHz */
++ li t2, PLL0_35MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL0_CFG(t0)
++ li t2, PLL1_35MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL1_CFG(t0)
++ li t2, PLL2_35MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL2_CFG(t0)
++
++ b do_reset
++
++boot_36mhz:
++ /* Configure PLL for 36 MHz */
++ li t2, PLL0_36MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL0_CFG(t0)
++ li t2, PLL1_36MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL1_CFG(t0)
++ li t2, PLL2_36MHZ_CONFIG
++ sw t2, LTQ_CGU_PLL2_CFG(t0)
++
++do_reset:
++ /* Store new clock config */
++ sw t3, LTQ_CGU_SYS(t0)
++
++ /* Perform software reset to activate new clock config */
++ li t2, LTQ_RCU_RST_REQ_VALUE
++ sw t2, LTQ_RCU_RST_REQ(t1)
++
++wait_reset:
++ b wait_reset
++
++finished:
++ jr ra
++
++ END(ltq_cgu_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/chipid.c
+@@ -0,0 +1,60 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_CHIPID_VERSION_SHIFT 28
++#define LTQ_CHIPID_VERSION_MASK (0xF << LTQ_CHIPID_VERSION_SHIFT)
++#define LTQ_CHIPID_PNUM_SHIFT 12
++#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
++
++struct ltq_chipid_regs {
++ u32 manid; /* Manufacturer identification */
++ u32 chipid; /* Chip identification */
++};
++
++static struct ltq_chipid_regs *ltq_chipid_regs =
++ (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
++
++unsigned int ltq_chip_version_get(void)
++{
++ u32 chipid;
++
++ chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++ return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
++}
++
++unsigned int ltq_chip_partnum_get(void)
++{
++ u32 chipid;
++
++ chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++ return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
++}
++
++const char *ltq_chip_partnum_str(void)
++{
++ enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
++
++ switch (partnum) {
++ case LTQ_SOC_DANUBE:
++ return "Danube";
++ case LTQ_SOC_DANUBE_S:
++ return "Danube-S";
++ case LTQ_SOC_TWINPASS:
++ return "Twinpass";
++ default:
++ printf("Unknown partnum: %x\n", partnum);
++ }
++
++ return "";
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/config.mk
+@@ -0,0 +1,27 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,)
++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE)
++
++ifdef CONFIG_SPL_BUILD
++PF_ABICALLS := -mno-abicalls
++PF_PIC := -fno-pic
++USE_PRIVATE_LIBGCC := yes
++endif
++
++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
++
++ifndef CONFIG_SPL_BUILD
++ifdef CONFIG_SYS_BOOT_NORSPL
++ALL-y += $(obj)u-boot.ltq.norspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
++endif
++endif
++
++LDSCRIPT := $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot.lds
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/ebu.c
+@@ -0,0 +1,51 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_EBU_CON_0_RST_VAL 0x8001F7FF
++
++#define LTQ_EBU_CON_WRDIS (1 << 31)
++
++struct ltq_ebu_regs {
++ u32 clc;
++ u32 rsvd0[3];
++ u32 con;
++ u32 rsvd1[3];
++ u32 addr_sel_0;
++ u32 addr_sel_1;
++ u32 rsvd2[14];
++ u32 con_0;
++ u32 con_1;
++};
++
++static struct ltq_ebu_regs *ltq_ebu_regs =
++ (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
++
++void ltq_ebu_init(void)
++{
++ /*
++ * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
++ * region control. This supports up to 32 MiB NOR flash in
++ * bank 0.
++ */
++ ltq_writel(&ltq_ebu_regs->addr_sel_0, 0x10000011);
++
++ /*
++ * Restore reset value to fix modifications by internal BootROM.
++ * Also disable write protection.
++ */
++ ltq_writel(&ltq_ebu_regs->con_0,
++ LTQ_EBU_CON_0_RST_VAL & ~LTQ_EBU_CON_WRDIS);
++}
++
++void *flash_swap_addr(unsigned long addr)
++{
++ return (void *)(addr ^ 2);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/mem.c
+@@ -0,0 +1,31 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
++
++static inline u32 ltq_mc_dc_read(u32 index)
++{
++ return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
++}
++
++phys_size_t initdram(int board_type)
++{
++ u32 col, row, dc04, dc19, dc20;
++
++ dc04 = ltq_mc_dc_read(4);
++ dc19 = ltq_mc_dc_read(19);
++ dc20 = ltq_mc_dc_read(20);
++
++ row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
++ col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
++
++ return (1 << (row + col)) * 4 * 2;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/mem_init.S
+@@ -0,0 +1,115 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* Must be configured in BOARDDIR */
++#include <ddr_settings.h>
++
++#define LTQ_MC_GEN_ERRCAUSE 0x0010
++#define LTQ_MC_GEN_ERRADDR 0x0020
++#define LTQ_MC_GEN_CON 0x0060
++#define LTQ_MC_GEN_STAT 0x0070
++#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE 0x5
++#define LTQ_MC_GEN_STAT_DLCK_PWRON 0xC
++
++#define LTQ_MC_DDR_DC03_MC_START 0x100
++
++ /* Store given value in MC DDR CCRx register */
++ .macro dc_sw num, val
++ li t2, \val
++ sw t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
++ .endm
++
++LEAF(ltq_mem_init)
++ /* Load MC General and MC DDR module base */
++ li t0, (LTQ_MC_GEN_BASE | KSEG1)
++ li t1, (LTQ_MC_DDR_BASE | KSEG1)
++
++ /* Clear access error log registers */
++ sw zero, LTQ_MC_GEN_ERRCAUSE(t0)
++ sw zero, LTQ_MC_GEN_ERRADDR(t0)
++
++ /* Enable DDR and SRAM module in memory controller */
++ li t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE
++ sw t2, LTQ_MC_GEN_CON(t0)
++
++ /* Clear start bit of DDR memory controller */
++ sw zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
++
++ /* Init memory controller registers with values ddr_settings.h */
++ dc_sw 0, MC_DC00_VALUE
++ dc_sw 1, MC_DC01_VALUE
++ dc_sw 2, MC_DC02_VALUE
++ dc_sw 4, MC_DC04_VALUE
++ dc_sw 5, MC_DC05_VALUE
++ dc_sw 6, MC_DC06_VALUE
++ dc_sw 7, MC_DC07_VALUE
++ dc_sw 8, MC_DC08_VALUE
++ dc_sw 9, MC_DC09_VALUE
++
++ dc_sw 10, MC_DC10_VALUE
++ dc_sw 11, MC_DC11_VALUE
++ dc_sw 12, MC_DC12_VALUE
++ dc_sw 13, MC_DC13_VALUE
++ dc_sw 14, MC_DC14_VALUE
++ dc_sw 15, MC_DC15_VALUE
++ dc_sw 16, MC_DC16_VALUE
++ dc_sw 17, MC_DC17_VALUE
++ dc_sw 18, MC_DC18_VALUE
++ dc_sw 19, MC_DC19_VALUE
++
++ dc_sw 20, MC_DC20_VALUE
++ dc_sw 21, MC_DC21_VALUE
++ dc_sw 22, MC_DC22_VALUE
++ dc_sw 23, MC_DC23_VALUE
++ dc_sw 24, MC_DC24_VALUE
++ dc_sw 25, MC_DC25_VALUE
++ dc_sw 26, MC_DC26_VALUE
++ dc_sw 27, MC_DC27_VALUE
++ dc_sw 28, MC_DC28_VALUE
++ dc_sw 29, MC_DC29_VALUE
++
++ dc_sw 30, MC_DC30_VALUE
++ dc_sw 31, MC_DC31_VALUE
++ dc_sw 32, MC_DC32_VALUE
++ dc_sw 33, MC_DC33_VALUE
++ dc_sw 34, MC_DC34_VALUE
++ dc_sw 35, MC_DC35_VALUE
++ dc_sw 36, MC_DC36_VALUE
++ dc_sw 37, MC_DC37_VALUE
++ dc_sw 38, MC_DC38_VALUE
++ dc_sw 39, MC_DC39_VALUE
++
++ dc_sw 40, MC_DC40_VALUE
++ dc_sw 41, MC_DC41_VALUE
++ dc_sw 42, MC_DC42_VALUE
++ dc_sw 43, MC_DC43_VALUE
++ dc_sw 44, MC_DC44_VALUE
++ dc_sw 45, MC_DC45_VALUE
++ dc_sw 46, MC_DC46_VALUE
++
++ /* Set start bit of DDR memory controller */
++ li t2, LTQ_MC_DDR_DC03_MC_START
++ sw t2, LTQ_MC_DDR_DC_OFFSET(3)(t1)
++
++ /* Wait until DLL has locked and core is ready for data transfers */
++wait_ready:
++ lw t2, LTQ_MC_GEN_STAT(t0)
++ li t3, LTQ_MC_GEN_STAT_DLCK_PWRON
++ and t2, t3
++ bne t2, t3, wait_ready
++
++finished:
++ jr ra
++
++ END(ltq_mem_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/pmu.c
+@@ -0,0 +1,118 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PMU_PWDCR_RESERVED 0xFD0C001C
++
++#define LTQ_PMU_PWDCR_TDM (1 << 25)
++#define LTQ_PMU_PWDCR_PPE_ENET0 (1 << 23)
++#define LTQ_PMU_PWDCR_PPE_ENET1 (1 << 22)
++#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
++#define LTQ_PMU_PWDCR_DEU (1 << 20)
++#define LTQ_PMU_PWDCR_UART1 (1 << 17)
++#define LTQ_PMU_PWDCR_SDIO (1 << 16)
++#define LTQ_PMU_PWDCR_AHB (1 << 15)
++#define LTQ_PMU_PWDCR_FPI0 (1 << 14)
++#define LTQ_PMU_PWDCR_PPE (1 << 13)
++#define LTQ_PMU_PWDCR_GPTC (1 << 12)
++#define LTQ_PMU_PWDCR_LEDC (1 << 11)
++#define LTQ_PMU_PWDCR_EBU (1 << 10)
++#define LTQ_PMU_PWDCR_DSL (1 << 9)
++#define LTQ_PMU_PWDCR_SPI (1 << 8)
++#define LTQ_PMU_PWDCR_UART0 (1 << 7)
++#define LTQ_PMU_PWDCR_USB (1 << 6)
++#define LTQ_PMU_PWDCR_DMA (1 << 5)
++#define LTQ_PMU_PWDCR_FPI1 (1 << 1)
++#define LTQ_PMU_PWDCR_USB_PHY (1 << 0)
++
++struct ltq_pmu_regs {
++ u32 rsvd0[7];
++ u32 pwdcr;
++ u32 sr;
++ u32 pwdcr1;
++ u32 sr1;
++};
++
++static struct ltq_pmu_regs *ltq_pmu_regs =
++ (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
++
++u32 ltq_pm_map(enum ltq_pm_modules module)
++{
++ u32 val;
++
++ switch (module) {
++ case LTQ_PM_CORE:
++ val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 |
++ LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
++ break;
++ case LTQ_PM_DMA:
++ val = LTQ_PMU_PWDCR_DMA;
++ break;
++ case LTQ_PM_ETH:
++ val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC |
++ LTQ_PMU_PWDCR_PPE;
++ break;
++ case LTQ_PM_SPI:
++ val = LTQ_PMU_PWDCR_SPI;
++ break;
++ default:
++ val = 0;
++ break;
++ }
++
++ return val;
++}
++
++int ltq_pm_enable(enum ltq_pm_modules module)
++{
++ const unsigned long timeout = 1000;
++ unsigned long timebase;
++ u32 sr, val;
++
++ val = ltq_pm_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
++
++ timebase = get_timer(0);
++
++ do {
++ sr = ltq_readl(&ltq_pmu_regs->sr);
++ if (~sr & val)
++ return 0;
++ } while (get_timer(timebase) < timeout);
++
++ return 1;
++}
++
++int ltq_pm_disable(enum ltq_pm_modules module)
++{
++ u32 val;
++
++ val = ltq_pm_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_setbits(&ltq_pmu_regs->pwdcr, val);
++
++ return 0;
++}
++
++void ltq_pmu_init(void)
++{
++ u32 set, clr;
++
++ clr = ltq_pm_map(LTQ_PM_CORE);
++ set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
++
++ ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/rcu.c
+@@ -0,0 +1,126 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
++#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
++#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
++#define LTQ_RCU_RD_DFE_AFE (1 << 12) /* Voice DFE/AFE */
++#define LTQ_RCU_RD_DSL_AFE (1 << 11) /* DSL AFE */
++#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
++#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
++#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
++#define LTQ_RCU_RD_ARC_DFE (1 << 7) /* ARC/DFE core */
++#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
++#define LTQ_RCU_RD_ENET_MAC1 (1 << 5) /* Ethernet MAC1 */
++#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
++#define LTQ_RCU_RD_CPU1 (1 << 3) /* CPU1 subsystem */
++#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
++#define LTQ_RCU_RD_CPU0 (1 << 1) /* CPU0 subsystem */
++#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
++
++#define LTQ_RCU_STAT_BOOT_SHIFT 18
++#define LTQ_RCU_STAT_BOOT_MASK (0x7 << LTQ_RCU_STAT_BOOT_SHIFT)
++
++struct ltq_rcu_regs {
++ u32 rsvd0[4];
++ u32 req; /* Reset request */
++ u32 stat; /* Reset status */
++ u32 usb_cfg; /* USB configure */
++ u32 rsvd1[2];
++ u32 pci_rdy; /* PCI boot ready */
++};
++
++static struct ltq_rcu_regs *ltq_rcu_regs =
++ (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
++
++u32 ltq_reset_map(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ switch (module) {
++ case LTQ_RESET_CORE:
++ case LTQ_RESET_SOFT:
++ val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1;
++ break;
++ case LTQ_RESET_DMA:
++ val = LTQ_RCU_RD_DMA;
++ break;
++ case LTQ_RESET_ETH:
++ val = LTQ_RCU_RD_PPE;
++ break;
++ case LTQ_RESET_HARD:
++ val = LTQ_RCU_RD_HRST;
++ break;
++ default:
++ val = 0;
++ break;
++ }
++
++ return val;
++}
++
++int ltq_reset_activate(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ val = ltq_reset_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_setbits(&ltq_rcu_regs->req, val);
++
++ return 0;
++}
++
++int ltq_reset_deactivate(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ val = ltq_reset_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_clrbits(&ltq_rcu_regs->req, val);
++
++ return 0;
++}
++
++enum ltq_boot_select ltq_boot_select(void)
++{
++ u32 stat;
++ unsigned int bootstrap;
++
++ stat = ltq_readl(&ltq_rcu_regs->stat);
++ bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
++
++ switch (bootstrap) {
++ case 0:
++ return BOOT_NOR_NO_BOOTROM;
++ case 1:
++ return BOOT_NOR;
++ case 2:
++ return BOOT_MII0;
++ case 3:
++ return BOOT_PCI;
++ case 4:
++ return BOOT_UART;
++ case 5:
++ return BOOT_SPI;
++ case 6:
++ return BOOT_NAND;
++ case 7:
++ return BOOT_RMII0;
++ default:
++ return BOOT_UNKNOWN;
++ }
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/u-boot.lds
+@@ -0,0 +1,69 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
++OUTPUT_ARCH(mips)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++
++ . = ALIGN(4);
++ .text : {
++ *(.text*)
++ }
++
++ . = ALIGN(4);
++ .rodata : {
++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
++ }
++
++ . = ALIGN(4);
++ .data : {
++ *(.data*)
++ }
++
++ . = ALIGN(4);
++ .sdata : {
++ *(.sdata*)
++ }
++
++ . = .;
++ _gp = ALIGN(16) + 0x7ff0;
++
++ .got : {
++ __got_start = .;
++ *(.got)
++ __got_end = .;
++ }
++
++ num_got_entries = (__got_end - __got_start) >> 2;
++
++#ifndef CONFIG_SPL_BUILD
++ . = ALIGN(4);
++ .u_boot_list : {
++ #include <u-boot.lst>
++ }
++#endif
++
++ . = ALIGN(4);
++ __image_copy_end = .;
++ uboot_end_data = .;
++
++ .bss (NOLOAD) : {
++ __bss_start = .;
++ *(.bss*)
++ *(.sbss*)
++ . = ALIGN(4);
++ __bss_end = .;
++ }
++
++ . = ALIGN(4);
++ __end = .;
++ uboot_end = .;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/Makefile
+@@ -0,0 +1,36 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)liblantiq-common.o
++
++START = start.o
++COBJS-y = cpu.o pmu.o
++COBJS-$(CONFIG_SPL_BUILD) += spl.o
++SOBJS-y = lowlevel_init.o
++
++COBJS := $(COBJS-y)
++SOBJS := $(SOBJS-y)
++SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
++START := $(addprefix $(obj),$(START))
++
++all: $(LIB)
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
+@@ -0,0 +1,60 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++
++static const char ltq_bootsel_strings[][16] = {
++ "NOR",
++ "NOR w/o BootROM",
++ "UART",
++ "UART w/o EEPROM",
++ "SPI",
++ "NAND",
++ "PCI",
++ "MII0",
++ "RMII0",
++ "RGMII1",
++ "unknown",
++};
++
++const char *ltq_boot_select_str(void)
++{ enum ltq_boot_select bootsel = ltq_boot_select();
++
++ if (bootsel > BOOT_UNKNOWN)
++ bootsel = BOOT_UNKNOWN;
++
++ return ltq_bootsel_strings[bootsel];
++}
++
++void ltq_chip_print_info(void)
++{
++ char buf[32];
++
++ printf("SoC: Lantiq %s v1.%u\n", ltq_chip_partnum_str(),
++ ltq_chip_version_get());
++ printf("CPU: %s MHz\n", strmhz(buf, ltq_get_cpu_clock()));
++ printf("IO: %s MHz\n", strmhz(buf, ltq_get_io_region_clock()));
++ printf("BUS: %s MHz\n", strmhz(buf, ltq_get_bus_clock()));
++ printf("BOOT: %s\n", ltq_boot_select_str());
++}
++
++int arch_cpu_init(void)
++{
++ ltq_pmu_init();
++ ltq_ebu_init();
++
++ return 0;
++}
++
++void _machine_restart(void)
++{
++ ltq_reset_activate(LTQ_RESET_CORE);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
+@@ -0,0 +1,21 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <asm/asm.h>
++#include <asm/regdef.h>
++
++NESTED(lowlevel_init, 0, ra)
++ move t8, ra
++
++ la t7, ltq_cgu_init
++ jalr t7
++
++ la t7, ltq_mem_init
++ jalr t7
++
++ jr t8
++ END(lowlevel_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c
+@@ -0,0 +1,10 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/pm.h>
++
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/spl.c
+@@ -0,0 +1,385 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <image.h>
++#include <version.h>
++#include <spi_flash.h>
++#include <linux/compiler.h>
++#include <lzma/LzmaDec.h>
++#include <linux/lzo.h>
++#include <asm/mipsregs.h>
++
++#if defined(CONFIG_LTQ_SPL_CONSOLE)
++#define spl_has_console 1
++
++#if defined(CONFIG_LTQ_SPL_DEBUG)
++#define spl_has_debug 1
++#else
++#define spl_has_debug 0
++#endif
++
++#else
++#define spl_has_console 0
++#endif
++
++#define spl_debug(fmt, args...) \
++ do { \
++ if (spl_has_debug) \
++ printf(fmt, ##args); \
++ } while (0)
++
++#define spl_puts(msg) \
++ do { \
++ if (spl_has_console) \
++ puts(msg); \
++ } while (0)
++
++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
++#define spl_boot_spi_flash 1
++#else
++#define spl_boot_spi_flash 0
++#ifndef CONFIG_SPL_SPI_BUS
++#define CONFIG_SPL_SPI_BUS 0
++#endif
++#ifndef CONFIG_SPL_SPI_CS
++#define CONFIG_SPL_SPI_CS 0
++#endif
++#ifndef CONFIG_SPL_SPI_MAX_HZ
++#define CONFIG_SPL_SPI_MAX_HZ 0
++#endif
++#ifndef CONFIG_SPL_SPI_MODE
++#define CONFIG_SPL_SPI_MODE 0
++#endif
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
++#define spl_boot_nor_flash 1
++#else
++#define spl_boot_nor_flash 0
++#endif
++
++#define spl_sync() __asm__ __volatile__("sync");
++
++struct spl_image {
++ ulong data_addr;
++ ulong entry_addr;
++ size_t data_size;
++ size_t entry_size;
++ u8 comp;
++};
++
++extern ulong __image_copy_end;
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/* Emulated malloc area needed for LZMA allocator in BSS */
++static u8 *spl_mem_ptr __maybe_unused;
++static size_t spl_mem_size __maybe_unused;
++
++static int spl_is_comp_lzma(const struct spl_image *spl)
++{
++#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
++ return spl->comp == IH_COMP_LZMA;
++#else
++ return 0;
++#endif
++}
++
++static int spl_is_comp_lzo(const struct spl_image *spl)
++{
++#if defined(CONFIG_LTQ_SPL_COMP_LZO)
++ return spl->comp == IH_COMP_LZO;
++#else
++ return 0;
++#endif
++}
++
++static int spl_is_compressed(const struct spl_image *spl)
++{
++ if (spl_is_comp_lzma(spl))
++ return 1;
++
++ if (spl_is_comp_lzo(spl))
++ return 1;
++
++ return 0;
++}
++
++static void spl_console_init(void)
++{
++ if (!spl_has_console)
++ return;
++
++ gd->flags |= GD_FLG_RELOC;
++ gd->baudrate = CONFIG_BAUDRATE;
++
++ serial_init();
++
++ gd->have_console = 1;
++
++ spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
++ U_BOOT_TIME ")\n");
++}
++
++static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl)
++{
++ u32 magic;
++
++ spl_puts("SPL: checking U-Boot image\n");
++
++ magic = image_get_magic(hdr);
++ if (magic != IH_MAGIC)
++ return -1;
++
++ spl->data_addr += image_get_header_size();
++ spl->entry_addr = image_get_load(hdr);
++ spl->data_size = image_get_data_size(hdr);
++ spl->comp = image_get_comp(hdr);
++
++ spl_debug("SPL: data %08lx, size %zu, entry %08lx, comp %u\n",
++ spl->data_addr, spl->data_size, spl->entry_addr, spl->comp);
++
++ return 0;
++}
++
++static void *spl_lzma_alloc(void *p, size_t size)
++{
++ u8 *ret;
++
++ if (size > spl_mem_size)
++ return NULL;
++
++ ret = spl_mem_ptr;
++ spl_mem_ptr += size;
++ spl_mem_size -= size;
++
++ return ret;
++}
++
++static void spl_lzma_free(void *p, void *addr)
++{
++}
++
++static int spl_copy_image(struct spl_image *spl)
++{
++ spl_puts("SPL: copying U-Boot to RAM\n");
++
++ memcpy((void *) spl->entry_addr, (const void *) spl->data_addr,
++ spl->data_size);
++
++ spl->entry_size = spl->data_size;
++
++ return 0;
++}
++
++static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr)
++{
++ SRes res;
++ const Byte *prop = (const Byte *) loadaddr;
++ const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE +
++ sizeof(uint64_t);
++ Byte *dest = (Byte *) spl->entry_addr;
++ SizeT dest_len = 0xFFFFFFFF;
++ SizeT src_len = spl->data_size - LZMA_PROPS_SIZE;
++ ELzmaStatus status = 0;
++ ISzAlloc alloc;
++
++ spl_puts("SPL: decompressing U-Boot with LZMA\n");
++
++ alloc.Alloc = spl_lzma_alloc;
++ alloc.Free = spl_lzma_free;
++ spl_mem_ptr = (u8 *) CONFIG_SPL_MALLOC_BASE;
++ spl_mem_size = CONFIG_SPL_MALLOC_MAX_SIZE;
++
++ res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE,
++ LZMA_FINISH_ANY, &status, &alloc);
++ if (res != SZ_OK)
++ return 1;
++
++ spl->entry_size = dest_len;
++
++ return 0;
++}
++
++static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr)
++{
++ size_t len;
++ int ret;
++
++ spl_puts("SPL: decompressing U-Boot with LZO\n");
++
++ ret = lzop_decompress(
++ (const unsigned char*) loadaddr, spl->data_size,
++ (unsigned char *) spl->entry_addr, &len);
++
++ spl->entry_size = len;
++
++ return ret;
++}
++
++static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr)
++{
++ int ret;
++
++ if (spl_is_comp_lzma(spl))
++ ret = spl_uncompress_lzma(spl, loadaddr);
++ else if (spl_is_comp_lzo(spl))
++ ret = spl_uncompress_lzo(spl, loadaddr);
++ else
++ ret = 1;
++
++ return ret;
++}
++
++static int spl_load_spi_flash(struct spl_image *spl)
++{
++ struct spi_flash sf;
++ image_header_t hdr;
++ int ret;
++ unsigned long loadaddr;
++
++ /*
++ * Image format:
++ *
++ * - 12 byte non-volatile bootstrap header
++ * - SPL binary
++ * - 12 byte non-volatile bootstrap header
++ * - 64 byte U-Boot mkimage header
++ * - U-Boot binary
++ */
++ spl->data_addr = (ulong) &__image_copy_end - CONFIG_SPL_TEXT_BASE + 24;
++
++ spl_puts("SPL: probing SPI flash\n");
++
++ spi_init();
++ ret = spi_flash_probe_spl(&sf, CONFIG_SPL_SPI_BUS, CONFIG_SPL_SPI_CS,
++ CONFIG_SPL_SPI_MAX_HZ, CONFIG_SPL_SPI_MODE);
++ if (ret)
++ return ret;
++
++ spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr);
++
++ ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr);
++ if (ret)
++ return ret;
++
++ spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr);
++
++ ret = spl_parse_image(&hdr, spl);
++ if (ret)
++ return ret;
++
++ if (spl_is_compressed(spl))
++ loadaddr = CONFIG_LOADADDR;
++ else
++ loadaddr = spl->entry_addr;
++
++ spl_puts("SPL: loading U-Boot to RAM\n");
++
++ ret = spi_flash_read(&sf, spl->data_addr, spl->data_size,
++ (void *) loadaddr);
++
++ if (spl_is_compressed(spl))
++ ret = spl_uncompress(spl, loadaddr);
++
++ return ret;
++}
++
++static int spl_load_nor_flash(struct spl_image *spl)
++{
++ const image_header_t *hdr;
++ int ret;
++
++ /*
++ * Image format:
++ *
++ * - SPL binary
++ * - 64 byte U-Boot mkimage header
++ * - U-Boot binary
++ */
++ spl->data_addr = (ulong) &__image_copy_end;
++ hdr = (const image_header_t *) &__image_copy_end;
++
++ spl_debug("SPL: checking image header at address %p\n", hdr);
++
++ ret = spl_parse_image(hdr, spl);
++ if (ret)
++ return ret;
++
++ if (spl_is_compressed(spl))
++ ret = spl_uncompress(spl, spl->data_addr);
++ else
++ ret = spl_copy_image(spl);
++
++ return ret;
++}
++
++static int spl_load(struct spl_image *spl)
++{
++ int ret;
++
++ if (spl_boot_spi_flash)
++ ret = spl_load_spi_flash(spl);
++ else if (spl_boot_nor_flash)
++ ret = spl_load_nor_flash(spl);
++ else
++ ret = 1;
++
++ return ret;
++}
++
++void __noreturn spl_lantiq_init(void)
++{
++ void (*uboot)(void) __noreturn;
++ struct spl_image spl;
++ gd_t gd_data;
++ int ret;
++
++ gd = &gd_data;
++ barrier();
++ memset((void *)gd, 0, sizeof(gd_t));
++
++ spl_console_init();
++
++ spl_debug("SPL: initializing\n");
++
++#if 0
++ spl_debug("CP0_CONFIG: %08x\n", read_c0_config());
++ spl_debug("CP0_CONFIG1: %08x\n", read_c0_config1());
++ spl_debug("CP0_CONFIG2: %08x\n", read_c0_config2());
++ spl_debug("CP0_CONFIG3: %08x\n", read_c0_config3());
++ spl_debug("CP0_CONFIG6: %08x\n", read_c0_config6());
++ spl_debug("CP0_CONFIG7: %08x\n", read_c0_config7());
++ spl_debug("CP0_STATUS: %08x\n", read_c0_status());
++ spl_debug("CP0_PRID: %08x\n", read_c0_prid());
++#endif
++
++ board_early_init_f();
++ timer_init();
++
++ memset(&spl, 0, sizeof(spl));
++
++ ret = spl_load(&spl);
++ if (ret)
++ goto hang;
++
++ spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr);
++ spl_puts("SPL: jumping to U-Boot\n");
++
++ flush_cache(spl.entry_addr, spl.entry_size);
++ spl_sync();
++
++ uboot = (void *) spl.entry_addr;
++ uboot();
++
++hang:
++ spl_puts("SPL: cannot start U-Boot\n");
++
++ for (;;)
++ ;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/start.S
+@@ -0,0 +1,144 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2003 Wolfgang Denk, wd@denx.de
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/regdef.h>
++#include <asm/mipsregs.h>
++
++#define S_PRIdCoID 16 /* Company ID (R) */
++#define M_PRIdCoID (0xff << S_PRIdCoID)
++#define S_PRIdImp 8 /* Implementation ID (R) */
++#define M_PRIdImp (0xff << S_PRIdImp)
++
++#define K_CacheAttrCWTnWA 0 /* Cacheable, write-thru, no write allocate */
++#define K_CacheAttrCWTWA 1 /* Cacheable, write-thru, write allocate */
++#define K_CacheAttrU 2 /* Uncached */
++#define K_CacheAttrC 3 /* Cacheable */
++#define K_CacheAttrCN 3 /* Cacheable, non-coherent */
++#define K_CacheAttrCCE 4 /* Cacheable, coherent, exclusive */
++#define K_CacheAttrCCS 5 /* Cacheable, coherent, shared */
++#define K_CacheAttrCCU 6 /* Cacheable, coherent, update */
++#define K_CacheAttrUA 7 /* Uncached accelerated */
++
++#define S_ConfigK23 28 /* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */
++#define M_ConfigK23 (0x7 << S_ConfigK23)
++#define W_ConfigK23 3
++#define S_ConfigKU 25 /* Kuseg coherency algorithm (FM MMU only) (R/W) */
++#define M_ConfigKU (0x7 << S_ConfigKU)
++#define W_ConfigKU 3
++
++#define S_ConfigMM 18 /* Merge mode (implementation specific) */
++#define M_ConfigMM (0x1 << S_ConfigMM)
++
++#define S_StatusBEV 22 /* Enable Boot Exception Vectors (R/W) */
++#define M_StatusBEV (0x1 << S_StatusBEV)
++
++#define S_StatusFR 26 /* Enable 64-bit FPRs (R/W) */
++#define M_StatusFR (0x1 << S_StatusFR)
++
++#define S_ConfigK0 0 /* Kseg0 coherency algorithm (R/W) */
++#define M_ConfigK0 (0x7 << S_ConfigK0)
++
++#define CONFIG0_MIPS32_64_MSK 0x8000ffff
++#define STATUS_MIPS32_64_MSK 0xfffcffff
++
++#define STATUS_MIPS24K 0
++#define CONFIG0_MIPS24K ((K_CacheAttrCN << S_ConfigK23) |\
++ (K_CacheAttrCN << S_ConfigKU) |\
++ (M_ConfigMM))
++
++#define STATUS_MIPS34K 0
++#define CONFIG0_MIPS34K ((K_CacheAttrCN << S_ConfigK23) |\
++ (K_CacheAttrCN << S_ConfigKU) |\
++ (M_ConfigMM))
++
++#define STATUS_MIPS32_64 (M_StatusBEV | M_StatusFR)
++#define CONFIG0_MIPS32_64 (K_CacheAttrCN << S_ConfigK0)
++
++#ifdef CONFIG_SOC_XWAY_DANUBE
++#define CONFIG0_LANTIQ (CONFIG0_MIPS24K | CONFIG0_MIPS32_64)
++#define STATUS_LANTIQ (STATUS_MIPS24K | STATUS_MIPS32_64)
++#endif
++
++#ifdef CONFIG_SOC_XWAY_VRX200
++#define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
++#define STATUS_LANTIQ (STATUS_MIPS34K | STATUS_MIPS32_64)
++#endif
++
++
++ .set noreorder
++
++ .globl _start
++ .text
++_start:
++ /* Entry point */
++ b main
++ nop
++
++ /* Lantiq SoC Boot config word */
++ .org 0x10
++#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
++ .word CONFIG_SYS_XWAY_EBU_BOOTCFG
++#else
++ .word 0
++#endif
++ .word 0
++
++ .align 4
++main:
++
++ /* Init Timer */
++ mtc0 zero, CP0_COUNT
++ mtc0 zero, CP0_COMPARE
++
++ /* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */
++ mfc0 t0, CP0_CONFIG
++ li t1, CONFIG0_MIPS32_64_MSK
++ and t0, t1
++ li t1, CONFIG0_LANTIQ
++ or t0, t1
++ mtc0 t0, CP0_CONFIG
++
++ mfc0 t0, CP0_STATUS
++ li t1, STATUS_MIPS32_64_MSK
++ and t0, t1
++ li t1, STATUS_LANTIQ
++ or t0, t1
++ mtc0 t0, CP0_STATUS
++
++ /* Initialize CGU */
++ la t9, ltq_cgu_init
++ jalr t9
++ nop
++
++ /* Initialize memory controller */
++ la t9, ltq_mem_init
++ jalr t9
++ nop
++
++ /* Initialize caches... */
++ la t9, mips_cache_reset
++ jalr t9
++ nop
++
++ /* Clear BSS */
++ la t1, __bss_start
++ la t2, __bss_end
++ sub t1, 4
++1:
++ addi t1, 4
++ bltl t1, t2, 1b
++ sw zero, 0(t1)
++
++ /* Setup stack pointer and force alignment on a 16 byte boundary */
++ li t0, (CONFIG_SPL_STACK_BASE & ~0xF)
++ la sp, 0(t0)
++
++ la t9, spl_lantiq_init
++ jr t9
++ nop
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
+@@ -0,0 +1,49 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \
++ LENGTH = CONFIG_SPL_MAX_SIZE }
++MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_BASE, \
++ LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
++
++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
++OUTPUT_ARCH(mips)
++ENTRY(_start)
++SECTIONS
++{
++ . = ALIGN(4);
++ .text : {
++ *(.text*)
++ } > .spl_mem
++
++ . = ALIGN(4);
++ .rodata : {
++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
++ } > .spl_mem
++
++ . = ALIGN(4);
++ .data : {
++ *(SORT_BY_ALIGNMENT(.data*))
++ *(SORT_BY_ALIGNMENT(.sdata*))
++ } > .spl_mem
++
++ . = ALIGN(4);
++ __image_copy_end = .;
++ uboot_end_data = .;
++
++ .bss : {
++ __bss_start = .;
++ *(.bss*)
++ *(.sbss*)
++ . = ALIGN(4);
++ __bss_end = .;
++ } > .bss_mem
++
++ . = ALIGN(4);
++ __end = .;
++ uboot_end = .;
++}
+--- a/arch/mips/cpu/mips32/start.S
++++ b/arch/mips/cpu/mips32/start.S
+@@ -55,166 +55,63 @@
+ #endif
+ .endm
+
+-#define RVECENT(f,n) \
+- b f; nop
+-#define XVECENT(f,bev) \
+- b f ; \
+- li k0,bev
+-
+- .set noreorder
+-
+- .globl _start
+- .text
+-_start:
+- RVECENT(reset,0) # U-boot entry point
+- RVECENT(reset,1) # software reboot
+-#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
+ /*
+ * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to
+ * access external NOR flashes. If the board boots from NOR flash the
+ * internal BootROM does a blind read at address 0xB0000010 to read the
+ * initial configuration for that EBU in order to access the flash
+ * device with correct parameters. This config option is board-specific.
++ * Default to 0 if this option is not set.
+ */
+- .word CONFIG_SYS_XWAY_EBU_BOOTCFG
+- .word 0x00000000
++ .macro lantiq_soc_bootcfg
++ .set push
++ .set noreorder
++ .org 0x10
++#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
++ .word CONFIG_SYS_XWAY_EBU_BOOTCFG
+ #else
+- RVECENT(romReserved,2)
++ .word 0
+ #endif
+- RVECENT(romReserved,3)
+- RVECENT(romReserved,4)
+- RVECENT(romReserved,5)
+- RVECENT(romReserved,6)
+- RVECENT(romReserved,7)
+- RVECENT(romReserved,8)
+- RVECENT(romReserved,9)
+- RVECENT(romReserved,10)
+- RVECENT(romReserved,11)
+- RVECENT(romReserved,12)
+- RVECENT(romReserved,13)
+- RVECENT(romReserved,14)
+- RVECENT(romReserved,15)
+- RVECENT(romReserved,16)
+- RVECENT(romReserved,17)
+- RVECENT(romReserved,18)
+- RVECENT(romReserved,19)
+- RVECENT(romReserved,20)
+- RVECENT(romReserved,21)
+- RVECENT(romReserved,22)
+- RVECENT(romReserved,23)
+- RVECENT(romReserved,24)
+- RVECENT(romReserved,25)
+- RVECENT(romReserved,26)
+- RVECENT(romReserved,27)
+- RVECENT(romReserved,28)
+- RVECENT(romReserved,29)
+- RVECENT(romReserved,30)
+- RVECENT(romReserved,31)
+- RVECENT(romReserved,32)
+- RVECENT(romReserved,33)
+- RVECENT(romReserved,34)
+- RVECENT(romReserved,35)
+- RVECENT(romReserved,36)
+- RVECENT(romReserved,37)
+- RVECENT(romReserved,38)
+- RVECENT(romReserved,39)
+- RVECENT(romReserved,40)
+- RVECENT(romReserved,41)
+- RVECENT(romReserved,42)
+- RVECENT(romReserved,43)
+- RVECENT(romReserved,44)
+- RVECENT(romReserved,45)
+- RVECENT(romReserved,46)
+- RVECENT(romReserved,47)
+- RVECENT(romReserved,48)
+- RVECENT(romReserved,49)
+- RVECENT(romReserved,50)
+- RVECENT(romReserved,51)
+- RVECENT(romReserved,52)
+- RVECENT(romReserved,53)
+- RVECENT(romReserved,54)
+- RVECENT(romReserved,55)
+- RVECENT(romReserved,56)
+- RVECENT(romReserved,57)
+- RVECENT(romReserved,58)
+- RVECENT(romReserved,59)
+- RVECENT(romReserved,60)
+- RVECENT(romReserved,61)
+- RVECENT(romReserved,62)
+- RVECENT(romReserved,63)
+- XVECENT(romExcHandle,0x200) # bfc00200: R4000 tlbmiss vector
+- RVECENT(romReserved,65)
+- RVECENT(romReserved,66)
+- RVECENT(romReserved,67)
+- RVECENT(romReserved,68)
+- RVECENT(romReserved,69)
+- RVECENT(romReserved,70)
+- RVECENT(romReserved,71)
+- RVECENT(romReserved,72)
+- RVECENT(romReserved,73)
+- RVECENT(romReserved,74)
+- RVECENT(romReserved,75)
+- RVECENT(romReserved,76)
+- RVECENT(romReserved,77)
+- RVECENT(romReserved,78)
+- RVECENT(romReserved,79)
+- XVECENT(romExcHandle,0x280) # bfc00280: R4000 xtlbmiss vector
+- RVECENT(romReserved,81)
+- RVECENT(romReserved,82)
+- RVECENT(romReserved,83)
+- RVECENT(romReserved,84)
+- RVECENT(romReserved,85)
+- RVECENT(romReserved,86)
+- RVECENT(romReserved,87)
+- RVECENT(romReserved,88)
+- RVECENT(romReserved,89)
+- RVECENT(romReserved,90)
+- RVECENT(romReserved,91)
+- RVECENT(romReserved,92)
+- RVECENT(romReserved,93)
+- RVECENT(romReserved,94)
+- RVECENT(romReserved,95)
+- XVECENT(romExcHandle,0x300) # bfc00300: R4000 cache vector
+- RVECENT(romReserved,97)
+- RVECENT(romReserved,98)
+- RVECENT(romReserved,99)
+- RVECENT(romReserved,100)
+- RVECENT(romReserved,101)
+- RVECENT(romReserved,102)
+- RVECENT(romReserved,103)
+- RVECENT(romReserved,104)
+- RVECENT(romReserved,105)
+- RVECENT(romReserved,106)
+- RVECENT(romReserved,107)
+- RVECENT(romReserved,108)
+- RVECENT(romReserved,109)
+- RVECENT(romReserved,110)
+- RVECENT(romReserved,111)
+- XVECENT(romExcHandle,0x380) # bfc00380: R4000 general vector
+- RVECENT(romReserved,113)
+- RVECENT(romReserved,114)
+- RVECENT(romReserved,115)
+- RVECENT(romReserved,116)
+- RVECENT(romReserved,116)
+- RVECENT(romReserved,118)
+- RVECENT(romReserved,119)
+- RVECENT(romReserved,120)
+- RVECENT(romReserved,121)
+- RVECENT(romReserved,122)
+- RVECENT(romReserved,123)
+- RVECENT(romReserved,124)
+- RVECENT(romReserved,125)
+- RVECENT(romReserved,126)
+- RVECENT(romReserved,127)
++ .word 0
++ .set pop
++ .endm
++
++ .macro reset_vector branch
++ .set push
++ .set noreorder
++ b \branch
++ nop
++ .set pop
++ .endm
++
++ .macro exception_vector offset branch
++ .set push
++ .set noreorder
++ .org \offset
++ b \branch
++ li k0, \offset
++ .set pop
++ .endm
++
++ .set noreorder
++
++ .globl _start
++ .text
++_start:
++ reset_vector reset # U-boot entry point
++ reset_vector reset # software reboot
++
++ lantiq_soc_bootcfg # Lantiq SoC Boot config word
++
++ exception_vector 0x200, halt # TLB miss
++ exception_vector 0x280, halt # XTLB miss
++ exception_vector 0x300, halt # Cache error
++ exception_vector 0x380, halt # General
++ exception_vector 0x400, halt # Interrupt, CauseIV
++ exception_vector 0x480, ejtag_exception # EJTAG debug
+
+- /*
+- * We hope there are no more reserved vectors!
+- * 128 * 8 == 1024 == 0x400
+- * so this is address R_VEC+0x400 == 0xbfc00400
+- */
+ .align 4
+ reset:
+-
+ /* Clear watch registers */
+ mtc0 zero, CP0_WATCHLO
+ mtc0 zero, CP0_WATCHHI
+@@ -222,13 +119,15 @@ reset:
+ /* WP(Watch Pending), SW0/1 should be cleared */
+ mtc0 zero, CP0_CAUSE
+
++#if 0
+ setup_c0_status_reset
++#endif
+
+ /* Init Timer */
+ mtc0 zero, CP0_COUNT
+ mtc0 zero, CP0_COMPARE
+
+-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
++#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_SYS_DISABLE_CACHE)
+ /* CONFIG0 register */
+ li t0, CONF_CM_UNCACHED
+ mtc0 t0, CP0_CONFIG
+@@ -323,6 +222,8 @@ relocate_code:
+ jalr t9
+ nop
+
++ sync
++
+ /* Jump to where we've relocated ourselves */
+ addi t0, s2, in_ram - _start
+ jr t0
+@@ -378,8 +279,12 @@ in_ram:
+ .end relocate_code
+
+ /* Exception handlers */
+-romReserved:
+- b romReserved
++ejtag_exception:
++ /* Set DEPC to halt and exit debug mode */
++ la k1, halt
++ mtc0 k1, CP0_DEPC
++ deret
++ nop
+
+-romExcHandle:
+- b romExcHandle
++halt:
++ b halt
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/Makefile
+@@ -0,0 +1,34 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(SOC).o
++
++COBJS-y += cgu.o chipid.o dcdc.o ebu.o gphy.o mem.o pmu.o rcu.o
++SOBJS-y += cgu_init.o mem_init.o
++SOBJS-y += gphy_fw.o
++
++COBJS := $(COBJS-y)
++SOBJS := $(SOBJS-y)
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
++
++all: $(LIB)
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/cgu.c
+@@ -0,0 +1,209 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/gphy.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_CGU_PLL1_PLLN_SHIFT 6
++#define LTQ_CGU_PLL1_PLLN_MASK (0x3F << LTQ_CGU_PLL1_PLLN_SHIFT)
++#define LTQ_CGU_PLL1_PLLM_SHIFT 2
++#define LTQ_CGU_PLL1_PLLM_MASK (0xF << LTQ_CGU_PLL1_PLLM_SHIFT)
++#define LTQ_CGU_PLL1_PLLL (1 << 1)
++#define LTQ_CGU_PLL1_PLL_EN 1
++
++#define LTQ_CGU_SYS_OCP_SHIFT 0
++#define LTQ_CGU_SYS_OCP_MASK (0x3 << LTQ_CGU_SYS_OCP_SHIFT)
++#define LTQ_CGU_SYS_CPU_SHIFT 4
++#define LTQ_CGU_SYS_CPU_MASK (0xF << LTQ_CGU_SYS_CPU_SHIFT)
++
++#define LTQ_CGU_UPDATE 1
++
++#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT 2
++#define LTQ_CGU_IFCLK_GPHY_SEL_MASK (0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT)
++
++struct ltq_cgu_regs {
++ u32 rsvd0;
++ u32 pll0_cfg; /* PLL0 config */
++ u32 pll1_cfg; /* PLL1 config */
++ u32 sys; /* System clock */
++ u32 clk_fsr; /* Clock frequency select */
++ u32 clk_gsr; /* Clock gating status */
++ u32 clk_gcr0; /* Clock gating control 0 */
++ u32 clk_gcr1; /* Clock gating control 1 */
++ u32 update; /* CGU update control */
++ u32 if_clk; /* Interface clock */
++ u32 ddr; /* DDR memory control */
++ u32 ct1_sr; /* CT status 1 */
++ u32 ct_kval; /* CT K value */
++ u32 pcm_cr; /* PCM control */
++ u32 pci_cr; /* PCI clock control */
++ u32 rsvd1;
++ u32 gphy1_cfg; /* GPHY1 config */
++ u32 gphy0_cfg; /* GPHY0 config */
++ u32 rsvd2[6];
++ u32 pll2_cfg; /* PLL2 config */
++};
++
++static struct ltq_cgu_regs *ltq_cgu_regs =
++ (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
++
++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
++{
++ return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
++}
++
++unsigned long ltq_get_io_region_clock(void)
++{
++ unsigned int ocp_sel;
++ unsigned long clk, cpu_clk;
++
++ cpu_clk = ltq_get_cpu_clock();
++
++ ocp_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_OCP_MASK,
++ LTQ_CGU_SYS_OCP_SHIFT);
++
++ switch (ocp_sel) {
++ case 0:
++ /* OCP ratio 1 */
++ clk = cpu_clk;
++ break;
++ case 2:
++ /* OCP ratio 2 */
++ clk = cpu_clk / 2;
++ break;
++ case 3:
++ /* OCP ratio 2.5 */
++ clk = (cpu_clk * 2) / 5;
++ break;
++ case 4:
++ /* OCP ratio 3 */
++ clk = cpu_clk / 3;
++ break;
++ default:
++ clk = 0;
++ break;
++ }
++
++ return clk;
++}
++
++unsigned long ltq_get_cpu_clock(void)
++{
++ unsigned int cpu_sel;
++ unsigned long clk;
++
++ cpu_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU_MASK,
++ LTQ_CGU_SYS_CPU_SHIFT);
++
++ switch (cpu_sel) {
++ case 0:
++ clk = CLOCK_600_MHZ;
++ break;
++ case 1:
++ clk = CLOCK_500_MHZ;
++ break;
++ case 2:
++ clk = CLOCK_393_MHZ;
++ break;
++ case 3:
++ clk = CLOCK_333_MHZ;
++ break;
++ case 5:
++ case 6:
++ clk = CLOCK_197_MHZ;
++ break;
++ case 7:
++ clk = CLOCK_166_MHZ;
++ break;
++ case 4:
++ case 8:
++ case 9:
++ clk = CLOCK_125_MHZ;
++ break;
++ default:
++ clk = 0;
++ break;
++ }
++
++ return clk;
++}
++
++unsigned long ltq_get_bus_clock(void)
++{
++ return ltq_get_io_region_clock();
++}
++
++void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk)
++{
++ ltq_clrbits(&ltq_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK);
++ ltq_setbits(&ltq_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT);
++}
++
++static inline int ltq_cgu_pll1_locked(void)
++{
++ u32 pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
++
++ return pll1_cfg & LTQ_CGU_PLL1_PLLL;
++}
++
++static inline void ltq_cgu_pll1_restart(unsigned m, unsigned n)
++{
++ u32 pll1_cfg;
++
++ ltq_clrbits(&ltq_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN);
++ ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
++
++ pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
++ pll1_cfg &= ~(LTQ_CGU_PLL1_PLLN_MASK | LTQ_CGU_PLL1_PLLM_MASK);
++ pll1_cfg |= n << LTQ_CGU_PLL1_PLLN_SHIFT;
++ pll1_cfg |= m << LTQ_CGU_PLL1_PLLM_SHIFT;
++ pll1_cfg |= LTQ_CGU_PLL1_PLL_EN;
++ ltq_writel(&ltq_cgu_regs->pll1_cfg, pll1_cfg);
++ ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
++
++ __udelay(1000);
++}
++
++/*
++ * From chapter 9 in errata sheet:
++ *
++ * Under certain condition, the PLL1 may failed to enter into lock
++ * status by hardware default N, M setting.
++ *
++ * Since system always starts from PLL0, the system software can run
++ * and re-program the PLL1 settings.
++ */
++static void ltq_cgu_pll1_init(void)
++{
++ unsigned i;
++ const unsigned pll1_m[] = { 1, 2, 3, 4 };
++ const unsigned pll1_n[] = { 21, 32, 43, 54 };
++
++ /* Check if PLL1 has locked with hardware default settings */
++ if (ltq_cgu_pll1_locked())
++ return;
++
++ for (i = 0; i < 4; i++) {
++ ltq_cgu_pll1_restart(pll1_m[i], pll1_n[i]);
++
++ if (ltq_cgu_pll1_locked())
++ goto done;
++ }
++
++done:
++ /* Restart with hardware default values M=5, N=64 */
++ ltq_cgu_pll1_restart(5, 64);
++}
++
++void ltq_pll_init(void)
++{
++ ltq_cgu_pll1_init();
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/cgu_init.S
+@@ -0,0 +1,120 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* RCU module register */
++#define LTQ_RCU_RST_REQ 0x0010 /* Reset request */
++#define LTQ_RCU_RST_REQ_VALUE ((1 << 14) | (1 << 1))
++
++/* CGU module register */
++#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
++#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
++#define LTQ_CGU_PLL2_CFG 0x0060 /* PLL2 config */
++#define LTQ_CGU_SYS 0x000C /* System clock */
++#define LTQ_CGU_CLK_FSR 0x0010 /* Clock frequency select */
++#define LTQ_CGU_UPDATE 0x0020 /* Clock update control */
++
++/* Valid SYS.CPU values */
++#define LTQ_CGU_SYS_CPU_SHIFT 4
++#define LTQ_CGU_SYS_CPU_600_MHZ 0x0
++#define LTQ_CGU_SYS_CPU_500_MHZ 0x1
++#define LTQ_CGU_SYS_CPU_393_MHZ 0x2
++#define LTQ_CGU_SYS_CPU_333_MHZ 0x3
++#define LTQ_CGU_SYS_CPU_197_MHZ 0x5
++#define LTQ_CGU_SYS_CPU_166_MHZ 0x7
++#define LTQ_CGU_SYS_CPU_125_MHZ 0x9
++
++/* Valid SYS.OCP values */
++#define LTQ_CGU_SYS_OCP_SHIFT 0
++#define LTQ_CGU_SYS_OCP_1 0x0
++#define LTQ_CGU_SYS_OCP_2 0x2
++#define LTQ_CGU_SYS_OCP_2_5 0x3
++#define LTQ_CGU_SYS_OCP_3 0x4
++
++/* Valid CLK_FSR.ETH values */
++#define LTQ_CGU_CLK_FSR_ETH_SHIFT 24
++#define LTQ_CGU_CLK_FSR_ETH_50_MHZ 0x0
++#define LTQ_CGU_CLK_FSR_ETH_25_MHZ 0x1
++#define LTQ_CGU_CLK_FSR_ETH_2_5_MHZ 0x2
++#define LTQ_CGU_CLK_FSR_ETH_125_MHZ 0x3
++
++/* Valid CLK_FSR.PPE values */
++#define LTQ_CGU_CLK_FSR_PPE_SHIFT 16
++#define LTQ_CGU_CLK_FSR_PPE_500_MHZ 0x0 /* Overclock frequency */
++#define LTQ_CGU_CLK_FSR_PPE_450_MHZ 0x1 /* High frequency */
++#define LTQ_CGU_CLK_FSR_PPE_400_MHZ 0x2 /* Low frequency */
++
++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_500_DDR_250)
++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_500_MHZ
++#define LTQ_CGU_SYS_OCP_CONFIG LTQ_CGU_SYS_OCP_2
++#define LTQ_CGU_CLK_FSR_ETH_CONFIG LTQ_CGU_CLK_FSR_ETH_125_MHZ
++#define LTQ_CGU_CLK_FSR_PPE_CONFIG LTQ_CGU_CLK_FSR_PPE_450_MHZ
++#else
++#error "Invalid system clock configuration!"
++#endif
++
++/* Build register values */
++#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_CPU_CONFIG << \
++ LTQ_CGU_SYS_CPU_SHIFT) | \
++ LTQ_CGU_SYS_OCP_CONFIG)
++
++#define LTQ_CGU_CLK_FSR_VALUE ((LTQ_CGU_CLK_FSR_ETH_CONFIG << \
++ LTQ_CGU_CLK_FSR_ETH_SHIFT) | \
++ (LTQ_CGU_CLK_FSR_PPE_CONFIG << \
++ LTQ_CGU_CLK_FSR_PPE_SHIFT))
++
++ .set noreorder
++
++LEAF(ltq_cgu_init)
++ /* Load current CGU register values */
++ li t0, (LTQ_CGU_BASE | KSEG1)
++ lw t1, LTQ_CGU_SYS(t0)
++ lw t2, LTQ_CGU_CLK_FSR(t0)
++
++ /* Load target CGU register values */
++ li t3, LTQ_CGU_SYS_VALUE
++ li t4, LTQ_CGU_CLK_FSR_VALUE
++
++ /* Only update registers if values differ */
++ bne t1, t3, update
++ nop
++ beq t2, t4, finished
++ nop
++
++update:
++ /* Store target register values */
++ sw t3, LTQ_CGU_SYS(t0)
++ sw t4, LTQ_CGU_CLK_FSR(t0)
++
++ /* Perform software reset to activate new clock config */
++#if 0
++ li t0, (LTQ_RCU_BASE | KSEG1)
++ lw t1, LTQ_RCU_RST_REQ(t0)
++ or t1, LTQ_RCU_RST_REQ_VALUE
++ sw t1, LTQ_RCU_RST_REQ(t0)
++#else
++ li t1, 1
++ sw t1, LTQ_CGU_UPDATE(t0)
++#endif
++
++#if 0
++wait_reset:
++ b wait_reset
++ nop
++#endif
++
++finished:
++ jr ra
++ nop
++
++ END(ltq_cgu_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/chipid.c
+@@ -0,0 +1,63 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_CHIPID_VERSION_SHIFT 28
++#define LTQ_CHIPID_VERSION_MASK (0x7 << LTQ_CHIPID_VERSION_SHIFT)
++#define LTQ_CHIPID_PNUM_SHIFT 12
++#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
++
++struct ltq_chipid_regs {
++ u32 manid; /* Manufacturer identification */
++ u32 chipid; /* Chip identification */
++};
++
++static struct ltq_chipid_regs *ltq_chipid_regs =
++ (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
++
++unsigned int ltq_chip_version_get(void)
++{
++ u32 chipid;
++
++ chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++ return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
++}
++
++unsigned int ltq_chip_partnum_get(void)
++{
++ u32 chipid;
++
++ chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++ return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
++}
++
++const char *ltq_chip_partnum_str(void)
++{
++ enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
++
++ switch (partnum) {
++ case LTQ_SOC_VRX268:
++ case LTQ_SOC_VRX268_2:
++ return "VRX268";
++ case LTQ_SOC_VRX288:
++ case LTQ_SOC_VRX288_2:
++ return "VRX288";
++ case LTQ_SOC_GRX288:
++ case LTQ_SOC_GRX288_2:
++ return "GRX288";
++ default:
++ printf("Unknown partnum: %x\n", partnum);
++ }
++
++ return "";
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/config.mk
+@@ -0,0 +1,32 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
++
++ifdef CONFIG_SPL_BUILD
++PF_ABICALLS := -mno-abicalls
++PF_PIC := -fno-pic
++USE_PRIVATE_LIBGCC := yes
++endif
++
++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
++
++ifndef CONFIG_SPL_BUILD
++ifdef CONFIG_SYS_BOOT_SFSPL
++ALL-y += $(obj)u-boot.ltq.sfspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl
++endif
++ifdef CONFIG_SYS_BOOT_NORSPL
++ALL-y += $(obj)u-boot.ltq.norspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
++endif
++endif
++
++LDSCRIPT := $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot.lds
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/dcdc.c
+@@ -0,0 +1,107 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_DCDC_CLK_SET0_CLK_SEL_P (1 << 6)
++#define LTQ_DCDC_CLK_SET1_SEL_DIV25 (1 << 5)
++#define LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE (1 << 5)
++
++struct ltq_dcdc_regs {
++ u8 b0_coeh; /* Coefficient b0 */
++ u8 b0_coel; /* Coefficient b0 */
++ u8 b1_coeh; /* Coefficient b1 */
++ u8 b1_coel; /* Coefficient b1 */
++ u8 b2_coeh; /* Coefficient b2 */
++ u8 b2_coel; /* Coefficient b2 */
++ u8 clk_set0; /* Clock setup */
++ u8 clk_set1; /* Clock setup */
++ u8 pwm_confh; /* Configure PWM */
++ u8 pwm_confl; /* Configure PWM */
++ u8 bias_vreg0; /* Bias and regulator setup */
++ u8 bias_vreg1; /* Bias and regulator setup */
++ u8 adc_gen0; /* ADC and general control */
++ u8 adc_gen1; /* ADC and general control */
++ u8 adc_con0; /* ADC and general config */
++ u8 adc_con1; /* ADC and general config */
++ u8 conf_test_ana; /* not documented */
++ u8 conf_test_dig; /* not documented */
++ u8 dcdc_status; /* not documented */
++ u8 pid_status; /* not documented */
++ u8 duty_cycle; /* not documented */
++ u8 non_ov_delay; /* not documented */
++ u8 analog_gain; /* not documented */
++ u8 duty_cycle_max_sat; /* not documented */
++ u8 duty_cycle_min_sat; /* not documented */
++ u8 duty_cycle_max; /* not documented */
++ u8 duty_cycle_min; /* not documented */
++ u8 error_max; /* not documented */
++ u8 error_read; /* not documented */
++ u8 delay_deglitch; /* not documented */
++ u8 latch_control; /* not documented */
++ u8 rsvd[240];
++ u8 osc_conf; /* OSC general config */
++ u8 osc_stat; /* OSC general status */
++};
++
++static struct ltq_dcdc_regs *ltq_dcdc_regs =
++ (struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE);
++
++void ltq_dcdc_init(unsigned int dig_ref)
++{
++ u8 dig_ref_cur, val;
++
++ /* Set duty cycle max sat. to 70/90, enable PID freeze */
++ ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x5A);
++ ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x46);
++ val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
++ val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
++ ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
++
++ /* Program new coefficients */
++ ltq_writeb(&ltq_dcdc_regs->b0_coeh, 0x00);
++ ltq_writeb(&ltq_dcdc_regs->b0_coel, 0x00);
++ ltq_writeb(&ltq_dcdc_regs->b1_coeh, 0xFF);
++ ltq_writeb(&ltq_dcdc_regs->b1_coel, 0xE6);
++ ltq_writeb(&ltq_dcdc_regs->b2_coeh, 0x00);
++ ltq_writeb(&ltq_dcdc_regs->b2_coel, 0x1B);
++ ltq_writeb(&ltq_dcdc_regs->non_ov_delay, 0x8B);
++
++ /* Set duty cycle max sat. to 60/108, disable PID freeze */
++ ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x6C);
++ ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x3C);
++ val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
++ val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
++ ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
++
++ /* Init clock and DLL settings */
++ val = ltq_readb(&ltq_dcdc_regs->clk_set0);
++ val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P;
++ ltq_writeb(&ltq_dcdc_regs->clk_set0, val);
++ val = ltq_readb(&ltq_dcdc_regs->clk_set1);
++ val |= LTQ_DCDC_CLK_SET1_SEL_DIV25;
++ ltq_writeb(&ltq_dcdc_regs->clk_set1, val);
++ ltq_writeb(&ltq_dcdc_regs->pwm_confh, 0xF9);
++
++ wmb();
++
++ /* Adapt value of digital reference of DCDC converter */
++ dig_ref_cur = ltq_readb(&ltq_dcdc_regs->bias_vreg1);
++
++ while (dig_ref_cur != dig_ref) {
++ if (dig_ref >= dig_ref_cur)
++ dig_ref_cur++;
++ else if (dig_ref < dig_ref_cur)
++ dig_ref_cur--;
++
++ ltq_writeb(&ltq_dcdc_regs->bias_vreg1, dig_ref_cur);
++ __udelay(1000);
++ }
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/ebu.c
+@@ -0,0 +1,112 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4)
++#define EBU_ADDRSEL_REGEN (1 << 0)
++
++#define EBU_CON_WRDIS (1 << 31)
++#define EBU_CON_AGEN_DEMUX (0x0 << 24)
++#define EBU_CON_AGEN_MUX (0x2 << 24)
++#define EBU_CON_SETUP (1 << 22)
++#define EBU_CON_WAIT_DIS (0x0 << 20)
++#define EBU_CON_WAIT_ASYNC (0x1 << 20)
++#define EBU_CON_WAIT_SYNC (0x2 << 20)
++#define EBU_CON_WINV (1 << 19)
++#define EBU_CON_PW_8BIT (0x0 << 16)
++#define EBU_CON_PW_16BIT (0x1 << 16)
++#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14)
++#define EBU_CON_BCGEN_CS (0x0 << 12)
++#define EBU_CON_BCGEN_INTEL (0x1 << 12)
++#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12)
++#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8)
++#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6)
++#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4)
++#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2)
++#define EBU_CON_CMULT_1 0x0
++#define EBU_CON_CMULT_4 0x1
++#define EBU_CON_CMULT_8 0x2
++#define EBU_CON_CMULT_16 0x3
++
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define ebu_region0_enable 1
++#else
++#define ebu_region0_enable 0
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define ebu_region1_enable 1
++#else
++#define ebu_region1_enable 0
++#endif
++
++struct ltq_ebu_regs {
++ u32 clc;
++ u32 rsvd0;
++ u32 id;
++ u32 rsvd1;
++ u32 con;
++ u32 rsvd2[3];
++ u32 addr_sel_0;
++ u32 addr_sel_1;
++ u32 addr_sel_2;
++ u32 addr_sel_3;
++ u32 rsvd3[12];
++ u32 con_0;
++ u32 con_1;
++ u32 con_2;
++ u32 con_3;
++};
++
++static struct ltq_ebu_regs *ltq_ebu_regs =
++ (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
++
++void ltq_ebu_init(void)
++{
++ if (ebu_region0_enable) {
++ /*
++ * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
++ * region control. This supports up to 32 MiB NOR flash in
++ * bank 0.
++ */
++ ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
++ EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
++
++ ltq_writel(&ltq_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
++ EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
++ EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++ EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
++ EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
++ EBU_CON_CMULT_16);
++ } else
++ ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
++
++ if (ebu_region1_enable) {
++ /*
++ * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
++ * region control. This supports NAND flash in bank 1.
++ */
++ ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
++ EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
++
++ ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
++ EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
++ EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++ EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
++ EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
++ EBU_CON_CMULT_4);
++ } else
++ ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
++}
++
++void *flash_swap_addr(unsigned long addr)
++{
++ return (void *)(addr ^ 2);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/gphy.c
+@@ -0,0 +1,59 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/gphy.h>
++
++static inline void ltq_gphy_copy(const void *fw_start, const void *fw_end,
++ ulong dst_addr)
++{
++ const ulong fw_len = (ulong) fw_end - (ulong) fw_start;
++ const ulong addr = CKSEG1ADDR(dst_addr);
++
++ debug("ltq_gphy_copy: addr %08lx, fw_start %p, fw_end %p\n",
++ addr, fw_start, fw_end);
++
++ memcpy((void *) addr, fw_start, fw_len);
++}
++
++void ltq_gphy_phy11g_a1x_load(ulong addr)
++{
++ extern ulong __ltq_fw_phy11g_a1x_start;
++ extern ulong __ltq_fw_phy11g_a1x_end;
++
++ ltq_gphy_copy(&__ltq_fw_phy11g_a1x_start, &__ltq_fw_phy11g_a1x_end,
++ addr);
++}
++
++void ltq_gphy_phy11g_a2x_load(ulong addr)
++{
++ extern ulong __ltq_fw_phy11g_a2x_start;
++ extern ulong __ltq_fw_phy11g_a2x_end;
++
++ ltq_gphy_copy(&__ltq_fw_phy11g_a2x_start, &__ltq_fw_phy11g_a2x_end,
++ addr);
++}
++
++void ltq_gphy_phy22f_a1x_load(ulong addr)
++{
++ extern ulong __ltq_fw_phy22f_a1x_start;
++ extern ulong __ltq_fw_phy22f_a1x_end;
++
++ ltq_gphy_copy(&__ltq_fw_phy22f_a1x_start, &__ltq_fw_phy22f_a1x_end,
++ addr);
++}
++
++void ltq_gphy_phy22f_a2x_load(ulong addr)
++{
++ extern ulong __ltq_fw_phy22f_a2x_start;
++ extern ulong __ltq_fw_phy22f_a2x_end;
++
++ ltq_gphy_copy(&__ltq_fw_phy22f_a2x_start, &__ltq_fw_phy22f_a2x_end,
++ addr);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
+@@ -0,0 +1,28 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <asm/asm.h>
++
++ .section .rodata.__ltq_fw_phy11g_a1x
++EXPORT(__ltq_fw_phy11g_a1x_start)
++ .incbin "fw_phy11g_a1x.bin"
++EXPORT(__ltq_fw_phy11g_a1x_end)
++
++ .section .rodata.__ltq_fw_phy11g_a2x
++EXPORT(__ltq_fw_phy11g_a2x_start)
++ .incbin "fw_phy11g_a2x.bin"
++EXPORT(__ltq_fw_phy11g_a2x_end)
++
++ .section .rodata.__ltq_fw_phy22f_a1x
++EXPORT(__ltq_fw_phy22f_a1x_start)
++ .incbin "fw_phy22f_a1x.bin"
++EXPORT(__ltq_fw_phy22f_a1x_end)
++
++ .section .rodata.__ltq_fw_phy22f_a2x
++EXPORT(__ltq_fw_phy22f_a2x_start)
++ .incbin "fw_phy22f_a2x.bin"
++EXPORT(__ltq_fw_phy22f_a2x_end)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/mem.c
+@@ -0,0 +1,58 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_CCR03_EIGHT_BANK_MODE (1 << 0)
++#define LTQ_CCR08_CS_MAP_SHIFT 24
++#define LTQ_CCR08_CS_MAP_MASK (0x3 << LTQ_CCR08_CS_MAP_SHIFT)
++#define LTQ_CCR11_COLUMN_SIZE_SHIFT 24
++#define LTQ_CCR11_COLUMN_SIZE_MASK (0x7 << LTQ_CCR11_COLUMN_SIZE_SHIFT)
++#define LTQ_CCR11_ADDR_PINS_MASK 0x7
++#define LTQ_CCR15_MAX_COL_REG_SHIFT 24
++#define LTQ_CCR15_MAX_COL_REG_MASK (0xF << LTQ_CCR15_MAX_COL_REG_SHIFT)
++#define LTQ_CCR16_MAX_ROW_REG_MASK 0xF
++
++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
++
++static inline u32 ltq_mc_ccr_read(u32 index)
++{
++ return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index));
++}
++
++phys_size_t initdram(int board_type)
++{
++ u32 max_col_reg, max_row_reg, column_size, addr_pins;
++ u32 banks, cs_map;
++ phys_size_t size;
++
++ banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4;
++
++ cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >>
++ LTQ_CCR08_CS_MAP_SHIFT;
++
++ column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >>
++ LTQ_CCR11_COLUMN_SIZE_SHIFT;
++
++ addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK;
++
++ max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >>
++ LTQ_CCR15_MAX_COL_REG_SHIFT;
++
++ max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK;
++
++ /*
++ * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects
++ * * datawidth (bytes)
++ */
++ size = (2 << (max_col_reg - column_size - 1)) *
++ (2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2;
++
++ return size;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/mem_init.S
+@@ -0,0 +1,234 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* Must be configured in BOARDDIR */
++#include <ddr_settings.h>
++
++#define LTQ_MC_DDR_START (1 << 8)
++#define LTQ_MC_DDR_DLL_LOCK_IND 1
++
++#define CCS_ALWAYS_LAST 0x0430
++#define CCS_AHBM_CR_BURST_EN (1 << 2)
++#define CCS_FPIM_CR_BURST_EN (1 << 1)
++
++#define CCR03_EIGHT_BANK_MODE (1 << 0)
++
++ /* Store given value in MC DDR CCRx register */
++ .macro ccr_sw num, val
++ li t1, \val
++ sw t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0)
++ .endm
++
++LEAF(ltq_mem_init)
++ /* Load MC DDR module base */
++ li t0, (LTQ_MC_DDR_BASE | KSEG1)
++
++ /* Put memory controller in inactive mode */
++ sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++
++ /* Init MC DDR CCR registers with values from ddr_settings.h */
++ ccr_sw 0, MC_CCR00_VALUE
++ ccr_sw 1, MC_CCR01_VALUE
++ ccr_sw 2, MC_CCR02_VALUE
++ ccr_sw 3, MC_CCR03_VALUE
++ ccr_sw 4, MC_CCR04_VALUE
++ ccr_sw 5, MC_CCR05_VALUE
++ ccr_sw 6, MC_CCR06_VALUE
++ ccr_sw 7, MC_CCR07_VALUE
++ ccr_sw 8, MC_CCR08_VALUE
++ ccr_sw 9, MC_CCR09_VALUE
++
++ ccr_sw 10, MC_CCR10_VALUE
++ ccr_sw 11, MC_CCR11_VALUE
++ ccr_sw 12, MC_CCR12_VALUE
++ ccr_sw 13, MC_CCR13_VALUE
++ ccr_sw 14, MC_CCR14_VALUE
++ ccr_sw 15, MC_CCR15_VALUE
++ ccr_sw 16, MC_CCR16_VALUE
++ ccr_sw 17, MC_CCR17_VALUE
++ ccr_sw 18, MC_CCR18_VALUE
++ ccr_sw 19, MC_CCR19_VALUE
++
++ ccr_sw 20, MC_CCR20_VALUE
++ ccr_sw 21, MC_CCR21_VALUE
++ ccr_sw 22, MC_CCR22_VALUE
++ ccr_sw 23, MC_CCR23_VALUE
++ ccr_sw 24, MC_CCR24_VALUE
++ ccr_sw 25, MC_CCR25_VALUE
++ ccr_sw 26, MC_CCR26_VALUE
++ ccr_sw 27, MC_CCR27_VALUE
++ ccr_sw 28, MC_CCR28_VALUE
++ ccr_sw 29, MC_CCR29_VALUE
++
++ ccr_sw 30, MC_CCR30_VALUE
++ ccr_sw 31, MC_CCR31_VALUE
++ ccr_sw 32, MC_CCR32_VALUE
++ ccr_sw 33, MC_CCR33_VALUE
++ ccr_sw 34, MC_CCR34_VALUE
++ ccr_sw 35, MC_CCR35_VALUE
++ ccr_sw 36, MC_CCR36_VALUE
++ ccr_sw 37, MC_CCR37_VALUE
++ ccr_sw 38, MC_CCR38_VALUE
++ ccr_sw 39, MC_CCR39_VALUE
++
++ ccr_sw 40, MC_CCR40_VALUE
++ ccr_sw 41, MC_CCR41_VALUE
++ ccr_sw 42, MC_CCR42_VALUE
++ ccr_sw 43, MC_CCR43_VALUE
++ ccr_sw 44, MC_CCR44_VALUE
++ ccr_sw 45, MC_CCR45_VALUE
++ ccr_sw 46, MC_CCR46_VALUE
++
++ ccr_sw 52, MC_CCR52_VALUE
++ ccr_sw 53, MC_CCR53_VALUE
++ ccr_sw 54, MC_CCR54_VALUE
++ ccr_sw 55, MC_CCR55_VALUE
++ ccr_sw 56, MC_CCR56_VALUE
++ ccr_sw 57, MC_CCR57_VALUE
++ ccr_sw 58, MC_CCR58_VALUE
++ ccr_sw 59, MC_CCR59_VALUE
++
++ ccr_sw 60, MC_CCR60_VALUE
++ ccr_sw 61, MC_CCR61_VALUE
++
++ /* Disable bursts between FPI Master bus and XBAR bus */
++ li t4, (LTQ_MC_GLOBAL_BASE | KSEG1)
++ li t5, CCS_AHBM_CR_BURST_EN
++ sw t5, CCS_ALWAYS_LAST(t4)
++
++ /* Init abort condition for DRAM probe */
++ move t4, zero
++
++ /*
++ * Put memory controller in active mode and start initialitation
++ * sequence for connected DDR-SDRAM device
++ */
++mc_start:
++ lw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++ li t2, LTQ_MC_DDR_START
++ or t1, t1, t2
++ sw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++
++ /*
++ * Wait until DLL has locked and core is ready for data transfers.
++ * DLL lock indication is in register CCR47 and CCR48
++ */
++wait_ready:
++ li t1, LTQ_MC_DDR_DLL_LOCK_IND
++ lw t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0)
++ and t2, t2, t1
++ bne t1, t2, wait_ready
++
++ lw t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0)
++ and t2, t2, t1
++ bne t1, t2, wait_ready
++
++#ifdef CONFIG_SYS_DRAM_PROBE
++dram_probe:
++ /* Initialization is finished after the second MC start */
++ bnez t4, mc_finished
++
++ /*
++ * Preload register values for CCR03 and CCR11. Initial settings
++ * are 8-bank mode enabled, 14 use address row bits, 10 used
++ * column address bits.
++ */
++ li t1, CONFIG_SYS_SDRAM_BASE_UC
++ li t5, MC_CCR03_VALUE
++ li t6, MC_CCR11_VALUE
++ addi t4, t4, 1
++
++ /*
++ * Store test values to DRAM at offsets 0 and 2^13 (bit 2 in bank select
++ * address BA[3]) and read back the value at offset 0. If the resulting
++ * value is equal to 1 we can skip to the next test. Otherwise
++ * the 8-bank mode does not work with the current DRAM device,
++ * thus we need to clear the according bit in register CCR03.
++ */
++ li t2, 1
++ sw t2, 0x0(t1)
++ li t3, (1 << 13)
++ add t3, t3, t1
++ sw zero, 0(t3)
++ lw t3, 0(t1)
++ bnez t3, row_col_test
++
++ /* Clear CCR03.EIGHT_BANK_MODE */
++ li t3, ~CCR03_EIGHT_BANK_MODE
++ and t5, t5, t3
++
++row_col_test:
++ /*
++ * Store test values to DRAM at offsets 0, 2^27 (bit 13 of row address
++ * RA[14]) and 2^26 (bit 12 of RA[14]). The chosen test values
++ * represent the difference between max. row address bits (14) and used
++ * row address bits. Then the read back value at offset 0 indicates
++ * the useable row address bits with the current DRAM device. This
++ * value must be set in the CCR11 register.
++ */
++ sw zero, 0(t1)
++
++ li t2, 1
++ li t3, (1 << 27)
++ add t3, t3, t1
++ sw t2, 0(t3)
++
++ li t2, 2
++ li t3, (1 << 26)
++ add t3, t3, t1
++ sw t2, 0(t3)
++
++ /* Update CCR11.ADDR_PINS */
++ lw t3, 0(t1)
++ add t6, t6, t3
++
++ /*
++ * Store test values to DRAM at offsets 0, 2^10 (bit 9 of column address
++ * CA[10]) and 2^9 (bit 8 of CA[10]). The chosen test values represent
++ * the difference between max. column address bits (12) and used
++ * column address bits. Then the read back value at offset 0 indicates
++ * the useable column address bits with the current DRAM device. This
++ * value must be set in the CCR11 register.
++ */
++ sw zero, 0(t1)
++
++ li t2, 1
++ li t3, (1 << 10)
++ add t3, t3, t1
++ sw t2, 0(t3)
++
++ li t2, 2
++ li t3, (1 << 9)
++ add t3, t3, t1
++ sw t2, 0(t3)
++
++ /* Update CCR11.COLUMN_SIZE */
++ lw t3, 0(t1)
++ sll t3, t3, 24
++ add t6, t6, t3
++
++ /* Put memory controller in inactive mode */
++ sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++
++ /* Update CCR03 and CCR11 and restart memory controller initialiation */
++ sw t5, LTQ_MC_DDR_CCR_OFFSET(3)(t0)
++ sw t6, LTQ_MC_DDR_CCR_OFFSET(11)(t0)
++ b mc_start
++
++mc_finished:
++#endif /* CONFIG_SYS_DRAM_PROBE */
++
++ jr ra
++
++ END(ltq_mem_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/pmu.c
+@@ -0,0 +1,131 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PMU_PWDCR_RESERVED ((1 << 13) | (1 << 4))
++
++#define LTQ_PMU_PWDCR_PCIELOC_EN (1 << 31)
++#define LTQ_PMU_PWDCR_GPHY (1 << 30)
++#define LTQ_PMU_PWDCR_PPE_TOP (1 << 29)
++#define LTQ_PMU_PWDCR_SWITCH (1 << 28)
++#define LTQ_PMU_PWDCR_USB1 (1 << 27)
++#define LTQ_PMU_PWDCR_USB1_PHY (1 << 26)
++#define LTQ_PMU_PWDCR_TDM (1 << 25)
++#define LTQ_PMU_PWDCR_PPE_DPLUS (1 << 24)
++#define LTQ_PMU_PWDCR_PPE_DPLUM (1 << 23)
++#define LTQ_PMU_PWDCR_PPE_EMA (1 << 22)
++#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
++#define LTQ_PMU_PWDCR_DEU (1 << 20)
++#define LTQ_PMU_PWDCR_PPE_SLL01 (1 << 19)
++#define LTQ_PMU_PWDCR_PPE_QSB (1 << 18)
++#define LTQ_PMU_PWDCR_UART1 (1 << 17)
++#define LTQ_PMU_PWDCR_SDIO (1 << 16)
++#define LTQ_PMU_PWDCR_AHBM (1 << 15)
++#define LTQ_PMU_PWDCR_FPIM (1 << 14)
++#define LTQ_PMU_PWDCR_GPTC (1 << 12)
++#define LTQ_PMU_PWDCR_LEDC (1 << 11)
++#define LTQ_PMU_PWDCR_EBU (1 << 10)
++#define LTQ_PMU_PWDCR_DSL (1 << 9)
++#define LTQ_PMU_PWDCR_SPI (1 << 8)
++#define LTQ_PMU_PWDCR_USIF (1 << 7)
++#define LTQ_PMU_PWDCR_USB0 (1 << 6)
++#define LTQ_PMU_PWDCR_DMA (1 << 5)
++#define LTQ_PMU_PWDCR_DFEV1 (1 << 3)
++#define LTQ_PMU_PWDCR_DFEV0 (1 << 2)
++#define LTQ_PMU_PWDCR_FPIS (1 << 1)
++#define LTQ_PMU_PWDCR_USB0_PHY (1 << 0)
++
++struct ltq_pmu_regs {
++ u32 rsvd0[7];
++ u32 pwdcr; /* Power down control */
++ u32 sr; /* Power down status */
++ u32 pwdcr1; /* Power down control 1 */
++ u32 sr1; /* Power down status 1 */
++};
++
++static struct ltq_pmu_regs *ltq_pmu_regs =
++ (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
++
++u32 ltq_pm_map(enum ltq_pm_modules module)
++{
++ u32 val;
++
++ switch (module) {
++ case LTQ_PM_CORE:
++ val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM |
++ LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
++ break;
++ case LTQ_PM_DMA:
++ val = LTQ_PMU_PWDCR_DMA;
++ break;
++ case LTQ_PM_ETH:
++ val = LTQ_PMU_PWDCR_GPHY | LTQ_PMU_PWDCR_PPE_TOP |
++ LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DPLUS |
++ LTQ_PMU_PWDCR_PPE_DPLUM | LTQ_PMU_PWDCR_PPE_EMA |
++ LTQ_PMU_PWDCR_PPE_TC | LTQ_PMU_PWDCR_PPE_SLL01 |
++ LTQ_PMU_PWDCR_PPE_QSB;
++ break;
++ case LTQ_PM_SPI:
++ val = LTQ_PMU_PWDCR_SPI;
++ break;
++ default:
++ val = 0;
++ break;
++ }
++
++ return val;
++}
++
++int ltq_pm_enable(enum ltq_pm_modules module)
++{
++ const unsigned long timeout = 1000;
++ unsigned long timebase;
++ u32 sr, val;
++
++ val = ltq_pm_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
++
++ timebase = get_timer(0);
++
++ do {
++ sr = ltq_readl(&ltq_pmu_regs->sr);
++ if (~sr & val)
++ return 0;
++ } while (get_timer(timebase) < timeout);
++
++ return 1;
++}
++
++int ltq_pm_disable(enum ltq_pm_modules module)
++{
++ u32 val;
++
++ val = ltq_pm_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_setbits(&ltq_pmu_regs->pwdcr, val);
++
++ return 0;
++}
++
++void ltq_pmu_init(void)
++{
++ u32 set, clr;
++
++ clr = ltq_pm_map(LTQ_PM_CORE);
++ set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
++
++ ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/rcu.c
+@@ -0,0 +1,195 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_RCU_RD_GPHY0 (1 << 31) /* GPHY0 */
++#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
++#define LTQ_RCU_RD_GPHY1 (1 << 29) /* GPHY1 */
++#define LTQ_RCU_RD_ENMIP2 (1 << 28) /* Enable NMI of PLL2 */
++#define LTQ_RCU_RD_REG25_PD (1 << 26) /* Power down 2.5V regulator */
++#define LTQ_RCU_RD_ENDINIT (1 << 25) /* FPI slave bus access */
++#define LTQ_RCU_RD_PPE_ATM_TC (1 << 23) /* PPE ATM TC */
++#define LTQ_RCU_RD_PCIE (1 << 22) /* PCI-E core */
++#define LTQ_RCU_RD_ETHSW (1 << 21) /* Ethernet switch */
++#define LTQ_RCU_RD_DSP_DEN (1 << 20) /* Enable DSP JTAG */
++#define LTQ_RCU_RD_TDM (1 << 19) /* TDM module interface */
++#define LTQ_RCU_RD_ENMIP1 (1 << 18) /* Enable NMI of PLL1 */
++#define LTQ_RCU_RD_SWBCK (1 << 17) /* Switch backward compat */
++#define LTQ_RCU_RD_HSNAND (1 << 16) /* HSNAND controller */
++#define LTQ_RCU_RD_ENMIP0 (1 << 15) /* Enable NMI of PLL0 */
++#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
++#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
++#define LTQ_RCU_RD_PCIE_PHY (1 << 12) /* PCI-E Phy */
++#define LTQ_RCU_RD_DFE_CORE (1 << 11) /* DFE core */
++#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
++#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
++#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
++#define LTQ_RCU_RD_DFE (1 << 7) /* DFE core */
++#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
++#define LTQ_RCU_RD_HRST_CFG (1 << 5) /* HW reset configuration */
++#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
++#define LTQ_RCU_RD_PPE_DSP (1 << 3) /* PPE DSP interface */
++#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
++#define LTQ_RCU_RD_CPU (1 << 1) /* CPU subsystem */
++#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
++
++#define LTQ_RCU_STAT_BOOT_SHIFT 17
++#define LTQ_RCU_STAT_BOOT_MASK (0xF << LTQ_RCU_STAT_BOOT_SHIFT)
++#define LTQ_RCU_STAT_BOOT_H (1 << 12)
++
++#define LTQ_RCU_GP_STRAP_CLOCKSOURCE (1 << 15)
++
++struct ltq_rcu_regs {
++ u32 rsvd0[4];
++ u32 req; /* Reset request */
++ u32 stat; /* Reset status */
++ u32 usb0_cfg; /* USB0 configure */
++ u32 gp_strap; /* GPIO strapping */
++ u32 gfs_add0; /* GPHY0 firmware base addr */
++ u32 stat2; /* SLIC and USB reset status */
++ u32 pci_rdy; /* PCI boot ready */
++ u32 ppe_conf; /* PPE ethernet config */
++ u32 pcie_phy_con; /* PCIE PHY config/status */
++ u32 usb1_cfg; /* USB1 configure */
++ u32 usb_ana_cfg1a; /* USB analog config 1a */
++ u32 usb_ana_cfg1b; /* USB analog config 1b */
++ u32 rsvd1;
++ u32 gf_mdio_add; /* GPHY0/1 MDIO address */
++ u32 req2; /* SLIC and USB reset request */
++ u32 ahb_endian; /* AHB bus endianess */
++ u32 rsvd2[4];
++ u32 gcc; /* General CPU config */
++ u32 rsvd3;
++ u32 gfs_add1; /* GPHY1 firmware base addr */
++};
++
++static struct ltq_rcu_regs *ltq_rcu_regs =
++ (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
++
++u32 ltq_reset_map(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ switch (module) {
++ case LTQ_RESET_CORE:
++ case LTQ_RESET_SOFT:
++ val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU | LTQ_RCU_RD_ENMIP2 |
++ LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
++ break;
++ case LTQ_RESET_DMA:
++ val = LTQ_RCU_RD_DMA;
++ break;
++ case LTQ_RESET_ETH:
++ val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
++ break;
++ case LTQ_RESET_PHY:
++ val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
++ break;
++ case LTQ_RESET_HARD:
++ val = LTQ_RCU_RD_HRST;
++ break;
++ default:
++ val = 0;
++ break;
++ }
++
++ return val;
++}
++
++int ltq_reset_activate(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ val = ltq_reset_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_setbits(&ltq_rcu_regs->req, val);
++
++ return 0;
++}
++
++int ltq_reset_deactivate(enum ltq_reset_modules module)
++{
++ u32 val;
++
++ val = ltq_reset_map(module);
++ if (unlikely(!val))
++ return 1;
++
++ ltq_clrbits(&ltq_rcu_regs->req, val);
++
++ return 0;
++}
++
++enum ltq_boot_select ltq_boot_select(void)
++{
++ u32 stat;
++ unsigned int bootstrap;
++
++ /*
++ * Boot select value is built from bits 20-17 and bit 12.
++ * The bit sequence is read as 4-2-1-0-3.
++ */
++ stat = ltq_readl(&ltq_rcu_regs->stat);
++ bootstrap = ((stat & LTQ_RCU_STAT_BOOT_H) << 4) |
++ ((stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT);
++
++ switch (bootstrap) {
++ case 0:
++ return BOOT_NOR_NO_BOOTROM;
++ case 1:
++ return BOOT_RGMII1;
++ case 2:
++ return BOOT_NOR;
++ case 4:
++ return BOOT_UART_NO_EEPROM;
++ case 6:
++ return BOOT_PCI;
++ case 8:
++ return BOOT_UART;
++ case 10:
++ return BOOT_SPI;
++ case 12:
++ return BOOT_NAND;
++ default:
++ return BOOT_UNKNOWN;
++ }
++}
++
++void ltq_rcu_gphy_boot(unsigned int id, ulong addr)
++{
++ u32 module;
++ void *gfs_add;
++
++ switch (id) {
++ case 0:
++ module = LTQ_RCU_RD_GPHY0;
++ gfs_add = &ltq_rcu_regs->gfs_add0;
++ break;
++ case 1:
++ module = LTQ_RCU_RD_GPHY1;
++ gfs_add = &ltq_rcu_regs->gfs_add1;
++ break;
++ default:
++ BUG();
++ }
++
++ /* Stop and reset GPHY */
++ ltq_setbits(&ltq_rcu_regs->req, module);
++
++ /* Configure firmware and boot address */
++ ltq_writel(gfs_add, CPHYSADDR(addr & 0xFFFFC000));
++
++ /* Start GPHY by releasing reset */
++ ltq_clrbits(&ltq_rcu_regs->req, module);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/u-boot.lds
+@@ -0,0 +1,69 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
++OUTPUT_ARCH(mips)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++
++ . = ALIGN(4);
++ .text : {
++ *(.text*)
++ }
++
++ . = ALIGN(4);
++ .rodata : {
++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
++ }
++
++ . = ALIGN(4);
++ .data : {
++ *(.data*)
++ }
++
++ . = ALIGN(4);
++ .sdata : {
++ *(.sdata*)
++ }
++
++ . = .;
++ _gp = ALIGN(16) + 0x7ff0;
++
++ .got : {
++ __got_start = .;
++ *(.got)
++ __got_end = .;
++ }
++
++ num_got_entries = (__got_end - __got_start) >> 2;
++
++#ifndef CONFIG_SPL_BUILD
++ . = ALIGN(4);
++ .u_boot_list : {
++ #include <u-boot.lst>
++ }
++#endif
++
++ . = ALIGN(4);
++ __image_copy_end = .;
++ uboot_end_data = .;
++
++ .bss (NOLOAD) : {
++ __bss_start = .;
++ *(.bss*)
++ *(.sbss*)
++ . = ALIGN(4);
++ __bss_end = .;
++ }
++
++ . = ALIGN(4);
++ __end = .;
++ uboot_end = .;
++}
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/config.h
+@@ -0,0 +1,156 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ *
++ * Common board configuration for Lantiq XWAY Danube family
++ *
++ * Use following defines in your board config to enable specific features
++ * and drivers for this SoC:
++ *
++ * CONFIG_LTQ_SUPPORT_UART
++ * - support the Danube ASC/UART interface and console
++ *
++ * CONFIG_LTQ_SUPPORT_NOR_FLASH
++ * - support a parallel NOR flash via the CFI interface in flash bank 0
++ *
++ * CONFIG_LTQ_SUPPORT_ETHERNET
++ * - support the Danube ETOP and MAC interface
++ *
++ * CONFIG_LTQ_SUPPORT_SPI_FLASH
++ * - support the Danube SPI interface and serial flash drivers
++ * - specific SPI flash drivers must be configured separately
++ */
++
++#ifndef __DANUBE_CONFIG_H__
++#define __DANUBE_CONFIG_H__
++
++/* CPU and SoC type */
++#define CONFIG_SOC_LANTIQ
++#define CONFIG_SOC_XWAY_DANUBE
++
++/* Cache configuration */
++#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
++#define CONFIG_SYS_DCACHE_SIZE (16 * 1024)
++#define CONFIG_SYS_ICACHE_SIZE (16 * 1024)
++#define CONFIG_SYS_CACHELINE_SIZE 32
++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++/*
++ * Supported clock modes
++ * PLL0 clock output is 333 MHz
++ * PLL1 clock output is 262.144 MHz
++ */
++#define LTQ_CLK_CPU_333_DDR_167 0 /* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_111_DDR_111 1 /* Base PLL0, OCP 1 */
++
++/* CPU speed */
++#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_333_DDR_167
++#define CONFIG_SYS_MIPS_TIMER_FREQ 166666667
++#define CONFIG_SYS_HZ 1000
++
++/* RAM */
++#define CONFIG_NR_DRAM_BANKS 1
++#define CONFIG_SYS_SDRAM_BASE 0x80000000
++#define CONFIG_SYS_MEMTEST_START 0x81000000
++#define CONFIG_SYS_MEMTEST_END 0x82000000
++#define CONFIG_SYS_LOAD_ADDR 0x81000000
++#define CONFIG_SYS_INIT_SP_OFFSET 0x4000
++
++/* SRAM */
++#define CONFIG_SYS_SRAM_BASE 0xBE180000
++#define CONFIG_SYS_SRAM_SIZE 0x10000
++
++/* ASC/UART driver and console */
++#define CONFIG_LANTIQ_SERIAL
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/* GPIO */
++#define CONFIG_LANTIQ_GPIO
++#define CONFIG_LTQ_GPIO_MAX_BANKS 2
++
++/* FLASH driver */
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT 256
++#define CONFIG_SYS_FLASH_BASE 0xB0000000
++#define CONFIG_FLASH_16BIT
++#define CONFIG_SYS_FLASH_CFI
++#define CONFIG_FLASH_CFI_DRIVER
++#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++#define CONFIG_FLASH_SHOW_PROGRESS 50
++#define CONFIG_SYS_FLASH_PROTECTION
++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++
++#define CONFIG_CMD_FLASH
++#else
++#define CONFIG_SYS_NO_FLASH
++#endif /* CONFIG_NOR_FLASH */
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_LANTIQ_SPI
++#define CONFIG_SPI_FLASH
++
++#define CONFIG_CMD_SF
++#define CONFIG_CMD_SPI
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
++#define CONFIG_LANTIQ_DMA
++#define CONFIG_LANTIQ_DANUBE_ETOP
++
++#define CONFIG_PHYLIB
++#define CONFIG_MII
++
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#endif
++
++#define CONFIG_SPL_MAX_SIZE (32 * 1024)
++#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024)
++#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024)
++#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024)
++/*#define CONFIG_SPL_STACK_BSS_IN_SRAM*/
++
++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \
++ CONFIG_SPL_MAX_SIZE + \
++ CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \
++ CONFIG_SYS_INIT_SP_OFFSET)
++#else
++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \
++ CONFIG_SYS_INIT_SP_OFFSET + \
++ CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \
++ CONFIG_SPL_BSS_MAX_SIZE)
++#endif
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define CONFIG_SYS_TEXT_BASE 0xa0100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_SYS_TEXT_BASE 0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SPL_TEXT_BASE 0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C
++#define CONFIG_XWAY_SWAP_BYTES
++#endif
++
++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
++
++#endif /* __DANUBE_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/gpio.h
+@@ -0,0 +1,13 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __DANUBE_GPIO_H__
++#define __DANUBE_GPIO_H__
++
++#include <asm/lantiq/gpio.h>
++
++#endif /* __DANUBE_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/soc.h
+@@ -0,0 +1,40 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __DANUBE_SOC_H__
++#define __DANUBE_SOC_H__
++
++#define LTQ_ASC0_BASE 0x1E100400
++#define LTQ_SPI_BASE 0x1E100800
++#define LTQ_GPIO_BASE 0x1E100B00
++#define LTQ_SSIO_BASE 0x1E100BB0
++#define LTQ_ASC1_BASE 0x1E100C00
++#define LTQ_DMA_BASE 0x1E104100
++
++#define LTQ_EBU_BASE 0x1E105300
++#define LTQ_EBU_REGION0_BASE 0x10000000
++#define LTQ_EBU_REGION0_SIZE (64 * 1024 * 1024)
++#define LTQ_EBU_REGION1_BASE 0x14000000
++#define LTQ_EBU_REGION1_SIZE (32 * 1024 * 1024)
++
++#define LTQ_PPE_BASE 0x1E180000
++#define LTQ_PPE_ETOP_BASE (LTQ_PPE_BASE + 0x11800)
++#define LTQ_PPE_ENET0_BASE (LTQ_PPE_BASE + 0x11840)
++
++#define LTQ_PMU_BASE 0x1F102000
++#define LTQ_CGU_BASE 0x1F103000
++#define LTQ_MPS_BASE 0x1F107000
++#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340)
++#define LTQ_RCU_BASE 0x1F203000
++
++#define LTQ_MC_GEN_BASE 0x1F800000
++#define LTQ_MC_SDR_BASE 0x1F800200
++#define LTQ_MC_DDR_BASE 0x1F801000
++#define LTQ_MC_DDR_DC_OFFSET(x) (x * 0x10)
++
++#endif /* __DANUBE_SOC_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/config.h
+@@ -0,0 +1,185 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ *
++ * Common board configuration for Lantiq XWAY VRX200 family
++ *
++ * Use following defines in your board config to enable specific features
++ * and drivers for this SoC:
++ *
++ * CONFIG_LTQ_SUPPORT_UART
++ * - support the VRX200 ASC/UART interface and console
++ *
++ * CONFIG_LTQ_SUPPORT_NOR_FLASH
++ * - support a parallel NOR flash via the CFI interface in flash bank 0
++ *
++ * CONFIG_LTQ_SUPPORT_SPI_FLASH
++ * - support the VRX200 SPI interface and serial flash drivers
++ * - specific SPI flash drivers must be configured separately
++ *
++ * CONFIG_LTQ_SUPPORT_ETHERNET
++ * - support the VRX200 internal switch
++ *
++ * CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH
++ * - build a preloader that runs in the internal SRAM and loads
++ * the U-Boot from SPI flash into RAM
++ */
++
++#ifndef __VRX200_CONFIG_H__
++#define __VRX200_CONFIG_H__
++
++/* CPU and SoC type */
++#define CONFIG_SOC_LANTIQ
++#define CONFIG_SOC_XWAY_VRX200
++
++/* Cache configuration */
++#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
++#define CONFIG_SYS_DCACHE_SIZE (32 * 1024)
++#define CONFIG_SYS_ICACHE_SIZE (32 * 1024)
++#define CONFIG_SYS_CACHELINE_SIZE 32
++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++/*
++ * Supported clock modes
++ * PLL0 clock output is 1000 MHz
++ * PLL1 clock output is 393.219 MHz
++ */
++#define LTQ_CLK_CPU_600_DDR_300 0 /* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_600_DDR_200 1 /* Base PLL0, OCP 3 */
++#define LTQ_CLK_CPU_500_DDR_250 2 /* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_500_DDR_200 3 /* Base PLL0, OCP 2.5 */
++#define LTQ_CLK_CPU_333_DDR_167 4 /* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_167_DDR_167 5 /* Base PLL0, OCP 1 */
++#define LTQ_CLK_CPU_125_DDR_125 6 /* Base PLL0, OCP 1 */
++#define LTQ_CLK_CPU_393_DDR_197 7 /* Base PLL1, OCP 2 */
++#define LTQ_CLK_CPU_197_DDR_197 8 /* Base PLL1, OCP 1 */
++
++/* CPU speed */
++#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_500_DDR_250
++#define CONFIG_SYS_MIPS_TIMER_FREQ 250000000
++#define CONFIG_SYS_HZ 1000
++
++/* RAM */
++#define CONFIG_NR_DRAM_BANKS 1
++#define CONFIG_SYS_SDRAM_BASE 0x80000000
++#define CONFIG_SYS_SDRAM_BASE_UC 0xa0000000
++#define CONFIG_SYS_MEMTEST_START 0x81000000
++#define CONFIG_SYS_MEMTEST_END 0x82000000
++#define CONFIG_SYS_LOAD_ADDR 0x81000000
++#define CONFIG_SYS_INIT_SP_OFFSET (32 * 1024)
++
++/* SRAM */
++#define CONFIG_SYS_SRAM_BASE 0xBE220000
++#define CONFIG_SYS_SRAM_SIZE 0x10000
++
++/* ASC/UART driver and console */
++#define CONFIG_LANTIQ_SERIAL
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/* GPIO */
++#define CONFIG_LANTIQ_GPIO
++#define CONFIG_LTQ_GPIO_MAX_BANKS 3
++#define CONFIG_LTQ_HAS_GPIO_BANK3
++
++/* FLASH driver */
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT 256
++#define CONFIG_SYS_FLASH_BASE 0xB0000000
++#define CONFIG_FLASH_16BIT
++#define CONFIG_SYS_FLASH_CFI
++#define CONFIG_FLASH_CFI_DRIVER
++#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++#define CONFIG_FLASH_SHOW_PROGRESS 50
++#define CONFIG_SYS_FLASH_PROTECTION
++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++
++#define CONFIG_CMD_FLASH
++#else
++#define CONFIG_SYS_NO_FLASH
++#endif /* CONFIG_NOR_FLASH */
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_LANTIQ_SPI
++#define CONFIG_SPI_FLASH
++
++#define CONFIG_CMD_SF
++#define CONFIG_CMD_SPI
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define CONFIG_NAND_LANTIQ
++#define CONFIG_SYS_MAX_NAND_DEVICE 1
++#define CONFIG_SYS_NAND_BASE 0xB4000000
++
++#define CONFIG_CMD_NAND
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
++#define CONFIG_LANTIQ_DMA
++#define CONFIG_LANTIQ_VRX200_SWITCH
++#define CONFIG_PHY_LANTIQ
++
++#define CONFIG_SYS_RX_ETH_BUFFER 8
++#define CONFIG_PHYLIB
++#define CONFIG_MII
++#define CONFIG_UDP_CHECKSUM
++
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#endif
++
++#define CONFIG_SPL_MAX_SIZE (32 * 1024)
++#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024)
++#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024)
++#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024)
++#define CONFIG_SPL_STACK_BSS_IN_SRAM
++
++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \
++ CONFIG_SPL_MAX_SIZE + \
++ CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \
++ CONFIG_SYS_INIT_SP_OFFSET)
++#else
++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \
++ CONFIG_SYS_INIT_SP_OFFSET + \
++ CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \
++ CONFIG_SPL_BSS_MAX_SIZE)
++#endif
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define CONFIG_SYS_TEXT_BASE 0xA0100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_SYS_TEXT_BASE 0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SPL_TEXT_BASE 0xBE220000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SPL_TEXT_BASE 0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C
++#define CONFIG_XWAY_SWAP_BYTES
++#endif
++
++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
++
++#endif /* __VRX200_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/gphy.h
+@@ -0,0 +1,66 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __VRX200_GPHY_H__
++#define __VRX200_GPHY_H__
++
++enum ltq_gphy_clk {
++ /* XTAL 36 MHz input */
++ LTQ_GPHY_CLK_36MHZ_XTAL = 1,
++ /* 25 MHz from PLL0 with divider */
++ LTQ_GPHY_CLK_25MHZ_PLL0 = 2,
++ /* derived from PLL2 output (XTAL is 36 MHz) */
++ LTQ_GPHY_CLK_24MHZ_PLL2 = 3,
++ /* 25 MHz Clock from Pin GPIO3 */
++ LTQ_GPHY_CLK_25MHZ_GPIO3 = 4,
++};
++
++/*
++ * Load PHY11G firmware for VRX200 v1.1 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy11g_a1x_load(ulong addr);
++
++/*
++ * Load PHY11G firmware for VRX200 v1.2 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy11g_a2x_load(ulong addr);
++
++/*
++ * Load PHY22F firmware for VRX200 v1.1 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy22f_a1x_load(ulong addr);
++
++/*
++ * Load PHY22F firmware for VRX200 v1.2 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy22f_a2x_load(ulong addr);
++
++/*
++ * Set clock source of internal GPHYs
++ *
++ * According registers resides in CGU address space. Thus this function
++ * is implemented by the CGU driver.
++ */
++extern void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk);
++
++/*
++ * Boot internal GPHY with id from given RAM address
++ *
++ * According registers resides in RCU address space. Thus this function
++ * is implemented by the RCU driver.
++ */
++extern void ltq_rcu_gphy_boot(unsigned int id, ulong addr);
++
++#endif /* __VRX200_GPHY_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/gpio.h
+@@ -0,0 +1,13 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __VRX200_GPIO_H__
++#define __VRX200_GPIO_H__
++
++#include <asm/lantiq/gpio.h>
++
++#endif /* __VRX200_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/nand.h
+@@ -0,0 +1,14 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#ifndef __VRX200_NAND_H__
++#define __VRX200_NAND_H__
++
++struct nand_chip;
++int ltq_nand_init(struct nand_chip *nand);
++
++#endif /* __VRX200_NAND_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/soc.h
+@@ -0,0 +1,46 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __VRX200_SOC_H__
++#define __VRX200_SOC_H__
++
++#define LTQ_ASC0_BASE 0x1E100400
++#define LTQ_SPI_BASE 0x1E100800
++#define LTQ_GPIO_BASE 0x1E100B00
++#define LTQ_SSIO_BASE 0x1E100BB0
++#define LTQ_ASC1_BASE 0x1E100C00
++#define LTQ_DMA_BASE 0x1E104100
++
++#define LTQ_EBU_BASE 0x1E105300
++#define LTQ_EBU_REGION0_BASE 0x10000000
++#define LTQ_EBU_REGION1_BASE 0x14000000
++#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0)
++
++#define LTQ_SWITCH_BASE 0x1E108000
++#define LTQ_SWITCH_CORE_BASE LTQ_SWITCH_BASE
++#define LTQ_SWITCH_TOP_PDI_BASE LTQ_SWITCH_CORE_BASE
++#define LTQ_SWITCH_BM_PDI_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x40)
++#define LTQ_SWITCH_MAC_PDI_0_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x900)
++#define LTQ_SWITCH_MAC_PDI_X_BASE(x) (LTQ_SWITCH_MAC_PDI_0_BASE + x * 0x30)
++#define LTQ_SWITCH_TOPLEVEL_BASE (LTQ_SWITCH_BASE + 4 * 0xC40)
++#define LTQ_SWITCH_MDIO_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE)
++#define LTQ_SWITCH_MII_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x36)
++#define LTQ_SWITCH_PMAC_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x82)
++
++#define LTQ_PMU_BASE 0x1F102000
++#define LTQ_CGU_BASE 0x1F103000
++#define LTQ_DCDC_BASE 0x1F106A00
++#define LTQ_MPS_BASE 0x1F107000
++#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340)
++#define LTQ_RCU_BASE 0x1F203000
++
++#define LTQ_MC_GLOBAL_BASE 0x1F400000
++#define LTQ_MC_DDR_BASE 0x1F401000
++#define LTQ_MC_DDR_CCR_OFFSET(x) (x * 0x10)
++
++#endif /* __VRX200_SOC_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/switch.h
+@@ -0,0 +1,514 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
++ */
++
++#ifndef __VR9_SWITCH_H__
++#define __VR9_SWITCH_H__
++
++/* Switch core registers */
++struct vr9_switch_core_regs {
++ __be32 swres;
++ /* TODO: implement registers */
++ __be32 rsvd0[0x3f];
++};
++
++/* Switch buffer management registers */
++struct vr9_switch_bm_regs {
++ struct bm_core {
++ __be32 ram_val3; /* RAM value 3 */
++ __be32 ram_val2; /* RAM value 2 */
++ __be32 ram_val1; /* RAM value 1 */
++ __be32 ram_val0; /* RAM value 0 */
++ __be32 ram_addr; /* RAM address */
++ __be32 ram_ctrl; /* RAM access control */
++ __be32 fsqm_gctrl; /* Free segment queue global control */
++ __be32 cons_sel; /* Number of consumed segments */
++ __be32 cons_pkt; /* Number of consumed packet pointers */
++ __be32 gctrl; /* Global control */
++ __be32 queue_gctrl; /* Queue manager global control */
++ /* TODO: implement registers */
++ __be32 rsvd0[0x35];
++ } core;
++
++ struct bm_port {
++ __be32 pcfg; /* Port config */
++ __be32 rmon_ctrl; /* RMON control */
++ } port[13];
++
++ __be32 rsvd0[0x66];
++
++ struct bm_queue {
++ __be32 rsvd0;
++ __be32 pqm_rs; /* Packet queue manager rate shape assignment */
++ } queue[32];
++
++ struct bm_shaper {
++ __be32 ctrl; /* Rate shaper control */
++ __be32 cbs; /* Rate shaper committed burst size */
++ __be32 ibs; /* Rate shaper instantaneous burst size */
++ __be32 cir_ext; /* Rate shaper rate exponent */
++ __be32 cir_mant; /* Rate shaper rate mantissa */
++ } shaper[16];
++
++ __be32 rsvd1[0x2a8];
++};
++
++/* Switch parser and classification engine registers */
++struct vr9_switch_pce_regs {
++ struct pce_core {
++ __be32 tbl_key[16]; /* Table key data */
++ __be32 tbl_mask; /* Table mask */
++ __be32 tbl_val[5]; /* Table value */
++ __be32 tbl_addr; /* Table entry address */
++ __be32 tbl_ctrl; /* Table access control */
++ __be32 tbl_stat; /* Table general status */
++ __be32 age_0; /* Aging counter config 0 */
++ __be32 age_1; /* Aging counter config 1 */
++ __be32 pmap_1; /* Port map (monitoring) */
++ __be32 pmap_2; /* Port map (multicast) */
++ __be32 pmap_3; /* Port map (unknown unicast) */
++ __be32 gctrl_0; /* Global control 0 */
++ __be32 gctrl_1; /* Global control 1 */
++ __be32 tcm_gctrl; /* Three-color marker global control */
++ __be32 igmp_ctrl; /* IGMP control */
++ __be32 igmp_drpm; /* IGMP default router port map */
++ __be32 igmp_age_0; /* IGMP aging 0 */
++ __be32 igmp_age_1; /* IGMP aging 1 */
++ __be32 igmp_stat; /* IGMP status */
++ __be32 wol_gctrl; /* Wake-on-LAN control */
++ __be32 wol_da_0; /* Wake-on-LAN destination address 0 */
++ __be32 wol_da_1; /* Wake-on-LAN destination address 1 */
++ __be32 wol_da_2; /* Wake-on-LAN destination address 2 */
++ __be32 wol_pw_0; /* Wake-on-LAN password 0 */
++ __be32 wol_pw_1; /* Wake-on-LAN password 1 */
++ __be32 wol_pw_2; /* Wake-on-LAN password 2 */
++ __be32 ier_0; /* PCE global interrupt enable 0 */
++ __be32 ier_1; /* PCE global interrupt enable 1 */
++ __be32 isr_0; /* PCE global interrupt status 0 */
++ __be32 isr_1; /* PCE global interrupt status 1 */
++ __be32 parser_stat; /* Parser status */
++ __be32 rsvd0[0x6];
++ } core;
++
++ __be32 rsvd0[0x10];
++
++ struct pce_port {
++ __be32 pctrl_0; /* Port control 0 */
++ __be32 pctrl_1; /* Port control 1 */
++ __be32 pctrl_2; /* Port control 2 */
++ __be32 pctrl_3; /* Port control 3 */
++ __be32 wol_ctrl; /* Wake-on-LAN control */
++ __be32 vlan_ctrl; /* VLAN control */
++ __be32 def_pvid; /* Default port VID */
++ __be32 pstat; /* Port status */
++ __be32 pier; /* Interrupt enable */
++ __be32 pisr; /* Interrupt status */
++ } port[13];
++
++ __be32 rsvd1[0x7e];
++
++ struct pce_meter {
++ /* TODO: implement registers */
++ __be32 rsvd0[0x7];
++ } meter[8];
++
++ __be32 rsvd2[0x308];
++};
++
++static inline unsigned int to_pce_tbl_key_id(unsigned int id)
++{
++ BUG_ON(id > 15);
++
++ return 15 - id;
++}
++
++static inline unsigned int to_pce_tbl_value_id(unsigned int id)
++{
++ BUG_ON(id > 4);
++
++ return 4 - id;
++}
++
++/* Switch ethernet MAC registers */
++struct vr9_switch_mac_regs {
++ struct mac_core {
++ __be32 test; /* MAC test */
++ __be32 pfad_cfg; /* Pause frame source address config */
++ __be32 pfsa_0; /* Pause frame source address 0 */
++ __be32 pfsa_1; /* Pause frame source address 1 */
++ __be32 pfsa_2; /* Pause frame source address 2 */
++ __be32 flen; /* Frame length */
++ __be32 vlan_etype_0; /* VLAN ethertype 0 */
++ __be32 vlan_etype_1; /* VLAN ethertype 1 */
++ __be32 ier; /* Interrupt enable */
++ __be32 isr; /* Interrupt status */
++ __be32 rsvd0[0x36];
++ } core;
++
++ struct mac_port {
++ __be32 pstat; /* Port status */
++ __be32 pisr; /* Interrupt status */
++ __be32 pier; /* Interrupt enable */
++ __be32 ctrl_0; /* Control 0 */
++ __be32 ctrl_1; /* Control 1 */
++ __be32 ctrl_2; /* Control 2 */
++ __be32 ctrl_3; /* Control 3 */
++ __be32 ctrl_4; /* Control 4 */
++ __be32 ctrl_5; /* Control 5 */
++ __be32 rsvd0[0x2];
++ __be32 testen; /* Test enable */
++ } port[13];
++
++ __be32 rsvd0[0xa4];
++};
++
++/* Switch Fetch DMA registers */
++struct vr9_switch_fdma_regs {
++ struct fdma_core {
++ __be32 ctrl; /* FDMA control */
++ __be32 stetype; /* Special tag ethertype control */
++ __be32 vtetype; /* VLAN tag ethertype control */
++ __be32 stat; /* FDMA status */
++ __be32 ier; /* FDMA interrupt enable */
++ __be32 isr; /* FDMA interrupt status */
++ } core;
++
++ __be32 rsvd0[0x3a];
++
++ struct fdma_port {
++ __be32 pctrl; /* Port control */
++ __be32 prio; /* Port priority */
++ __be32 pstat_0; /* Port status 0 */
++ __be32 pstat_1; /* Port status 1 */
++ __be32 tstamp_0; /* Egress time stamp 0 */
++ __be32 tstamp_1; /* Egress time stamp 1 */
++ } port[13];
++
++ __be32 rsvd1[0x72];
++};
++
++/* Switch Store DMA registers */
++struct vr9_switch_sdma_regs {
++ struct sdma_core {
++ __be32 ctrl; /* SDMA Control */
++ __be32 fcthr_1; /* Flow control threshold 1 */
++ __be32 rsvd0;
++ __be32 fcthr_3; /* Flow control threshold 3 */
++ __be32 fcthr_4; /* Flow control threshold 4 */
++ __be32 fcthr_5; /* Flow control threshold 5 */
++ __be32 fcthr_6; /* Flow control threshold 6 */
++ __be32 fcthr_7; /* Flow control threshold 7 */
++ __be32 stat_0; /* SDMA status 0 */
++ __be32 stat_1; /* SDMA status 1 */
++ __be32 stat_2; /* SDMA status 2 */
++ __be32 ier; /* SDMA interrupt enable */
++ __be32 isr; /* SDMA interrupt status */
++ } core;
++
++ __be32 rsvd0[0x73];
++
++ struct sdma_port {
++ __be32 pctrl; /* Port control */
++ __be32 prio; /* Port priority */
++ __be32 pstat_0; /* Port status 0 */
++ __be32 pstat_1; /* Port status 1 */
++ __be32 tstamp_0; /* Ingress time stamp 0 */
++ __be32 tstamp_1; /* Ingress time stamp 1 */
++ } port[13];
++
++ __be32 rsvd1[0x32];
++};
++
++/* Switch MDIO control and status registers */
++struct vr9_switch_mdio_regs {
++ __be32 glob_ctrl; /* Global control 0 */
++ __be32 rsvd0[7];
++ __be32 mdio_ctrl; /* MDIO control */
++ __be32 mdio_read; /* MDIO read data */
++ __be32 mdio_write; /* MDIO write data */
++ __be32 mdc_cfg_0; /* MDC clock configuration 0 */
++ __be32 mdc_cfg_1; /* MDC clock configuration 1 */
++ __be32 rsvd1[0x3];
++ __be32 phy_addr[6]; /* PHY address port 5..0 */
++ __be32 mdio_stat[6]; /* MDIO PHY polling status port 0..5 */
++ __be32 aneg_eee[6]; /* EEE auto-neg overrides port 0..5 */
++ __be32 rsvd2[0x14];
++};
++
++static inline unsigned int to_mdio_phyaddr_id(unsigned int id)
++{
++ BUG_ON(id > 5);
++
++ return 5 - id;
++}
++
++/* Switch xMII control registers */
++struct vr9_switch_mii_regs {
++ __be32 mii_cfg0; /* xMII port 0 configuration */
++ __be32 pcdu0; /* Port 0 clock delay configuration */
++ __be32 mii_cfg1; /* xMII port 1 configuration */
++ __be32 pcdu1; /* Port 1 clock delay configuration */
++ __be32 rsvd0[0x6];
++ __be32 mii_cfg5; /* xMII port 5 configuration */
++ __be32 pcdu5; /* Port 5 clock delay configuration */
++ __be32 rsvd1[0x14];
++ __be32 rxb_ctl_0; /* Port 0 receive buffer control */
++ __be32 rxb_ctl_1; /* Port 1 receive buffer control */
++ __be32 rxb_ctl_5; /* Port 5 receive buffer control */
++ __be32 rsvd2[0x28];
++ __be32 dbg_ctl; /* Debug control */
++};
++
++/* Switch Pseudo-MAC registers */
++struct vr9_switch_pmac_regs {
++ __be32 hd_ctl; /* PMAC header control */
++ __be32 tl; /* PMAC type/length */
++ __be32 sa1; /* PMAC source address 1 */
++ __be32 sa2; /* PMAC source address 2 */
++ __be32 sa3; /* PMAC source address 3 */
++ __be32 da1; /* PMAC destination address 1 */
++ __be32 da2; /* PMAC destination address 2 */
++ __be32 da3; /* PMAC destination address 3 */
++ __be32 vlan; /* PMAC VLAN */
++ __be32 rx_ipg; /* PMAC interpacket gap in RX direction */
++ __be32 st_etype; /* PMAC special tag ethertype */
++ __be32 ewan; /* PMAC ethernet WAN group */
++ __be32 ctl; /* PMAC control */
++ __be32 rsvd0[0x2];
++};
++
++struct vr9_switch_regs {
++ struct vr9_switch_core_regs core;
++ struct vr9_switch_bm_regs bm;
++ struct vr9_switch_pce_regs pce;
++ struct vr9_switch_mac_regs mac;
++ struct vr9_switch_fdma_regs fdma;
++ struct vr9_switch_sdma_regs sdma;
++ struct vr9_switch_mdio_regs mdio;
++ struct vr9_switch_mii_regs mii;
++ struct vr9_switch_pmac_regs pmac;
++};
++
++static inline void *to_pce_tbl_key(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ return &regs->pce.core.tbl_key[to_pce_tbl_key_id(id)];
++}
++
++static inline void *to_pce_tbl_value(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ return &regs->pce.core.tbl_val[to_pce_tbl_value_id(id)];
++}
++
++static inline void *to_mac_ctrl(struct vr9_switch_regs *regs,
++ unsigned int id, unsigned int ctrl)
++{
++ struct mac_port *mac = &regs->mac.port[id];
++
++ switch (ctrl) {
++ case 0:
++ return &mac->ctrl_0;
++ case 1:
++ return &mac->ctrl_1;
++ case 2:
++ return &mac->ctrl_2;
++ case 3:
++ return &mac->ctrl_3;
++ case 4:
++ return &mac->ctrl_4;
++ case 5:
++ return &mac->ctrl_5;
++ default:
++ return NULL;
++ }
++}
++
++static inline void *to_mdio_phyaddr(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ return &regs->mdio.phy_addr[to_mdio_phyaddr_id(id)];
++}
++
++static inline void *to_mii_miicfg(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ switch (id) {
++ case 0:
++ return &regs->mii.mii_cfg0;
++ case 1:
++ return &regs->mii.mii_cfg1;
++ case 5:
++ return &regs->mii.mii_cfg5;
++ default:
++ return NULL;
++ }
++}
++
++static inline void *to_mii_pcdu(struct vr9_switch_regs *regs,
++ unsigned int id)
++{
++ switch (id) {
++ case 0:
++ return &regs->mii.pcdu0;
++ case 1:
++ return &regs->mii.pcdu1;
++ case 5:
++ return &regs->mii.pcdu5;
++ default:
++ return NULL;
++ }
++}
++
++#define VR9_SWITCH_REG_OFFSET(reg) (4 * (reg))
++
++#define BUILD_CHECK_VR9_REG(name, offset) \
++ BUILD_BUG_ON(offsetof(struct vr9_switch_regs, name) != (4 * offset))
++
++static inline void build_check_vr9_registers(void)
++{
++ BUILD_CHECK_VR9_REG(core, 0x0);
++ BUILD_CHECK_VR9_REG(bm.core, 0x40);
++ BUILD_CHECK_VR9_REG(bm.core.queue_gctrl, 0x4a);
++ BUILD_CHECK_VR9_REG(bm.port[0], 0x80);
++ BUILD_CHECK_VR9_REG(bm.queue, 0x100);
++ BUILD_CHECK_VR9_REG(bm.shaper, 0x140);
++ BUILD_CHECK_VR9_REG(pce.core, 0x438);
++ BUILD_CHECK_VR9_REG(pce.core.tbl_ctrl, 0x44f);
++ BUILD_CHECK_VR9_REG(pce.core.parser_stat, 0x469);
++ BUILD_CHECK_VR9_REG(pce.port[0], 0x480);
++ BUILD_CHECK_VR9_REG(pce.meter[0], 0x580);
++ BUILD_CHECK_VR9_REG(mac.core, 0x8c0);
++ BUILD_CHECK_VR9_REG(mac.port[0].pstat, 0x900);
++ BUILD_CHECK_VR9_REG(mac.port[0].ctrl_0, 0x903);
++ BUILD_CHECK_VR9_REG(mac.port[1].pstat, 0x90c);
++ BUILD_CHECK_VR9_REG(mac.port[1].ctrl_0, 0x90f);
++ BUILD_CHECK_VR9_REG(mac.port[2].pstat, 0x918);
++ BUILD_CHECK_VR9_REG(mac.port[2].ctrl_0, 0x91b);
++ BUILD_CHECK_VR9_REG(fdma.core, 0xa40);
++ BUILD_CHECK_VR9_REG(fdma.port[0], 0xa80);
++ BUILD_CHECK_VR9_REG(sdma.core, 0xb40);
++ BUILD_CHECK_VR9_REG(sdma.port[0], 0xbc0);
++ BUILD_CHECK_VR9_REG(mdio, 0xc40);
++ BUILD_CHECK_VR9_REG(mii, (0xc40 + 0x36));
++ BUILD_CHECK_VR9_REG(pmac, (0xc40 + 0x82));
++}
++
++#define BM_GCTRL_F_SRES 1
++
++#define MAC_CTRL0_BM (1 << 12)
++#define MAC_CTRL0_APADEN (1 << 11)
++#define MAC_CTRL0_VPAD2EN (1 << 10)
++#define MAC_CTRL0_VPADEN (1 << 9)
++#define MAC_CTRL0_PADEN (1 << 8)
++#define MAC_CTRL0_FCS (1 << 7)
++#define MAC_CTRL0_FCON_SHIFT 4
++#define MAC_CTRL0_FCON_AUTO (0x0 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_RX (0x1 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_TX (0x2 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_RXTX (0x3 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_NONE (0x4 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FDUP_SHIFT 2
++#define MAC_CTRL0_FDUP_AUTO (0x0 << MAC_CTRL0_FDUP_SHIFT)
++#define MAC_CTRL0_FDUP_EN (0x1 << MAC_CTRL0_FDUP_SHIFT)
++#define MAC_CTRL0_FDUP_DIS (0x3 << MAC_CTRL0_FDUP_SHIFT)
++#define MAC_CTRL0_GMII_AUTO 0x0
++#define MAC_CTRL0_GMII_MII 0x1
++#define MAC_CTRL0_GMII_GMII 0x2
++#define MAC_CTRL0_GMII_GMII_2G 0x3
++
++#define MAC_CTRL1_DEFERMODE (1 << 15)
++#define MAC_CTRL1_SHORTPRE (1 << 8)
++
++#define MAC_CTRL2_MLEN (1 << 3)
++#define MAC_CTRL2_LCHKL (1 << 2)
++#define MAC_CTRL2_LCHKS_DIS 0x0
++#define MAC_CTRL2_LCHKS_UNTAG 0x1
++#define MAC_CTRL2_LCHKS_TAG 0x2
++
++#define PHY_ADDR_LNKST_SHIFT 13
++#define PHY_ADDR_LNKST_AUTO (0x0 << PHY_ADDR_LNKST_SHIFT)
++#define PHY_ADDR_LNKST_UP (0x1 << PHY_ADDR_LNKST_SHIFT)
++#define PHY_ADDR_LNKST_DOWN (0x2 << PHY_ADDR_LNKST_SHIFT)
++#define PHY_ADDR_SPEED_SHIFT 11
++#define PHY_ADDR_SPEED_M10 (0x0 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_SPEED_M100 (0x1 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_SPEED_G1 (0x2 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_SPEED_AUTO (0x3 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_FDUP_SHIFT 9
++#define PHY_ADDR_FDUP_AUTO (0x0 << PHY_ADDR_FDUP_SHIFT)
++#define PHY_ADDR_FDUP_EN (0x1 << PHY_ADDR_FDUP_SHIFT)
++#define PHY_ADDR_FDUP_DIS (0x3 << PHY_ADDR_FDUP_SHIFT)
++#define PHY_ADDR_FCONTX_SHIFT 7
++#define PHY_ADDR_FCONTX_AUTO (0x0 << PHY_ADDR_FCONTX_SHIFT)
++#define PHY_ADDR_FCONTX_EN (0x1 << PHY_ADDR_FCONTX_SHIFT)
++#define PHY_ADDR_FCONTX_DIS (0x3 << PHY_ADDR_FCONTX_SHIFT)
++#define PHY_ADDR_FCONRX_SHIFT 5
++#define PHY_ADDR_FCONRX_AUTO (0x0 << PHY_ADDR_FCONRX_SHIFT)
++#define PHY_ADDR_FCONRX_EN (0x1 << PHY_ADDR_FCONRX_SHIFT)
++#define PHY_ADDR_FCONRX_DIS (0x3 << PHY_ADDR_FCONRX_SHIFT)
++
++#define MII_CFG_RES (1 << 15)
++#define MII_CFG_EN (1 << 14)
++#define MII_CFG_LDCLKDIS (1 << 12)
++#define MII_CFG_MIIRATE_SHIFT 4
++#define MII_CFG_MIIRATE_MASK (0x7 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M2P5 (0x0 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M25 (0x1 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M125 (0x2 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M50 (0x3 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_AUTO (0x4 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIMODE_MASK 0xf
++#define MII_CFG_MIIMODE_MIIP 0x0
++#define MII_CFG_MIIMODE_MIIM 0x1
++#define MII_CFG_MIIMODE_RMIIP 0x2
++#define MII_CFG_MIIMODE_RMIIM 0x3
++#define MII_CFG_MIIMODE_RGMII 0x4
++
++#define PCDU_RXDLY_SHIFT 7
++#define PCDU_RXDLY_MASK (0x7 << PCDU_RXDLY_SHIFT)
++#define PCDU_TXDLY_MASK 0x7
++
++#define PMAC_HD_CTL_FC (1 << 10)
++#define PMAC_HD_CTL_CCRC (1 << 9)
++#define PMAC_HD_CTL_RST (1 << 8)
++#define PMAC_HD_CTL_AST (1 << 7)
++#define PMAC_HD_CTL_RXSH (1 << 6)
++#define PMAC_HD_CTL_RC (1 << 4)
++#define PMAC_HD_CTL_AS (1 << 3)
++#define PMAC_HD_CTL_AC (1 << 2)
++
++#define PCE_PCTRL_0_IGSTEN (1 << 11)
++
++#define FDMA_PCTRL_STEN (1 << 1)
++#define FDMA_PCTRL_EN (1 << 0)
++
++#define SDMA_PCTRL_EN (1 << 0)
++
++#define MDIO_GLOB_CTRL_SE (1 << 15)
++
++#define MDIO_MDC_CFG1_RES (1 << 15)
++#define MDIO_MDC_CFG1_MCEN (1 << 8)
++
++#define MDIO_CTRL_MBUSY (1 << 12)
++#define MDIO_CTRL_OP_READ (1 << 11)
++#define MDIO_CTRL_OP_WRITE (1 << 10)
++#define MDIO_CTRL_PHYAD_SHIFT 5
++#define MDIO_CTRL_PHYAD_MASK (0x1f << MDIO_CTRL_PHYAD_SHIFT)
++#define MDIO_CTRL_REGAD_MASK 0x1f
++
++#endif
+--- a/arch/mips/include/asm/asm.h
++++ b/arch/mips/include/asm/asm.h
+@@ -53,6 +53,7 @@
+ .align 2; \
+ .type symbol, @function; \
+ .ent symbol, 0; \
++ .section .text.symbol,"x"; \
+ symbol: .frame sp, 0, ra
+
+ /*
+@@ -62,7 +63,8 @@ symbol: .frame sp, 0, ra
+ .globl symbol; \
+ .align 2; \
+ .type symbol, @function; \
+- .ent symbol, 0; \
++ .ent symbol, 0; \
++ .section .text.symbol,"x"; \
+ symbol: .frame sp, framesize, rpc
+
+ /*
+--- /dev/null
++++ b/arch/mips/include/asm/gpio.h
+@@ -0,0 +1,7 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ */
++
++#include <asm/arch/gpio.h>
++#include <asm-generic/gpio.h>
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/chipid.h
+@@ -0,0 +1,74 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_CHIPID_H__
++#define __LANTIQ_CHIPID_H__
++
++enum ltq_chip_partnum {
++ LTQ_SOC_UNKNOWN = 0,
++ LTQ_SOC_VRX288_2 = 0x000B, /* VRX288 v1.2 */
++ LTQ_SOC_VRX268_2 = 0x000C, /* VRX268 v1.2 */
++ LTQ_SOC_GRX288_2 = 0x000D, /* GRX288 v1.2 */
++ LTQ_SOC_DANUBE = 0x0129,
++ LTQ_SOC_DANUBE_S = 0x012B,
++ LTQ_SOC_TWINPASS = 0x012D,
++ LTQ_SOC_VRX288 = 0x01C0, /* VRX288 v1.1 */
++ LTQ_SOC_VRX268 = 0x01C2, /* VRX268 v1.1 */
++ LTQ_SOC_GRX288 = 0x01C9, /* GRX288 v1.1 */
++};
++
++extern unsigned int ltq_chip_version_get(void);
++extern unsigned int ltq_chip_partnum_get(void);
++extern const char *ltq_chip_partnum_str(void);
++
++extern void ltq_chip_print_info(void);
++
++#ifdef CONFIG_SOC_XWAY_DANUBE
++static inline int ltq_soc_is_danube(void)
++{
++ return 1;
++}
++#else
++static inline int ltq_soc_is_danube(void)
++{
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_SOC_XWAY_VRX200
++static inline int ltq_soc_is_vrx200(void)
++{
++ return 1;
++}
++
++static inline int ltq_soc_is_vrx200_v1(void)
++{
++ return ltq_chip_version_get() == 1;
++}
++
++static inline int ltq_soc_is_vrx200_v2(void)
++{
++ return ltq_chip_version_get() == 2;
++}
++#else
++static inline int ltq_soc_is_vrx200(void)
++{
++ return 0;
++}
++
++static inline int ltq_soc_is_vrx200_v1(void)
++{
++ return 0;
++}
++
++static inline int ltq_soc_is_vrx200_v2(void)
++{
++ return 0;
++}
++#endif
++
++#endif /* __LANTIQ_CHIPID_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/clk.h
+@@ -0,0 +1,33 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ *
++ * Based on Lantiq port in Linux kernel
++ */
++
++#ifndef __LANTIQ_CLK_H__
++#define __LANTIQ_CLK_H__
++
++/* Symbolic clock speeds */
++enum ltq_clk {
++ CLOCK_83_MHZ = 83333333,
++ CLOCK_111_MHZ = 111111111,
++ CLOCK_125_MHZ = 125000000,
++ CLOCK_133_MHZ = 133333333,
++ CLOCK_166_MHZ = 166666667,
++ CLOCK_197_MHZ = 197000000,
++ CLOCK_333_MHZ = 333333333,
++ CLOCK_393_MHZ = 393219000,
++ CLOCK_500_MHZ = 500000000,
++ CLOCK_600_MHZ = 600000000,
++ CLOCK_1000_MHZ = 1000000000,
++};
++
++extern unsigned long ltq_get_cpu_clock(void);
++extern unsigned long ltq_get_bus_clock(void);
++extern unsigned long ltq_get_io_region_clock(void);
++
++#endif /* __LANTIQ_CLK_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/config.h
+@@ -0,0 +1,166 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_CONFIG_H__
++#define __LANTIQ_CONFIG_H__
++
++/* Memory usage */
++#define CONFIG_SYS_MAXARGS 24
++#define CONFIG_SYS_MALLOC_LEN 1024*1024
++#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024
++
++/* Command line */
++#define CONFIG_SYS_PROMPT CONFIG_MACH_TYPE " # "
++#define CONFIG_SYS_CBSIZE 512
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
++ sizeof(CONFIG_SYS_PROMPT)+16)
++
++#define CONFIG_SYS_HUSH_PARSER
++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
++
++/*
++ * Enable advanced console features on demand to reduce
++ * flash and RAM footprint
++ */
++#if defined(CONFIG_LTQ_ADVANCED_CONSOLE)
++#define CONFIG_SYS_LONGHELP
++#define CONFIG_AUTO_COMPLETE
++#define CONFIG_CMDLINE_EDITING
++#endif
++
++/* SPI flash SPL */
++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_SPL
++#define CONFIG_SPL_SPI_SUPPORT
++#define CONFIG_SPL_SPI_FLASH_SUPPORT
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SPL
++#endif
++
++/* Common SPL */
++#if defined(CONFIG_SPL)
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SPL_LIBGENERIC_SUPPORT
++#define CONFIG_SPL_GPIO_SUPPORT
++#define CONFIG_SPL_START_S_PATH \
++ "arch/mips/cpu/mips32/lantiq-common"
++#define CONFIG_SPL_LDSCRIPT \
++ "arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds"
++#endif
++
++#if defined(CONFIG_LTQ_SPL_CONSOLE)
++#define CONFIG_SPL_SERIAL_SUPPORT
++#define CONFIG_SPL_LIBCOMMON_SUPPORT
++#endif
++
++#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
++#define CONFIG_LZMA
++#define CONFIG_SPL_LZMA_SUPPORT
++#endif
++
++#if defined(CONFIG_LTQ_SPL_COMP_LZO)
++#define CONFIG_LZO
++#define CONFIG_SPL_LZO_SUPPORT
++#endif
++
++/* Basic commands */
++#define CONFIG_CMD_BDI
++#define CONFIG_CMD_EDITENV
++#define CONFIG_CMD_IMI
++#define CONFIG_CMD_MEMORY
++#define CONFIG_CMD_RUN
++#define CONFIG_CMD_SAVEENV
++#define CONFIG_CMD_LOADS
++#define CONFIG_CMD_LOADB
++
++/* Other U-Boot settings */
++#define CONFIG_UBOOT_VERSION
++#define CONFIG_TIMESTAMP
++
++/* Default environment */
++#define CONFIG_ENV_CONSOLEDEV \
++ "consoledev=" CONFIG_CONSOLE_DEV "\0"
++
++#define CONFIG_ENV_ADDCONSOLE \
++ "addconsole=setenv bootargs $bootargs" \
++ " console=$consoledev,$baudrate\0"
++
++#if defined(CONFIG_NET_DEV)
++#define CONFIG_ENV_NETDEV \
++ "netdev=" CONFIG_NET_DEV "\0"
++#else
++#define CONFIG_ENV_NETDEV \
++ "netdev=eth0\0"
++#endif
++
++#define CONFIG_ENV_ADDIP \
++ "addip=setenv bootargs $bootargs" \
++ " ip=$ipaddr:$serverip::::$netdev:off\0"
++
++#define CONFIG_ENV_ADDETH \
++ "addeth=setenv bootargs $bootargs" \
++ " ethaddr=$ethaddr\0"
++
++#define CONFIG_ENV_ADDMACHTYPE \
++ "addmachtype=setenv bootargs $bootargs" \
++ " machtype=" CONFIG_MACH_TYPE "\0"
++
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define CONFIG_ENV_WRITE_UBOOT_NOR \
++ "write-uboot-nor=" \
++ "protect off " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
++ "erase " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
++ "cp.b $fileaddr " __stringify(CONFIG_SYS_FLASH_BASE) " $filesize\0"
++
++#define CONFIG_ENV_LOAD_UBOOT_NOR \
++ "load-uboot-nor=tftpboot u-boot.bin\0" \
++ "load-uboot-norspl=tftpboot u-boot.ltq.norspl\0" \
++ "load-uboot-norspl-lzo=tftpboot u-boot.ltq.lzo.norspl\0" \
++ "load-uboot-norspl-lzma=tftpboot u-boot.ltq.lzma.norspl\0"
++#else
++#define CONFIG_ENV_WRITE_UBOOT_NOR
++#define CONFIG_ENV_LOAD_UBOOT_NOR
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_ENV_SF_PROBE \
++ "sf-probe=sf probe " __stringify(CONFIG_ENV_SPI_CS) " " \
++ __stringify(CONFIG_ENV_SPI_MAX_HZ) " " \
++ __stringify(CONFIG_ENV_SPI_MODE) " \0"
++
++#define CONFIG_ENV_WRITE_UBOOT_SF \
++ "write-uboot-sf=" \
++ "run sf-probe && sf erase 0 +$filesize && " \
++ "sf write $fileaddr 0 $filesize\0"
++
++#define CONFIG_ENV_LOAD_UBOOT_SF \
++ "load-uboot-sfspl=tftpboot u-boot.ltq.sfspl\0" \
++ "load-uboot-sfspl-lzo=tftpboot u-boot.ltq.lzo.sfspl\0" \
++ "load-uboot-sfspl-lzma=tftpboot u-boot.ltq.lzma.sfspl\0"
++#else
++#define CONFIG_ENV_SF_PROBE
++#define CONFIG_ENV_WRITE_UBOOT_SF
++#define CONFIG_ENV_LOAD_UBOOT_SF
++#endif
++
++#define CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_CONSOLEDEV \
++ CONFIG_ENV_ADDCONSOLE \
++ CONFIG_ENV_NETDEV \
++ CONFIG_ENV_ADDIP \
++ CONFIG_ENV_ADDETH \
++ CONFIG_ENV_ADDMACHTYPE \
++ CONFIG_ENV_WRITE_UBOOT_NOR \
++ CONFIG_ENV_LOAD_UBOOT_NOR \
++ CONFIG_ENV_SF_PROBE \
++ CONFIG_ENV_WRITE_UBOOT_SF \
++ CONFIG_ENV_LOAD_UBOOT_SF
++
++#endif /* __LANTIQ_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/cpu.h
+@@ -0,0 +1,35 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#ifndef __LANTIQ_CPU_H__
++#define __LANTIQ_CPU_H__
++
++enum ltq_boot_select {
++ BOOT_NOR,
++ BOOT_NOR_NO_BOOTROM,
++ BOOT_UART,
++ BOOT_UART_NO_EEPROM,
++ BOOT_SPI,
++ BOOT_NAND,
++ BOOT_PCI,
++ BOOT_MII0,
++ BOOT_RMII0,
++ BOOT_RGMII1,
++ BOOT_UNKNOWN,
++};
++
++enum ltq_boot_select ltq_boot_select(void);
++const char *ltq_boot_select_str(void);
++
++void ltq_pmu_init(void);
++void ltq_ebu_init(void);
++void ltq_gpio_init(void);
++
++void ltq_pll_init(void);
++void ltq_dcdc_init(unsigned int dig_ref);
++
++#endif /* __LANTIQ_CPU_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/dma.h
+@@ -0,0 +1,95 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_DMA_H__
++#define __LANTIQ_DMA_H__
++
++enum ltq_dma_endianess {
++ LTQ_DMA_ENDIANESS_B0_B1_B2_B3, /* No byte swapping */
++ LTQ_DMA_ENDIANESS_B1_B0_B3_B2, /* B0B1B2B3 => B1B0B3B2 */
++ LTQ_DMA_ENDIANESS_B2_B3_B0_B1, /* B0B1B2B3 => B2B3B0B1 */
++ LTQ_DMA_ENDIANESS_B3_B2_B1_B0, /* B0B1B2B3 => B3B2B1B0 */
++};
++
++enum ltq_dma_burst_len {
++ LTQ_DMA_BURST_2WORDS = 1,
++ LTQ_DMA_BURST_4WORDS = 2,
++ LTQ_DMA_BURST_8WORDS = 3,
++};
++
++struct ltq_dma_desc {
++ u32 ctl;
++ u32 addr;
++};
++
++struct ltq_dma_channel {
++ struct ltq_dma_device *dev;
++ u8 chan_no;
++ u8 class;
++ u16 num_desc;
++ struct ltq_dma_desc *desc_base;
++ void *mem_base;
++ u32 dma_addr;
++};
++
++struct ltq_dma_device {
++ enum ltq_dma_endianess rx_endian_swap;
++ enum ltq_dma_endianess tx_endian_swap;
++ enum ltq_dma_burst_len rx_burst_len;
++ enum ltq_dma_burst_len tx_burst_len;
++ struct ltq_dma_channel rx_chan;
++ struct ltq_dma_channel tx_chan;
++ u8 port;
++};
++
++/**
++ * Initialize DMA hardware and driver
++ */
++void ltq_dma_init(void);
++
++/**
++ * Register given DMA client context
++ *
++ * @returns 0 on success, negative value otherwise
++ */
++int ltq_dma_register(struct ltq_dma_device *dev);
++
++/**
++ * Reset and halt all channels related to given DMA client
++ */
++void ltq_dma_reset(struct ltq_dma_device *dev);
++void ltq_dma_enable(struct ltq_dma_device *dev);
++void ltq_dma_disable(struct ltq_dma_device *dev);
++
++/**
++ * Map RX DMA descriptor to memory region
++ *
++ * @returns 0 on success, negative value otherwise
++ */
++int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len);
++
++/**
++ * Check if new data is available.
++ *
++ * @returns length of received data, 0 otherwise
++ */
++int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index);
++
++int ltq_dma_rx_length(struct ltq_dma_device *dev, int index);
++
++/**
++ * Map TX DMA descriptor to memory region
++ *
++ * @returns 0 on success, negative value otherwise
++ */
++int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
++ unsigned long timeout);
++
++int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
++ unsigned long timeout);
++
++#endif /* __LANTIQ_DMA_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/eth.h
+@@ -0,0 +1,36 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_ETH_H__
++#define __LANTIQ_ETH_H__
++
++#include <phy.h>
++
++enum LTQ_ETH_PORT_FLAGS {
++ LTQ_ETH_PORT_NONE = 0,
++ LTQ_ETH_PORT_PHY = 1,
++ LTQ_ETH_PORT_SWITCH = (1 << 1),
++ LTQ_ETH_PORT_MAC = (1 << 2),
++};
++
++struct ltq_eth_port_config {
++ u8 num;
++ u8 phy_addr;
++ u16 flags;
++ phy_interface_t phy_if;
++ u8 rgmii_rx_delay;
++ u8 rgmii_tx_delay;
++};
++
++struct ltq_eth_board_config {
++ const struct ltq_eth_port_config *ports;
++ int num_ports;
++};
++
++extern int ltq_eth_initialize(const struct ltq_eth_board_config *board_config);
++
++#endif /* __LANTIQ_ETH_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/gpio.h
+@@ -0,0 +1,51 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_GPIO_H__
++#define __LANTIQ_GPIO_H__
++
++enum ltq_gpio_dir {
++ GPIO_DIR_IN = 0,
++ GPIO_DIR_OUT
++};
++
++enum ltq_gpio_od {
++ GPIO_OD_ACTIVE = 0,
++ GPIO_OD_NORMAL
++};
++
++enum ltq_gpio_altsel {
++ GPIO_ALTSEL_CLR = 0,
++ GPIO_ALTSEL_SET
++};
++
++extern int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir);
++extern int gpio_set_opendrain(unsigned gpio, int od);
++
++static inline int gpio_to_port(unsigned gpio)
++{
++ return gpio >> 4;
++}
++
++static inline int gpio_to_pin(unsigned gpio)
++{
++ return gpio & 0xF;
++}
++
++static inline int gpio_to_bit(unsigned gpio)
++{
++ return 1 << gpio_to_pin(gpio);
++}
++
++static inline int gpio_to_gpio(unsigned port, unsigned pin)
++{
++ return (port << 4) | (pin & 0xF);
++}
++
++#include <asm-generic/gpio.h>
++
++#endif /* __LANTIQ_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/io.h
+@@ -0,0 +1,38 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_IO_H__
++#define __LANTIQ_IO_H__
++
++#include <asm/io.h>
++
++#define ltq_readb(a) __raw_readb(a)
++#define ltq_writeb(a, v) __raw_writeb(v, a)
++
++#define ltq_readl(a) __raw_readl(a)
++#define ltq_writel(a, v) __raw_writel(v, a)
++
++#define ltq_clrbits(a, clear) \
++ ltq_writel(a, ltq_readl(a) & ~(clear))
++
++#define ltq_setbits(a, set) \
++ ltq_writel(a, ltq_readl(a) | (set))
++
++#define ltq_clrsetbits(a, clear, set) \
++ ltq_writel(a, (ltq_readl(a) & ~(clear)) | (set))
++
++static inline void ltq_reg_dump(const void *addr, const char *desc)
++{
++ u32 data;
++
++ data = ltq_readl(addr);
++ printf("ltq_reg_dump: %s 0x%p = 0x%08x\n",
++ desc, addr, data);
++}
++
++#endif /* __LANTIQ_IO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/pm.h
+@@ -0,0 +1,22 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_PM_H__
++#define __LANTIQ_PM_H__
++
++enum ltq_pm_modules {
++ LTQ_PM_CORE,
++ LTQ_PM_DMA,
++ LTQ_PM_ETH,
++ LTQ_PM_SPI,
++};
++
++u32 ltq_pm_map(enum ltq_pm_modules module);
++int ltq_pm_enable(enum ltq_pm_modules module);
++int ltq_pm_disable(enum ltq_pm_modules module);
++
++#endif /* __LANTIQ_PM_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/reset.h
+@@ -0,0 +1,38 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __LANTIQ_RESET_H__
++#define __LANTIQ_RESET_H__
++
++enum ltq_reset_modules {
++ LTQ_RESET_CORE,
++ LTQ_RESET_DMA,
++ LTQ_RESET_ETH,
++ LTQ_RESET_PHY,
++ LTQ_RESET_HARD,
++ LTQ_RESET_SOFT,
++};
++
++extern u32 ltq_reset_map(enum ltq_reset_modules module);
++extern int ltq_reset_activate(enum ltq_reset_modules module);
++extern int ltq_reset_deactivate(enum ltq_reset_modules module);
++
++static inline int ltq_reset_once(enum ltq_reset_modules module, ulong usec)
++{
++ int ret;
++
++ ret = ltq_reset_activate(module);
++ if (ret)
++ return ret;
++
++ __udelay(usec);
++ ret = ltq_reset_deactivate(module);
++
++ return ret;
++}
++
++#endif /* __LANTIQ_RESET_H__ */
+--- a/arch/mips/include/asm/mipsregs.h
++++ b/arch/mips/include/asm/mipsregs.h
+@@ -46,7 +46,10 @@
+ #define CP0_ENTRYLO1 $3
+ #define CP0_CONF $3
+ #define CP0_CONTEXT $4
++#define CP0_CONTEXTCONFIG $4,1
++#define CP0_USERLOCAL $4,1
+ #define CP0_PAGEMASK $5
++#define CP0_PAGEGRAIN $5,1
+ #define CP0_WIRED $6
+ #define CP0_INFO $7
+ #define CP0_BADVADDR $8
+@@ -54,10 +57,19 @@
+ #define CP0_ENTRYHI $10
+ #define CP0_COMPARE $11
+ #define CP0_STATUS $12
++#define CP0_INTCTL $12,1
++#define CP0_SRSCTL $12,2
++#define CP0_SRSMAP $12,3
++#define CP0_SRSHIGH $12,4
+ #define CP0_CAUSE $13
+ #define CP0_EPC $14
+ #define CP0_PRID $15
++#define CP0_EBASE $15,1
+ #define CP0_CONFIG $16
++#define CP0_CONFIG1 $16,1
++#define CP0_CONFIG2 $16,2
++#define CP0_CONFIG3 $16,3
++#define CP0_CONFIG7 $16,7
+ #define CP0_LLADDR $17
+ #define CP0_WATCHLO $18
+ #define CP0_WATCHHI $19
+@@ -70,7 +82,17 @@
+ #define CP0_ECC $26
+ #define CP0_CACHEERR $27
+ #define CP0_TAGLO $28
++#define CP0_ITAGLO $28
++#define CP0_IDATALO $28,1
++#define CP0_DTAGLO $28,2
++#define CP0_DDATALO $28,3
++#define CP0_L23TAGLO $28,4
++#define CP0_L23DATALO $28,5
+ #define CP0_TAGHI $29
++#define CP0_IDATAHI $29,1
++#define CP0_DTAGHI $29,2
++#define CP0_L23TAGHI $29,4
++#define CP0_L23DATAHI $29,5
+ #define CP0_ERROREPC $30
+ #define CP0_DESAVE $31
+
+@@ -395,6 +417,12 @@
+ #define CAUSEF_BD (_ULCAST_(1) << 31)
+
+ /*
++ * Bits in the coprocessor 0 EBase register.
++ */
++#define EBASEB_CPUNUM 0
++#define EBASEF_CPUNUM (_ULCAST_(1023))
++
++/*
+ * Bits in the coprocessor 0 config register.
+ */
+ /* Generic bits. */
+--- a/arch/mips/include/asm/u-boot-mips.h
++++ b/arch/mips/include/asm/u-boot-mips.h
+@@ -9,3 +9,4 @@ extern ulong uboot_end_data;
+ extern ulong uboot_end;
+
+ extern int incaip_set_cpuclk(void);
++extern int arch_cpu_init(void);
+--- a/arch/mips/lib/board.c
++++ b/arch/mips/lib/board.c
+@@ -50,6 +50,16 @@ static char *failed = "*** failed ***\n"
+ */
+ const unsigned long mips_io_port_base = -1;
+
++int __arch_cpu_init(void)
++{
++ /*
++ * Nothing to do in this dummy implementation
++ */
++ return 0;
++}
++int arch_cpu_init(void)
++ __attribute__((weak, alias("__arch_cpu_init")));
++
+ int __board_early_init_f(void)
+ {
+ /*
+@@ -123,6 +133,7 @@ static int init_baudrate(void)
+ typedef int (init_fnc_t)(void);
+
+ init_fnc_t *init_sequence[] = {
++ arch_cpu_init,
+ board_early_init_f,
+ timer_init,
+ env_init, /* initialize environment */
+--- /dev/null
++++ b/board/lantiq/easy50712/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/lantiq/easy50712/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/lantiq/easy50712/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define MC_DC00_VALUE 0x1B1B
++#define MC_DC01_VALUE 0x0
++#define MC_DC02_VALUE 0x0
++#define MC_DC03_VALUE 0x0
++#define MC_DC04_VALUE 0x0
++#define MC_DC05_VALUE 0x200
++#define MC_DC06_VALUE 0x605
++#define MC_DC07_VALUE 0x303
++#define MC_DC08_VALUE 0x102
++#define MC_DC09_VALUE 0x70a
++#define MC_DC10_VALUE 0x203
++#define MC_DC11_VALUE 0xc02
++#define MC_DC12_VALUE 0x1C8
++#define MC_DC13_VALUE 0x1
++#define MC_DC14_VALUE 0x0
++#define MC_DC15_VALUE 0x13c
++#define MC_DC16_VALUE 0xC800
++#define MC_DC17_VALUE 0xd
++#define MC_DC18_VALUE 0x300
++#define MC_DC19_VALUE 0x200
++#define MC_DC20_VALUE 0xA04
++#define MC_DC21_VALUE 0xd00
++#define MC_DC22_VALUE 0xd0d
++#define MC_DC23_VALUE 0x0
++#define MC_DC24_VALUE 0x62
++#define MC_DC25_VALUE 0x0
++#define MC_DC26_VALUE 0x0
++#define MC_DC27_VALUE 0x0
++#define MC_DC28_VALUE 0x510
++#define MC_DC29_VALUE 0x2d89
++#define MC_DC30_VALUE 0x8300
++#define MC_DC31_VALUE 0x0
++#define MC_DC32_VALUE 0x0
++#define MC_DC33_VALUE 0x0
++#define MC_DC34_VALUE 0x0
++#define MC_DC35_VALUE 0x0
++#define MC_DC36_VALUE 0x0
++#define MC_DC37_VALUE 0x0
++#define MC_DC38_VALUE 0x0
++#define MC_DC39_VALUE 0x0
++#define MC_DC40_VALUE 0x0
++#define MC_DC41_VALUE 0x0
++#define MC_DC42_VALUE 0x0
++#define MC_DC43_VALUE 0x0
++#define MC_DC44_VALUE 0x0
++#define MC_DC45_VALUE 0x500
++#define MC_DC46_VALUE 0x0
+--- /dev/null
++++ b/board/lantiq/easy50712/easy50712.c
+@@ -0,0 +1,106 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <spi.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++static void gpio_init(void)
++{
++ /* SPI/CS output (low-active) for serial flash */
++ gpio_direction_output(22, 1);
++
++ /* enable CLK_OUT2 for external switch */
++ gpio_set_altfunc(3, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++ gpio_init();
++
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* MAC0: Lantiq ADM6996I switch */
++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device adm6996i_dev = {
++ .name = "adm6996i",
++ .cpu_port = 5,
++ .port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++ /* Deactivate HRST line to release reset of ADM6996I switch */
++ ltq_reset_once(LTQ_RESET_HARD, 200000);
++
++ /* ADM6996I needs some time to come out of reset */
++ __udelay(50000);
++
++ return switch_device_register(&adm6996i_dev);
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++ if (bus)
++ return 0;
++
++ switch (cs) {
++ case 2:
++ return 1;
++ default:
++ return 0;
++ }
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 2:
++ gpio_set_value(22, 0);
++ break;
++ default:
++ break;
++ }
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 2:
++ gpio_set_value(22, 1);
++ break;
++ default:
++ break;
++ }
++}
+--- /dev/null
++++ b/board/lantiq/easy80920/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/lantiq/easy80920/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/lantiq/easy80920/ddr_settings.h
+@@ -0,0 +1,70 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define MC_CCR00_VALUE 0x101
++#define MC_CCR01_VALUE 0x1000100
++#define MC_CCR02_VALUE 0x1010000
++#define MC_CCR03_VALUE 0x101
++#define MC_CCR04_VALUE 0x1000000
++#define MC_CCR05_VALUE 0x1000101
++#define MC_CCR06_VALUE 0x1000100
++#define MC_CCR07_VALUE 0x1010000
++#define MC_CCR08_VALUE 0x1000101
++#define MC_CCR09_VALUE 0x0
++#define MC_CCR10_VALUE 0x2000100
++#define MC_CCR11_VALUE 0x2000300
++#define MC_CCR12_VALUE 0x30000
++#define MC_CCR13_VALUE 0x202
++#define MC_CCR14_VALUE 0x7080A0F
++#define MC_CCR15_VALUE 0x2040F
++#define MC_CCR16_VALUE 0x40000
++#define MC_CCR17_VALUE 0x70102
++#define MC_CCR18_VALUE 0x4020002
++#define MC_CCR19_VALUE 0x30302
++#define MC_CCR20_VALUE 0x8000700
++#define MC_CCR21_VALUE 0x40F020A
++#define MC_CCR22_VALUE 0x0
++#define MC_CCR23_VALUE 0xC020000
++#define MC_CCR24_VALUE 0x4401B04
++#define MC_CCR25_VALUE 0x0
++#define MC_CCR26_VALUE 0x0
++#define MC_CCR27_VALUE 0x6420000
++#define MC_CCR28_VALUE 0x0
++#define MC_CCR29_VALUE 0x0
++#define MC_CCR30_VALUE 0x798
++#define MC_CCR31_VALUE 0x0
++#define MC_CCR32_VALUE 0x0
++#define MC_CCR33_VALUE 0x650000
++#define MC_CCR34_VALUE 0x200C8
++#define MC_CCR35_VALUE 0x1D445D
++#define MC_CCR36_VALUE 0xC8
++#define MC_CCR37_VALUE 0xC351
++#define MC_CCR38_VALUE 0x0
++#define MC_CCR39_VALUE 0x141F04
++#define MC_CCR40_VALUE 0x142704
++#define MC_CCR41_VALUE 0x141b42
++#define MC_CCR42_VALUE 0x141b42
++#define MC_CCR43_VALUE 0x566504
++#define MC_CCR44_VALUE 0x566504
++#define MC_CCR45_VALUE 0x565F17
++#define MC_CCR46_VALUE 0x565F17
++#define MC_CCR47_VALUE 0x0
++#define MC_CCR48_VALUE 0x0
++#define MC_CCR49_VALUE 0x0
++#define MC_CCR50_VALUE 0x0
++#define MC_CCR51_VALUE 0x0
++#define MC_CCR52_VALUE 0x133
++#define MC_CCR53_VALUE 0xF3014B27
++#define MC_CCR54_VALUE 0xF3014B27
++#define MC_CCR55_VALUE 0xF3014B27
++#define MC_CCR56_VALUE 0xF3014B27
++#define MC_CCR57_VALUE 0x7800301
++#define MC_CCR58_VALUE 0x7800301
++#define MC_CCR59_VALUE 0x7800301
++#define MC_CCR60_VALUE 0x7800301
++#define MC_CCR61_VALUE 0x4
+--- /dev/null
++++ b/board/lantiq/easy80920/easy80920.c
+@@ -0,0 +1,139 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <spi.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SPL_BUILD)
++#define do_gpio_init 1
++#define do_pll_init 1
++#define do_dcdc_init 0
++#elif defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init 1
++#define do_pll_init 0
++#define do_dcdc_init 1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define do_gpio_init 1
++#define do_pll_init 1
++#define do_dcdc_init 1
++#else
++#define do_gpio_init 0
++#define do_pll_init 0
++#define do_dcdc_init 1
++#endif
++
++static void gpio_init(void)
++{
++ /* SPI CS 0.4 to serial flash */
++ gpio_direction_output(10, 1);
++
++ /* EBU.FL_CS1 as output for NAND CE */
++ gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* EBU.FL_A23 as output for NAND CLE */
++ gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* EBU.FL_A24 as output for NAND ALE */
++ gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* GPIO 3.0 as input for NAND Ready Busy */
++ gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++ /* GPIO 3.1 as output for NAND Read */
++ gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++ if (do_gpio_init)
++ gpio_init();
++
++ if (do_pll_init)
++ ltq_pll_init();
++
++ if (do_dcdc_init)
++ ltq_dcdc_init(0x7F);
++
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++ /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
++ { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++ /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++ /* GMAC3: unused */
++ { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++ /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
++ { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++ const ulong fw_addr = 0x80FF0000;
++
++ ltq_gphy_phy11g_a1x_load(fw_addr);
++
++ ltq_cgu_gphy_clk_src(clk);
++
++ ltq_rcu_gphy_boot(0, fw_addr);
++ ltq_rcu_gphy_boot(1, fw_addr);
++
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++ if (bus)
++ return 0;
++
++ if (cs == 4)
++ return 1;
++
++ return 0;
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 4:
++ gpio_set_value(10, 0);
++ break;
++ default:
++ break;
++ }
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 4:
++ gpio_set_value(10, 1);
++ break;
++ default:
++ break;
++ }
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -444,10 +444,17 @@ dbau1500 mips
+ dbau1550 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550
+ dbau1550_el mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN
+ pb1000 mips mips32 pb1x00 - au1x00 pb1x00:PB1000
++easy50712_nor mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NOR
++easy50712_norspl mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NORSPL
++easy50712_ram mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_RAM
+ incaip mips mips32 incaip - incaip
+ incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000
+ incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000
+ incaip_150MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=150000000
++easy80920_nor mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NOR
++easy80920_norspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NORSPL
++easy80920_ram mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_RAM
++easy80920_sfspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_SFSPL
+ qi_lb60 mips xburst qi_lb60 qi
+ adp-ag101 nds32 n1213 adp-ag101 AndesTech ag101
+ adp-ag101p nds32 n1213 adp-ag101p AndesTech ag101
+--- a/drivers/dma/Makefile
++++ b/drivers/dma/Makefile
+@@ -28,6 +28,7 @@ LIB := $(obj)libdma.o
+ COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
+ COBJS-$(CONFIG_APBH_DMA) += apbh_dma.o
+ COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
++COBJS-$(CONFIG_LANTIQ_DMA) += lantiq_dma.o
+ COBJS-$(CONFIG_OMAP3_DMA) += omap3_dma.o
+
+ COBJS := $(COBJS-y)
+--- /dev/null
++++ b/drivers/dma/lantiq_dma.c
+@@ -0,0 +1,388 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <watchdog.h>
++#include <linux/compiler.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/dma.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/arch/soc.h>
++#include <asm/processor.h>
++
++#define DMA_CTRL_PKTARB (1 << 31)
++#define DMA_CTRL_MBRSTARB (1 << 30)
++#define DMA_CTRL_MBRSTCNT_SHIFT 16
++#define DMA_CTRL_MBRSTCNT_MASK (0x3ff << DMA_CTRL_MBRSTCNT_SHIFT)
++#define DMA_CTRL_DRB (1 << 8)
++#define DMA_CTRL_RESET (1 << 0)
++
++#define DMA_CPOLL_EN (1 << 31)
++#define DMA_CPOLL_CNT_SHIFT 4
++#define DMA_CPOLL_CNT_MASK (0xFFF << DMA_CPOLL_CNT_SHIFT)
++
++#define DMA_CCTRL_TXWGT_SHIFT 16
++#define DMA_CCTRL_TXWGT_MASK (0x3 << DMA_CCTRL_TXWGT_SHIFT)
++#define DMA_CCTRL_CLASS_SHIFT 9
++#define DMA_CCTRL_CLASS_MASK (0x3 << DMA_CCTRL_CLASS_SHIFT)
++#define DMA_CCTRL_RST (1 << 1)
++#define DMA_CCTRL_ONOFF (1 << 0)
++
++#define DMA_PCTRL_TXBL_SHIFT 4
++#define DMA_PCTRL_TXBL_2WORDS (1 << DMA_PCTRL_TXBL_SHIFT)
++#define DMA_PCTRL_TXBL_4WORDS (2 << DMA_PCTRL_TXBL_SHIFT)
++#define DMA_PCTRL_TXBL_8WORDS (3 << DMA_PCTRL_TXBL_SHIFT)
++#define DMA_PCTRL_RXBL_SHIFT 2
++#define DMA_PCTRL_RXBL_2WORDS (1 << DMA_PCTRL_RXBL_SHIFT)
++#define DMA_PCTRL_RXBL_4WORDS (2 << DMA_PCTRL_RXBL_SHIFT)
++#define DMA_PCTRL_RXBL_8WORDS (3 << DMA_PCTRL_RXBL_SHIFT)
++#define DMA_PCTRL_TXENDI_SHIFT 10
++#define DMA_PCTRL_TXENDI_MASK (0x3 << DMA_PCTRL_TXENDI_SHIFT)
++#define DMA_PCTRL_RXENDI_SHIFT 8
++#define DMA_PCTRL_RXENDI_MASK (0x3 << DMA_PCTRL_RXENDI_SHIFT)
++
++#define DMA_DESC_OWN (1 << 31)
++#define DMA_DESC_C (1 << 30)
++#define DMA_DESC_SOP (1 << 29)
++#define DMA_DESC_EOP (1 << 28)
++#define DMA_DESC_TX_OFFSET(x) ((x & 0x1f) << 23)
++#define DMA_DESC_RX_OFFSET(x) ((x & 0x3) << 23)
++#define DMA_DESC_LENGTH(x) (x & 0xffff)
++
++#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
++
++struct ltq_dma_regs {
++ u32 clc; /* Clock control */
++ u32 rsvd0;
++ u32 id; /* Identification */
++ u32 rsvd1;
++ u32 ctrl; /* Control */
++ u32 cpoll; /* Channel polling */
++ u32 cs; /* Channel select */
++ u32 cctrl; /* Channel control */
++ u32 cdba; /* Channel descriptor base address */
++ u32 cdlen; /* Channel descriptor length */
++ u32 cis; /* Channel interrupt status */
++ u32 cie; /* Channel interrupt enable */
++ u32 cgbl; /* Channel global buffer length */
++ u32 cdptnrd; /* Current descriptor pointer */
++ u32 rsvd2[2];
++ u32 ps; /* Port select */
++ u32 pctrl; /* Port control */
++ u32 rsvd3[43];
++ u32 irnen; /* Interrupt node enable */
++ u32 irncr; /* Interrupt node control */
++ u32 irnicr; /* Interrupt capture */
++};
++
++static struct ltq_dma_regs *ltq_dma_regs =
++ (struct ltq_dma_regs *) CKSEG1ADDR(LTQ_DMA_BASE);
++
++static inline unsigned long ltq_dma_addr_to_virt(u32 dma_addr)
++{
++ return KSEG0ADDR(dma_addr);
++}
++
++static inline u32 ltq_virt_to_dma_addr(void *addr)
++{
++ return CPHYSADDR(addr);
++}
++
++static inline int ltq_dma_burst_align(enum ltq_dma_burst_len burst_len)
++{
++ switch (burst_len) {
++ case LTQ_DMA_BURST_2WORDS:
++ return 2 * 4;
++ case LTQ_DMA_BURST_4WORDS:
++ return 4 * 4;
++ case LTQ_DMA_BURST_8WORDS:
++ return 8 * 4;
++ }
++
++ return 0;
++}
++
++static inline void ltq_dma_sync(void)
++{
++ __asm__ __volatile__("sync");
++}
++
++static inline void ltq_dma_dcache_wb_inv(const void *ptr, size_t size)
++{
++ unsigned long addr = (unsigned long) ptr;
++
++ flush_dcache_range(addr, addr + size);
++ ltq_dma_sync();
++}
++
++static inline void ltq_dma_dcache_inv(const void *ptr, size_t size)
++{
++ unsigned long addr = (unsigned long) ptr;
++
++ invalidate_dcache_range(addr, addr + size);
++}
++
++void ltq_dma_init(void)
++{
++ /* Power up DMA */
++ ltq_pm_enable(LTQ_PM_DMA);
++
++ /* Reset DMA */
++ ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_RESET);
++
++ /* Disable and clear all interrupts */
++ ltq_writel(&ltq_dma_regs->irnen, 0);
++ ltq_writel(&ltq_dma_regs->irncr, 0xFFFFF);
++
++#if 0
++ /* Enable packet arbitration */
++ ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_PKTARB);
++#endif
++
++#if 0
++ /* Enable descriptor read back */
++ ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_DRB);
++#endif
++
++ /* Enable polling for descriptor fetching for all channels */
++ ltq_writel(&ltq_dma_regs->cpoll, DMA_CPOLL_EN |
++ (4 << DMA_CPOLL_CNT_SHIFT));
++}
++
++static void ltq_dma_channel_reset(struct ltq_dma_channel *chan)
++{
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
++}
++
++static void ltq_dma_channel_enable(struct ltq_dma_channel *chan)
++{
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
++}
++
++static void ltq_dma_channel_disable(struct ltq_dma_channel *chan)
++{
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_clrbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
++}
++
++static void ltq_dma_port_init(struct ltq_dma_device *dev)
++{
++ u32 pctrl;
++
++ pctrl = dev->tx_endian_swap << DMA_PCTRL_TXENDI_SHIFT;
++ pctrl |= dev->rx_endian_swap << DMA_PCTRL_RXENDI_SHIFT;
++ pctrl |= dev->tx_burst_len << DMA_PCTRL_TXBL_SHIFT;
++ pctrl |= dev->rx_burst_len << DMA_PCTRL_RXBL_SHIFT;
++
++ ltq_writel(&ltq_dma_regs->ps, dev->port);
++ ltq_writel(&ltq_dma_regs->pctrl, pctrl);
++}
++
++static int ltq_dma_alloc_descriptors(struct ltq_dma_device *dev,
++ struct ltq_dma_channel *chan)
++{
++ size_t size;
++ void *desc_base;
++
++ size = ALIGN(sizeof(struct ltq_dma_desc) * chan->num_desc +
++ ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
++
++ chan->mem_base = malloc(size);
++ if (!chan->mem_base)
++ return 1;
++
++ memset(chan->mem_base, 0, size);
++ ltq_dma_dcache_wb_inv(chan->mem_base, size);
++
++ desc_base = PTR_ALIGN(chan->mem_base, ARCH_DMA_MINALIGN);
++
++ debug("DMA: mem %p, desc %p\n", chan->mem_base, desc_base);
++
++ /* Align descriptor base to 8 bytes */
++ chan->desc_base = (void *) CKSEG1ADDR(desc_base);
++ chan->dma_addr = CPHYSADDR(desc_base);
++ chan->dev = dev;
++
++ debug("DMA: desc_base %p, size %u\n", chan->desc_base, size);
++
++ /* Configure hardware with location of descriptor list */
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_writel(&ltq_dma_regs->cdba, chan->dma_addr);
++ ltq_writel(&ltq_dma_regs->cdlen, chan->num_desc);
++ ltq_writel(&ltq_dma_regs->cctrl, (3 << DMA_CCTRL_TXWGT_SHIFT) |
++ (chan->class << DMA_CCTRL_CLASS_SHIFT));
++ ltq_writel(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
++
++ return 0;
++}
++
++static void ltq_dma_free_descriptors(struct ltq_dma_channel *chan)
++{
++ ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++ ltq_writel(&ltq_dma_regs->cdba, 0);
++ ltq_writel(&ltq_dma_regs->cdlen, 0);
++
++ ltq_dma_channel_reset(chan);
++
++ free(chan->mem_base);
++}
++
++int ltq_dma_register(struct ltq_dma_device *dev)
++{
++ int ret;
++
++ ltq_dma_port_init(dev);
++
++ ret = ltq_dma_alloc_descriptors(dev, &dev->rx_chan);
++ if (ret)
++ return ret;
++
++ ret = ltq_dma_alloc_descriptors(dev, &dev->tx_chan);
++ if (ret) {
++ ltq_dma_free_descriptors(&dev->rx_chan);
++ return ret;
++ }
++
++ return 0;
++}
++
++void ltq_dma_reset(struct ltq_dma_device *dev)
++{
++ ltq_dma_channel_reset(&dev->rx_chan);
++ ltq_dma_channel_reset(&dev->tx_chan);
++}
++
++void ltq_dma_enable(struct ltq_dma_device *dev)
++{
++ ltq_dma_channel_enable(&dev->rx_chan);
++ ltq_dma_channel_enable(&dev->tx_chan);
++}
++
++void ltq_dma_disable(struct ltq_dma_device *dev)
++{
++ ltq_dma_channel_disable(&dev->rx_chan);
++ ltq_dma_channel_disable(&dev->tx_chan);
++}
++
++int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len)
++{
++ struct ltq_dma_channel *chan = &dev->rx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++ u32 dma_addr = ltq_virt_to_dma_addr(data);
++ unsigned int offset;
++
++ offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
++
++ ltq_dma_dcache_inv(data, len);
++
++#if 0
++ printf("%s: index %d, data %p, dma_addr %08x, offset %u, len %d\n",
++ __func__, index, data, dma_addr, offset, len);
++#endif
++
++
++ desc->addr = dma_addr - offset;
++ desc->ctl = DMA_DESC_OWN | DMA_DESC_RX_OFFSET(offset) |
++ DMA_DESC_LENGTH(len);
++
++#if 0
++ printf("%s: index %d, desc %p, desc->ctl %08x\n",
++ __func__, index, desc, desc->ctl);
++#endif
++
++ return 0;
++}
++
++int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index)
++{
++ struct ltq_dma_channel *chan = &dev->rx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++
++#if 0
++ printf("%s: index %d, desc %p, desc->ctl %08x\n",
++ __func__, index, desc, desc->ctl);
++#endif
++
++ if (desc->ctl & DMA_DESC_OWN)
++ return 0;
++
++ if (desc->ctl & DMA_DESC_C)
++ return 1;
++
++ return 0;
++}
++
++int ltq_dma_rx_length(struct ltq_dma_device *dev, int index)
++{
++ struct ltq_dma_channel *chan = &dev->rx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++
++ return DMA_DESC_LENGTH(desc->ctl);
++}
++
++int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
++ unsigned long timeout)
++{
++ struct ltq_dma_channel *chan = &dev->tx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++ unsigned int offset;
++ unsigned long timebase = get_timer(0);
++ u32 dma_addr = ltq_virt_to_dma_addr(data);
++
++ while (desc->ctl & DMA_DESC_OWN) {
++ WATCHDOG_RESET();
++
++ if (get_timer(timebase) >= timeout) {
++#if 0
++ printf("%s: timeout: index %d, desc %p, desc->ctl %08x\n",
++ __func__, index, desc, desc->ctl);
++#endif
++ return -1;
++ }
++ }
++
++ offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
++
++#if 0
++ printf("%s: index %d, desc %p, data %p, dma_addr %08x, offset %u, len %d\n",
++ __func__, index, desc, data, dma_addr, offset, len);
++#endif
++
++ ltq_dma_dcache_wb_inv(data, len);
++
++ desc->addr = dma_addr - offset;
++ desc->ctl = DMA_DESC_OWN | DMA_DESC_SOP | DMA_DESC_EOP |
++ DMA_DESC_TX_OFFSET(offset) | DMA_DESC_LENGTH(len);
++
++#if 0
++ printf("%s: index %d, desc %p, desc->ctl %08x\n",
++ __func__, index, desc, desc->ctl);
++#endif
++
++ return 0;
++}
++
++int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
++ unsigned long timeout)
++{
++ struct ltq_dma_channel *chan = &dev->tx_chan;
++ struct ltq_dma_desc *desc = &chan->desc_base[index];
++ unsigned long timebase = get_timer(0);
++
++ while ((desc->ctl & (DMA_DESC_OWN | DMA_DESC_C)) != DMA_DESC_C) {
++ WATCHDOG_RESET();
++
++ if (get_timer(timebase) >= timeout)
++ return -1;
++ }
++
++ return 0;
++}
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -28,6 +28,7 @@ LIB := $(obj)libgpio.o
+ COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o
+ COBJS-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
+ COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
++COBJS-$(CONFIG_LANTIQ_GPIO) += lantiq_gpio.o
+ COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o
+ COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o
+ COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o
+--- /dev/null
++++ b/drivers/gpio/lantiq_gpio.c
+@@ -0,0 +1,330 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/gpio.h>
++#include <asm/lantiq/io.h>
++
++#define SSIO_GPIO_BASE 64
++
++#define SSIO_CON0_SWU (1 << 31)
++#define SSIO_CON0_RZFL (1 << 26)
++#define SSIO_CON0_GPHY1_SHIFT 27
++#define SSIO_CON0_GPHY1_CONFIG ((CONFIG_LTQ_SSIO_GPHY1_MODE & 0x7) << 27)
++
++#define SSIO_CON1_US_FPI (2 << 30)
++#define SSIO_CON1_FPID_2HZ (0 << 23)
++#define SSIO_CON1_FPID_4HZ (1 << 23)
++#define SSIO_CON1_FPID_8HZ (2 << 23)
++#define SSIO_CON1_FPID_10HZ (3 << 23)
++#define SSIO_CON1_FPIS_1_2 (1 << 20)
++#define SSIO_CON1_FPIS_1_32 (2 << 20)
++#define SSIO_CON1_FPIS_1_64 (3 << 20)
++
++#define SSIO_CON1_GPHY2_SHIFT 15
++#define SSIO_CON1_GPHY2_CONFIG ((CONFIG_LTQ_SSIO_GPHY2_MODE & 0x7) << 15)
++
++#define SSIO_CON1_GROUP2 (1 << 2)
++#define SSIO_CON1_GROUP1 (1 << 1)
++#define SSIO_CON1_GROUP0 (1 << 0)
++#define SSIO_CON1_GROUP_CONFIG (0x3)
++
++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
++#define enable_ssio 1
++#else
++#define enable_ssio 0
++
++#define CONFIG_LTQ_SSIO_GPHY1_MODE 0
++#define CONFIG_LTQ_SSIO_GPHY2_MODE 0
++#define CONFIG_LTQ_SSIO_INIT_VALUE 0
++#endif
++
++#ifdef CONFIG_LTQ_SSIO_EDGE_FALLING
++#define SSIO_RZFL_CONFIG SSIO_CON0_RZFL
++#else
++#define SSIO_RZFL_CONFIG 0
++#endif
++
++struct ltq_gpio_port_regs {
++ __be32 out;
++ __be32 in;
++ __be32 dir;
++ __be32 altsel0;
++ __be32 altsel1;
++ __be32 od;
++ __be32 stoff;
++ __be32 pudsel;
++ __be32 puden;
++ __be32 rsvd1[3];
++};
++
++struct ltq_gpio_regs {
++ u32 rsvd[4];
++ struct ltq_gpio_port_regs ports[CONFIG_LTQ_GPIO_MAX_BANKS];
++};
++
++struct ltq_gpio3_regs {
++ u32 rsvd0[13];
++ __be32 od;
++ __be32 pudsel;
++ __be32 puden;
++ u32 rsvd1[9];
++ __be32 altsel1;
++ u32 rsvd2[14];
++ __be32 out;
++ __be32 in;
++ __be32 dir;
++ __be32 altsel0;
++};
++
++struct ltq_ssio_regs {
++ __be32 con0;
++ __be32 con1;
++ __be32 cpu0;
++ __be32 cpu1;
++ __be32 ar;
++};
++
++static struct ltq_gpio_regs *ltq_gpio_regs =
++ (struct ltq_gpio_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
++
++static struct ltq_gpio3_regs *ltq_gpio3_regs =
++ (struct ltq_gpio3_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
++
++static struct ltq_ssio_regs *ltq_ssio_regs =
++ (struct ltq_ssio_regs *) CKSEG1ADDR(LTQ_SSIO_BASE);
++
++static int is_gpio_bank3(unsigned int port)
++{
++#ifdef CONFIG_LTQ_HAS_GPIO_BANK3
++ return port == 3;
++#else
++ return 0;
++#endif
++}
++
++static int is_gpio_ssio(unsigned int gpio)
++{
++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
++ return gpio >= SSIO_GPIO_BASE;
++#else
++ return 0;
++#endif
++}
++
++static inline int ssio_gpio_to_bit(unsigned gpio)
++{
++ return 1 << (gpio - SSIO_GPIO_BASE);
++}
++
++int ltq_gpio_init(void)
++{
++ ltq_writel(&ltq_ssio_regs->ar, 0);
++ ltq_writel(&ltq_ssio_regs->cpu0, CONFIG_LTQ_SSIO_INIT_VALUE);
++ ltq_writel(&ltq_ssio_regs->cpu1, 0);
++ ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_SWU);
++
++ if (enable_ssio) {
++ ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_GPHY1_CONFIG |
++ SSIO_RZFL_CONFIG);
++ ltq_writel(&ltq_ssio_regs->con1, SSIO_CON1_US_FPI |
++ SSIO_CON1_FPID_8HZ | SSIO_CON1_GPHY2_CONFIG |
++ SSIO_CON1_GROUP_CONFIG);
++ }
++
++ return 0;
++}
++
++int gpio_request(unsigned gpio, const char *label)
++{
++ return 0;
++}
++
++int gpio_free(unsigned gpio)
++{
++ return 0;
++}
++
++int gpio_direction_input(unsigned gpio)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++ const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
++ const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
++ const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
++
++ if (is_gpio_ssio(gpio))
++ return 0;
++
++ if (is_gpio_bank3(port)) {
++ gpio_od = &ltq_gpio3_regs->od;
++ gpio_altsel0 = &ltq_gpio3_regs->altsel0;
++ gpio_altsel1 = &ltq_gpio3_regs->altsel1;
++ gpio_dir = &ltq_gpio3_regs->dir;
++ }
++
++ /*
++ * Reset open drain and altsel configs to workaround improper
++ * reset values or unwanted modifications by BootROM
++ */
++ ltq_clrbits(gpio_od, gpio_to_bit(gpio));
++ ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
++ ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
++
++ /* Switch to input */
++ ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
++
++ return 0;
++}
++
++int gpio_direction_output(unsigned gpio, int value)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++ const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
++ const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
++ const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
++ const void *gpio_out = &ltq_gpio_regs->ports[port].out;
++ u32 data = gpio_to_bit(gpio);
++
++ if (is_gpio_ssio(gpio)) {
++ data = ssio_gpio_to_bit(gpio);
++ if (value)
++ ltq_setbits(&ltq_ssio_regs->cpu0, data);
++ else
++ ltq_clrbits(&ltq_ssio_regs->cpu0, data);
++
++ return 0;
++ }
++
++ if (is_gpio_bank3(port)) {
++ gpio_od = &ltq_gpio3_regs->od;
++ gpio_altsel0 = &ltq_gpio3_regs->altsel0;
++ gpio_altsel1 = &ltq_gpio3_regs->altsel1;
++ gpio_dir = &ltq_gpio3_regs->dir;
++ gpio_out = &ltq_gpio3_regs->out;
++ }
++
++ /*
++ * Reset open drain and altsel configs to workaround improper
++ * reset values or unwanted modifications by BootROM
++ */
++ ltq_setbits(gpio_od, data);
++ ltq_clrbits(gpio_altsel0, data);
++ ltq_clrbits(gpio_altsel1, data);
++
++ if (value)
++ ltq_setbits(gpio_out, data);
++ else
++ ltq_clrbits(gpio_out, data);
++
++ /* Switch to output */
++ ltq_setbits(gpio_dir, data);
++
++ return 0;
++}
++
++int gpio_get_value(unsigned gpio)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_in = &ltq_gpio_regs->ports[port].in;
++ u32 data = gpio_to_bit(gpio);
++ u32 val;
++
++ if (is_gpio_ssio(gpio)) {
++ gpio_in = &ltq_ssio_regs->cpu0;
++ data = ssio_gpio_to_bit(gpio);
++ }
++
++ if (is_gpio_bank3(port))
++ gpio_in = &ltq_gpio3_regs->in;
++
++ val = ltq_readl(gpio_in);
++
++ return !!(val & data);
++}
++
++int gpio_set_value(unsigned gpio, int value)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_out = &ltq_gpio_regs->ports[port].out;
++ u32 data = gpio_to_bit(gpio);
++
++ if (is_gpio_ssio(gpio)) {
++ gpio_out = &ltq_ssio_regs->cpu0;
++ data = ssio_gpio_to_bit(gpio);
++ }
++
++ if (is_gpio_bank3(port))
++ gpio_out = &ltq_gpio3_regs->out;
++
++ if (value)
++ ltq_setbits(gpio_out, data);
++ else
++ ltq_clrbits(gpio_out, data);
++
++ return 0;
++}
++
++int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++ const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
++ const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
++ const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
++
++ if (is_gpio_ssio(gpio))
++ return 0;
++
++ if (is_gpio_bank3(port)) {
++ gpio_od = &ltq_gpio3_regs->od;
++ gpio_altsel0 = &ltq_gpio3_regs->altsel0;
++ gpio_altsel1 = &ltq_gpio3_regs->altsel1;
++ gpio_dir = &ltq_gpio3_regs->dir;
++ }
++
++ if (altsel0)
++ ltq_setbits(gpio_altsel0, gpio_to_bit(gpio));
++ else
++ ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
++
++ if (altsel1)
++ ltq_setbits(gpio_altsel1, gpio_to_bit(gpio));
++ else
++ ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
++
++ if (dir) {
++ ltq_setbits(gpio_od, gpio_to_bit(gpio));
++ ltq_setbits(gpio_dir, gpio_to_bit(gpio));
++ } else {
++ ltq_clrbits(gpio_od, gpio_to_bit(gpio));
++ ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
++ }
++
++ return 0;
++}
++
++int gpio_set_opendrain(unsigned gpio, int od)
++{
++ unsigned port = gpio_to_port(gpio);
++ const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++
++ if (is_gpio_ssio(gpio))
++ return 0;
++
++ if (is_gpio_bank3(port))
++ gpio_od = &ltq_gpio3_regs->od;
++
++ if (od)
++ ltq_setbits(gpio_od, gpio_to_bit(gpio));
++ else
++ ltq_clrbits(gpio_od, gpio_to_bit(gpio));
++
++ return 0;
++}
+--- a/drivers/mtd/cfi_flash.c
++++ b/drivers/mtd/cfi_flash.c
+@@ -177,6 +177,18 @@ u64 flash_read64(void *addr)__attribute_
+ #define flash_read64 __flash_read64
+ #endif
+
++static inline void *__flash_swap_addr(unsigned long addr)
++{
++ return (void *) addr;
++}
++
++#ifdef CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++void *flash_swap_addr(unsigned long addr)
++ __attribute__((weak, alias("__flash_swap_addr")));
++#else
++#define flash_swap_addr __flash_swap_addr
++#endif
++
+ /*-----------------------------------------------------------------------
+ */
+ #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
+@@ -212,7 +224,7 @@ flash_map (flash_info_t * info, flash_se
+ {
+ unsigned int byte_offset = offset * info->portwidth;
+
+- return (void *)(info->start[sect] + byte_offset);
++ return flash_swap_addr(info->start[sect] + byte_offset);
+ }
+
+ static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -67,6 +67,7 @@ COBJS-$(CONFIG_NAND_JZ4740) += jz4740_na
+ COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
+ COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
+ COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
++COBJS-$(CONFIG_NAND_LANTIQ) += lantiq_nand.o
+ COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
+ COBJS-$(CONFIG_NAND_MXC) += mxc_nand.o
+ COBJS-$(CONFIG_NAND_MXS) += mxs_nand.o
+--- /dev/null
++++ b/drivers/mtd/nand/lantiq_nand.c
+@@ -0,0 +1,127 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#include <common.h>
++#include <linux/mtd/nand.h>
++#include <linux/compiler.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/nand.h>
++#include <asm/lantiq/io.h>
++
++#define NAND_CON_ECC_ON (1 << 31)
++#define NAND_CON_LATCH_PRE (1 << 23)
++#define NAND_CON_LATCH_WP (1 << 22)
++#define NAND_CON_LATCH_SE (1 << 21)
++#define NAND_CON_LATCH_CS (1 << 20)
++#define NAND_CON_LATCH_CLE (1 << 19)
++#define NAND_CON_LATCH_ALE (1 << 18)
++#define NAND_CON_OUT_CS1 (1 << 10)
++#define NAND_CON_IN_CS1 (1 << 8)
++#define NAND_CON_PRE_P (1 << 7)
++#define NAND_CON_WP_P (1 << 6)
++#define NAND_CON_SE_P (1 << 5)
++#define NAND_CON_CS_P (1 << 4)
++#define NAND_CON_CLE_P (1 << 3)
++#define NAND_CON_ALE_P (1 << 2)
++#define NAND_CON_CSMUX (1 << 1)
++#define NAND_CON_NANDM (1 << 0)
++
++#define NAND_WAIT_WR_C (1 << 3)
++#define NAND_WAIT_RDBY (1 << 0)
++
++#define NAND_CMD_ALE (1 << 2)
++#define NAND_CMD_CLE (1 << 3)
++#define NAND_CMD_CS (1 << 4)
++#define NAND_CMD_SE (1 << 5)
++#define NAND_CMD_WP (1 << 6)
++#define NAND_CMD_PRE (1 << 7)
++
++struct ltq_nand_regs {
++ __be32 con; /* NAND controller control */
++ __be32 wait; /* NAND Flash Device RD/BY State */
++ __be32 ecc0; /* NAND Flash ECC Register 0 */
++ __be32 ecc_ac; /* NAND Flash ECC Register address counter */
++ __be32 ecc_cr; /* NAND Flash ECC Comparison */
++};
++
++static struct ltq_nand_regs *ltq_nand_regs =
++ (struct ltq_nand_regs *) CKSEG1ADDR(LTQ_EBU_NAND_BASE);
++
++static void ltq_nand_wait_ready(void)
++{
++ while ((ltq_readl(&ltq_nand_regs->wait) & NAND_WAIT_WR_C) == 0)
++ ;
++}
++
++static int ltq_nand_dev_ready(struct mtd_info *mtd)
++{
++ u32 data = ltq_readl(&ltq_nand_regs->wait);
++ return data & NAND_WAIT_RDBY;
++}
++
++static void ltq_nand_select_chip(struct mtd_info *mtd, int chip)
++{
++ if (chip == 0) {
++ ltq_setbits(&ltq_nand_regs->con, NAND_CON_NANDM);
++ ltq_setbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
++ } else {
++ ltq_clrbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
++ ltq_clrbits(&ltq_nand_regs->con, NAND_CON_NANDM);
++ }
++}
++
++static void ltq_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
++{
++ struct nand_chip *chip = mtd->priv;
++ unsigned long addr = (unsigned long) chip->IO_ADDR_W;
++
++ if (ctrl & NAND_CTRL_CHANGE) {
++ if (ctrl & NAND_ALE)
++ addr |= NAND_CMD_ALE;
++ else
++ addr &= ~NAND_CMD_ALE;
++
++ if (ctrl & NAND_CLE)
++ addr |= NAND_CMD_CLE;
++ else
++ addr &= ~NAND_CMD_CLE;
++
++ chip->IO_ADDR_W = (void __iomem *) addr;
++ }
++
++ if (cmd != NAND_CMD_NONE) {
++ writeb(cmd, chip->IO_ADDR_W);
++ ltq_nand_wait_ready();
++ }
++}
++
++int ltq_nand_init(struct nand_chip *nand)
++{
++ /* Enable NAND, set NAND CS to EBU CS1, enable EBU CS mux */
++ ltq_writel(&ltq_nand_regs->con, NAND_CON_OUT_CS1 | NAND_CON_IN_CS1 |
++ NAND_CON_PRE_P | NAND_CON_WP_P | NAND_CON_SE_P |
++ NAND_CON_CS_P | NAND_CON_CSMUX);
++
++ nand->dev_ready = ltq_nand_dev_ready;
++ nand->select_chip = ltq_nand_select_chip;
++ nand->cmd_ctrl = ltq_nand_cmd_ctrl;
++
++ nand->chip_delay = 30;
++ nand->options = 0;
++ nand->ecc.mode = NAND_ECC_SOFT;
++
++ /* Enable CS bit in address offset */
++ nand->IO_ADDR_R = nand->IO_ADDR_R + NAND_CMD_CS;
++ nand->IO_ADDR_W = nand->IO_ADDR_W + NAND_CMD_CS;
++
++ return 0;
++}
++
++__weak int board_nand_init(struct nand_chip *chip)
++{
++ return ltq_nand_init(chip);
++}
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -51,6 +51,8 @@ COBJS-$(CONFIG_GRETH) += greth.o
+ COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
+ COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
+ COBJS-$(CONFIG_LAN91C96) += lan91c96.o
++COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o
++COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o
+ COBJS-$(CONFIG_MACB) += macb.o
+ COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
+ COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
+--- /dev/null
++++ b/drivers/net/lantiq_danube_etop.c
+@@ -0,0 +1,411 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <switch.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/dma.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PPE_ETOP_MDIO_ACC_RA (1 << 31)
++#define LTQ_PPE_ETOP_MDIO_CFG_UMM1 (1 << 2)
++#define LTQ_PPE_ETOP_MDIO_CFG_UMM0 (1 << 1)
++
++#define LTQ_PPE_ETOP_CFG_TCKINV1 (1 << 11)
++#define LTQ_PPE_ETOP_CFG_TCKINV0 (1 << 10)
++#define LTQ_PPE_ETOP_CFG_FEN1 (1 << 9)
++#define LTQ_PPE_ETOP_CFG_FEN0 (1 << 8)
++#define LTQ_PPE_ETOP_CFG_SEN1 (1 << 7)
++#define LTQ_PPE_ETOP_CFG_SEN0 (1 << 6)
++#define LTQ_PPE_ETOP_CFG_TURBO1 (1 << 5)
++#define LTQ_PPE_ETOP_CFG_REMII1 (1 << 4)
++#define LTQ_PPE_ETOP_CFG_OFF1 (1 << 3)
++#define LTQ_PPE_ETOP_CFG_TURBO0 (1 << 2)
++#define LTQ_PPE_ETOP_CFG_REMII0 (1 << 1)
++#define LTQ_PPE_ETOP_CFG_OFF0 (1 << 0)
++
++#define LTQ_PPE_ENET0_MAC_CFG_CGEN (1 << 11)
++#define LTQ_PPE_ENET0_MAC_CFG_DUPLEX (1 << 2)
++#define LTQ_PPE_ENET0_MAC_CFG_SPEED (1 << 1)
++#define LTQ_PPE_ENET0_MAC_CFG_LINK (1 << 0)
++
++#define LTQ_PPE_ENETS0_CFG_FTUC (1 << 28)
++
++#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX
++#define LTQ_ETH_TX_BUFFER_CNT 8
++#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN
++#define LTQ_ETH_IP_ALIGN 2
++
++#define LTQ_MDIO_DRV_NAME "ltq-mdio"
++#define LTQ_ETH_DRV_NAME "ltq-eth"
++
++struct ltq_ppe_etop_regs {
++ u32 mdio_cfg; /* MDIO configuration */
++ u32 mdio_acc; /* MDIO access */
++ u32 cfg; /* ETOP configuration */
++ u32 ig_vlan_cos; /* IG VLAN priority CoS mapping */
++ u32 ig_dscp_cos3; /* IG DSCP CoS mapping 3 */
++ u32 ig_dscp_cos2; /* IG DSCP CoS mapping 2 */
++ u32 ig_dscp_cos1; /* IG DSCP CoS mapping 1 */
++ u32 ig_dscp_cos0; /* IG DSCP CoS mapping 0 */
++ u32 ig_plen_ctrl; /* IG frame length control */
++ u32 rsvd0[3];
++ u32 vpid; /* VLAN protocol ID */
++};
++
++struct ltq_ppe_enet_regs {
++ u32 mac_cfg; /* MAC configuration */
++ u32 rsvd0[3];
++ u32 ig_cfg; /* Ingress configuration */
++ u32 ig_pgcnt; /* Ingress buffer used page count */
++ u32 rsvd1;
++ u32 ig_buf_ctrl; /* Ingress buffer backpressure ctrl */
++ u32 cos_cfg; /* Classification configuration */
++ u32 ig_drop; /* Total ingress drop frames */
++ u32 ig_err; /* Total ingress error frames */
++ u32 mac_da0; /* Ingress MAC address 0 */
++ u32 mac_da1; /* Ingress MAC address 1 */
++ u32 rsvd2[22];
++ u32 pgcnt; /* Page counter */
++ u32 rsvd3;
++ u32 hf_ctrl; /* Half duplex control */
++ u32 tx_ctrl; /* Transmit control */
++ u32 rsvd4;
++ u32 vlcos0; /* VLAN insertion config CoS 0 */
++ u32 vlcos1; /* VLAN insertion config CoS 1 */
++ u32 vlcos2; /* VLAN insertion config CoS 2 */
++ u32 vlcos3; /* VLAN insertion config CoS 3 */
++ u32 eg_col; /* Total egress collision frames */
++ u32 eg_drop; /* Total egress drop frames */
++};
++
++struct ltq_eth_priv {
++ struct ltq_dma_device dma_dev;
++ struct mii_dev *bus;
++ struct eth_device *dev;
++ int rx_num;
++ int tx_num;
++};
++
++struct ltq_mdio_access {
++ union {
++ struct {
++ unsigned ra:1;
++ unsigned rw:1;
++ unsigned rsvd:4;
++ unsigned phya:5;
++ unsigned rega:5;
++ unsigned phyd:16;
++ } reg;
++ u32 val;
++ };
++};
++
++static struct ltq_ppe_etop_regs *ltq_ppe_etop_regs =
++ (struct ltq_ppe_etop_regs *) CKSEG1ADDR(LTQ_PPE_ETOP_BASE);
++
++static struct ltq_ppe_enet_regs *ltq_ppe_enet0_regs =
++ (struct ltq_ppe_enet_regs *) CKSEG1ADDR(LTQ_PPE_ENET0_BASE);
++
++static inline int ltq_mdio_poll(void)
++{
++ struct ltq_mdio_access acc;
++ unsigned cnt = 10000;
++
++ while (likely(cnt--)) {
++ acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
++ if (!acc.reg.ra)
++ return 0;
++ }
++
++ return 1;
++}
++
++static int ltq_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
++ int regnum)
++{
++ struct ltq_mdio_access acc;
++ int ret;
++
++ acc.val = 0;
++ acc.reg.ra = 1;
++ acc.reg.rw = 1;
++ acc.reg.phya = addr;
++ acc.reg.rega = regnum;
++
++ ret = ltq_mdio_poll();
++ if (ret)
++ return ret;
++
++ ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
++
++ ret = ltq_mdio_poll();
++ if (ret)
++ return ret;
++
++ acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
++
++ return acc.reg.phyd;
++}
++
++static int ltq_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
++ int regnum, u16 val)
++{
++ struct ltq_mdio_access acc;
++ int ret;
++
++ acc.val = 0;
++ acc.reg.ra = 1;
++ acc.reg.rw = 0;
++ acc.reg.phya = addr;
++ acc.reg.rega = regnum;
++ acc.reg.phyd = val;
++
++ ret = ltq_mdio_poll();
++ if (ret)
++ return ret;
++
++ ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
++
++ return 0;
++}
++
++static inline void ltq_eth_write_hwaddr(const struct eth_device *dev)
++{
++ u32 da0, da1;
++
++ da0 = (dev->enetaddr[0] << 24) + (dev->enetaddr[1] << 16) +
++ (dev->enetaddr[2] << 8) + dev->enetaddr[3];
++ da1 = (dev->enetaddr[4] << 24) + (dev->enetaddr[5] << 16);
++
++ ltq_writel(&ltq_ppe_enet0_regs->mac_da0, da0);
++ ltq_writel(&ltq_ppe_enet0_regs->mac_da1, da1);
++}
++
++static inline u8 *ltq_eth_rx_packet_align(int rx_num)
++{
++ u8 *packet = (u8 *) NetRxPackets[rx_num];
++
++ /*
++ * IP header needs
++ */
++ return packet + LTQ_ETH_IP_ALIGN;
++}
++
++static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ int i;
++
++ ltq_eth_write_hwaddr(dev);
++
++ for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
++ ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
++ LTQ_ETH_RX_DATA_SIZE);
++
++ ltq_dma_enable(dma_dev);
++
++ priv->rx_num = 0;
++ priv->tx_num = 0;
++
++ return 0;
++}
++
++static void ltq_eth_halt(struct eth_device *dev)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++
++ ltq_dma_reset(dma_dev);
++}
++
++static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ int err;
++
++ /* Minimum payload length w/ CRC is 60 bytes */
++ if (length < 60)
++ length = 60;
++
++ err = ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
++ if (err) {
++ puts("NET: timeout on waiting for TX descriptor\n");
++ return -1;
++ }
++
++ priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
++
++ return err;
++}
++
++static int ltq_eth_recv(struct eth_device *dev)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ u8 *packet;
++ int len;
++
++ if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
++ return 0;
++
++#if 0
++ printf("%s: rx_num %d\n", __func__, priv->rx_num);
++#endif
++
++ len = ltq_dma_rx_length(dma_dev, priv->rx_num);
++ packet = ltq_eth_rx_packet_align(priv->rx_num);
++
++#if 0
++ printf("%s: received: packet %p, len %u, rx_num %d\n",
++ __func__, packet, len, priv->rx_num);
++#endif
++
++ if (len)
++ NetReceive(packet, len);
++
++ ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
++ LTQ_ETH_RX_DATA_SIZE);
++
++ priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
++
++ return 0;
++}
++
++static void ltq_eth_hw_init(const struct ltq_eth_port_config *port)
++{
++ u32 data;
++
++ /* Power up ethernet subsystems */
++ ltq_pm_enable(LTQ_PM_ETH);
++
++ /* Reset ethernet subsystems */
++ ltq_reset_once(LTQ_RESET_ETH, 1);
++
++ /* Disable MDIO auto-detection */
++ ltq_clrbits(&ltq_ppe_etop_regs->mdio_cfg, LTQ_PPE_ETOP_MDIO_CFG_UMM1 |
++ LTQ_PPE_ETOP_MDIO_CFG_UMM0);
++
++ /* Enable CRC generation, Full Duplex, 100Mbps, Link up */
++ ltq_writel(&ltq_ppe_enet0_regs->mac_cfg, LTQ_PPE_ENET0_MAC_CFG_CGEN |
++ LTQ_PPE_ENET0_MAC_CFG_DUPLEX |
++ LTQ_PPE_ENET0_MAC_CFG_SPEED |
++ LTQ_PPE_ENET0_MAC_CFG_LINK);
++
++ /* Reset ETOP cfg and disable all */
++ data = LTQ_PPE_ETOP_CFG_OFF0 | LTQ_PPE_ETOP_CFG_OFF1;
++
++ /* Enable ENET0, enable store and fetch */
++ data &= ~LTQ_PPE_ETOP_CFG_OFF0;
++ data |= LTQ_PPE_ETOP_CFG_SEN0 | LTQ_PPE_ETOP_CFG_FEN0;
++
++ if (port->phy_if == PHY_INTERFACE_MODE_RMII)
++ data |= LTQ_PPE_ETOP_CFG_REMII0;
++ else
++ data &= ~LTQ_PPE_ETOP_CFG_REMII0;
++
++ ltq_writel(&ltq_ppe_etop_regs->cfg, data);
++
++ /* Set allowed packet length from 64 bytes to 1518 bytes */
++ ltq_writel(&ltq_ppe_etop_regs->ig_plen_ctrl, (64 << 16) | 1518);
++
++ /* Enable filter for unicast packets */
++ ltq_setbits(&ltq_ppe_enet0_regs->ig_cfg, LTQ_PPE_ENETS0_CFG_FTUC);
++}
++
++int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
++{
++ struct eth_device *dev;
++ struct mii_dev *bus;
++ struct ltq_eth_priv *priv;
++ struct ltq_dma_device *dma_dev;
++ const struct ltq_eth_port_config *port = &board_config->ports[0];
++ struct phy_device *phy;
++ struct switch_device *sw;
++ int ret;
++
++ ltq_dma_init();
++ ltq_eth_hw_init(port);
++
++ dev = calloc(1, sizeof(*dev));
++ if (!dev)
++ return -1;
++
++ priv = calloc(1, sizeof(*priv));
++ if (!priv)
++ return -1;
++
++ bus = mdio_alloc();
++ if (!bus)
++ return -1;
++
++ sprintf(dev->name, LTQ_ETH_DRV_NAME);
++ dev->priv = priv;
++ dev->init = ltq_eth_init;
++ dev->halt = ltq_eth_halt;
++ dev->recv = ltq_eth_recv;
++ dev->send = ltq_eth_send;
++
++ sprintf(bus->name, LTQ_MDIO_DRV_NAME);
++ bus->read = ltq_mdio_read;
++ bus->write = ltq_mdio_write;
++ bus->priv = priv;
++
++ dma_dev = &priv->dma_dev;
++ dma_dev->port = 0;
++ dma_dev->rx_chan.chan_no = 6;
++ dma_dev->rx_chan.class = 3;
++ dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
++ dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++ dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
++ dma_dev->tx_chan.chan_no = 7;
++ dma_dev->tx_chan.class = 3;
++ dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
++ dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++ dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
++
++ priv->bus = bus;
++ priv->dev = dev;
++
++ ret = ltq_dma_register(dma_dev);
++ if (ret)
++ return ret;
++
++ ret = mdio_register(bus);
++ if (ret)
++ return ret;
++
++ ret = eth_register(dev);
++ if (ret)
++ return ret;
++
++ if (port->flags & LTQ_ETH_PORT_SWITCH) {
++ sw = switch_connect(bus);
++ if (!sw)
++ return -1;
++
++ switch_setup(sw);
++ }
++
++ if (port->flags & LTQ_ETH_PORT_PHY) {
++ phy = phy_connect(bus, port->phy_addr, dev, port->phy_if);
++ if (!phy)
++ return -1;
++
++ phy_config(phy);
++ }
++
++ return 0;
++}
+--- /dev/null
++++ b/drivers/net/lantiq_vrx200_switch.c
+@@ -0,0 +1,676 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010-2011 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define DEBUG
++
++#include <common.h>
++#include <malloc.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <linux/compiler.h>
++#include <asm/gpio.h>
++#include <asm/processor.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/dma.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/switch.h>
++
++#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX
++#define LTQ_ETH_TX_BUFFER_CNT 8
++#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN
++#define LTQ_ETH_IP_ALIGN 2
++
++#define LTQ_MDIO_DRV_NAME "ltq-mdio"
++#define LTQ_ETH_DRV_NAME "ltq-eth"
++
++#define LTQ_ETHSW_MAX_GMAC 6
++#define LTQ_ETHSW_PMAC 6
++
++struct ltq_mdio_phy_addr_reg {
++ union {
++ struct {
++ unsigned rsvd:1;
++ unsigned lnkst:2; /* Link status control */
++ unsigned speed:2; /* Speed control */
++ unsigned fdup:2; /* Full duplex control */
++ unsigned fcontx:2; /* Flow control mode TX */
++ unsigned fconrx:2; /* Flow control mode RX */
++ unsigned addr:5; /* PHY address */
++ } bits;
++ u16 val;
++ };
++};
++
++enum ltq_mdio_phy_addr_lnkst {
++ LTQ_MDIO_PHY_ADDR_LNKST_AUTO = 0,
++ LTQ_MDIO_PHY_ADDR_LNKST_UP = 1,
++ LTQ_MDIO_PHY_ADDR_LNKST_DOWN = 2,
++};
++
++enum ltq_mdio_phy_addr_speed {
++ LTQ_MDIO_PHY_ADDR_SPEED_M10 = 0,
++ LTQ_MDIO_PHY_ADDR_SPEED_M100 = 1,
++ LTQ_MDIO_PHY_ADDR_SPEED_G1 = 2,
++ LTQ_MDIO_PHY_ADDR_SPEED_AUTO = 3,
++};
++
++enum ltq_mdio_phy_addr_fdup {
++ LTQ_MDIO_PHY_ADDR_FDUP_AUTO = 0,
++ LTQ_MDIO_PHY_ADDR_FDUP_ENABLE = 1,
++ LTQ_MDIO_PHY_ADDR_FDUP_DISABLE = 3,
++};
++
++enum ltq_mdio_phy_addr_fcon {
++ LTQ_MDIO_PHY_ADDR_FCON_AUTO = 0,
++ LTQ_MDIO_PHY_ADDR_FCON_ENABLE = 1,
++ LTQ_MDIO_PHY_ADDR_FCON_DISABLE = 3,
++};
++
++struct ltq_mii_mii_cfg_reg {
++ union {
++ struct {
++ unsigned res:1; /* Hardware reset */
++ unsigned en:1; /* xMII interface enable */
++ unsigned isol:1; /* xMII interface isolate */
++ unsigned ldclkdis:1; /* Link down clock disable */
++ unsigned rsvd:1;
++ unsigned crs:2; /* CRS sensitivity config */
++ unsigned rgmii_ibs:1; /* RGMII In Band status */
++ unsigned rmii:1; /* RMII ref clock direction */
++ unsigned miirate:3; /* xMII interface clock rate */
++ unsigned miimode:4; /* xMII interface mode */
++ } bits;
++ u16 val;
++ };
++};
++
++enum ltq_mii_mii_cfg_miirate {
++ LTQ_MII_MII_CFG_MIIRATE_M2P5 = 0,
++ LTQ_MII_MII_CFG_MIIRATE_M25 = 1,
++ LTQ_MII_MII_CFG_MIIRATE_M125 = 2,
++ LTQ_MII_MII_CFG_MIIRATE_M50 = 3,
++ LTQ_MII_MII_CFG_MIIRATE_AUTO = 4,
++};
++
++enum ltq_mii_mii_cfg_miimode {
++ LTQ_MII_MII_CFG_MIIMODE_MIIP = 0,
++ LTQ_MII_MII_CFG_MIIMODE_MIIM = 1,
++ LTQ_MII_MII_CFG_MIIMODE_RMIIP = 2,
++ LTQ_MII_MII_CFG_MIIMODE_RMIIM = 3,
++ LTQ_MII_MII_CFG_MIIMODE_RGMII = 4,
++};
++
++struct ltq_eth_priv {
++ struct ltq_dma_device dma_dev;
++ struct mii_dev *bus;
++ struct eth_device *dev;
++ struct phy_device *phymap[LTQ_ETHSW_MAX_GMAC];
++ int rx_num;
++ int tx_num;
++};
++
++static struct vr9_switch_regs *switch_regs =
++ (struct vr9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE);
++
++static inline void vr9_switch_sync(void)
++{
++ __asm__("sync");
++}
++
++static inline int vr9_switch_mdio_is_busy(void)
++{
++ u32 mdio_ctrl = ltq_readl(&switch_regs->mdio.mdio_ctrl);
++
++ return mdio_ctrl & MDIO_CTRL_MBUSY;
++}
++
++static inline void vr9_switch_mdio_poll(void)
++{
++ while (vr9_switch_mdio_is_busy())
++ cpu_relax();
++}
++
++static int vr9_switch_mdio_read(struct mii_dev *bus, int phyad, int devad,
++ int regad)
++{
++ u32 mdio_ctrl;
++ int retval;
++
++ mdio_ctrl = MDIO_CTRL_OP_READ |
++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
++ (regad & MDIO_CTRL_REGAD_MASK);
++
++ vr9_switch_mdio_poll();
++ ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
++ vr9_switch_mdio_poll();
++ retval = ltq_readl(&switch_regs->mdio.mdio_read);
++
++ return retval;
++}
++
++static int vr9_switch_mdio_write(struct mii_dev *bus, int phyad, int devad,
++ int regad, u16 val)
++{
++ u32 mdio_ctrl;
++
++ mdio_ctrl = MDIO_CTRL_OP_WRITE |
++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
++ (regad & MDIO_CTRL_REGAD_MASK);
++
++ vr9_switch_mdio_poll();
++ ltq_writel(&switch_regs->mdio.mdio_write, val);
++ ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
++
++ return 0;
++}
++
++static void ltq_eth_gmac_update(struct phy_device *phydev, int num)
++{
++ struct ltq_mdio_phy_addr_reg phy_addr_reg;
++ struct ltq_mii_mii_cfg_reg mii_cfg_reg;
++
++ phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
++
++ switch (num) {
++ case 0:
++ case 1:
++ case 5:
++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
++ break;
++ default:
++ mii_cfg_reg.val = 0;
++ break;
++ }
++
++ phy_addr_reg.bits.addr = phydev->addr;
++
++ if (phydev->link)
++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_UP;
++ else
++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
++
++ switch (phydev->speed) {
++ case SPEED_1000:
++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_G1;
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M125;
++ break;
++ case SPEED_100:
++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M100;
++ switch (mii_cfg_reg.bits.miimode) {
++ case LTQ_MII_MII_CFG_MIIMODE_RMIIM:
++ case LTQ_MII_MII_CFG_MIIMODE_RMIIP:
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M50;
++ break;
++ default:
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M25;
++ break;
++ }
++ break;
++ default:
++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
++ break;
++ }
++
++ if (phydev->duplex == DUPLEX_FULL)
++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_ENABLE;
++ else
++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
++
++ ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
++
++ switch (num) {
++ case 0:
++ case 1:
++ case 5:
++ ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
++ break;
++ default:
++ break;
++ }
++}
++
++static inline u8 *ltq_eth_rx_packet_align(int rx_num)
++{
++ u8 *packet = (u8 *) NetRxPackets[rx_num];
++
++ /*
++ * IP header needs
++ */
++ return packet + LTQ_ETH_IP_ALIGN;
++}
++
++static int ltq_eth_init(struct eth_device *dev, bd_t * bis)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ struct phy_device *phydev;
++ int i;
++
++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
++ phydev = priv->phymap[i];
++ if (!phydev)
++ continue;
++
++ phy_startup(phydev);
++ ltq_eth_gmac_update(phydev, i);
++ }
++
++ for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
++ ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
++ LTQ_ETH_RX_DATA_SIZE);
++
++ ltq_dma_enable(dma_dev);
++
++ priv->rx_num = 0;
++ priv->tx_num = 0;
++
++ return 0;
++}
++
++static void ltq_eth_halt(struct eth_device *dev)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ struct phy_device *phydev;
++ int i;
++
++ ltq_dma_reset(dma_dev);
++
++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
++ phydev = priv->phymap[i];
++ if (!phydev)
++ continue;
++
++ phy_shutdown(phydev);
++ phydev->link = 0;
++ ltq_eth_gmac_update(phydev, i);
++ }
++}
++
++static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++
++#if 0
++ printf("%s: packet %p, len %d\n", __func__, packet, length);
++#endif
++
++ ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
++ priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
++
++ return 0;
++}
++
++static int ltq_eth_recv(struct eth_device *dev)
++{
++ struct ltq_eth_priv *priv = dev->priv;
++ struct ltq_dma_device *dma_dev = &priv->dma_dev;
++ u8 *packet;
++ int len;
++
++ if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
++ return 0;
++
++#if 0
++ printf("%s: rx_num %d\n", __func__, priv->rx_num);
++#endif
++
++ len = ltq_dma_rx_length(dma_dev, priv->rx_num);
++ packet = ltq_eth_rx_packet_align(priv->rx_num);
++
++#if 0
++ printf("%s: received: packet %p, len %u, rx_num %d\n",
++ __func__, packet, len, priv->rx_num);
++#endif
++
++ if (len)
++ NetReceive(packet, len);
++
++ ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
++ LTQ_ETH_RX_DATA_SIZE);
++
++ priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
++
++ return 0;
++}
++
++static void ltq_eth_gmac_init(int num)
++{
++ struct ltq_mdio_phy_addr_reg phy_addr_reg;
++ struct ltq_mii_mii_cfg_reg mii_cfg_reg;
++
++ /* Reset PHY status to link down */
++ phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
++ phy_addr_reg.bits.addr = num;
++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
++ ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
++
++ /* Reset and disable MII interface */
++ switch (num) {
++ case 0:
++ case 1:
++ case 5:
++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
++ mii_cfg_reg.bits.en = 0;
++ mii_cfg_reg.bits.res = 1;
++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
++ ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
++ break;
++ default:
++ break;
++ }
++
++ /*
++ * - enable frame checksum generation
++ * - enable padding of short frames
++ * - disable flow control
++ */
++ ltq_writel(to_mac_ctrl(switch_regs, num, 0),
++ MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
++
++ vr9_switch_sync();
++}
++
++static void ltq_eth_pmac_init(void)
++{
++ /*
++ * WAR: buffer congestion:
++ * - shorten preambel to 1 byte
++ * - set TX IPG to 7 bytes
++ */
++#if 1
++ ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 1),
++ MAC_CTRL1_SHORTPRE | 7);
++#endif
++
++ /*
++ * WAR: systematical concept weakness ACM bug
++ * - set maximum number of used buffer segments to 254
++ * - soft-reset BM FSQM
++ */
++#if 1
++ ltq_writel(&switch_regs->bm.core.fsqm_gctrl, 253);
++ ltq_setbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
++ ltq_clrbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
++#endif
++
++ /*
++ * WAR: switch MAC drop bug
++ */
++#if 1
++ ltq_writel(to_pce_tbl_key(switch_regs, 0), 0xf);
++ ltq_writel(to_pce_tbl_value(switch_regs, 0), 0x40);
++ ltq_writel(&switch_regs->pce.core.tbl_addr, 0x3);
++ ltq_writel(&switch_regs->pce.core.tbl_ctrl, 0x902f);
++#endif
++
++ /*
++ * Configure frame header control:
++ * - enable flow control
++ * - enable CRC check for packets from DMA to PMAC
++ * - remove special tag from packets from PMAC to DMA
++ * - add CRC for packets from DMA to PMAC
++ */
++ ltq_writel(&switch_regs->pmac.hd_ctl, /*PMAC_HD_CTL_FC |*/
++ PMAC_HD_CTL_CCRC | PMAC_HD_CTL_RST | PMAC_HD_CTL_AC |
++ PMAC_HD_CTL_RC);
++
++#if 1
++ ltq_writel(&switch_regs->pmac.rx_ipg, 0x8b);
++#endif
++
++ /*
++ * - enable frame checksum generation
++ * - enable padding of short frames
++ * - disable flow control
++ */
++ ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 0),
++ MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
++
++ vr9_switch_sync();
++}
++
++static void ltq_eth_hw_init(void)
++{
++ int i;
++
++ /* Power up ethernet and switch subsystems */
++ ltq_pm_enable(LTQ_PM_ETH);
++
++ /* Reset ethernet and switch subsystems */
++#if 0
++ ltq_reset_once(LTQ_RESET_ETH, 10);
++#endif
++
++ /* Enable switch macro */
++ ltq_setbits(&switch_regs->mdio.glob_ctrl, MDIO_GLOB_CTRL_SE);
++
++ /* Disable MDIO auto-polling for all ports */
++ ltq_writel(&switch_regs->mdio.mdc_cfg_0, 0);
++
++ /*
++ * Enable and set MDIO management clock to 2.5 MHz. This is the
++ * maximum clock for FE PHYs.
++ * Formula for clock is:
++ *
++ * 50 MHz
++ * x = ----------- - 1
++ * 2 * f_MDC
++ */
++ ltq_writel(&switch_regs->mdio.mdc_cfg_1, MDIO_MDC_CFG1_RES |
++ MDIO_MDC_CFG1_MCEN | 5);
++
++ vr9_switch_sync();
++
++ /* Init MAC connected to CPU */
++ ltq_eth_pmac_init();
++
++ /* Init MACs connected to external MII interfaces */
++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++)
++ ltq_eth_gmac_init(i);
++}
++
++static void ltq_eth_port_config(struct ltq_eth_priv *priv,
++ const struct ltq_eth_port_config *port)
++{
++ struct ltq_mii_mii_cfg_reg mii_cfg_reg;
++ struct phy_device *phydev;
++ int setup_gpio = 0;
++
++ switch (port->num) {
++ case 0: /* xMII0 */
++ case 1: /* xMII1 */
++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
++ port->num));
++ mii_cfg_reg.bits.en = port->flags ? 1 : 0;
++
++ switch (port->phy_if) {
++ case PHY_INTERFACE_MODE_MII:
++ if (port->flags & LTQ_ETH_PORT_PHY)
++ /* MII MAC mode, connected to external PHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_MIIM;
++ else
++ /* MII PHY mode, connected to external MAC */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_MIIP;
++ setup_gpio = 1;
++ break;
++ case PHY_INTERFACE_MODE_RMII:
++ if (port->flags & LTQ_ETH_PORT_PHY)
++ /* RMII MAC mode, connected to external PHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_RMIIM;
++ else
++ /* RMII PHY mode, connected to external MAC */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_RMIIP;
++ setup_gpio = 1;
++ break;
++ case PHY_INTERFACE_MODE_RGMII:
++ /* RGMII MAC mode, connected to external PHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_RGMII;
++ setup_gpio = 1;
++
++ /* RGMII clock delays */
++ ltq_writel(to_mii_pcdu(switch_regs, port->num),
++ port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
++ port->rgmii_tx_delay);
++ break;
++ default:
++ break;
++ }
++
++ ltq_writel(to_mii_miicfg(switch_regs, port->num),
++ mii_cfg_reg.val);
++ break;
++ case 2: /* internal GPHY0 */
++ case 3: /* internal GPHY0 */
++ case 4: /* internal GPHY1 */
++ switch (port->phy_if) {
++ case PHY_INTERFACE_MODE_MII:
++ case PHY_INTERFACE_MODE_GMII:
++ setup_gpio = 1;
++ break;
++ default:
++ break;
++ }
++ break;
++ case 5: /* internal GPHY1 or xMII2 */
++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
++ port->num));
++ mii_cfg_reg.bits.en = port->flags ? 1 : 0;
++
++ switch (port->phy_if) {
++ case PHY_INTERFACE_MODE_MII:
++ /* MII MAC mode, connected to internal GPHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_MIIM;
++ setup_gpio = 1;
++ break;
++ case PHY_INTERFACE_MODE_RGMII:
++ /* RGMII MAC mode, connected to external PHY */
++ mii_cfg_reg.bits.miimode =
++ LTQ_MII_MII_CFG_MIIMODE_RGMII;
++ setup_gpio = 1;
++
++ /* RGMII clock delays */
++ ltq_writel(to_mii_pcdu(switch_regs, port->num),
++ port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
++ port->rgmii_tx_delay);
++ break;
++ default:
++ break;
++ }
++
++ ltq_writel(to_mii_miicfg(switch_regs, port->num),
++ mii_cfg_reg.val);
++ break;
++ default:
++ break;
++ }
++
++ /* Setup GPIOs for MII with external PHYs/MACs */
++ if (setup_gpio) {
++ /* MII/MDIO */
++ gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
++ GPIO_DIR_OUT);
++ /* MII/MDC */
++ gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
++ GPIO_DIR_OUT);
++ }
++
++ /* Connect to internal/external PHYs */
++ if (port->flags & LTQ_ETH_PORT_PHY) {
++ phydev = phy_connect(priv->bus, port->phy_addr, priv->dev,
++ port->phy_if);
++ if (phydev)
++ phy_config(phydev);
++
++ priv->phymap[port->num] = phydev;
++ }
++}
++
++int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
++{
++ struct eth_device *dev;
++ struct mii_dev *bus;
++ struct ltq_eth_priv *priv;
++ struct ltq_dma_device *dma_dev;
++ int i, ret;
++
++ build_check_vr9_registers();
++
++ ltq_dma_init();
++ ltq_eth_hw_init();
++
++ dev = calloc(1, sizeof(struct eth_device));
++ if (!dev)
++ return -1;
++
++ priv = calloc(1, sizeof(struct ltq_eth_priv));
++ if (!priv)
++ return -1;
++
++ bus = mdio_alloc();
++ if (!bus)
++ return -1;
++
++ sprintf(dev->name, LTQ_ETH_DRV_NAME);
++ dev->priv = priv;
++ dev->init = ltq_eth_init;
++ dev->halt = ltq_eth_halt;
++ dev->recv = ltq_eth_recv;
++ dev->send = ltq_eth_send;
++
++ sprintf(bus->name, LTQ_MDIO_DRV_NAME);
++ bus->read = vr9_switch_mdio_read;
++ bus->write = vr9_switch_mdio_write;
++ bus->priv = priv;
++
++ dma_dev = &priv->dma_dev;
++ dma_dev->port = 0;
++ dma_dev->rx_chan.chan_no = 0;
++ dma_dev->rx_chan.class = 0;
++ dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
++ dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++ dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
++ dma_dev->tx_chan.chan_no = 1;
++ dma_dev->tx_chan.class = 0;
++ dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
++ dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++ dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
++
++ priv->bus = bus;
++ priv->dev = dev;
++
++ ret = ltq_dma_register(dma_dev);
++ if (ret)
++ return -1;
++
++ ret = mdio_register(bus);
++ if (ret)
++ return -1;
++
++ ret = eth_register(dev);
++ if (ret)
++ return -1;
++
++ for (i = 0; i < board_config->num_ports; i++)
++ ltq_eth_port_config(priv, &board_config->ports[i]);
++
++ return 0;
++}
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -34,6 +34,7 @@ COBJS-$(CONFIG_PHYLIB_10G) += generic_10
+ COBJS-$(CONFIG_PHY_ATHEROS) += atheros.o
+ COBJS-$(CONFIG_PHY_BROADCOM) += broadcom.o
+ COBJS-$(CONFIG_PHY_DAVICOM) += davicom.o
++COBJS-$(CONFIG_PHY_LANTIQ) += lantiq.o
+ COBJS-$(CONFIG_PHY_LXT) += lxt.o
+ COBJS-$(CONFIG_PHY_MARVELL) += marvell.o
+ COBJS-$(CONFIG_PHY_MICREL) += micrel.o
+--- /dev/null
++++ b/drivers/net/phy/lantiq.c
+@@ -0,0 +1,239 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define DEBUG
++
++#include <common.h>
++#include <miiphy.h>
++
++#define ADVERTIZE_MPD (1 << 10)
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/*
++ * Update link status.
++ *
++ * Based on genphy_update_link in phylib.c
++ */
++static int ltq_phy_update_link(struct phy_device *phydev)
++{
++ unsigned int mii_reg;
++
++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
++
++ /*
++ * If we already saw the link up, and it hasn't gone down, then
++ * we don't need to wait for autoneg again
++ */
++ if (phydev->link && mii_reg & BMSR_LSTATUS)
++ return 0;
++
++ if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
++ phydev->link = 0;
++ return 0;
++ } else {
++ /* Read the link a second time to clear the latched state */
++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
++
++ if (mii_reg & BMSR_LSTATUS)
++ phydev->link = 1;
++ else
++ phydev->link = 0;
++ }
++
++ return 0;
++}
++
++/*
++ * Update speed and duplex.
++ *
++ * Based on genphy_parse_link in phylib.c
++ */
++static int ltq_phy_parse_link(struct phy_device *phydev)
++{
++ unsigned int mii_reg;
++
++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
++
++ /* We're using autonegotiation */
++ if (mii_reg & BMSR_ANEGCAPABLE) {
++ u32 lpa = 0;
++ u32 gblpa = 0;
++
++ /* Check for gigabit capability */
++ if (mii_reg & BMSR_ERCAP) {
++ /* We want a list of states supported by
++ * both PHYs in the link
++ */
++ gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
++ gblpa &= phy_read(phydev,
++ MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
++ }
++
++ /* Set the baseline so we only have to set them
++ * if they're different
++ */
++ phydev->speed = SPEED_10;
++ phydev->duplex = DUPLEX_HALF;
++
++ /* Check the gigabit fields */
++ if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
++ phydev->speed = SPEED_1000;
++
++ if (gblpa & PHY_1000BTSR_1000FD)
++ phydev->duplex = DUPLEX_FULL;
++
++ /* We're done! */
++ return 0;
++ }
++
++ lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
++ lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
++
++ if (lpa & (LPA_100FULL | LPA_100HALF)) {
++ phydev->speed = SPEED_100;
++
++ if (lpa & LPA_100FULL)
++ phydev->duplex = DUPLEX_FULL;
++
++ } else if (lpa & LPA_10FULL)
++ phydev->duplex = DUPLEX_FULL;
++ } else {
++ u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
++
++ phydev->speed = SPEED_10;
++ phydev->duplex = DUPLEX_HALF;
++
++ if (bmcr & BMCR_FULLDPLX)
++ phydev->duplex = DUPLEX_FULL;
++
++ if (bmcr & BMCR_SPEED1000)
++ phydev->speed = SPEED_1000;
++ else if (bmcr & BMCR_SPEED100)
++ phydev->speed = SPEED_100;
++ }
++
++ return 0;
++}
++
++static int ltq_phy_config(struct phy_device *phydev)
++{
++ u16 val;
++
++ /* Advertise as Multi-port device */
++ val = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
++ val |= ADVERTIZE_MPD;
++ phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, val);
++
++ genphy_config_aneg(phydev);
++
++ return 0;
++}
++
++static int ltq_phy_startup(struct phy_device *phydev)
++{
++ /*
++ * Update PHY status immediately without any delays as genphy_startup
++ * does because VRX200 switch needs to be configured dependent
++ * on this information.
++ */
++ ltq_phy_update_link(phydev);
++ ltq_phy_parse_link(phydev);
++
++ debug("ltq_phy: addr %d, link %d, speed %d, duplex %d\n",
++ phydev->addr, phydev->link, phydev->speed, phydev->duplex);
++
++ return 0;
++}
++
++static struct phy_driver xrx_11g_13_driver = {
++ .name = "Lantiq XWAY XRX PHY11G v1.3 and earlier",
++ .uid = 0x030260D0,
++ .mask = 0xFFFFFFF0,
++ .features = PHY_GBIT_FEATURES,
++ .config = ltq_phy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++static struct phy_driver xrx_11g_14_driver = {
++ .name = "Lantiq XWAY XRX PHY11G v1.4 and later",
++ .uid = 0xd565a408,
++ .mask = 0xFFFFFFF8,
++ .features = PHY_GBIT_FEATURES,
++ .config = ltq_phy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++static struct phy_driver xrx_22f_14_driver = {
++ .name = "Lantiq XWAY XRX PHY22F v1.4 and later",
++ .uid = 0xd565a418,
++ .mask = 0xFFFFFFF8,
++ .features = PHY_BASIC_FEATURES,
++ .config = ltq_phy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++static struct phy_driver pef7071_driver = {
++ .name = "Lantiq XWAY PEF7071",
++ .uid = 0xd565a400,
++ .mask = 0xFFFFFFFF,
++ .features = PHY_GBIT_FEATURES,
++ .config = ltq_phy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++static struct phy_driver xrx_genphy_driver = {
++ .name = "Generic PHY at Lantiq XWAY XRX switch",
++ .uid = 0,
++ .mask = 0,
++ .features = 0,
++ .config = genphy_config,
++ .startup = ltq_phy_startup,
++ .shutdown = genphy_shutdown,
++};
++
++int phy_lantiq_init(void)
++{
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++ xrx_11g_13_driver.config = ltq_phy_config;
++ xrx_11g_13_driver.startup = ltq_phy_startup;
++ xrx_11g_13_driver.shutdown = genphy_shutdown;
++ xrx_11g_13_driver.name += gd->reloc_off;
++
++ xrx_11g_14_driver.config = ltq_phy_config;
++ xrx_11g_14_driver.startup = ltq_phy_startup;
++ xrx_11g_14_driver.shutdown = genphy_shutdown;
++ xrx_11g_14_driver.name += gd->reloc_off;
++
++ xrx_22f_14_driver.config = ltq_phy_config;
++ xrx_22f_14_driver.startup = ltq_phy_startup;
++ xrx_22f_14_driver.shutdown = genphy_shutdown;
++ xrx_22f_14_driver.name += gd->reloc_off;
++
++ pef7071_driver.config = ltq_phy_config;
++ pef7071_driver.startup = ltq_phy_startup;
++ pef7071_driver.shutdown = genphy_shutdown;
++ pef7071_driver.name += gd->reloc_off;
++
++ xrx_genphy_driver.config = genphy_config;
++ xrx_genphy_driver.startup = ltq_phy_startup;
++ xrx_genphy_driver.shutdown = genphy_shutdown;
++ xrx_genphy_driver.name += gd->reloc_off;
++#endif
++
++ phy_register(&xrx_11g_13_driver);
++ phy_register(&xrx_11g_14_driver);
++ phy_register(&xrx_22f_14_driver);
++ phy_register(&pef7071_driver);
++ phy_register(&xrx_genphy_driver);
++
++ return 0;
++}
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -32,6 +32,8 @@
+ #include <phy.h>
+ #include <errno.h>
+
++DECLARE_GLOBAL_DATA_PTR;
++
+ /* Generic PHY support and helper functions */
+
+ /**
+@@ -420,6 +422,16 @@ static LIST_HEAD(phy_drivers);
+
+ int phy_init(void)
+ {
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++ INIT_LIST_HEAD(&phy_drivers);
++
++ genphy_driver.config = genphy_config;
++ genphy_driver.startup = genphy_startup;
++ genphy_driver.shutdown = genphy_shutdown;
++
++ genphy_driver.name += gd->reloc_off;
++#endif
++
+ #ifdef CONFIG_PHY_ATHEROS
+ phy_atheros_init();
+ #endif
+@@ -429,6 +441,9 @@ int phy_init(void)
+ #ifdef CONFIG_PHY_DAVICOM
+ phy_davicom_init();
+ #endif
++#ifdef CONFIG_PHY_LANTIQ
++ phy_lantiq_init();
++#endif
+ #ifdef CONFIG_PHY_LXT
+ phy_lxt_init();
+ #endif
+--- a/drivers/serial/Makefile
++++ b/drivers/serial/Makefile
+@@ -42,6 +42,7 @@ COBJS-$(CONFIG_SYS_NS16550_SERIAL) += se
+ COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
+ COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
+ COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
++COBJS-$(CONFIG_LANTIQ_SERIAL) += serial_lantiq.o
+ COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
+ COBJS-$(CONFIG_MXC_UART) += serial_mxc.o
+ COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
+--- /dev/null
++++ b/drivers/serial/serial_lantiq.c
+@@ -0,0 +1,264 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <serial.h>
++#include <asm/errno.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#if CONFIG_CONSOLE_ASC == 0
++#define LTQ_ASC_BASE LTQ_ASC0_BASE
++#else
++#define LTQ_ASC_BASE LTQ_ASC1_BASE
++#endif
++
++#define LTQ_ASC_ID_TXFS_SHIFT 24
++#define LTQ_ASC_ID_TXFS_MASK (0x3F << LTQ_ASC_ID_TXFS_SHIFT)
++#define LTQ_ASC_ID_RXFS_SHIFT 16
++#define LTQ_ASC_ID_RXFS_MASK (0x3F << LTQ_ASC_ID_RXFS_SHIFT)
++
++#define LTQ_ASC_MCON_R (1 << 15)
++#define LTQ_ASC_MCON_FDE (1 << 9)
++
++#define LTQ_ASC_WHBSTATE_SETREN (1 << 1)
++#define LTQ_ASC_WHBSTATE_CLRREN (1 << 0)
++
++#define LTQ_ASC_RXFCON_RXFITL_SHIFT 8
++#define LTQ_ASC_RXFCON_RXFITL_MASK (0x3F << LTQ_ASC_RXFCON_RXFITL_SHIFT)
++#define LTQ_ASC_RXFCON_RXFITL_RXFFLU (1 << 1)
++#define LTQ_ASC_RXFCON_RXFITL_RXFEN (1 << 0)
++
++#define LTQ_ASC_TXFCON_TXFITL_SHIFT 8
++#define LTQ_ASC_TXFCON_TXFITL_MASK (0x3F << LTQ_ASC_TXFCON_TXFITL_SHIFT)
++#define LTQ_ASC_TXFCON_TXFITL_TXFFLU (1 << 1)
++#define LTQ_ASC_TXFCON_TXFITL_TXFEN (1 << 0)
++
++#define LTQ_ASC_FSTAT_TXFREE_SHIFT 24
++#define LTQ_ASC_FSTAT_TXFREE_MASK (0x3F << LTQ_ASC_FSTAT_TXFREE_SHIFT)
++#define LTQ_ASC_FSTAT_RXFREE_SHIFT 16
++#define LTQ_ASC_FSTAT_RXFREE_MASK (0x3F << LTQ_ASC_FSTAT_RXFREE_SHIFT)
++#define LTQ_ASC_FSTAT_TXFFL_SHIFT 8
++#define LTQ_ASC_FSTAT_TXFFL_MASK (0x3F << LTQ_ASC_FSTAT_TXFFL_SHIFT)
++#define LTQ_ASC_FSTAT_RXFFL_MASK 0x3F
++
++#ifdef __BIG_ENDIAN
++#define LTQ_ASC_RBUF_OFFSET 3
++#define LTQ_ASC_TBUF_OFFSET 3
++#else
++#define LTQ_ASC_RBUF_OFFSET 0
++#define LTQ_ASC_TBUF_OFFSET 0
++#endif
++
++struct ltq_asc_regs {
++ u32 clc;
++ u32 pisel;
++ u32 id;
++ u32 rsvd0;
++ u32 mcon;
++ u32 state;
++ u32 whbstate;
++ u32 rsvd1;
++ u8 tbuf[4];
++ u8 rbuf[4];
++ u32 rsvd2[2];
++ u32 abcon;
++ u32 abstat;
++ u32 whbabcon;
++ u32 whbabstat;
++ u32 rxfcon;
++ u32 txfcon;
++ u32 fstat;
++ u32 rsvd3;
++ u32 bg;
++ u32 bg_timer;
++ u32 fdv;
++ u32 pmw;
++ u32 modcon;
++ u32 modstat;
++};
++
++DECLARE_GLOBAL_DATA_PTR;
++
++static struct ltq_asc_regs *ltq_asc_regs =
++ (struct ltq_asc_regs *) CKSEG1ADDR(LTQ_ASC_BASE);
++
++static int ltq_serial_init(void)
++{
++ /* Set clock divider for normal run mode to 1 and enable module */
++ ltq_writel(&ltq_asc_regs->clc, 0x100);
++
++ /* Reset MCON register */
++ ltq_writel(&ltq_asc_regs->mcon, 0);
++
++ /* Use Port A as receiver input */
++ ltq_writel(&ltq_asc_regs->pisel, 0);
++
++ /* Enable and flush RX/TX FIFOs */
++ ltq_setbits(&ltq_asc_regs->rxfcon,
++ LTQ_ASC_RXFCON_RXFITL_RXFFLU | LTQ_ASC_RXFCON_RXFITL_RXFEN);
++ ltq_setbits(&ltq_asc_regs->txfcon,
++ LTQ_ASC_TXFCON_TXFITL_TXFFLU | LTQ_ASC_TXFCON_TXFITL_TXFEN);
++
++ serial_setbrg();
++
++ /* Disable error flags, enable receiver */
++ ltq_writel(&ltq_asc_regs->whbstate, LTQ_ASC_WHBSTATE_SETREN);
++
++ return 0;
++}
++
++/*
++ * fdv asc_clk
++ * Baudrate = ----- * -------------
++ * 512 16 * (bg + 1)
++ */
++static void ltq_serial_calc_br_fdv(unsigned long asc_clk,
++ unsigned long baudrate, u16 *fdv,
++ u16 *bg)
++{
++ const u32 c = asc_clk / (16 * 512);
++ u32 diff1, diff2;
++ u32 bg_calc, br_calc, i;
++
++ diff1 = baudrate;
++ for (i = 512; i > 0; i--) {
++ /* Calc bg for current fdv value */
++ bg_calc = i * c / baudrate;
++
++ /* Impossible baudrate */
++ if (!bg_calc)
++ return;
++
++ /*
++ * Calc diff to target baudrate dependent on current
++ * bg and fdv values
++ */
++ br_calc = i * c / bg_calc;
++ if (br_calc > baudrate)
++ diff2 = br_calc - baudrate;
++ else
++ diff2 = baudrate - br_calc;
++
++ /* Perfect values found */
++ if (diff2 == 0) {
++ *fdv = i;
++ *bg = bg_calc - 1;
++ return;
++ }
++
++ if (diff2 < diff1) {
++ *fdv = i;
++ *bg = bg_calc - 1;
++ diff1 = diff2;
++ }
++ }
++}
++
++static void ltq_serial_setbrg(void)
++{
++ unsigned long asc_clk, baudrate;
++ u16 bg = 0;
++ u16 fdv = 511;
++
++ /* ASC clock is same as FPI clock with CLC.RMS = 1 */
++ asc_clk = ltq_get_bus_clock();
++ baudrate = gd->baudrate;
++
++ /* Calculate FDV and BG values */
++ ltq_serial_calc_br_fdv(asc_clk, baudrate, &fdv, &bg);
++
++ /* Disable baudrate generator */
++ ltq_clrbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
++
++ /* Enable fractional divider */
++ ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_FDE);
++
++ /* Set fdv and bg values */
++ ltq_writel(&ltq_asc_regs->fdv, fdv);
++ ltq_writel(&ltq_asc_regs->bg, bg);
++
++ /* Enable baudrate generator */
++ ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
++}
++
++static unsigned int ltq_serial_tx_free(void)
++{
++ unsigned int txfree;
++
++ txfree = (ltq_readl(&ltq_asc_regs->fstat) &
++ LTQ_ASC_FSTAT_TXFREE_MASK) >>
++ LTQ_ASC_FSTAT_TXFREE_SHIFT;
++
++ return txfree;
++}
++
++static unsigned int ltq_serial_rx_fill(void)
++{
++ unsigned int rxffl;
++
++ rxffl = ltq_readl(&ltq_asc_regs->fstat) & LTQ_ASC_FSTAT_RXFFL_MASK;
++
++ return rxffl;
++}
++
++static void ltq_serial_tx(const char c)
++{
++ ltq_writeb(&ltq_asc_regs->tbuf[LTQ_ASC_TBUF_OFFSET], c);
++}
++
++static u8 ltq_serial_rx(void)
++{
++ return ltq_readb(&ltq_asc_regs->rbuf[LTQ_ASC_RBUF_OFFSET]);
++}
++
++static void ltq_serial_putc(const char c)
++{
++ if (c == '\n')
++ ltq_serial_putc('\r');
++
++ while (!ltq_serial_tx_free())
++ ;
++
++ ltq_serial_tx(c);
++}
++
++static int ltq_serial_getc(void)
++{
++ while (!ltq_serial_rx_fill())
++ ;
++
++ return ltq_serial_rx();
++}
++
++static int ltq_serial_tstc(void)
++{
++ return (0 != ltq_serial_rx_fill());
++}
++
++static struct serial_device ltq_serial_drv = {
++ .name = "ixp_serial",
++ .start = ltq_serial_init,
++ .stop = NULL,
++ .setbrg = ltq_serial_setbrg,
++ .putc = ltq_serial_putc,
++ .puts = default_serial_puts,
++ .getc = ltq_serial_getc,
++ .tstc = ltq_serial_tstc,
++};
++
++void ixp_serial_initialize(void)
++{
++ serial_register(&ltq_serial_drv);
++}
++
++__weak struct serial_device *default_serial_console(void)
++{
++ return &ltq_serial_drv;
++}
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -36,6 +36,7 @@ COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
+ COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
+ COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
+ COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
++COBJS-$(CONFIG_LANTIQ_SPI) += lantiq_spi.o
+ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
+ COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
+ COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
+--- /dev/null
++++ b/drivers/spi/lantiq_spi.c
+@@ -0,0 +1,476 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <spi.h>
++#include <malloc.h>
++#include <watchdog.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_SPI_CLC_RMC_SHIFT 8
++#define LTQ_SPI_CLC_RMC_MASK (0xFF << LTQ_SPI_CLC_RMC_SHIFT)
++#define LTQ_SPI_CLC_DISS (1 << 1)
++#define LTQ_SPI_CLC_DISR 1
++
++#define LTQ_SPI_ID_TXFS_SHIFT 24
++#define LTQ_SPI_ID_TXFS_MASK (0x3F << LTQ_SPI_ID_TXFS_SHIFT)
++#define LTQ_SPI_ID_RXFS_SHIFT 16
++#define LTQ_SPI_ID_RXFS_MASK (0x3F << LTQ_SPI_ID_RXFS_SHIFT)
++
++#define LTQ_SPI_CON_ENBV (1 << 22)
++#define LTQ_SPI_CON_BM_SHIFT 16
++#define LTQ_SPI_CON_BM_MASK (0x1F << LTQ_SPI_CON_BM_SHIFT)
++#define LTQ_SPI_CON_LB (1 << 7)
++#define LTQ_SPI_CON_PO (1 << 6)
++#define LTQ_SPI_CON_PH (1 << 5)
++#define LTQ_SPI_CON_HB (1 << 4)
++#define LTQ_SPI_CON_RXOFF (1 << 1)
++#define LTQ_SPI_CON_TXOFF 1
++
++#define LTQ_SPI_STAT_RXBV_SHIFT 28
++#define LTQ_SPI_STAT_RXBV_MASK (0x7 << LTQ_SPI_STAT_RXBV_SHIFT)
++#define LTQ_SPI_STAT_BSY (1 << 13)
++
++#define LTQ_SPI_WHBSTATE_SETMS (1 << 3)
++#define LTQ_SPI_WHBSTATE_CLRMS (1 << 2)
++#define LTQ_SPI_WHBSTATE_SETEN (1 << 1)
++#define LTQ_SPI_WHBSTATE_CLREN 1
++
++#define LTQ_SPI_TXFCON_TXFLU (1 << 1)
++#define LTQ_SPI_TXFCON_TXFEN 1
++
++#define LTQ_SPI_RXFCON_RXFLU (1 << 1)
++#define LTQ_SPI_RXFCON_RXFEN 1
++
++#define LTQ_SPI_FSTAT_RXFFL_MASK 0x3f
++#define LTQ_SPI_FSTAT_TXFFL_SHIFT 8
++#define LTQ_SPI_FSTAT_TXFFL_MASK (0x3f << LTQ_SPI_FSTAT_TXFFL_SHIFT)
++
++#define LTQ_SPI_RXREQ_RXCNT_MASK 0xFFFF
++#define LTQ_SPI_RXCNT_TODO_MASK 0xFFFF
++
++#define LTQ_SPI_GPIO_DIN 16
++#define LTQ_SPI_GPIO_DOUT 17
++#define LTQ_SPI_GPIO_CLK 18
++
++struct ltq_spi_regs {
++ u32 clc; /* Clock control */
++ u32 pisel; /* Port input select */
++ u32 id; /* Identification */
++ u32 rsvd0;
++ u32 con; /* Control */
++ u32 stat; /* Status */
++ u32 whbstate; /* Write HW modified state */
++ u32 rsvd1;
++ u32 tb; /* Transmit buffer */
++ u32 rb; /* Receive buffer */
++ u32 rsvd2[2];
++ u32 rxfcon; /* Recevie FIFO control */
++ u32 txfcon; /* Transmit FIFO control */
++ u32 fstat; /* FIFO status */
++ u32 rsvd3;
++ u32 brt; /* Baudrate timer */
++ u32 brstat; /* Baudrate timer status */
++ u32 rsvd4[6];
++ u32 sfcon; /* Serial frame control */
++ u32 sfstat; /* Serial frame status */
++ u32 rsvd5[2];
++ u32 gpocon; /* General purpose output control */
++ u32 gpostat; /* General purpose output status */
++ u32 fgpo; /* Force general purpose output */
++ u32 rsvd6;
++ u32 rxreq; /* Receive request */
++ u32 rxcnt; /* Receive count */
++ u32 rsvd7[25];
++ u32 dmacon; /* DMA control */
++};
++
++struct ltq_spi_slave {
++ struct spi_slave slave;
++ unsigned int max_hz;
++ unsigned int mode;
++ unsigned int len;
++ unsigned int brt;
++ unsigned int tx_cnt;
++ unsigned int rx_cnt;
++ unsigned int rx_req;
++ const u8 *tx;
++ u8 *rx;
++ u8 txfs;
++ u8 rxfs;
++};
++
++static inline struct ltq_spi_slave *to_ltq_spi_slave(struct spi_slave *slave)
++{
++ return container_of(slave, struct ltq_spi_slave, slave);
++}
++
++#ifdef CONFIG_SPL_BUILD
++/*
++ * We do not have or want malloc in a SPI flash SPL.
++ * Neither we have to support multiple SPI slaves. Thus we put the
++ * SPI slave context in BSS for SPL builds.
++ */
++static struct ltq_spi_slave ltq_spi_slave;
++
++static inline struct ltq_spi_slave *ltq_spi_slave_alloc(void)
++{
++ return &ltq_spi_slave;
++}
++
++static inline void ltq_spi_slave_free(struct spi_slave *slave)
++{
++}
++#else
++static inline struct ltq_spi_slave *ltq_spi_slave_alloc(void)
++{
++ return malloc(sizeof(struct ltq_spi_slave));
++}
++
++static inline void ltq_spi_slave_free(struct spi_slave *slave)
++{
++ struct ltq_spi_slave *sl;
++
++ if (slave) {
++ sl = to_ltq_spi_slave(slave);
++ free(sl);
++ }
++}
++#endif
++
++static struct ltq_spi_regs *ltq_spi_regs =
++ (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE);
++
++void spi_init(void)
++{
++ /* Power up SPI subsystem */
++ ltq_pm_enable(LTQ_PM_SPI);
++
++ /* Enable module and set clock divider to 1 */
++ ltq_writel(&ltq_spi_regs->clc, 1 << LTQ_SPI_CLC_RMC_SHIFT);
++
++ /* SPI/DIN input */
++ gpio_set_altfunc(16, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++ /* SPI/DOUT output */
++ gpio_set_altfunc(17, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* SPI/CLK output */
++ gpio_set_altfunc(18, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++static inline u32 ltq_spi_calc_br(unsigned int max_hz)
++{
++ u32 speed_hz, spi_hz;
++ u16 brt;
++
++ /* SPI module clock is same as FPI bus clock */
++ spi_hz = ltq_get_bus_clock();
++
++ /*
++ * f_SPI
++ * baudrate = --------------
++ * 2 * (BR + 1)
++ */
++ spi_hz /= 2;
++
++ for (brt = 0; brt < 0xFFFF; brt++) {
++ speed_hz = spi_hz / (brt + 1);
++ if (speed_hz <= max_hz)
++ break;
++ }
++
++ return brt;
++}
++
++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
++ unsigned int max_hz, unsigned int mode)
++{
++ u32 id;
++ struct ltq_spi_slave *sl;
++
++ if (!spi_cs_is_valid(bus, cs))
++ return NULL;
++
++ sl = ltq_spi_slave_alloc();
++ if (!sl)
++ return NULL;
++
++ /* Read HW capabilities */
++ id = ltq_readl(&ltq_spi_regs->id);
++ sl->txfs = (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT;
++ sl->rxfs = (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT;
++
++ sl->slave.bus = bus;
++ sl->slave.cs = cs;
++ sl->max_hz = max_hz;
++ sl->mode = mode;
++
++ sl->brt = ltq_spi_calc_br(max_hz);
++
++ return &sl->slave;
++}
++
++void spi_free_slave(struct spi_slave *slave)
++{
++ ltq_spi_slave_free(slave);
++}
++
++static int ltq_spi_wait_ready(struct ltq_spi_slave *sl)
++{
++ u32 stat;
++ const unsigned long timeout = 20000;
++ unsigned long timebase;
++
++ timebase = get_timer(0);
++
++ do {
++ WATCHDOG_RESET();
++
++ stat = ltq_readl(&ltq_spi_regs->stat);
++
++ if (!(stat & LTQ_SPI_STAT_BSY))
++ return 0;
++ } while (get_timer(timebase) < timeout);
++
++ return 1;
++}
++
++int spi_claim_bus(struct spi_slave *slave)
++{
++ struct ltq_spi_slave *sl = to_ltq_spi_slave(slave);
++ u32 con;
++ int ret;
++
++ /* Put module in configuration mode */
++ ltq_setbits(&ltq_spi_regs->whbstate, LTQ_SPI_WHBSTATE_CLREN);
++
++ /* Enable and flush RX and TX FIFOs */
++ ltq_setbits(&ltq_spi_regs->txfcon,
++ LTQ_SPI_TXFCON_TXFLU | LTQ_SPI_TXFCON_TXFEN);
++ ltq_setbits(&ltq_spi_regs->rxfcon,
++ LTQ_SPI_RXFCON_RXFLU | LTQ_SPI_RXFCON_RXFEN);
++
++ ret = ltq_spi_wait_ready(sl);
++ if (ret)
++ return ret;
++
++ /* Set baudrate */
++ ltq_writel(&ltq_spi_regs->brt, sl->brt);
++
++ /*
++ * Disable byte valid control (ENBV = 0) and
++ * set data width to 8 bit (BM = 7)
++ */
++ con = (7 << LTQ_SPI_CON_BM_SHIFT);
++
++ /* Disable transmitter and receiver */
++ con |= (LTQ_SPI_CON_RXOFF | LTQ_SPI_CON_TXOFF);
++
++ /* Set SPI mode
++ * Mapping: Mode CPOL CPHA CON.PO CON.PH
++ * 0 0 0 0 1
++ * 1 0 1 0 0
++ * 2 1 0 1 1
++ * 3 1 1 1 0
++ */
++ if (sl->mode & SPI_CPHA)
++ con &= ~LTQ_SPI_CON_PH;
++ else
++ con |= LTQ_SPI_CON_PH;
++
++ if (sl->mode & SPI_CPOL)
++ con |= LTQ_SPI_CON_PO;
++ else
++ con &= ~LTQ_SPI_CON_PO;
++
++ /* Set heading control */
++ if (sl->mode & SPI_LSB_FIRST)
++ con &= ~LTQ_SPI_CON_HB;
++ else
++ con |= LTQ_SPI_CON_HB;
++
++ /* Set loopback control */
++ if (sl->mode & SPI_LOOP)
++ con |= LTQ_SPI_CON_LB;
++ else
++ con &= ~LTQ_SPI_CON_LB;
++
++ ltq_writel(&ltq_spi_regs->con, con);
++
++ /* Set SPI master mode and enable SPI */
++ ltq_setbits(&ltq_spi_regs->whbstate,
++ LTQ_SPI_WHBSTATE_SETEN | LTQ_SPI_WHBSTATE_SETMS);
++
++ return 0;
++}
++
++void spi_release_bus(struct spi_slave *slave)
++{
++ /* Put module in configuration mode */
++ ltq_setbits(&ltq_spi_regs->whbstate, LTQ_SPI_WHBSTATE_CLREN);
++
++ /* Flush RX and TX FIFOs */
++ ltq_setbits(&ltq_spi_regs->txfcon, LTQ_SPI_TXFCON_TXFLU);
++ ltq_setbits(&ltq_spi_regs->rxfcon, LTQ_SPI_RXFCON_RXFLU);
++}
++
++static inline void ltq_spi_txfifo_write(struct ltq_spi_slave *sl)
++{
++ u32 fstat, tb;
++ u16 fifo_space;
++
++ fstat = ltq_readl(&ltq_spi_regs->fstat);
++ fifo_space = sl->txfs - ((fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >>
++ LTQ_SPI_FSTAT_TXFFL_SHIFT);
++
++ while (sl->tx_cnt < sl->len && fifo_space) {
++ tb = *sl->tx++;
++ ltq_writel(&ltq_spi_regs->tb, tb);
++ fifo_space--;
++ sl->tx_cnt++;
++ }
++}
++
++static inline void ltq_spi_rx_request(struct ltq_spi_slave *sl)
++{
++ u32 rxreq, rxreq_max;
++
++ /*
++ * In RX-only mode the serial clock is activated only after writing
++ * the expected amount of RX bytes into RXREQ register.
++ * To avoid receive overflows at high clocks it is better to request
++ * only the amount of bytes that fits into all FIFOs. This value
++ * depends on the FIFO size implemented in hardware.
++ */
++ rxreq = sl->len - sl->rx_cnt;
++ rxreq_max = sl->rxfs << 2;
++ rxreq = min(rxreq_max, rxreq);
++
++ if (!sl->rx_req && rxreq && sl->rx_cnt < sl->len) {
++ ltq_writel(&ltq_spi_regs->rxreq, rxreq);
++ sl->rx_req = rxreq;
++ }
++}
++
++static void ltq_spi_rxfifo_read(struct ltq_spi_slave *sl)
++{
++ u32 fstat, data, *rx32;
++ u16 fifo_fill;
++ u8 rxbv, shift, *rx8;
++
++ /* Determine how much FIFOs are filled with RX data */
++ fstat = ltq_readl(&ltq_spi_regs->fstat);
++ fifo_fill = fstat & LTQ_SPI_FSTAT_RXFFL_MASK;
++
++ /*
++ * The 32 bit FIFO is always used completely independent from the
++ * bits_per_word value. Thus four bytes have to be read at once
++ * per FIFO.
++ */
++ rx32 = (u32 *) sl->rx;
++ while (sl->len - sl->rx_cnt >= 4 && fifo_fill) {
++ data = ltq_readl(&ltq_spi_regs->rb);
++ *rx32++ = data;
++ sl->rx_cnt += 4;
++ sl->rx_req -= 4;
++ sl->rx += 4;
++ fifo_fill--;
++ }
++
++ /*
++ * If there are remaining bytes, read byte count from STAT.RXBV
++ * register and read the data byte-wise.
++ */
++ while (fifo_fill && sl->rx_cnt < sl->len) {
++ fstat = ltq_readl(&ltq_spi_regs->stat);
++ rxbv = (fstat & LTQ_SPI_STAT_RXBV_MASK) >>
++ LTQ_SPI_STAT_RXBV_SHIFT;
++
++ if (!rxbv)
++ break;
++
++ data = ltq_readl(&ltq_spi_regs->rb);
++
++ shift = (rxbv - 1) * 8;
++ rx8 = sl->rx;
++
++ while (rxbv) {
++ *rx8++ = (data >> shift) & 0xFF;
++ rxbv--;
++ shift -= 8;
++ sl->rx_cnt++;
++ sl->rx_req--;
++ sl->rx++;
++ }
++
++ fifo_fill--;
++ }
++}
++
++int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
++ const void *dout, void *din, unsigned long flags)
++{
++ struct ltq_spi_slave *sl = to_ltq_spi_slave(slave);
++ int ret;
++
++ if (bitlen % 8)
++ return 1;
++
++ if (!bitlen) {
++ ret = 0;
++ goto done;
++ }
++
++ sl->len = bitlen / 8;
++ sl->tx = dout;
++ sl->rx = din;
++ sl->tx_cnt = 0;
++ sl->rx_cnt = 0;
++ sl->rx_req = 0;
++
++ if (flags & SPI_XFER_BEGIN)
++ spi_cs_activate(slave);
++
++ /* Enable transmitter */
++ if (sl->tx)
++ ltq_clrbits(&ltq_spi_regs->con, LTQ_SPI_CON_TXOFF);
++
++ /* Enable receiver */
++ if (sl->rx)
++ ltq_clrbits(&ltq_spi_regs->con, LTQ_SPI_CON_RXOFF);
++
++ if (sl->tx)
++ ltq_spi_txfifo_write(sl);
++ else if (sl->rx)
++ ltq_spi_rx_request(sl);
++
++ while (sl->tx_cnt != sl->len && sl->rx_cnt != sl->len) {
++ if (sl->rx) {
++ ltq_spi_rxfifo_read(sl);
++
++ if (sl->tx)
++ ltq_spi_txfifo_write(sl);
++ else
++ ltq_spi_rx_request(sl);
++ } else if (sl->tx)
++ ltq_spi_txfifo_write(sl);
++ }
++
++ ret = ltq_spi_wait_ready(sl);
++
++done:
++ /* Disable transmitter and receiver */
++ ltq_setbits(&ltq_spi_regs->con, LTQ_SPI_CON_TXOFF | LTQ_SPI_CON_RXOFF);
++
++ if (flags & SPI_XFER_END)
++ spi_cs_deactivate(slave);
++
++ return ret;
++}
+--- /dev/null
++++ b/include/configs/easy50712.h
+@@ -0,0 +1,78 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "EASY50712"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "Lantiq EASY50712 Danube Reference Board"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++#define CONFIG_LTQ_SUPPORT_SPI_FLASH
++#define CONFIG_SPI_FLASH_ATMEL /* Have an AT45DB321D serial flash */
++
++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */
++
++#define CONFIG_LTQ_SPL_COMP_LZO
++#define CONFIG_LTQ_SPL_CONSOLE
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_ADM6996I
++
++/* Environment */
++#define CONFIG_ENV_SPI_BUS 0
++#define CONFIG_ENV_SPI_CS 2
++#define CONFIG_ENV_SPI_MAX_HZ 20000000
++#define CONFIG_ENV_SPI_MODE 0
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (256 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (128 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE (8 * 1024)
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR
++
++#endif /* __CONFIG_H */
+--- /dev/null
++++ b/include/configs/easy80920.h
+@@ -0,0 +1,93 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "EASY80920"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "Lantiq EASY80920 VRX200 Family Board"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++#define CONFIG_LTQ_SUPPORT_SPI_FLASH
++#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29LV620 serial flash */
++
++#define CONFIG_LTQ_SUPPORT_NAND_FLASH
++
++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */
++#define CONFIG_SPL_SPI_BUS 0
++#define CONFIG_SPL_SPI_CS 4
++#define CONFIG_SPL_SPI_MAX_HZ 25000000
++#define CONFIG_SPL_SPI_MODE 0
++
++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */
++
++#define CONFIG_LTQ_SPL_COMP_LZO
++#define CONFIG_LTQ_SPL_CONSOLE
++
++#define CONFIG_SYS_DRAM_PROBE
++
++/* Environment */
++#define CONFIG_ENV_SPI_BUS CONFIG_SPL_SPI_BUS
++#define CONFIG_ENV_SPI_CS CONFIG_SPL_SPI_CS
++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SPL_SPI_MAX_HZ
++#define CONFIG_ENV_SPI_MODE CONFIG_SPL_SPI_MODE
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (384 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_ENV_IS_IN_SPI_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE (8 * 1024)
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
++
++#define CONFIG_ENV_UPDATE_UBOOT_SF \
++ "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR \
++ CONFIG_ENV_UPDATE_UBOOT_SF
++
++#endif /* __CONFIG_H */
+--- a/include/phy.h
++++ b/include/phy.h
+@@ -220,6 +220,7 @@ int gen10g_discover_mmds(struct phy_devi
+ int phy_atheros_init(void);
+ int phy_broadcom_init(void);
+ int phy_davicom_init(void);
++int phy_lantiq_init(void);
+ int phy_lxt_init(void);
+ int phy_marvell_init(void);
+ int phy_micrel_init(void);
+--- a/spl/Makefile
++++ b/spl/Makefile
+@@ -81,6 +81,8 @@ LIBS-$(CONFIG_SPL_POST_MEM_SUPPORT) += p
+ LIBS-$(CONFIG_SPL_NET_SUPPORT) += net/libnet.o
+ LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/libnet.o
+ LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/libphy.o
++LIBS-$(CONFIG_SPL_LZMA_SUPPORT) += lib/lzma/liblzma.o
++LIBS-$(CONFIG_SPL_LZO_SUPPORT) += lib/lzo/liblzo.o
+
+ ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+ LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
+--- a/tools/.gitignore
++++ b/tools/.gitignore
+@@ -2,6 +2,7 @@
+ /envcrc
+ /gen_eth_addr
+ /img2srec
++/ltq-boot-image
+ /kwboot
+ /mkenvimage
+ /mkimage
+--- a/tools/Makefile
++++ b/tools/Makefile
+@@ -65,6 +65,7 @@ BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_lo
+ BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
+ BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX)
+ BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
++BIN_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image$(SFX)
+ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
+ BIN_FILES-y += mkenvimage$(SFX)
+ BIN_FILES-y += mkimage$(SFX)
+@@ -89,6 +90,7 @@ OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envc
+ NOPED_OBJ_FILES-y += fit_image.o
+ OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
+ OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
++OBJ_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image.o
+ OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
+ NOPED_OBJ_FILES-y += aisimage.o
+ NOPED_OBJ_FILES-y += kwbimage.o
+@@ -193,6 +195,10 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o
+ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+ $(HOSTSTRIP) $@
+
++$(obj)ltq-boot-image$(SFX): $(obj)ltq-boot-image.o
++ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
++ $(HOSTSTRIP) $@
++
+ $(obj)xway-swap-bytes$(SFX): $(obj)xway-swap-bytes.o
+ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+ $(HOSTSTRIP) $@
+--- /dev/null
++++ b/tools/ltq-boot-image.c
+@@ -0,0 +1,316 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <getopt.h>
++#include <compiler.h>
++#include <sys/stat.h>
++
++enum image_types {
++ IMAGE_NONE,
++ IMAGE_SFSPL
++};
++
++/* Lantiq non-volatile bootstrap command IDs */
++enum nvb_cmd_ids {
++ NVB_CMD_DEBUG = 0x11,
++ NVB_CMD_REGCFG = 0x22,
++ NVB_CMD_IDWNLD = 0x33,
++ NVB_CMD_CDWNLD = 0x44,
++ NVB_CMD_DWNLD = 0x55,
++ NVB_CMD_IFCFG = 0x66,
++ NVB_CMD_START = 0x77
++};
++
++/* Lantiq non-volatile bootstrap command flags */
++enum nvb_cmd_flags {
++ NVB_FLAG_START = 1,
++ NVB_FLAG_DEC = (1 << 1),
++ NVB_FLAG_DBG = (1 << 2),
++ NVB_FLAG_SDBG = (1 << 3),
++ NVB_FLAG_CFG0 = (1 << 4),
++ NVB_FLAG_CFG1 = (1 << 5),
++ NVB_FLAG_CFG2 = (1 << 6),
++ NVB_FLAG_RST = (1 << 7)
++};
++
++struct args {
++ enum image_types type;
++ __u32 entry_addr;
++ const char *uboot_bin;
++ const char *spl_bin;
++ const char *out_bin;
++};
++
++static void usage_msg(const char *name)
++{
++ fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n",
++ name);
++ fprintf(stderr, " Image types:\n"
++ " sfspl - SPL + [compressed] U-Boot for SPI flash\n");
++}
++
++static enum image_types parse_image_type(const char *type)
++{
++ if (!type)
++ return IMAGE_NONE;
++
++ if (!strncmp(type, "sfspl", 6))
++ return IMAGE_SFSPL;
++
++ return IMAGE_NONE;
++}
++
++static int parse_args(int argc, char *argv[], struct args *arg)
++{
++ int opt;
++
++ memset(arg, 0, sizeof(*arg));
++
++ while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) {
++ switch (opt) {
++ case 'h':
++ usage_msg(argv[0]);
++ return 1;
++ case 't':
++ arg->type = parse_image_type(optarg);
++ break;
++ case 'e':
++ arg->entry_addr = strtoul(optarg, NULL, 16);
++ break;
++ case 'u':
++ arg->uboot_bin = optarg;
++ break;
++ case 's':
++ arg->spl_bin = optarg;
++ break;
++ case 'o':
++ arg->out_bin = optarg;
++ break;
++ default:
++ fprintf(stderr, "Invalid option -%c\n", opt);
++ goto parse_error;
++ }
++ }
++
++ if (arg->type == IMAGE_NONE) {
++ fprintf(stderr, "Invalid image type\n");
++ goto parse_error;
++ }
++
++ if (!arg->uboot_bin) {
++ fprintf(stderr, "Missing U-Boot binary\n");
++ goto parse_error;
++ }
++
++ if (!arg->out_bin) {
++ fprintf(stderr, "Missing output binary\n");
++ goto parse_error;
++ }
++
++ if (arg->type == IMAGE_SFSPL && !arg->spl_bin) {
++ fprintf(stderr, "Missing SPL binary\n");
++ goto parse_error;
++ }
++
++ return 0;
++
++parse_error:
++ usage_msg(argv[0]);
++ return -1;
++}
++
++static __u32 build_nvb_command(unsigned cmdid, unsigned cmdflags)
++{
++ __u32 cmd;
++ __u16 tag;
++
++ tag = (cmdid << 8) | cmdflags;
++ cmd = (tag << 16) | (0xFFFF - tag);
++
++ return cpu_to_be32(cmd);
++}
++
++static int write_header(int fd, const void *hdr, size_t size)
++{
++ ssize_t n;
++
++ n = write(fd, hdr, size);
++ if (n != size) {
++ fprintf(stderr, "Cannot write header: %s\n",
++ strerror(errno));
++ return -1;
++ }
++
++ return 0;
++}
++
++static int write_nvb_dwnld_header(int fd, size_t size, __u32 addr)
++{
++ __u32 hdr[3];
++
++ hdr[0] = build_nvb_command(NVB_CMD_DWNLD, NVB_FLAG_START |
++ NVB_FLAG_SDBG);
++ hdr[1] = cpu_to_be32(size + 4);
++ hdr[2] = cpu_to_be32(addr);
++
++ return write_header(fd, hdr, sizeof(hdr));
++}
++
++static int write_nvb_start_header(int fd, __u32 addr)
++{
++ __u32 hdr[3];
++
++ hdr[0] = build_nvb_command(NVB_CMD_START, NVB_FLAG_SDBG);
++ hdr[1] = cpu_to_be32(4);
++ hdr[2] = cpu_to_be32(addr);
++
++ return write_header(fd, hdr, sizeof(hdr));
++}
++
++static int open_input_bin(const char *name, void **ptr, size_t *size)
++{
++ struct stat sbuf;
++ int ret, fd;
++
++ fd = open(name, O_RDONLY | O_BINARY);
++ if (0 > fd) {
++ fprintf(stderr, "Cannot open %s: %s\n", name,
++ strerror(errno));
++ return -1;
++ }
++
++ ret = fstat(fd, &sbuf);
++ if (0 > ret) {
++ fprintf(stderr, "Cannot fstat %s: %s\n", name,
++ strerror(errno));
++ return -1;
++ }
++
++ *ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
++ if (*ptr == MAP_FAILED) {
++ fprintf(stderr, "Cannot mmap %s: %s\n", name,
++ strerror(errno));
++ return -1;
++ }
++
++ *size = sbuf.st_size;
++
++ return fd;
++}
++
++static void close_input_bin(int fd, void *ptr, size_t size)
++{
++ munmap(ptr, size);
++ close(fd);
++}
++
++static int copy_bin(int fd, void *ptr, size_t size)
++{
++ ssize_t n;
++
++ n = write(fd, ptr, size);
++ if (n != size) {
++ fprintf(stderr, "Cannot copy binary: %s\n", strerror(errno));
++ return -1;
++ }
++
++ return 0;
++}
++
++static int open_output_bin(const char *name)
++{
++ int fd;
++
++ fd = open(name, O_RDWR | O_CREAT | O_TRUNC | O_SYNC | O_BINARY, 0666);
++ if (0 > fd) {
++ fprintf(stderr, "Cannot open %s: %s\n", name,
++ strerror(errno));
++ return -1;
++ }
++
++ return fd;
++}
++
++static int create_sfspl(const struct args *arg)
++{
++ int out_fd, uboot_fd, spl_fd, ret;
++ void *uboot_ptr, *spl_ptr;
++ size_t uboot_size, spl_size;
++
++ out_fd = open_output_bin(arg->out_bin);
++ if (0 > out_fd)
++ goto err;
++
++ spl_fd = open_input_bin(arg->spl_bin, &spl_ptr, &spl_size);
++ if (0 > spl_fd)
++ goto err_spl;
++
++ uboot_fd = open_input_bin(arg->uboot_bin, &uboot_ptr, &uboot_size);
++ if (0 > uboot_fd)
++ goto err_uboot;
++
++ ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr);
++ if (ret)
++ goto err_write;
++
++ ret = copy_bin(out_fd, spl_ptr, spl_size);
++ if (ret)
++ goto err_write;
++
++ ret = write_nvb_start_header(out_fd, arg->entry_addr);
++ if (ret)
++ goto err_write;
++
++ ret = copy_bin(out_fd, uboot_ptr, uboot_size);
++ if (ret)
++ goto err_write;
++
++ close_input_bin(uboot_fd, uboot_ptr, uboot_size);
++ close_input_bin(spl_fd, spl_ptr, spl_size);
++ close(out_fd);
++
++ return 0;
++
++err_write:
++ close_input_bin(uboot_fd, uboot_ptr, uboot_size);
++err_uboot:
++ close_input_bin(spl_fd, spl_ptr, spl_size);
++err_spl:
++ close(out_fd);
++err:
++ return -1;
++}
++
++int main(int argc, char *argv[])
++{
++ int ret;
++ struct args arg;
++
++ ret = parse_args(argc, argv, &arg);
++ if (ret)
++ goto done;
++
++ switch (arg.type) {
++ case IMAGE_SFSPL:
++ ret = create_sfspl(&arg);
++ break;
++ default:
++ fprintf(stderr, "Image type not implemented\n");
++ ret = -1;
++ break;
++ }
++
++done:
++ if (ret >= 0)
++ return EXIT_SUCCESS;
++
++ return EXIT_FAILURE;
++}
diff --git a/package/boot/uboot-lantiq/patches/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch b/package/boot/uboot-lantiq/patches/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch
new file mode 100644
index 0000000..ba24bae
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch
@@ -0,0 +1,33 @@
+From 2c6115188c7353a601835885a6c544240cfc479e Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Fri, 30 Nov 2012 18:09:25 +0100
+Subject: MIPS: VRX200: add option to boot from AVM EVA loader
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/arch/mips/cpu/mips32/vrx200/config.mk
++++ b/arch/mips/cpu/mips32/vrx200/config.mk
+@@ -17,6 +17,9 @@ endif
+ LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
+
+ ifndef CONFIG_SPL_BUILD
++ifdef CONFIG_SYS_BOOT_EVA
++ALL-y += $(obj)u-boot.bin.lzma
++endif
+ ifdef CONFIG_SYS_BOOT_SFSPL
+ ALL-y += $(obj)u-boot.ltq.sfspl
+ ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
+--- a/arch/mips/include/asm/arch-vrx200/config.h
++++ b/arch/mips/include/asm/arch-vrx200/config.h
+@@ -161,6 +161,11 @@
+ #define CONFIG_SYS_DISABLE_CACHE
+ #endif
+
++#if defined(CONFIG_SYS_BOOT_EVA)
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#endif
++
+ #if defined(CONFIG_SYS_BOOT_NOR)
+ #define CONFIG_SYS_TEXT_BASE 0xB0000000
+ #endif
diff --git a/package/boot/uboot-lantiq/patches/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch b/package/boot/uboot-lantiq/patches/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch
new file mode 100644
index 0000000..b680a97
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch
@@ -0,0 +1,355 @@
+From 51f04c00e831b49587f9f766ff1af67d2122feb2 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Fri, 30 Nov 2012 18:09:47 +0100
+Subject: MIPS: add board support for AVM FritzBox 3370
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/avm/fb3370/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/avm/fb3370/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/avm/fb3370/ddr_settings.h
+@@ -0,0 +1,70 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#define MC_CCR00_VALUE 0x101
++#define MC_CCR01_VALUE 0x1000100
++#define MC_CCR02_VALUE 0x1010000
++#define MC_CCR03_VALUE 0x101
++#define MC_CCR04_VALUE 0x1000000
++#define MC_CCR05_VALUE 0x1000101
++#define MC_CCR06_VALUE 0x1000100
++#define MC_CCR07_VALUE 0x1010000
++#define MC_CCR08_VALUE 0x1000101
++#define MC_CCR09_VALUE 0x0
++#define MC_CCR10_VALUE 0x2000100
++#define MC_CCR11_VALUE 0x2000300
++#define MC_CCR12_VALUE 0x30000
++#define MC_CCR13_VALUE 0x202
++#define MC_CCR14_VALUE 0x7080A0F
++#define MC_CCR15_VALUE 0x2040F
++#define MC_CCR16_VALUE 0x40000
++#define MC_CCR17_VALUE 0x70102
++#define MC_CCR18_VALUE 0x4020002
++#define MC_CCR19_VALUE 0x30302
++#define MC_CCR20_VALUE 0x8000700
++#define MC_CCR21_VALUE 0x40F020A
++#define MC_CCR22_VALUE 0x0
++#define MC_CCR23_VALUE 0xC020000
++#define MC_CCR24_VALUE 0x4401B04
++#define MC_CCR25_VALUE 0x0
++#define MC_CCR26_VALUE 0x0
++#define MC_CCR27_VALUE 0x6420000
++#define MC_CCR28_VALUE 0x0
++#define MC_CCR29_VALUE 0x0
++#define MC_CCR30_VALUE 0x798
++#define MC_CCR31_VALUE 0x0
++#define MC_CCR32_VALUE 0x0
++#define MC_CCR33_VALUE 0x650000
++#define MC_CCR34_VALUE 0x200C8
++#define MC_CCR35_VALUE 0x1D445D
++#define MC_CCR36_VALUE 0xC8
++#define MC_CCR37_VALUE 0xC351
++#define MC_CCR38_VALUE 0x0
++#define MC_CCR39_VALUE 0x141F04
++#define MC_CCR40_VALUE 0x142704
++#define MC_CCR41_VALUE 0x141b42
++#define MC_CCR42_VALUE 0x141b42
++#define MC_CCR43_VALUE 0x566504
++#define MC_CCR44_VALUE 0x566504
++#define MC_CCR45_VALUE 0x565F17
++#define MC_CCR46_VALUE 0x565F17
++#define MC_CCR47_VALUE 0x0
++#define MC_CCR48_VALUE 0x0
++#define MC_CCR49_VALUE 0x0
++#define MC_CCR50_VALUE 0x0
++#define MC_CCR51_VALUE 0x0
++#define MC_CCR52_VALUE 0x133
++#define MC_CCR53_VALUE 0xF3014B27
++#define MC_CCR54_VALUE 0xF3014B27
++#define MC_CCR55_VALUE 0xF3014B27
++#define MC_CCR56_VALUE 0xF3014B27
++#define MC_CCR57_VALUE 0x7800301
++#define MC_CCR58_VALUE 0x7800301
++#define MC_CCR59_VALUE 0x7800301
++#define MC_CCR60_VALUE 0x7800301
++#define MC_CCR61_VALUE 0x4
+--- /dev/null
++++ b/board/avm/fb3370/fb3370.c
+@@ -0,0 +1,139 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#include <common.h>
++#include <spi.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SPL_BUILD)
++#define do_gpio_init 1
++#define do_pll_init 1
++#define do_dcdc_init 0
++#elif defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init 1
++#define do_pll_init 0
++#define do_dcdc_init 1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define do_gpio_init 1
++#define do_pll_init 1
++#define do_dcdc_init 1
++#else
++#define do_gpio_init 0
++#define do_pll_init 0
++#define do_dcdc_init 1
++#endif
++
++static void gpio_init(void)
++{
++ /* SPI CS 0.4 to serial flash */
++ gpio_direction_output(10, 1);
++
++ /* EBU.FL_CS1 as output for NAND CE */
++ gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* EBU.FL_A23 as output for NAND CLE */
++ gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* EBU.FL_A24 as output for NAND ALE */
++ gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++ /* GPIO 3.0 as input for NAND Ready Busy */
++ gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++ /* GPIO 3.1 as output for NAND Read */
++ gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++ if (do_gpio_init)
++ gpio_init();
++
++ if (do_pll_init)
++ ltq_pll_init();
++
++ if (do_dcdc_init)
++ ltq_dcdc_init(0x7F);
++
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++ /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
++ { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++ /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++ /* GMAC3: unused */
++ { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++ /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
++ { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++ const ulong fw_addr = 0x80FF0000;
++
++ ltq_gphy_phy11g_a1x_load(fw_addr);
++
++ ltq_cgu_gphy_clk_src(clk);
++
++ ltq_rcu_gphy_boot(0, fw_addr);
++ ltq_rcu_gphy_boot(1, fw_addr);
++
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++ if (bus)
++ return 0;
++
++ if (cs == 4)
++ return 1;
++
++ return 0;
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 4:
++ gpio_set_value(10, 0);
++ break;
++ default:
++ break;
++ }
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++ switch (slave->cs) {
++ case 4:
++ gpio_set_value(10, 1);
++ break;
++ default:
++ break;
++ }
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -451,6 +451,9 @@ incaip mips
+ incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000
+ incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000
+ incaip_150MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=150000000
++fb3370_ram mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_RAM
++fb3370_eva mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_EVA
++fb3370_sfspl mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_SFSPL
+ easy80920_nor mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NOR
+ easy80920_norspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NORSPL
+ easy80920_ram mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_RAM
+--- /dev/null
++++ b/include/configs/fb3370.h
+@@ -0,0 +1,75 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "FB3370"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "AVM FritzBox 3370"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_SPI_FLASH
++#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29LV620 serial flash */
++
++#define CONFIG_LTQ_SUPPORT_NAND_FLASH
++
++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */
++#define CONFIG_SPL_SPI_BUS 0
++#define CONFIG_SPL_SPI_CS 4
++#define CONFIG_SPL_SPI_MAX_HZ 25000000
++#define CONFIG_SPL_SPI_MODE 0
++
++#define CONFIG_LTQ_SPL_COMP_LZO
++#define CONFIG_LTQ_SPL_CONSOLE
++
++#define CONFIG_SYS_DRAM_PROBE
++
++/* Environment */
++#define CONFIG_ENV_SPI_BUS CONFIG_SPL_SPI_BUS
++#define CONFIG_ENV_SPI_CS CONFIG_SPL_SPI_CS
++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SPL_SPI_MAX_HZ
++#define CONFIG_ENV_SPI_MODE CONFIG_SPL_SPI_MODE
++
++#if defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_ENV_IS_IN_SPI_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE (8 * 1024)
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++#define CONFIG_ENV_UPDATE_UBOOT_SF \
++ "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_SF
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch b/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch
new file mode 100644
index 0000000..810770a
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch
@@ -0,0 +1,264 @@
+From 66b56aa3a4810f10e0b0c77bb87279a8d64b566b Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Fri, 16 Dec 2011 11:55:45 +0100
+Subject: MIPS: add board support for Gigaset SX76X
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/gigaset/sx76x/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/gigaset/sx76x/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/gigaset/sx76x/ddr_settings.h
+@@ -0,0 +1,56 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * generated with lantiq_ram_extract_magic.awk
++ *
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ */
++
++#define MC_DC00_VALUE 0x1B1B
++#define MC_DC01_VALUE 0x0
++#define MC_DC02_VALUE 0x0
++#define MC_DC03_VALUE 0x0
++#define MC_DC04_VALUE 0x0
++#define MC_DC05_VALUE 0x200
++#define MC_DC06_VALUE 0x605
++#define MC_DC07_VALUE 0x303
++#define MC_DC08_VALUE 0x202
++#define MC_DC09_VALUE 0x70A
++#define MC_DC10_VALUE 0x203
++#define MC_DC11_VALUE 0xC02
++#define MC_DC12_VALUE 0x1C8
++#define MC_DC13_VALUE 0x1
++#define MC_DC14_VALUE 0x0
++#define MC_DC15_VALUE 0xF3E
++#define MC_DC16_VALUE 0xC800
++#define MC_DC17_VALUE 0xD
++#define MC_DC18_VALUE 0x300
++#define MC_DC19_VALUE 0x200
++#define MC_DC20_VALUE 0xA04
++#define MC_DC21_VALUE 0xF00
++#define MC_DC22_VALUE 0xF0F
++#define MC_DC23_VALUE 0x0
++#define MC_DC24_VALUE 0x63
++#define MC_DC25_VALUE 0x0
++#define MC_DC26_VALUE 0x100
++#define MC_DC27_VALUE 0x0
++#define MC_DC28_VALUE 0x514
++#define MC_DC29_VALUE 0x2D89
++#define MC_DC30_VALUE 0x8300
++#define MC_DC31_VALUE 0x2002
++#define MC_DC32_VALUE 0x0
++#define MC_DC33_VALUE 0x0
++#define MC_DC34_VALUE 0x0
++#define MC_DC35_VALUE 0x0
++#define MC_DC36_VALUE 0x0
++#define MC_DC37_VALUE 0x0
++#define MC_DC38_VALUE 0x0
++#define MC_DC39_VALUE 0x0
++#define MC_DC40_VALUE 0x0
++#define MC_DC41_VALUE 0x0
++#define MC_DC42_VALUE 0x0
++#define MC_DC43_VALUE 0x0
++#define MC_DC44_VALUE 0x0
++#define MC_DC45_VALUE 0x500
++#define MC_DC46_VALUE 0x0
+--- /dev/null
++++ b/board/gigaset/sx76x/sx76x.c
+@@ -0,0 +1,66 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++static void gpio_init(void)
++{
++ /* Activate reset line of ADM6996I switch */
++ gpio_direction_output(19, 0);
++}
++
++int board_early_init_f(void)
++{
++ gpio_init();
++
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* MAC0: Lantiq ADM6996I switch */
++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device adm6996i_dev = {
++ .name = "adm6996i",
++ .cpu_port = 5,
++ .port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++ /* Deactivate reset line of ADM6996I switch */
++ gpio_set_value(19, 1);
++
++ /* ADM6996I needs some time to come out of reset */
++ __udelay(50000);
++
++ return switch_device_register(&adm6996i_dev);
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -447,6 +447,8 @@ pb1000 mips
+ easy50712_nor mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NOR
+ easy50712_norspl mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NORSPL
+ easy50712_ram mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_RAM
++gigasx76x_nor mips mips32 sx76x gigaset danube sx76x:SYS_BOOT_NOR
++gigasx76x_ram mips mips32 sx76x gigaset danube sx76x:SYS_BOOT_RAM
+ incaip mips mips32 incaip - incaip
+ incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000
+ incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000
+--- /dev/null
++++ b/include/configs/sx76x.h
+@@ -0,0 +1,71 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "GIGASX76X"
++#define CONFIG_IDENT_STRING " sx76x"
++#define CONFIG_BOARD_NAME "Gigaset sx76x"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_ADM6996I
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (256 * 1024)
++#define CONFIG_ENV_SIZE (8 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_SIZE (2 * 1024)
++#endif
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Compression */
++#define CONFIG_LZMA
++
++/* Auto boot */
++#define CONFIG_BOOTDELAY 2
++
++/* Environment configuration */
++#define CONFIG_BOOTCOMMAND \
++ "run addeth; bootm ${kernel_addr}"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch b/package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch
new file mode 100644
index 0000000..4156089
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch
@@ -0,0 +1,248 @@
+From 289f7ed5d725067b4eb4b1a105bb63d55bf20392 Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Wed, 29 Aug 2012 22:08:41 +0200
+Subject: MIPS: add board support for Arcadyan ARV7518
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/arv7518pw.c
+@@ -0,0 +1,52 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* MAC0: Atheros ar8216 switch */
++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device ar8216_dev = {
++ .name = "ar8216",
++ .cpu_port = 0,
++ .port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++ return switch_device_register(&ar8216_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/ddr_settings.h
+@@ -0,0 +1,56 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * generated with lantiq_ram_extract_magic.awk
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#define MC_DC00_VALUE 0x1B1B
++#define MC_DC01_VALUE 0x0
++#define MC_DC02_VALUE 0x0
++#define MC_DC03_VALUE 0x0
++#define MC_DC04_VALUE 0x0
++#define MC_DC05_VALUE 0x200
++#define MC_DC06_VALUE 0x605
++#define MC_DC07_VALUE 0x303
++#define MC_DC08_VALUE 0x102
++#define MC_DC09_VALUE 0x70A
++#define MC_DC10_VALUE 0x203
++#define MC_DC11_VALUE 0xC02
++#define MC_DC12_VALUE 0x1C8
++#define MC_DC13_VALUE 0x1
++#define MC_DC14_VALUE 0x0
++#define MC_DC15_VALUE 0x134
++#define MC_DC16_VALUE 0xC800
++#define MC_DC17_VALUE 0xD
++#define MC_DC18_VALUE 0x301
++#define MC_DC19_VALUE 0x200
++#define MC_DC20_VALUE 0xA03
++#define MC_DC21_VALUE 0x1400
++#define MC_DC22_VALUE 0x1414
++#define MC_DC23_VALUE 0x0
++#define MC_DC24_VALUE 0x5B
++#define MC_DC25_VALUE 0x0
++#define MC_DC26_VALUE 0x0
++#define MC_DC27_VALUE 0x0
++#define MC_DC28_VALUE 0x510
++#define MC_DC29_VALUE 0x4E20
++#define MC_DC30_VALUE 0x8235
++#define MC_DC31_VALUE 0x0
++#define MC_DC32_VALUE 0x0
++#define MC_DC33_VALUE 0x0
++#define MC_DC34_VALUE 0x0
++#define MC_DC35_VALUE 0x0
++#define MC_DC36_VALUE 0x0
++#define MC_DC37_VALUE 0x0
++#define MC_DC38_VALUE 0x0
++#define MC_DC39_VALUE 0x0
++#define MC_DC40_VALUE 0x0
++#define MC_DC41_VALUE 0x0
++#define MC_DC42_VALUE 0x0
++#define MC_DC43_VALUE 0x0
++#define MC_DC44_VALUE 0x0
++#define MC_DC45_VALUE 0x500
++#define MC_DC46_VALUE 0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -438,6 +438,8 @@ vct_premium mips
+ vct_premium_onenand mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND
+ vct_premium_onenand_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE
+ vct_premium_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_SMALL_IMAGE
++arv7518pw_ram mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_RAM
++arv7518pw_nor mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_NOR
+ dbau1000 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1000
+ dbau1100 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1100
+ dbau1500 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1500
+--- /dev/null
++++ b/include/configs/arv7518pw.h
+@@ -0,0 +1,69 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "ARV7518PW"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "Arcadyan ARV7518PW"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_AR8216
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SIZE (64 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_SIZE (2 * 1024)
++#endif
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Compression */
++#define CONFIG_LZMA
++
++/* Auto boot */
++#define CONFIG_BOOTDELAY 2
++
++/* Environment configuration */
++#define CONFIG_BOOTCOMMAND \
++ "run addeth; bootm ${kernel_addr}"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch b/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch
new file mode 100644
index 0000000..4698e67
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch
@@ -0,0 +1,248 @@
+From 4a738c02a7190756e01ba58c93c4b07bc6d6c2aa Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Wed, 29 Aug 2012 22:08:42 +0200
+Subject: MIPS: add board support for Arcadyan ARV4519
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/Makefile
+@@ -0,0 +1,29 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++COBJS = $(BOARD).o
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/arv4519pw.c
+@@ -0,0 +1,52 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++ return 0;
++}
++
++int checkboard(void)
++{
++ puts("Board: " CONFIG_BOARD_NAME "\n");
++ ltq_chip_print_info();
++
++ return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++ /* MAC0: Atheros ar8216 switch */
++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++ .ports = eth_port_config,
++ .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++ return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device ar8216_dev = {
++ .name = "ar8216",
++ .cpu_port = 0,
++ .port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++ return switch_device_register(&ar8216_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/config.mk
+@@ -0,0 +1,8 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/ddr_settings.h
+@@ -0,0 +1,56 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * generated with lantiq_ram_extract_magic.awk
++ *
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ */
++
++#define MC_DC00_VALUE 0x1B1B
++#define MC_DC01_VALUE 0x0
++#define MC_DC02_VALUE 0x0
++#define MC_DC03_VALUE 0x0
++#define MC_DC04_VALUE 0x0
++#define MC_DC05_VALUE 0x200
++#define MC_DC06_VALUE 0x605
++#define MC_DC07_VALUE 0x303
++#define MC_DC08_VALUE 0x102
++#define MC_DC09_VALUE 0x70A
++#define MC_DC10_VALUE 0x203
++#define MC_DC11_VALUE 0xC02
++#define MC_DC12_VALUE 0x1C8
++#define MC_DC13_VALUE 0x1
++#define MC_DC14_VALUE 0x0
++#define MC_DC15_VALUE 0x131
++#define MC_DC16_VALUE 0xC800
++#define MC_DC17_VALUE 0xD
++#define MC_DC18_VALUE 0x301
++#define MC_DC19_VALUE 0x200
++#define MC_DC20_VALUE 0xA04
++#define MC_DC21_VALUE 0x1700
++#define MC_DC22_VALUE 0x1717
++#define MC_DC23_VALUE 0x0
++#define MC_DC24_VALUE 0x5A
++#define MC_DC25_VALUE 0x0
++#define MC_DC26_VALUE 0x0
++#define MC_DC27_VALUE 0x0
++#define MC_DC28_VALUE 0x510
++#define MC_DC29_VALUE 0x4E20
++#define MC_DC30_VALUE 0x8235
++#define MC_DC31_VALUE 0x0
++#define MC_DC32_VALUE 0x0
++#define MC_DC33_VALUE 0x0
++#define MC_DC34_VALUE 0x0
++#define MC_DC35_VALUE 0x0
++#define MC_DC36_VALUE 0x0
++#define MC_DC37_VALUE 0x0
++#define MC_DC38_VALUE 0x0
++#define MC_DC39_VALUE 0x0
++#define MC_DC40_VALUE 0x0
++#define MC_DC41_VALUE 0x0
++#define MC_DC42_VALUE 0x0
++#define MC_DC43_VALUE 0x0
++#define MC_DC44_VALUE 0x0
++#define MC_DC45_VALUE 0x500
++#define MC_DC46_VALUE 0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -438,6 +438,8 @@ vct_premium mips
+ vct_premium_onenand mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND
+ vct_premium_onenand_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE
+ vct_premium_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_SMALL_IMAGE
++arv4519pw_ram mips mips32 arv4519pw arcadyan danube arv4519pw:SYS_BOOT_RAM
++arv4519pw_nor mips mips32 arv4519pw arcadyan danube arv4519pw:SYS_BOOT_NOR
+ arv7518pw_ram mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_RAM
+ arv7518pw_nor mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_NOR
+ dbau1000 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1000
+--- /dev/null
++++ b/include/configs/arv4519pw.h
+@@ -0,0 +1,69 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE "ARV4519PW"
++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME "Arcadyan ARV4519PW"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_AR8216
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET (192 * 1024)
++#define CONFIG_ENV_SIZE (64 * 1024)
++#define CONFIG_ENV_SECT_SIZE (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_SIZE (2 * 1024)
++#endif
++
++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_CONSOLE_ASC 1
++#define CONFIG_CONSOLE_DEV "ttyLTQ1"
++
++/* Commands */
++#define CONFIG_CMD_PING
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Compression */
++#define CONFIG_LZMA
++
++/* Auto boot */
++#define CONFIG_BOOTDELAY 2
++
++/* Environment configuration */
++#define CONFIG_BOOTCOMMAND \
++ "run addeth; bootm ${kernel_addr}"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ CONFIG_ENV_LANTIQ_DEFAULTS \
++ CONFIG_ENV_UPDATE_UBOOT_NOR \
++ "kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch b/package/boot/uboot-lantiq/patches/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch
new file mode 100644
index 0000000..77d48d1
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch
@@ -0,0 +1,361 @@
+From 1b77d4249b5addbf3b0848db6992a445019a1865 Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Wed, 29 Aug 2012 22:08:42 +0200
+Subject: tools: add some helper tools for Lantiq SoCs
+
+Signed-off-by: Luka Perkov Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/tools/gct.pl
+@@ -0,0 +1,155 @@
++#!/usr/bin/perl
++
++#use strict;
++#use Cwd;
++#use Env;
++
++my $aline;
++my $lineid;
++my $length;
++my $address;
++my @bytes;
++my $addstr;
++my $chsum=0;
++my $count=0;
++my $firstime=1;
++my $i;
++my $currentaddr;
++my $tmp;
++my $holder="";
++my $loadaddr;
++
++if(@ARGV < 2){
++ die("\n Syntax: perl gct.pl uart_ddr_settings.conf u-boot.srec u-boot.asc\n");
++}
++
++open(IN_UART_DDR_SETTINGS, "<$ARGV[0]") || die("failed to open uart_ddr_settings.conf\n");
++open(IN_UART_SREC, "<$ARGV[1]") || die("failed to open u-boot.srec\n");
++open(OUT_UBOOT_ASC, ">$ARGV[2]") || die("failed to open u-boot.asc\n");
++
++$i=0;
++while ($line = <IN_UART_DDR_SETTINGS>){
++ if($line=~/\w/){
++ if($line!~/[;#\*]/){
++ if($i eq 0){
++ printf OUT_UBOOT_ASC ("33333333");
++ }
++ chomp($line);
++ $line=~s/\t//;
++ @array=split(/ +/,$line);
++ $j=0;
++ while(@array[$j]!~/\w/){
++ $j=$j+1;
++ }
++ $addr=@array[$j];
++ $regval=@array[$j+1];
++ $addr=~s/0x//;
++ $regval=~s/0x//;
++ printf OUT_UBOOT_ASC ("%08x%08x",hex($addr),hex($regval));
++ $i=$i+1;
++ if($i eq 8){
++ $i=0;
++ printf OUT_UBOOT_ASC ("\n");
++ }
++ }
++ }
++}
++
++while($i lt 8 && $i gt 0){
++ printf OUT_UBOOT_ASC "00"x8;
++ $i=$i+1;
++}
++
++if($i eq 8){
++ printf OUT_UBOOT_ASC ("\n");
++}
++
++while($aline=<IN_UART_SREC>){
++ $aline=uc($aline);
++ chomp($aline);
++ next if(($aline=~/^S0/) || ($aline=~/^S7/));
++ ($lineid, $length, $address, @bytes) = unpack"A2A2A8"."A2"x300, $aline;
++ $length = hex($length);
++ $address = hex($address);
++ $length -=5;
++ $i=0;
++
++ while($length>0){
++ if($firstime==1){
++ $addstr = sprintf("%x", $address);
++ $addstr = "0"x(8-length($addstr)).$addstr;
++ print OUT_UBOOT_ASC $addstr;
++ addchsum($addstr);
++ $firstime=0;
++ $currentaddr=$address;
++ $loadaddr = $addstr;
++ }
++ else{
++ if($count==64){
++ $addstr = sprintf("%x", $currentaddr);
++ $addstr = "0"x(8-length($addstr)).$addstr;
++ print OUT_UBOOT_ASC $addstr;
++ addchsum($addstr);
++ $count=0;
++ }
++#printf("*** %x != %x\n", $address, $currentaddr) if $address != $currentaddr;
++ }
++ if($currentaddr < $address) {
++ print OUT_UBOOT_ASC "00";
++ addchsum("00");
++ $count++;
++ $currentaddr++;
++ }
++ else {
++ while($count<64){
++ $bytes[$i]=~tr/ABCDEF/abcdef/;
++ print OUT_UBOOT_ASC "$bytes[$i]";
++ addchsum($bytes[$i]);
++ $i++;
++ $count++;
++ $currentaddr++;
++ $length--;
++ last if($length==0);
++ }
++ }
++ if($count==64){
++ print OUT_UBOOT_ASC "\n";
++ }
++ }
++}
++if($count != 64){
++ $tmp = "00";
++ for($i=0;$i<(64-$count);$i++){
++ print OUT_UBOOT_ASC "00";
++ addchsum($tmp);
++ }
++ print OUT_UBOOT_ASC "\n";
++}
++
++
++print OUT_UBOOT_ASC "11"x4;
++use integer;
++$chsum=$chsum & 0xffffffff;
++$chsum = sprintf("%X", $chsum);
++$chsum = "0"x(8-length($chsum)).$chsum;
++$chsum =~tr/ABCDEF/abcdef/;
++print OUT_UBOOT_ASC $chsum;
++print OUT_UBOOT_ASC "00"x60;
++print OUT_UBOOT_ASC "\n";
++
++print OUT_UBOOT_ASC "99"x4;
++print OUT_UBOOT_ASC $loadaddr;
++print OUT_UBOOT_ASC "00"x60;
++print OUT_UBOOT_ASC "\n";
++
++close OUT_UBOOT_ASC;
++
++sub addchsum{
++ my $cc=$_[0];
++ $holder=$holder.$cc;
++ if(length($holder)==8){
++ $holder = hex($holder);
++ $chsum+=$holder;
++ $holder="";
++ }
++}
+--- /dev/null
++++ b/tools/lantiq_extract_openwrt_patches.sh
+@@ -0,0 +1,15 @@
++#!/bin/bash
++
++set -e
++set -x
++
++test $# -eq 1
++
++openwrt_root=$(readlink -f $1)
++test -d $openwrt_root
++
++uboot_lantiq_dir=$openwrt_root/package/boot/uboot-lantiq/patches
++test -d $uboot_lantiq_dir
++
++rm -vf $uboot_lantiq_dir/*
++git format-patch -k -p --no-renames --text --full-index -o $uboot_lantiq_dir v2012.10..openwrt/v2013.01
+--- /dev/null
++++ b/tools/lantiq_ram_extract_magic.awk
+@@ -0,0 +1,70 @@
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++#
++# usage: mips-openwrt-linux-objdump -EB -b binary -m mips:isa32r2 -D YOUR_IMAGE_DUMP | awk -f lantiq_ram_extract_magic.awk
++#
++
++BEGIN {
++ print "/* "
++ print " * This file is released under the terms of GPL v2 and any later version. "
++ print " * See the file COPYING in the root directory of the source tree for details. "
++ print " * "
++ print " * generated with lantiq_ram_extract_magic.awk "
++ print " * "
++ print " * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> "
++ print " */ "
++ print ""
++
++ mc_dc_value=0
++ mc_dc_number=0
++ right_section=0
++ mc_dc_value_print=0
++ mc_dc_number_print=0
++}
++
++/t2,[0-9]+$/ {
++ if (right_section) {
++ split($4, tmp, ",")
++ mc_dc_value=sprintf("%X", tmp[2])
++ mc_dc_value_print=1
++ }
++}
++
++/t2,0x[0-9a-f]+$/ {
++ if (right_section) {
++ split($4, tmp, ",0x")
++ mc_dc_value=sprintf("%s", tmp[2])
++ mc_dc_value=toupper(mc_dc_value)
++ mc_dc_value_print=1
++ }
++}
++
++/t2,[0-9]+\(t1\)$/ {
++ if (right_section) {
++ split($4, tmp, ",")
++ split(tmp[2], tmp, "(")
++ mc_dc_number=tmp[1]/16
++ mc_dc_number_print=1
++ }
++}
++
++{
++ if (right_section && mc_dc_number_print && mc_dc_value_print) {
++ if (mc_dc_number < 10)
++ print "#define MC_DC0" mc_dc_number "_VALUE\t0x" mc_dc_value
++ else
++ print "#define MC_DC" mc_dc_number "_VALUE\t0x" mc_dc_value
++ mc_dc_value_print=0
++ mc_dc_number_print=0
++ }
++
++ if ($4 == "t1,t1,0x1000")
++ right_section=1
++
++
++ if ($4 == "t2,736(t1)")
++ right_section=0
++}
+--- /dev/null
++++ b/tools/lantiq_ram_init_uart.awk
+@@ -0,0 +1,101 @@
++#!/usr/bin/awk -f
++#
++# This file is released under the terms of GPL v2 and any later version.
++# See the file COPYING in the root directory of the source tree for details.
++#
++# Copyright (C) 2011-2012 Luka Perkov <luka@openwrt.org>
++# Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++#
++# usage: awk -f lantiq_ram_init_uart.awk -v soc=<danube|ar9|vr9> PATH_TO_BOARD/ddr_settings.h
++#
++
++function print_header()
++{
++ print "; "
++ print "; This file is released under the terms of GPL v2 and any later version. "
++ print "; See the file COPYING in the root directory of the source tree for details. "
++ print "; "
++ print "; generated with lantiq_ram_init_uart.awk "
++ print "; "
++ print "; Copyright (C) 2011-2012 Luka Perkov <luka@openwrt.org> "
++ print "; Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@gmail.com> "
++ print "; "
++ print ""
++}
++
++function mc_ddr1_prologue()
++{
++ /* Clear access error log registers */
++ print "0xbf800010", "0x0"
++ print "0xbf800020", "0x0"
++
++ /* Enable DDR and SRAM module in memory controller */
++ print "0xbf800060", "0x5"
++
++ /* Clear start bit of DDR memory controller */
++ print "0xbf801030", "0x0"
++}
++
++function mc_ddr1_epilogue()
++{
++ /* Set start bit of DDR memory controller */
++ print "0xbf801030", "0x100"
++}
++
++function mc_ddr2_prologue()
++{
++ /* Put memory controller in inactive mode */
++ print "0xbf401070", "0x0"
++}
++
++function mc_ddr2_epilogue(mc_ccr07_value)
++{
++ /* Put memory controller in active mode */
++ mc_ccr07_value = or(mc_ccr07_value, 0x100)
++ printf("0xbf401070 0x%x\n", mc_ccr07_value)
++}
++
++BEGIN {
++ switch (soc) {
++ case "danube":
++ case "ar9":
++ reg_base = 0xbf801000
++ print_header()
++ mc_ddr1_prologue()
++ break
++ case "vr9":
++ reg_base = 0xbf401000
++ print_header()
++ mc_ddr2_prologue()
++ break
++ default:
++ print "Invalid or no value for soc specified!"
++ exit 1
++ }
++
++ mc_ccr07_value = 0
++}
++
++/^#define/ {
++ printf("0x%x %s\n", reg_base, tolower($3))
++ reg_base += 0x10
++}
++
++/^#define(.*)MC_CCR07_VALUE/ {
++ printf("0x%x %s\n", reg_base, tolower($3))
++ reg_base += 0x10
++ mc_ccr07_value = strtonum($3)
++}
++
++END {
++ switch (soc) {
++ case "danube":
++ case "ar9":
++ mc_ddr1_epilogue()
++ break
++ case "vr9":
++ mc_ddr2_epilogue(mc_ccr07_value)
++ break
++ default:
++ }
++}
diff --git a/package/boot/uboot-omap35xx/.svn/entries b/package/boot/uboot-omap35xx/.svn/entries
new file mode 100644
index 0000000..9de4baa
--- /dev/null
+++ b/package/boot/uboot-omap35xx/.svn/entries
@@ -0,0 +1,65 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap35xx
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+files
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+9740ce10bcacfd7eca1e227f2f9acde9
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1940
+
diff --git a/package/boot/uboot-omap35xx/.svn/text-base/Makefile.svn-base b/package/boot/uboot-omap35xx/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..928acc7
--- /dev/null
+++ b/package/boot/uboot-omap35xx/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2010.12
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/omap3_overo
+ TITLE:=U-boot for the gumstix board
+endef
+
+UBOOTS:=omap3_overo
+
+define Package/uboot/template
+define Package/uboot-omap35xx-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_omap35xx
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUbootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Prepare
+ $(call Build/Prepare/Default)
+ $(CP) ./files/* $(PKG_BUILD_DIR)
+ find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf
+endef
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/template
+define Package/uboot-omap35xx-$(1)/install
+ $(INSTALL_DIR) $$(1)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.bin $(BIN_DIR)/$(2)
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.bin)) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUbootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-omap35xx-$(u))) \
+)
diff --git a/package/boot/uboot-omap35xx/Makefile b/package/boot/uboot-omap35xx/Makefile
new file mode 100644
index 0000000..928acc7
--- /dev/null
+++ b/package/boot/uboot-omap35xx/Makefile
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2010.12
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/omap3_overo
+ TITLE:=U-boot for the gumstix board
+endef
+
+UBOOTS:=omap3_overo
+
+define Package/uboot/template
+define Package/uboot-omap35xx-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_omap35xx
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUbootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Prepare
+ $(call Build/Prepare/Default)
+ $(CP) ./files/* $(PKG_BUILD_DIR)
+ find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf
+endef
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/template
+define Package/uboot-omap35xx-$(1)/install
+ $(INSTALL_DIR) $$(1)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.bin $(BIN_DIR)/$(2)
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.bin)) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUbootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-omap35xx-$(u))) \
+)
diff --git a/package/boot/uboot-omap35xx/files/.svn/entries b/package/boot/uboot-omap35xx/files/.svn/entries
new file mode 100644
index 0000000..62713ad
--- /dev/null
+++ b/package/boot/uboot-omap35xx/files/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap35xx/files
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+include
+dir
+
diff --git a/package/boot/uboot-omap35xx/files/include/.svn/entries b/package/boot/uboot-omap35xx/files/include/.svn/entries
new file mode 100644
index 0000000..7b6d6a1
--- /dev/null
+++ b/package/boot/uboot-omap35xx/files/include/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap35xx/files/include
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+configs
+dir
+
diff --git a/package/boot/uboot-omap35xx/files/include/configs/.svn/entries b/package/boot/uboot-omap35xx/files/include/configs/.svn/entries
new file mode 100644
index 0000000..8d43469
--- /dev/null
+++ b/package/boot/uboot-omap35xx/files/include/configs/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap35xx/files/include/configs
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+omap3_overo.h
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+3b947b5d726443e694c1a0a5c77058c6
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9612
+
diff --git a/package/boot/uboot-omap35xx/files/include/configs/.svn/text-base/omap3_overo.h.svn-base b/package/boot/uboot-omap35xx/files/include/configs/.svn/text-base/omap3_overo.h.svn-base
new file mode 100644
index 0000000..e1c930d
--- /dev/null
+++ b/package/boot/uboot-omap35xx/files/include/configs/.svn/text-base/omap3_overo.h.svn-base
@@ -0,0 +1,316 @@
+/*
+ * Configuration settings for the Gumstix Overo board.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_ARMV7 1 /* This is an ARM V7 CPU core */
+#define CONFIG_OMAP 1 /* in a TI OMAP core */
+#define CONFIG_OMAP34XX 1 /* which is a 34XX */
+#define CONFIG_OMAP3430 1 /* which is in a 3430 */
+#define CONFIG_OMAP3_OVERO 1 /* working with overo */
+
+#define CONFIG_SDRC /* The chip has SDRC controller */
+
+#include <asm/arch/cpu.h> /* get chip and board defs */
+#include <asm/arch/omap3.h>
+
+/*
+ * Display CPU and Board information
+ */
+#define CONFIG_DISPLAY_CPUINFO 1
+#define CONFIG_DISPLAY_BOARDINFO 1
+
+/* Clock Defines */
+#define V_OSCK 26000000 /* Clock output from T2 */
+#define V_SCLK (V_OSCK >> 1)
+
+#undef CONFIG_USE_IRQ /* no support for IRQs */
+#define CONFIG_MISC_INIT_R
+
+#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG 1
+#define CONFIG_REVISION_TAG 1
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */
+ /* Sector */
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (128 << 10))
+ /* initial data */
+
+/*
+ * Hardware drivers
+ */
+
+/*
+ * NS16550 Configuration
+ */
+#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */
+
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE (-4)
+#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_CONS_INDEX 3
+#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3
+#define CONFIG_SERIAL3 3
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, \
+ 115200}
+#define CONFIG_GENERIC_MMC 1
+#define CONFIG_MMC 1
+#define CONFIG_OMAP_HSMMC 1
+#define CONFIG_DOS_PARTITION 1
+
+/* DDR - I use Micron DDR */
+#define CONFIG_OMAP3_MICRON_DDR 1
+
+/* commands to include */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_EXT2 /* EXT2 Support */
+#define CONFIG_CMD_FAT /* FAT support */
+#define CONFIG_CMD_JFFS2 /* JFFS2 Support */
+
+#define CONFIG_CMD_I2C /* I2C serial bus support */
+#define CONFIG_CMD_MMC /* MMC support */
+#define CONFIG_CMD_NAND /* NAND support */
+
+#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */
+#undef CONFIG_CMD_FPGA /* FPGA configuration Support */
+#undef CONFIG_CMD_IMI /* iminfo */
+#undef CONFIG_CMD_IMLS /* List all found images */
+#undef CONFIG_CMD_NFS /* NFS support */
+#define CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */
+
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_HARD_I2C 1
+#define CONFIG_SYS_I2C_SPEED 100000
+#define CONFIG_SYS_I2C_SLAVE 1
+#define CONFIG_SYS_I2C_BUS 0
+#define CONFIG_SYS_I2C_BUS_SELECT 1
+#define CONFIG_I2C_MULTI_BUS 1
+#define CONFIG_DRIVER_OMAP34XX_I2C 1
+
+/*
+ * TWL4030
+ */
+#define CONFIG_TWL4030_POWER 1
+#define CONFIG_TWL4030_LED 1
+
+/*
+ * Board NAND Info.
+ */
+#define CONFIG_SYS_NAND_QUIET_TEST 1
+#define CONFIG_NAND_OMAP_GPMC
+#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */
+ /* to access nand */
+#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */
+ /* to access nand */
+ /* at CS0 */
+#define GPMC_NAND_ECC_LP_x16_LAYOUT 1
+
+#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */
+ /* devices */
+#define CONFIG_JFFS2_NAND
+/* nand device jffs2 lives on */
+#define CONFIG_JFFS2_DEV "nand0"
+/* start of jffs2 partition */
+#define CONFIG_JFFS2_PART_OFFSET 0x680000
+#define CONFIG_JFFS2_PART_SIZE 0xf980000 /* size of jffs2 */
+ /* partition */
+
+/* Environment information */
+#define CONFIG_BOOTDELAY 5
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "loadaddr=0x82000000\0" \
+ "console=ttyO2,115200n8\0" \
+ "mpurate=500\0" \
+ "vram=12M\0" \
+ "dvimode=1024x768MR-16@60\0" \
+ "defaultdisplay=dvi\0" \
+ "mmcdev=0\0" \
+ "mmcroot=/dev/mmcblk0p2 rw\0" \
+ "mmcrootfstype=ext3 rootwait\0" \
+ "nandroot='ubi0:rootfs ubi.mtd=5 ubi.mtd=6 ubi.mtd=7'\0" \
+ "nandrootfstype=ubifs\0" \
+ "mmcargs=setenv bootargs console=${console} " \
+ "mpurate=${mpurate} " \
+ "vram=${vram} " \
+ "omapfb.mode=dvi:${dvimode} " \
+ "omapfb.debug=y " \
+ "omapdss.def_disp=${defaultdisplay} " \
+ "root=${mmcroot} " \
+ "rootfstype=${mmcrootfstype}\0" \
+ "nandargs=setenv bootargs console=${console} " \
+ "mpurate=${mpurate} " \
+ "vram=${vram} " \
+ "omapfb.mode=dvi:${dvimode} " \
+ "omapfb.debug=y " \
+ "omapdss.def_disp=${defaultdisplay} " \
+ "root=${nandroot} " \
+ "rootfstype=${nandrootfstype}\0" \
+ "loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr\0" \
+ "bootscript=echo Running bootscript from mmc ...; " \
+ "source ${loadaddr}\0" \
+ "loaduimage=fatload mmc ${mmcdev} ${loadaddr} uImage\0" \
+ "mmcboot=echo Booting from mmc ...; " \
+ "run mmcargs; " \
+ "bootm ${loadaddr}\0" \
+ "nandboot=echo Booting from nand ...; " \
+ "run nandargs; " \
+ "nand read ${loadaddr} 280000 200000; " \
+ "bootm ${loadaddr}\0" \
+
+#define CONFIG_BOOTCOMMAND \
+ "if mmc rescan ${mmcdev}; then " \
+ "if run loadbootscript; then " \
+ "run bootscript; " \
+ "else " \
+ "if run loaduimage; then " \
+ "run mmcboot; " \
+ "else run nandboot; " \
+ "fi; " \
+ "fi; " \
+ "else run nandboot; fi"
+
+#define CONFIG_AUTO_COMPLETE 1
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define CONFIG_SYS_PROMPT "Overo # "
+#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS 16 /* max number of command */
+ /* args */
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+/* memtest works on */
+#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0)
+#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \
+ 0x01F00000) /* 31MB */
+
+#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default load */
+ /* address */
+/*
+ * OMAP3 has 12 GP timers, they can be driven by the system clock
+ * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK).
+ * This rate is divided by a local divisor.
+ */
+#define CONFIG_SYS_TIMERBASE OMAP34XX_GPT2
+#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
+#define CONFIG_SYS_HZ 1000
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE (128 << 10) /* regular stack 128 KiB */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ (4 << 10) /* IRQ stack 4 KiB */
+#define CONFIG_STACKSIZE_FIQ (4 << 10) /* FIQ stack 4 KiB */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
+#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
+#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
+#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
+
+/* SDRAM Bank Allocation method */
+#define SDRC_R_B_C 1
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+
+/* **** PISMO SUPPORT *** */
+
+/* Configure the PISMO */
+#define PISMO1_NAND_SIZE GPMC_SIZE_128M
+#define PISMO1_ONEN_SIZE GPMC_SIZE_128M
+
+#define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */
+
+#define CONFIG_SYS_FLASH_BASE boot_flash_base
+
+/* Monitor at start of flash */
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
+#define CONFIG_SYS_ONENAND_BASE ONENAND_MAP
+
+#define CONFIG_ENV_IS_IN_NAND 1
+#define ONENAND_ENV_OFFSET 0x240000 /* environment starts here */
+#define SMNAND_ENV_OFFSET 0x240000 /* environment starts here */
+
+#define CONFIG_SYS_ENV_SECT_SIZE boot_flash_sec
+#define CONFIG_ENV_OFFSET boot_flash_off
+#define CONFIG_ENV_ADDR SMNAND_ENV_OFFSET
+
+#ifndef __ASSEMBLY__
+extern unsigned int boot_flash_base;
+extern volatile unsigned int boot_flash_env_addr;
+extern unsigned int boot_flash_off;
+extern unsigned int boot_flash_sec;
+extern unsigned int boot_flash_type;
+#endif
+
+#if defined(CONFIG_CMD_NET)
+/*----------------------------------------------------------------------------
+ * SMSC9211 Ethernet from SMSC9118 family
+ *----------------------------------------------------------------------------
+ */
+
+#define CONFIG_NET_MULTI
+#define CONFIG_SMC911X 1
+#define CONFIG_SMC911X_32_BIT
+#define CONFIG_SMC911X_BASE 0x2C000000
+
+#endif /* (CONFIG_CMD_NET) */
+
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_RAM_ADDR 0x4020f800
+#define CONFIG_SYS_INIT_RAM_SIZE 0x800
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
+ CONFIG_SYS_INIT_RAM_SIZE - \
+ GENERATED_GBL_DATA_SIZE)
+
+#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-omap35xx/files/include/configs/omap3_overo.h b/package/boot/uboot-omap35xx/files/include/configs/omap3_overo.h
new file mode 100644
index 0000000..e1c930d
--- /dev/null
+++ b/package/boot/uboot-omap35xx/files/include/configs/omap3_overo.h
@@ -0,0 +1,316 @@
+/*
+ * Configuration settings for the Gumstix Overo board.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_ARMV7 1 /* This is an ARM V7 CPU core */
+#define CONFIG_OMAP 1 /* in a TI OMAP core */
+#define CONFIG_OMAP34XX 1 /* which is a 34XX */
+#define CONFIG_OMAP3430 1 /* which is in a 3430 */
+#define CONFIG_OMAP3_OVERO 1 /* working with overo */
+
+#define CONFIG_SDRC /* The chip has SDRC controller */
+
+#include <asm/arch/cpu.h> /* get chip and board defs */
+#include <asm/arch/omap3.h>
+
+/*
+ * Display CPU and Board information
+ */
+#define CONFIG_DISPLAY_CPUINFO 1
+#define CONFIG_DISPLAY_BOARDINFO 1
+
+/* Clock Defines */
+#define V_OSCK 26000000 /* Clock output from T2 */
+#define V_SCLK (V_OSCK >> 1)
+
+#undef CONFIG_USE_IRQ /* no support for IRQs */
+#define CONFIG_MISC_INIT_R
+
+#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG 1
+#define CONFIG_REVISION_TAG 1
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */
+ /* Sector */
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (128 << 10))
+ /* initial data */
+
+/*
+ * Hardware drivers
+ */
+
+/*
+ * NS16550 Configuration
+ */
+#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */
+
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE (-4)
+#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_CONS_INDEX 3
+#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3
+#define CONFIG_SERIAL3 3
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, \
+ 115200}
+#define CONFIG_GENERIC_MMC 1
+#define CONFIG_MMC 1
+#define CONFIG_OMAP_HSMMC 1
+#define CONFIG_DOS_PARTITION 1
+
+/* DDR - I use Micron DDR */
+#define CONFIG_OMAP3_MICRON_DDR 1
+
+/* commands to include */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_EXT2 /* EXT2 Support */
+#define CONFIG_CMD_FAT /* FAT support */
+#define CONFIG_CMD_JFFS2 /* JFFS2 Support */
+
+#define CONFIG_CMD_I2C /* I2C serial bus support */
+#define CONFIG_CMD_MMC /* MMC support */
+#define CONFIG_CMD_NAND /* NAND support */
+
+#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */
+#undef CONFIG_CMD_FPGA /* FPGA configuration Support */
+#undef CONFIG_CMD_IMI /* iminfo */
+#undef CONFIG_CMD_IMLS /* List all found images */
+#undef CONFIG_CMD_NFS /* NFS support */
+#define CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */
+
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_HARD_I2C 1
+#define CONFIG_SYS_I2C_SPEED 100000
+#define CONFIG_SYS_I2C_SLAVE 1
+#define CONFIG_SYS_I2C_BUS 0
+#define CONFIG_SYS_I2C_BUS_SELECT 1
+#define CONFIG_I2C_MULTI_BUS 1
+#define CONFIG_DRIVER_OMAP34XX_I2C 1
+
+/*
+ * TWL4030
+ */
+#define CONFIG_TWL4030_POWER 1
+#define CONFIG_TWL4030_LED 1
+
+/*
+ * Board NAND Info.
+ */
+#define CONFIG_SYS_NAND_QUIET_TEST 1
+#define CONFIG_NAND_OMAP_GPMC
+#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */
+ /* to access nand */
+#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */
+ /* to access nand */
+ /* at CS0 */
+#define GPMC_NAND_ECC_LP_x16_LAYOUT 1
+
+#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */
+ /* devices */
+#define CONFIG_JFFS2_NAND
+/* nand device jffs2 lives on */
+#define CONFIG_JFFS2_DEV "nand0"
+/* start of jffs2 partition */
+#define CONFIG_JFFS2_PART_OFFSET 0x680000
+#define CONFIG_JFFS2_PART_SIZE 0xf980000 /* size of jffs2 */
+ /* partition */
+
+/* Environment information */
+#define CONFIG_BOOTDELAY 5
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "loadaddr=0x82000000\0" \
+ "console=ttyO2,115200n8\0" \
+ "mpurate=500\0" \
+ "vram=12M\0" \
+ "dvimode=1024x768MR-16@60\0" \
+ "defaultdisplay=dvi\0" \
+ "mmcdev=0\0" \
+ "mmcroot=/dev/mmcblk0p2 rw\0" \
+ "mmcrootfstype=ext3 rootwait\0" \
+ "nandroot='ubi0:rootfs ubi.mtd=5 ubi.mtd=6 ubi.mtd=7'\0" \
+ "nandrootfstype=ubifs\0" \
+ "mmcargs=setenv bootargs console=${console} " \
+ "mpurate=${mpurate} " \
+ "vram=${vram} " \
+ "omapfb.mode=dvi:${dvimode} " \
+ "omapfb.debug=y " \
+ "omapdss.def_disp=${defaultdisplay} " \
+ "root=${mmcroot} " \
+ "rootfstype=${mmcrootfstype}\0" \
+ "nandargs=setenv bootargs console=${console} " \
+ "mpurate=${mpurate} " \
+ "vram=${vram} " \
+ "omapfb.mode=dvi:${dvimode} " \
+ "omapfb.debug=y " \
+ "omapdss.def_disp=${defaultdisplay} " \
+ "root=${nandroot} " \
+ "rootfstype=${nandrootfstype}\0" \
+ "loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr\0" \
+ "bootscript=echo Running bootscript from mmc ...; " \
+ "source ${loadaddr}\0" \
+ "loaduimage=fatload mmc ${mmcdev} ${loadaddr} uImage\0" \
+ "mmcboot=echo Booting from mmc ...; " \
+ "run mmcargs; " \
+ "bootm ${loadaddr}\0" \
+ "nandboot=echo Booting from nand ...; " \
+ "run nandargs; " \
+ "nand read ${loadaddr} 280000 200000; " \
+ "bootm ${loadaddr}\0" \
+
+#define CONFIG_BOOTCOMMAND \
+ "if mmc rescan ${mmcdev}; then " \
+ "if run loadbootscript; then " \
+ "run bootscript; " \
+ "else " \
+ "if run loaduimage; then " \
+ "run mmcboot; " \
+ "else run nandboot; " \
+ "fi; " \
+ "fi; " \
+ "else run nandboot; fi"
+
+#define CONFIG_AUTO_COMPLETE 1
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define CONFIG_SYS_PROMPT "Overo # "
+#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS 16 /* max number of command */
+ /* args */
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+/* memtest works on */
+#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0)
+#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \
+ 0x01F00000) /* 31MB */
+
+#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default load */
+ /* address */
+/*
+ * OMAP3 has 12 GP timers, they can be driven by the system clock
+ * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK).
+ * This rate is divided by a local divisor.
+ */
+#define CONFIG_SYS_TIMERBASE OMAP34XX_GPT2
+#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
+#define CONFIG_SYS_HZ 1000
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE (128 << 10) /* regular stack 128 KiB */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ (4 << 10) /* IRQ stack 4 KiB */
+#define CONFIG_STACKSIZE_FIQ (4 << 10) /* FIQ stack 4 KiB */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
+#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
+#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
+#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
+
+/* SDRAM Bank Allocation method */
+#define SDRC_R_B_C 1
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+
+/* **** PISMO SUPPORT *** */
+
+/* Configure the PISMO */
+#define PISMO1_NAND_SIZE GPMC_SIZE_128M
+#define PISMO1_ONEN_SIZE GPMC_SIZE_128M
+
+#define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */
+
+#define CONFIG_SYS_FLASH_BASE boot_flash_base
+
+/* Monitor at start of flash */
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
+#define CONFIG_SYS_ONENAND_BASE ONENAND_MAP
+
+#define CONFIG_ENV_IS_IN_NAND 1
+#define ONENAND_ENV_OFFSET 0x240000 /* environment starts here */
+#define SMNAND_ENV_OFFSET 0x240000 /* environment starts here */
+
+#define CONFIG_SYS_ENV_SECT_SIZE boot_flash_sec
+#define CONFIG_ENV_OFFSET boot_flash_off
+#define CONFIG_ENV_ADDR SMNAND_ENV_OFFSET
+
+#ifndef __ASSEMBLY__
+extern unsigned int boot_flash_base;
+extern volatile unsigned int boot_flash_env_addr;
+extern unsigned int boot_flash_off;
+extern unsigned int boot_flash_sec;
+extern unsigned int boot_flash_type;
+#endif
+
+#if defined(CONFIG_CMD_NET)
+/*----------------------------------------------------------------------------
+ * SMSC9211 Ethernet from SMSC9118 family
+ *----------------------------------------------------------------------------
+ */
+
+#define CONFIG_NET_MULTI
+#define CONFIG_SMC911X 1
+#define CONFIG_SMC911X_32_BIT
+#define CONFIG_SMC911X_BASE 0x2C000000
+
+#endif /* (CONFIG_CMD_NET) */
+
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_RAM_ADDR 0x4020f800
+#define CONFIG_SYS_INIT_RAM_SIZE 0x800
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
+ CONFIG_SYS_INIT_RAM_SIZE - \
+ GENERATED_GBL_DATA_SIZE)
+
+#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-omap4/.svn/entries b/package/boot/uboot-omap4/.svn/entries
new file mode 100644
index 0000000..b8dfce9
--- /dev/null
+++ b/package/boot/uboot-omap4/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap4
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+5d245a30082c95e1b75afc31e6884530
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2010
+
diff --git a/package/boot/uboot-omap4/.svn/text-base/Makefile.svn-base b/package/boot/uboot-omap4/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..d128e16
--- /dev/null
+++ b/package/boot/uboot-omap4/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2011.12
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=7f29b9f6da44d6e46e988e7561fd1d5f
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/omap4_panda
+ TITLE:=U-Boot for the Pandaboard
+endef
+
+UBOOTS:=omap4_panda
+
+define Package/uboot/template
+define Package/uboot-omap4-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_omap4
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUbootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Prepare
+ $(call Build/Prepare/Default)
+# $(CP) ./files/* $(PKG_BUILD_DIR)
+ find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf
+endef
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/template
+define Package/uboot-omap4-$(1)/install
+ $(INSTALL_DIR) $$(1)
+ $(CP) $(PKG_BUILD_DIR)/MLO $(BIN_DIR)/MLO-$(BOARD)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.img $(BIN_DIR)/$(2)
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.img)) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUbootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-omap4-$(u))) \
+)
diff --git a/package/boot/uboot-omap4/Makefile b/package/boot/uboot-omap4/Makefile
new file mode 100644
index 0000000..d128e16
--- /dev/null
+++ b/package/boot/uboot-omap4/Makefile
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2011.12
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=7f29b9f6da44d6e46e988e7561fd1d5f
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/omap4_panda
+ TITLE:=U-Boot for the Pandaboard
+endef
+
+UBOOTS:=omap4_panda
+
+define Package/uboot/template
+define Package/uboot-omap4-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_omap4
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUbootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Prepare
+ $(call Build/Prepare/Default)
+# $(CP) ./files/* $(PKG_BUILD_DIR)
+ find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf
+endef
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/template
+define Package/uboot-omap4-$(1)/install
+ $(INSTALL_DIR) $$(1)
+ $(CP) $(PKG_BUILD_DIR)/MLO $(BIN_DIR)/MLO-$(BOARD)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.img $(BIN_DIR)/$(2)
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.img)) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUbootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-omap4-$(u))) \
+)
diff --git a/package/boot/uboot-pxa/.svn/entries b/package/boot/uboot-pxa/.svn/entries
new file mode 100644
index 0000000..cd230d0
--- /dev/null
+++ b/package/boot/uboot-pxa/.svn/entries
@@ -0,0 +1,65 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-pxa
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+patches
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+0fadf5838e09edaec577b298d7e9c4eb
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1980
+
diff --git a/package/boot/uboot-pxa/.svn/text-base/Makefile.svn-base b/package/boot/uboot-pxa/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..7fe747c
--- /dev/null
+++ b/package/boot/uboot-pxa/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2011.08.25
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://github.com/ashcharles/verdex-uboot.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=ca6bf3ef6ac5f5132a359b43dfa31e07076b74b7
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/gumstix
+ TITLE:=U-Boot for the Gumstix Verdex
+endef
+
+UBOOTS:=gumstix
+
+define Package/uboot/template
+define Package/uboot-pxa-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_pxa
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+endef
+endef
+
+define BuildUBootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ u-boot.bin \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/default
+ $(INSTALL_DIR) $(BIN_DIR)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.bin \
+ $(BIN_DIR)/openwrt-$(BOARD)-$(1)-u-boot.bin
+endef
+
+define Package/uboot/install/template
+define Package/uboot-pxa-$(1)/install
+ $(call Package/uboot/install/default,$(2))
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),$(u))) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUBootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-pxa-$(u))) \
+)
diff --git a/package/boot/uboot-pxa/Makefile b/package/boot/uboot-pxa/Makefile
new file mode 100644
index 0000000..7fe747c
--- /dev/null
+++ b/package/boot/uboot-pxa/Makefile
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2011.08.25
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=git://github.com/ashcharles/verdex-uboot.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=ca6bf3ef6ac5f5132a359b43dfa31e07076b74b7
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/gumstix
+ TITLE:=U-Boot for the Gumstix Verdex
+endef
+
+UBOOTS:=gumstix
+
+define Package/uboot/template
+define Package/uboot-pxa-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_pxa
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/U-Boot
+ VARIANT:=$(1)
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+endef
+endef
+
+define BuildUBootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ u-boot.bin \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/default
+ $(INSTALL_DIR) $(BIN_DIR)
+ $(CP) $(PKG_BUILD_DIR)/u-boot.bin \
+ $(BIN_DIR)/openwrt-$(BOARD)-$(1)-u-boot.bin
+endef
+
+define Package/uboot/install/template
+define Package/uboot-pxa-$(1)/install
+ $(call Package/uboot/install/default,$(2))
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),$(u))) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUBootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-pxa-$(u))) \
+)
diff --git a/package/boot/uboot-pxa/patches/.svn/entries b/package/boot/uboot-pxa/patches/.svn/entries
new file mode 100644
index 0000000..be5d3b6
--- /dev/null
+++ b/package/boot/uboot-pxa/patches/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-pxa/patches
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+001-squashfs_rootfstype_cmdline.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+cb4baee4e5cf315fe29485e6f3c4d943
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1105
+
diff --git a/package/boot/uboot-pxa/patches/.svn/text-base/001-squashfs_rootfstype_cmdline.patch.svn-base b/package/boot/uboot-pxa/patches/.svn/text-base/001-squashfs_rootfstype_cmdline.patch.svn-base
new file mode 100644
index 0000000..cfef66b
--- /dev/null
+++ b/package/boot/uboot-pxa/patches/.svn/text-base/001-squashfs_rootfstype_cmdline.patch.svn-base
@@ -0,0 +1,13 @@
+diff --git a/include/configs/gumstix.h b/include/configs/gumstix.h
+index 319da63..5483993 100644
+--- a/include/configs/gumstix.h
++++ b/include/configs/gumstix.h
+@@ -136,7 +136,7 @@
+ #define CONFIG_MISC_INIT_R /* misc_init_r function in gumstix sets board serial number */
+
+ #define CONFIG_BOOTFILE boot/uImage
+-#define CONFIG_BOOTARGS "console=ttyS0,115200n8 root=1f01 rootfstype=jffs2 reboot=cold,hard"
++#define CONFIG_BOOTARGS "console=ttyS0,115200n8 root=1f01 rootfstype=squashfs,jffs2 reboot=cold,hard"
+ #define CONFIG_BOOTCOMMAND "icache on; setenv stderr nulldev; setenv stdout nulldev; if pinit on && fatload ide 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on CF...; autoscr; else if mmcinit && fatload mmc 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on MMC...; autoscr; else setenv stdout serial; setenv stderr serial; katload 100000 && bootm; fi; fi"
+ #define CONFIG_BOOTDELAY 2 /* in seconds */
+ #define CONFIG_EXTRA_ENV_SETTINGS "verify=no"
diff --git a/package/boot/uboot-pxa/patches/001-squashfs_rootfstype_cmdline.patch b/package/boot/uboot-pxa/patches/001-squashfs_rootfstype_cmdline.patch
new file mode 100644
index 0000000..cfef66b
--- /dev/null
+++ b/package/boot/uboot-pxa/patches/001-squashfs_rootfstype_cmdline.patch
@@ -0,0 +1,13 @@
+diff --git a/include/configs/gumstix.h b/include/configs/gumstix.h
+index 319da63..5483993 100644
+--- a/include/configs/gumstix.h
++++ b/include/configs/gumstix.h
+@@ -136,7 +136,7 @@
+ #define CONFIG_MISC_INIT_R /* misc_init_r function in gumstix sets board serial number */
+
+ #define CONFIG_BOOTFILE boot/uImage
+-#define CONFIG_BOOTARGS "console=ttyS0,115200n8 root=1f01 rootfstype=jffs2 reboot=cold,hard"
++#define CONFIG_BOOTARGS "console=ttyS0,115200n8 root=1f01 rootfstype=squashfs,jffs2 reboot=cold,hard"
+ #define CONFIG_BOOTCOMMAND "icache on; setenv stderr nulldev; setenv stdout nulldev; if pinit on && fatload ide 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on CF...; autoscr; else if mmcinit && fatload mmc 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on MMC...; autoscr; else setenv stdout serial; setenv stderr serial; katload 100000 && bootm; fi; fi"
+ #define CONFIG_BOOTDELAY 2 /* in seconds */
+ #define CONFIG_EXTRA_ENV_SETTINGS "verify=no"
diff --git a/package/boot/uboot-xburst/.svn/entries b/package/boot/uboot-xburst/.svn/entries
new file mode 100644
index 0000000..f21bf90
--- /dev/null
+++ b/package/boot/uboot-xburst/.svn/entries
@@ -0,0 +1,68 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T17:11:15.287568Z
+35042
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+files
+dir
+
+patches
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+e4c7934e9ef907cf8d46a731519a560c
+2013-01-07T17:11:15.287568Z
+35042
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1820
+
diff --git a/package/boot/uboot-xburst/.svn/text-base/Makefile.svn-base b/package/boot/uboot-xburst/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..f4c8ad9
--- /dev/null
+++ b/package/boot/uboot-xburst/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,83 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2012.10-rc2
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=451c07271940016cec6f5ad8a155263b
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/qi_lb60
+ TITLE:=U-boot for the qi_lb60 board
+endef
+
+UBOOTS:=qi_lb60
+
+define Package/uboot/template
+define Package/uboot-xburst-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_xburst
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/UBoot/WebHome
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUbootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/template
+define Package/uboot-xburst-$(1)/install
+ $(CP) $(PKG_BUILD_DIR)/u-boot-xburst.bin $(BIN_DIR)/$(2)
+ rmdir $$(1)
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.bin)) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUbootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-xburst-$(u))) \
+)
diff --git a/package/boot/uboot-xburst/Makefile b/package/boot/uboot-xburst/Makefile
new file mode 100644
index 0000000..f4c8ad9
--- /dev/null
+++ b/package/boot/uboot-xburst/Makefile
@@ -0,0 +1,83 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=u-boot
+PKG_VERSION:=2012.10-rc2
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
+PKG_MD5SUM:=451c07271940016cec6f5ad8a155263b
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define uboot/Default
+ TITLE:=
+ CONFIG:=
+ IMAGE:=
+endef
+
+define uboot/qi_lb60
+ TITLE:=U-boot for the qi_lb60 board
+endef
+
+UBOOTS:=qi_lb60
+
+define Package/uboot/template
+define Package/uboot-xburst-$(1)
+ SECTION:=boot
+ CATEGORY:=Boot Loaders
+ DEPENDS:=@TARGET_xburst
+ TITLE:=$(2)
+ URL:=http://www.denx.de/wiki/UBoot/WebHome
+ VARIANT:=$(1)
+endef
+endef
+
+define BuildUbootPackage
+ $(eval $(uboot/Default))
+ $(eval $(uboot/$(1)))
+ $(call Package/uboot/template,$(1),$(TITLE))
+endef
+
+
+ifdef BUILD_VARIANT
+$(eval $(call uboot/$(BUILD_VARIANT)))
+UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
+UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
+endif
+
+define Build/Configure
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(UBOOT_CONFIG)_config
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CROSS_COMPILE=$(TARGET_CROSS)
+endef
+
+define Package/uboot/install/template
+define Package/uboot-xburst-$(1)/install
+ $(CP) $(PKG_BUILD_DIR)/u-boot-xburst.bin $(BIN_DIR)/$(2)
+ rmdir $$(1)
+endef
+endef
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.bin)) \
+)
+
+$(foreach u,$(UBOOTS), \
+ $(eval $(call BuildUbootPackage,$(u))) \
+ $(eval $(call BuildPackage,uboot-xburst-$(u))) \
+)
diff --git a/package/boot/uboot-xburst/files/.svn/entries b/package/boot/uboot-xburst/files/.svn/entries
new file mode 100644
index 0000000..df14e18
--- /dev/null
+++ b/package/boot/uboot-xburst/files/.svn/entries
@@ -0,0 +1,40 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+include
+dir
+
+board
+dir
+
+cpu
+dir
+
+nand_spl
+dir
+
diff --git a/package/boot/uboot-xburst/files/board/.svn/entries b/package/boot/uboot-xburst/files/board/.svn/entries
new file mode 100644
index 0000000..9c92717
--- /dev/null
+++ b/package/boot/uboot-xburst/files/board/.svn/entries
@@ -0,0 +1,37 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/board
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+nanonote
+dir
+
+sakc
+dir
+
+n516
+dir
+
diff --git a/package/boot/uboot-xburst/files/board/n516/.svn/entries b/package/boot/uboot-xburst/files/board/n516/.svn/entries
new file mode 100644
index 0000000..7556702
--- /dev/null
+++ b/package/boot/uboot-xburst/files/board/n516/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/board/n516
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-xburst/files/board/nanonote/.svn/entries b/package/boot/uboot-xburst/files/board/nanonote/.svn/entries
new file mode 100644
index 0000000..cd3d211
--- /dev/null
+++ b/package/boot/uboot-xburst/files/board/nanonote/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/board/nanonote
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-xburst/files/board/sakc/.svn/entries b/package/boot/uboot-xburst/files/board/sakc/.svn/entries
new file mode 100644
index 0000000..e22ec07
--- /dev/null
+++ b/package/boot/uboot-xburst/files/board/sakc/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/board/sakc
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-xburst/files/cpu/.svn/entries b/package/boot/uboot-xburst/files/cpu/.svn/entries
new file mode 100644
index 0000000..d6e3dc5
--- /dev/null
+++ b/package/boot/uboot-xburst/files/cpu/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/cpu
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+mips
+dir
+
diff --git a/package/boot/uboot-xburst/files/cpu/mips/.svn/entries b/package/boot/uboot-xburst/files/cpu/mips/.svn/entries
new file mode 100644
index 0000000..05c73eb
--- /dev/null
+++ b/package/boot/uboot-xburst/files/cpu/mips/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/cpu/mips
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-xburst/files/include/.svn/entries b/package/boot/uboot-xburst/files/include/.svn/entries
new file mode 100644
index 0000000..8288f2b
--- /dev/null
+++ b/package/boot/uboot-xburst/files/include/.svn/entries
@@ -0,0 +1,34 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/include
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+asm-mips
+dir
+
+configs
+dir
+
diff --git a/package/boot/uboot-xburst/files/include/asm-mips/.svn/entries b/package/boot/uboot-xburst/files/include/asm-mips/.svn/entries
new file mode 100644
index 0000000..2a61466
--- /dev/null
+++ b/package/boot/uboot-xburst/files/include/asm-mips/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/include/asm-mips
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-xburst/files/include/configs/.svn/entries b/package/boot/uboot-xburst/files/include/configs/.svn/entries
new file mode 100644
index 0000000..52a7f07
--- /dev/null
+++ b/package/boot/uboot-xburst/files/include/configs/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/include/configs
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-xburst/files/nand_spl/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/.svn/entries
new file mode 100644
index 0000000..b02ad1e
--- /dev/null
+++ b/package/boot/uboot-xburst/files/nand_spl/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+board
+dir
+
diff --git a/package/boot/uboot-xburst/files/nand_spl/board/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/board/.svn/entries
new file mode 100644
index 0000000..3aae273
--- /dev/null
+++ b/package/boot/uboot-xburst/files/nand_spl/board/.svn/entries
@@ -0,0 +1,37 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl/board
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+nanonote
+dir
+
+sakc
+dir
+
+n516
+dir
+
diff --git a/package/boot/uboot-xburst/files/nand_spl/board/n516/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/board/n516/.svn/entries
new file mode 100644
index 0000000..081f719
--- /dev/null
+++ b/package/boot/uboot-xburst/files/nand_spl/board/n516/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl/board/n516
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-xburst/files/nand_spl/board/nanonote/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/board/nanonote/.svn/entries
new file mode 100644
index 0000000..5e23a35
--- /dev/null
+++ b/package/boot/uboot-xburst/files/nand_spl/board/nanonote/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl/board/nanonote
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-xburst/files/nand_spl/board/sakc/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/board/sakc/.svn/entries
new file mode 100644
index 0000000..d7a0ad0
--- /dev/null
+++ b/package/boot/uboot-xburst/files/nand_spl/board/sakc/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl/board/sakc
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
diff --git a/package/boot/uboot-xburst/patches/.svn/entries b/package/boot/uboot-xburst/patches/.svn/entries
new file mode 100644
index 0000000..352f1b4
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/.svn/entries
@@ -0,0 +1,232 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/patches
+svn://svn.openwrt.org/openwrt
+
+
+
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+318bc9342da0200c534c0b1552a9c2d5
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6931
+
+0005-add-nanonote-lcd-support.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+9e8ff8de93294556ae1855c647aa3b20
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+27030
+
+0001-qi_lb60-add-nand-spl-support.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+d3a431d733f776288d3a555a25581e94
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+27630
+
+0006-enable-silent-console.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+cda7306fbff5de64b84db2e0f5420c5e
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1788
+
+0003-add-mmc-support.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+c509ed47f09ab80e5ca3be62e6733000
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+47318
+
+0002-qi_lb60-add-software-usbboot-support.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+d400befeef1d1a82fe35fc586fa32061
+2013-01-07T14:10:01.049177Z
+35034
+mirko
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+22384
+
diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0001-qi_lb60-add-nand-spl-support.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0001-qi_lb60-add-nand-spl-support.patch.svn-base
new file mode 100644
index 0000000..e770243
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/.svn/text-base/0001-qi_lb60-add-nand-spl-support.patch.svn-base
@@ -0,0 +1,894 @@
+From 0329cf7965956a5a7044827e0ce88ae8d5150e54 Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Fri, 12 Oct 2012 09:46:58 +0800
+Subject: [PATCH 1/6] qi_lb60: add nand spl support
+
+ The JZ4740 CPU can load 8KB from two different addresses:
+ 1. the normal area up to 8KB starting from NAND flash address 0x00000000
+ 2. the backup area up to 8KB starting from NAND flash address 0x00002000
+
+Signed-off-by: Xiangfu <xiangfu@openmobilefree.net>
+---
+ Makefile | 12 +++
+ arch/mips/cpu/xburst/Makefile | 7 +-
+ arch/mips/cpu/xburst/cpu.c | 4 +
+ arch/mips/cpu/xburst/jz4740.c | 82 +++++++----------
+ arch/mips/cpu/xburst/spl/Makefile | 47 ++++++++++
+ arch/mips/cpu/xburst/spl/start.S | 63 +++++++++++++
+ board/qi/qi_lb60/Makefile | 4 +
+ board/qi/qi_lb60/qi_lb60-spl.c | 30 +++++++
+ board/qi/qi_lb60/qi_lb60.c | 8 +-
+ board/qi/qi_lb60/u-boot-spl.lds | 61 +++++++++++++
+ drivers/mtd/nand/jz4740_nand.c | 39 ++++++++-
+ include/configs/qi_lb60.h | 175 ++++++++++++++++++-------------------
+ 12 files changed, 386 insertions(+), 146 deletions(-)
+ create mode 100644 arch/mips/cpu/xburst/spl/Makefile
+ create mode 100644 arch/mips/cpu/xburst/spl/start.S
+ create mode 100644 board/qi/qi_lb60/qi_lb60-spl.c
+ create mode 100644 board/qi/qi_lb60/u-boot-spl.lds
+
+diff --git a/Makefile b/Makefile
+index 34d9075..a22778e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -393,6 +393,10 @@ ALL-y += $(obj)u-boot-nodtb-tegra.bin
+ endif
+ endif
+
++ifeq ($(CPU),xburst)
++ALL-y += $(obj)u-boot-xburst.bin
++endif
++
+ all: $(ALL-y) $(SUBDIR_EXAMPLES)
+
+ $(obj)u-boot.dtb: $(obj)u-boot
+@@ -506,6 +510,14 @@ $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
+ endif
+ endif
+
++ifeq ($(CPU),xburst)
++$(obj)u-boot-xburst.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
++ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync bs=8192 count=1
++ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=8192 count=1
++ tr '\0' '\377' < /dev/zero | dd of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=16384 count=1
++ cat $(obj)spl/u-boot-pad.bin u-boot.bin > $@
++endif
++
+ ifeq ($(CONFIG_SANDBOX),y)
+ GEN_UBOOT = \
+ cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
+diff --git a/arch/mips/cpu/xburst/Makefile b/arch/mips/cpu/xburst/Makefile
+index b1f2ae4..ec35e55 100644
+--- a/arch/mips/cpu/xburst/Makefile
++++ b/arch/mips/cpu/xburst/Makefile
+@@ -24,9 +24,12 @@ include $(TOPDIR)/config.mk
+
+ LIB = $(obj)lib$(CPU).o
+
++COBJS-y = cpu.o jz_serial.o
++
++ifneq ($(CONFIG_SPL_BUILD),y)
+ START = start.o
+-SOBJS-y =
+-COBJS-y = cpu.o timer.o jz_serial.o
++COBJS-y += timer.o
++endif
+
+ COBJS-$(CONFIG_JZ4740) += jz4740.o
+
+diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c
+index ddcbfaa..1432838 100644
+--- a/arch/mips/cpu/xburst/cpu.c
++++ b/arch/mips/cpu/xburst/cpu.c
+@@ -42,6 +42,8 @@
+ : \
+ : "i" (op), "R" (*(unsigned char *)(addr)))
+
++#ifndef CONFIG_SPL_BUILD
++
+ void __attribute__((weak)) _machine_restart(void)
+ {
+ struct jz4740_wdt *wdt = (struct jz4740_wdt *)JZ4740_WDT_BASE;
+@@ -109,6 +111,8 @@ void invalidate_dcache_range(ulong start_addr, ulong stop)
+ cache_op(Hit_Invalidate_D, addr);
+ }
+
++#endif
++
+ void flush_icache_all(void)
+ {
+ u32 addr, t = 0;
+diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c
+index c0b9817..8816aa3 100644
+--- a/arch/mips/cpu/xburst/jz4740.c
++++ b/arch/mips/cpu/xburst/jz4740.c
+@@ -32,31 +32,19 @@ int disable_interrupts(void)
+ return 0;
+ }
+
+-/*
+- * PLL output clock = EXTAL * NF / (NR * NO)
+- * NF = FD + 2, NR = RD + 2
+- * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
+- */
+ void pll_init(void)
+ {
+ struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE;
+
+- register unsigned int cfcr, plcr1;
+- int n2FR[33] = {
+- 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
+- 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
+- 9
+- };
+- int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
+- int nf, pllout2;
++ register unsigned int cfcr, plcr;
++ unsigned int nf, pllout2;
+
+ cfcr = CPM_CPCCR_CLKOEN |
+- CPM_CPCCR_PCS |
+- (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
+- (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
+- (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
+- (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
+- (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
++ (0 << CPM_CPCCR_CDIV_BIT) |
++ (2 << CPM_CPCCR_HDIV_BIT) |
++ (2 << CPM_CPCCR_PDIV_BIT) |
++ (2 << CPM_CPCCR_MDIV_BIT) |
++ (2 << CPM_CPCCR_LDIV_BIT);
+
+ pllout2 = (cfcr & CPM_CPCCR_PCS) ?
+ CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2);
+@@ -65,15 +53,18 @@ void pll_init(void)
+ writel(pllout2 / 48000000 - 1, &cpm->uhccdr);
+
+ nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL;
+- plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
++ plcr = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
+ (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
+ (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
+- (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
++ (0x32 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
+ CPM_CPPCR_PLLEN; /* enable PLL */
+
+ /* init PLL */
+ writel(cfcr, &cpm->cpccr);
+- writel(plcr1, &cpm->cppcr);
++ writel(plcr, &cpm->cppcr);
++
++ while (!(readl(&cpm->cppcr) & CPM_CPPCR_PLLS))
++ ;
+ }
+
+ void sdram_init(void)
+@@ -92,26 +83,12 @@ void sdram_init(void)
+ 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
+ };
+
+- int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
+-
+ cpu_clk = CONFIG_SYS_CPU_SPEED;
+- mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
++ mem_clk = 84000000;
+
+ writel(0, &emc->bcr); /* Disable bus release */
+ writew(0, &emc->rtcsr); /* Disable clock for counting */
+
+- /* Fault DMCR value for mode register setting*/
+-#define SDRAM_ROW0 11
+-#define SDRAM_COL0 8
+-#define SDRAM_BANK40 0
+-
+- dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) |
+- ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) |
+- (SDRAM_BANK40 << EMC_DMCR_BA_BIT) |
+- (SDRAM_BW16 << EMC_DMCR_BW_BIT) |
+- EMC_DMCR_EPIN |
+- cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
+-
+ /* Basic DMCR value */
+ dmcr = ((SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) |
+ ((SDRAM_COL - 8) << EMC_DMCR_CA_BIT) |
+@@ -128,31 +105,31 @@ void sdram_init(void)
+ if (tmp > 11)
+ tmp = 11;
+ dmcr |= (tmp - 4) << EMC_DMCR_TRAS_BIT;
+- tmp = SDRAM_RCD / ns;
+
++ tmp = SDRAM_RCD / ns;
+ if (tmp > 3)
+ tmp = 3;
+ dmcr |= tmp << EMC_DMCR_RCD_BIT;
+- tmp = SDRAM_TPC / ns;
+
++ tmp = SDRAM_TPC / ns;
+ if (tmp > 7)
+ tmp = 7;
+ dmcr |= tmp << EMC_DMCR_TPC_BIT;
+- tmp = SDRAM_TRWL / ns;
+
++ tmp = SDRAM_TRWL / ns;
+ if (tmp > 3)
+ tmp = 3;
+ dmcr |= tmp << EMC_DMCR_TRWL_BIT;
+- tmp = (SDRAM_TRAS + SDRAM_TPC) / ns;
+
++ tmp = (SDRAM_TRAS + SDRAM_TPC) / ns;
+ if (tmp > 14)
+ tmp = 14;
+ dmcr |= ((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT;
+
+ /* SDRAM mode value */
+- sdmode = EMC_SDMR_BT_SEQ |
+- EMC_SDMR_OM_NORMAL |
+- EMC_SDMR_BL_4 |
++ sdmode = EMC_SDMR_BT_SEQ |
++ EMC_SDMR_OM_NORMAL |
++ EMC_SDMR_BL_4 |
+ cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
+
+ /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
+@@ -172,8 +149,8 @@ void sdram_init(void)
+ if (tmp > 0xff)
+ tmp = 0xff;
+ writew(tmp, &emc->rtcor);
++
+ writew(0, &emc->rtcnt);
+- /* Divisor is 64, CKO/64 */
+ writew(EMC_RTCSR_CKS_64, &emc->rtcsr);
+
+ /* Wait for number of auto-refresh cycles */
+@@ -182,13 +159,17 @@ void sdram_init(void)
+ ;
+
+ /* Stage 3. Mode Register Set */
++ dmcr0 = (11 << EMC_DMCR_RA_BIT) |
++ (8 << EMC_DMCR_CA_BIT) |
++ (0 << EMC_DMCR_BA_BIT) |
++ EMC_DMCR_EPIN |
++ (SDRAM_BW16 << EMC_DMCR_BW_BIT) |
++ cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
+ writel(dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr);
+ writeb(0, JZ4740_EMC_SDMR0 | sdmode);
+
+ /* Set back to basic DMCR value */
+ writel(dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr);
+-
+- /* everything is ok now */
+ }
+
+ DECLARE_GLOBAL_DATA_PTR;
+@@ -232,9 +213,10 @@ void rtc_init(void)
+ phys_size_t initdram(int board_type)
+ {
+ struct jz4740_emc *emc = (struct jz4740_emc *)JZ4740_EMC_BASE;
+- u32 dmcr;
+- u32 rows, cols, dw, banks;
+- ulong size;
++
++ unsigned int dmcr;
++ unsigned int rows, cols, dw, banks;
++ unsigned long size;
+
+ dmcr = readl(&emc->dmcr);
+ rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT);
+diff --git a/arch/mips/cpu/xburst/spl/Makefile b/arch/mips/cpu/xburst/spl/Makefile
+new file mode 100644
+index 0000000..f45e8c8
+--- /dev/null
++++ b/arch/mips/cpu/xburst/spl/Makefile
+@@ -0,0 +1,47 @@
++#
++# Copyright (C) 2011 Xiangfu Liu <xiangfu@openmobilefree.net>
++#
++# See file CREDITS for list of people who contributed to this
++# project.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of the GNU General Public License as
++# published by the Free Software Foundation; either version 2 of
++# the License, or (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++# MA 02111-1307 USA
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(CPU).o
++
++START = start.o
++SOBJS-y =
++COBJS-y =
++
++SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
++OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
++START := $(addprefix $(obj),$(START))
++
++all: $(obj).depend $(START) $(LIB)
++
++$(LIB): $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+diff --git a/arch/mips/cpu/xburst/spl/start.S b/arch/mips/cpu/xburst/spl/start.S
+new file mode 100644
+index 0000000..e31c4c8
+--- /dev/null
++++ b/arch/mips/cpu/xburst/spl/start.S
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (c) 2010 Xiangfu Liu <xiangfu@openmobilefree.net>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 3 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <version.h>
++#include <asm/regdef.h>
++#include <asm/mipsregs.h>
++#include <asm/addrspace.h>
++#include <asm/cacheops.h>
++
++#include <asm/jz4740.h>
++
++ .set noreorder
++
++ .globl _start
++ .text
++_start:
++ .word JZ4740_NANDBOOT_CFG /* fetched during NAND Boot */
++reset:
++ /*
++ * STATUS register
++ * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
++ */
++ li t0, 0x0040FC04
++ mtc0 t0, CP0_STATUS
++ /*
++ * CAUSE register
++ * IV=1, use the specical interrupt vector (0x200)
++ */
++ li t1, 0x00800000
++ mtc0 t1, CP0_CAUSE
++
++ bal 1f
++ nop
++ .word _GLOBAL_OFFSET_TABLE_
++1:
++ move gp, ra
++ lw t1, 0(ra)
++ move gp, t1
++
++ la sp, 0x80004000
++ la t9, nand_spl_boot
++ j t9
++ nop
+diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile
+index 5dae11b..e399246 100644
+--- a/board/qi/qi_lb60/Makefile
++++ b/board/qi/qi_lb60/Makefile
+@@ -22,7 +22,11 @@ include $(TOPDIR)/config.mk
+
+ LIB = $(obj)lib$(BOARD).o
+
++ifeq ($(CONFIG_SPL_BUILD),y)
++COBJS := $(BOARD)-spl.o
++else
+ COBJS := $(BOARD).o
++endif
+
+ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c
+new file mode 100644
+index 0000000..3fe3fa3
+--- /dev/null
++++ b/board/qi/qi_lb60/qi_lb60-spl.c
+@@ -0,0 +1,30 @@
++/*
++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.cc>
++ *
++ * 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
++ * 3 of the License, or (at your option) any later version.
++ */
++
++#include <common.h>
++#include <nand.h>
++#include <asm/io.h>
++#include <asm/jz4740.h>
++
++void nand_spl_boot(void)
++{
++ __gpio_as_sdram_16bit_4720();
++ __gpio_as_uart0();
++ __gpio_jtag_to_uart0();
++
++ serial_init();
++
++ pll_init();
++ sdram_init();
++
++ nand_init();
++
++ puts("\nQi LB60 SPL: Starting U-Boot ...\n");
++ nand_boot();
++}
+diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
+index d975209..3bd4e2f 100644
+--- a/board/qi/qi_lb60/qi_lb60.c
++++ b/board/qi/qi_lb60/qi_lb60.c
+@@ -1,5 +1,5 @@
+ /*
+- * Authors: Xiangfu Liu <xiangfu@sharism.cc>
++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+@@ -97,8 +97,10 @@ int board_early_init_f(void)
+ /* U-Boot common routines */
+ int checkboard(void)
+ {
+- printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC, Speed %ld MHz)\n",
+- gd->cpu_clk / 1000000);
++ printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC)\n");
++ printf(" CPU: %ld\n", gd->cpu_clk);
++ printf(" MEM: %ld\n", gd->mem_clk);
++ printf(" DEV: %ld\n", gd->dev_clk);
+
+ return 0;
+ }
+diff --git a/board/qi/qi_lb60/u-boot-spl.lds b/board/qi/qi_lb60/u-boot-spl.lds
+new file mode 100644
+index 0000000..930537f
+--- /dev/null
++++ b/board/qi/qi_lb60/u-boot-spl.lds
+@@ -0,0 +1,61 @@
++/*
++ * (C) Copyright 2012 Xiangfu Liu <xiangfu@openmobilefree.net>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
++
++OUTPUT_ARCH(mips)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x80000000;
++ . = ALIGN(4);
++ .text :
++ {
++ *(.text)
++ }
++
++ . = ALIGN(4);
++ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
++
++ . = ALIGN(4);
++ .data : { *(.data) }
++
++ . = ALIGN(4);
++ .sdata : { *(.sdata) }
++
++ _gp = ALIGN(16);
++
++ __got_start = .;
++ .got : { *(.got) }
++ __got_end = .;
++
++ . = .;
++ __u_boot_cmd_start = .;
++ .u_boot_cmd : { *(.u_boot_cmd) }
++ __u_boot_cmd_end = .;
++
++ uboot_end_data = .;
++ num_got_entries = (__got_end - __got_start) >> 2;
++
++ . = ALIGN(4);
++ .sbss : { *(.sbss) }
++ .bss : { *(.bss) }
++ uboot_end = .;
++}
++ASSERT(uboot_end <= 0x80002000, "NAND bootstrap too big");
+diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
+index 3ec34f3..24a4921 100644
+--- a/drivers/mtd/nand/jz4740_nand.c
++++ b/drivers/mtd/nand/jz4740_nand.c
+@@ -15,6 +15,9 @@
+ #include <asm/io.h>
+ #include <asm/jz4740.h>
+
++#ifdef CONFIG_SPL_BUILD
++#define printf(s) puts(s)
++#endif
+ #define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000)
+ #define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000)
+ #define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000)
+@@ -176,7 +179,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+ for (k = 0; k < 9; k++)
+ writeb(read_ecc[k], &emc->nfpar[k]);
+ }
+- /* Set PRDY */
++
+ writel(readl(&emc->nfecr) | EMC_NFECR_PRDY, &emc->nfecr);
+
+ /* Wait for completion */
+@@ -184,7 +187,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+ status = readl(&emc->nfints);
+ } while (!(status & EMC_NFINTS_DECF));
+
+- /* disable ecc */
++ /* Disable ECC */
+ writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr);
+
+ /* Check decoding */
+@@ -192,7 +195,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+ return 0;
+
+ if (status & EMC_NFINTS_UNCOR) {
+- printf("uncorrectable ecc\n");
++ printf("JZ4740 uncorrectable ECC\n");
+ return -1;
+ }
+
+@@ -230,6 +233,32 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+ return errcnt;
+ }
+
++#ifdef CONFIG_SPL_BUILD
++static void jz_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
++{
++ int i;
++ struct nand_chip *this = mtd->priv;
++
++#if (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R3) || \
++ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R2)
++ for (i = 0; i < len; i += 2)
++ buf[i] = readw(this->IO_ADDR_R);
++#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R3) || \
++ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R2)
++ for (i = 0; i < len; i++)
++ buf[i] = readb(this->IO_ADDR_R);
++#else
++ #error JZ4740_NANDBOOT_CFG not defined or wrong
++#endif
++}
++
++static uint8_t jz_nand_read_byte(struct mtd_info *mtd)
++{
++ struct nand_chip *this = mtd->priv;
++ return readb(this->IO_ADDR_R);
++}
++#endif
++
+ /*
+ * Main initialization routine
+ */
+@@ -254,6 +283,10 @@ int board_nand_init(struct nand_chip *nand)
+ nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
+ nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
+ nand->ecc.layout = &qi_lb60_ecclayout_2gb;
++#ifdef CONFIG_SPL_BUILD
++ nand->read_byte = jz_nand_read_byte;
++ nand->read_buf = jz_nand_read_buf;
++#endif
+ nand->chip_delay = 50;
+ nand->options = NAND_USE_FLASH_BBT;
+
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index 4bb5bbc..7bff444 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -1,5 +1,5 @@
+ /*
+- * Authors: Xiangfu Liu <xiangfu.z@gmail.com>
++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+@@ -14,7 +14,6 @@
+ #define CONFIG_SYS_LITTLE_ENDIAN
+ #define CONFIG_JZSOC /* Jz SoC */
+ #define CONFIG_JZ4740 /* Jz4740 SoC */
+-#define CONFIG_NAND_JZ4740
+
+ #define CONFIG_SYS_CPU_SPEED 336000000 /* CPU clock: 336 MHz */
+ #define CONFIG_SYS_EXTAL 12000000 /* EXTAL freq: 12 MHz */
+@@ -24,24 +23,43 @@
+ #define CONFIG_SYS_UART_BASE JZ4740_UART0_BASE /* Base of the UART channel */
+ #define CONFIG_BAUDRATE 57600
+
++#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL)
++#define CONFIG_BOOTDELAY 0
++#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
++#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x280000;bootm"
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
++#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
++#define CONFIG_SYS_LOAD_ADDR 0x80600000
++#define CONFIG_SYS_MEMTEST_START 0x80100000
++#define CONFIG_SYS_MEMTEST_END 0x80A00000
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
++
++#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024)
++#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)
++
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
++
++#define CONFIG_SYS_LONGHELP
++#define CONFIG_SYS_MAXARGS 16
++#define CONFIG_SYS_PROMPT "NanoNote# "
++
+ #define CONFIG_SKIP_LOWLEVEL_INIT
+ #define CONFIG_BOARD_EARLY_INIT_F
+ #define CONFIG_SYS_NO_FLASH
+ #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */
+-#define CONFIG_ENV_OVERWRITE
+-
+-#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL)
+-#define CONFIG_BOOTDELAY 0
+-#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
+-#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x200000;bootm"
+
+ /*
+- * Command line configuration.
++ * Command line configuration
+ */
+ #define CONFIG_CMD_BOOTD /* bootd */
+ #define CONFIG_CMD_CONSOLE /* coninfo */
+ #define CONFIG_CMD_ECHO /* echo arguments */
+-
+ #define CONFIG_CMD_LOADB /* loadb */
+ #define CONFIG_CMD_LOADS /* loads */
+ #define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop mtest */
+@@ -58,45 +76,16 @@
+ #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+
+ /*
+- * Miscellaneous configurable options
+- */
+-#define CONFIG_SYS_MAXARGS 16
+-#define CONFIG_SYS_LONGHELP
+-#define CONFIG_SYS_PROMPT "NanoNote# "
+-#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
+-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+-
+-#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024)
+-#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)
+-
+-#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
+-#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
+-#define CONFIG_SYS_LOAD_ADDR 0x80600000
+-#define CONFIG_SYS_MEMTEST_START 0x80100000
+-#define CONFIG_SYS_MEMTEST_END 0x80800000
+-
+-/*
+- * Environment
++ * NAND driver configuration
+ */
+-#define CONFIG_ENV_IS_IN_NAND /* use NAND for environment vars */
+-
+-#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+-/*
+- * if board nand flash is 1GB, set to 1
+- * if board nand flash is 2GB, set to 2
+- * for change the PAGE_SIZE and BLOCK_SIZE
+- * will delete when there is no 1GB flash
+- */
+-#define NANONOTE_NAND_SIZE 2
+-
+-#define CONFIG_SYS_NAND_PAGE_SIZE (2048 * NANONOTE_NAND_SIZE)
+-#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * NANONOTE_NAND_SIZE << 10)
+-/* nand bad block was marked at this page in a block, start from 0 */
++#define CONFIG_NAND_JZ4740
++#define CONFIG_SYS_NAND_PAGE_SIZE 4096
++#define CONFIG_SYS_NAND_BLOCK_SIZE (512 << 10)
++/* NAND bad block was marked at this page in a block, start from 0 */
+ #define CONFIG_SYS_NAND_BADBLOCK_PAGE 127
+ #define CONFIG_SYS_NAND_PAGE_COUNT 128
+ #define CONFIG_SYS_NAND_BAD_BLOCK_POS 0
+-/* ECC offset position in oob area, default value is 6 if it isn't defined */
+-#define CONFIG_SYS_NAND_ECC_POS (6 * NANONOTE_NAND_SIZE)
++#define CONFIG_SYS_NAND_ECC_POS 12
+ #define CONFIG_SYS_NAND_ECCSIZE 512
+ #define CONFIG_SYS_NAND_ECCBYTES 9
+ #define CONFIG_SYS_NAND_ECCPOS \
+@@ -115,10 +104,9 @@
+ #define CONFIG_SYS_ONENAND_BASE CONFIG_SYS_NAND_BASE
+ #define CONFIG_SYS_MAX_NAND_DEVICE 1
+ #define CONFIG_SYS_NAND_SELECT_DEVICE 1 /* nand driver supports mutipl.*/
+-#define CONFIG_NAND_SPL_TEXT_BASE 0x80000000
+
+ /*
+- * IPL (Initial Program Loader, integrated inside CPU)
++ * IPL (Initial Program Loader, integrated inside Ingenic Xburst JZ4740 CPU)
+ * Will load first 8k from NAND (SPL) into cache and execute it from there.
+ *
+ * SPL (Secondary Program Loader)
+@@ -130,77 +118,88 @@
+ * NUB (NAND U-Boot)
+ * This NAND U-Boot (NUB) is a special U-Boot version which can be started
+ * from RAM. Therefore it mustn't (re-)configure the SDRAM controller.
+- *
+ */
++
++/*
++ * NAND SPL configuration
++ */
++#define CONFIG_SPL
++#define CONFIG_SPL_LIBGENERIC_SUPPORT
++#define CONFIG_SPL_LIBCOMMON_SUPPORT
++#define CONFIG_SPL_NAND_LOAD
++#define CONFIG_SPL_NAND_SIMPLE
++#define CONFIG_SPL_NAND_SUPPORT
++#define CONFIG_SPL_TEXT_BASE 0x80000000
++#define CONFIG_SPL_START_S_PATH "arch/mips/cpu/xburst/spl"
++
++#define CONFIG_SYS_NAND_5_ADDR_CYCLE
++#define CONFIG_SYS_NAND_HW_ECC_OOBFIRST
++#define JZ4740_NANDBOOT_CFG JZ4740_NANDBOOT_B8R3
++
+ #define CONFIG_SYS_NAND_U_BOOT_DST 0x80100000 /* Load NUB to this addr */
+ #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST
+-/* Start NUB from this addr*/
++ /* Start NUB from this addr */
++#define CONFIG_SYS_NAND_U_BOOT_OFFS (32 << 10) /* Offset of NUB */
++#define CONFIG_SYS_NAND_U_BOOT_SIZE (256 << 10) /* Size of NUB */
+
+ /*
+- * Define the partitioning of the NAND chip (only RAM U-Boot is needed here)
++ * Environment configuration
+ */
+-#define CONFIG_SYS_NAND_U_BOOT_OFFS (256 << 10) /* Offset to RAM U-Boot image */
+-#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 << 10) /* Size of RAM U-Boot image */
+-
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_IS_IN_NAND
+ #define CONFIG_ENV_SIZE (4 << 10)
+ #define CONFIG_ENV_OFFSET \
+ (CONFIG_SYS_NAND_BLOCK_SIZE + CONFIG_SYS_NAND_U_BOOT_SIZE)
+ #define CONFIG_ENV_OFFSET_REDUND \
+ (CONFIG_ENV_OFFSET + CONFIG_SYS_NAND_BLOCK_SIZE)
+
+-#define CONFIG_SYS_TEXT_BASE 0x80100000
+-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+-
+ /*
+- * SDRAM Info.
++ * CPU cache configuration
+ */
+-#define CONFIG_NR_DRAM_BANKS 1
++#define CONFIG_SYS_DCACHE_SIZE 16384
++#define CONFIG_SYS_ICACHE_SIZE 16384
++#define CONFIG_SYS_CACHELINE_SIZE 32
+
+ /*
+- * Cache Configuration
++ * SDRAM configuration
+ */
+-#define CONFIG_SYS_DCACHE_SIZE 16384
+-#define CONFIG_SYS_ICACHE_SIZE 16384
+-#define CONFIG_SYS_CACHELINE_SIZE 32
++#define CONFIG_NR_DRAM_BANKS 1
++
++#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */
++#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
++#define SDRAM_ROW 13 /* Row address: 11 to 13 */
++#define SDRAM_COL 9 /* Column address: 8 to 12 */
++#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */
++#define SDRAM_TRAS 45 /* RAS# Active Time */
++#define SDRAM_RCD 20 /* RAS# to CAS# Delay */
++#define SDRAM_TPC 20 /* RAS# Precharge Time */
++#define SDRAM_TRWL 7 /* Write Latency Time */
++#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */
+
+ /*
+- * GPIO definition
++ * GPIO configuration
+ */
+-#define GPIO_LCD_CS (2 * 32 + 21)
+-#define GPIO_AMP_EN (3 * 32 + 4)
++#define GPIO_LCD_CS (2 * 32 + 21)
++#define GPIO_AMP_EN (3 * 32 + 4)
+
+-#define GPIO_SDPW_EN (3 * 32 + 2)
+-#define GPIO_SD_DETECT (3 * 32 + 0)
++#define GPIO_SDPW_EN (3 * 32 + 2)
++#define GPIO_SD_DETECT (3 * 32 + 0)
+
+-#define GPIO_BUZZ_PWM (3 * 32 + 27)
+-#define GPIO_USB_DETECT (3 * 32 + 28)
++#define GPIO_BUZZ_PWM (3 * 32 + 27)
++#define GPIO_USB_DETECT (3 * 32 + 28)
+
+-#define GPIO_AUDIO_POP (1 * 32 + 29)
+-#define GPIO_COB_TEST (1 * 32 + 30)
++#define GPIO_AUDIO_POP (1 * 32 + 29)
++#define GPIO_COB_TEST (1 * 32 + 30)
+
+ #define GPIO_KEYOUT_BASE (2 * 32 + 10)
+-#define GPIO_KEYIN_BASE (3 * 32 + 18)
+-#define GPIO_KEYIN_8 (3 * 32 + 26)
++#define GPIO_KEYIN_BASE (3 * 32 + 18)
++#define GPIO_KEYIN_8 (3 * 32 + 26)
+
+-#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */
++#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */
+ #define GPIO_SD_VCC_EN_N GPIO_SDPW_EN /* SD Card Power Enable */
+
+ #define SPEN GPIO_LCD_CS /* LCDCS :Serial command enable */
+ #define SPDA (2 * 32 + 22) /* LCDSCL:Serial command clock input */
+ #define SPCK (2 * 32 + 23) /* LCDSDA:Serial command data input */
+
+-/* SDRAM paramters */
+-#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */
+-#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
+-#define SDRAM_ROW 13 /* Row address: 11 to 13 */
+-#define SDRAM_COL 9 /* Column address: 8 to 12 */
+-#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */
+-
+-/* SDRAM Timings, unit: ns */
+-#define SDRAM_TRAS 45 /* RAS# Active Time */
+-#define SDRAM_RCD 20 /* RAS# to CAS# Delay */
+-#define SDRAM_TPC 20 /* RAS# Precharge Time */
+-#define SDRAM_TRWL 7 /* Write Latency Time */
+-#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */
+-
+ #endif
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0002-qi_lb60-add-software-usbboot-support.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0002-qi_lb60-add-software-usbboot-support.patch.svn-base
new file mode 100644
index 0000000..feaf297
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/.svn/text-base/0002-qi_lb60-add-software-usbboot-support.patch.svn-base
@@ -0,0 +1,916 @@
+From fa51192b912d296b8eec10f7d44c6c17eb1dd368 Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Fri, 12 Oct 2012 09:47:39 +0800
+Subject: [PATCH 2/6] qi_lb60: add software usbboot support
+
+ JZ4740 CPU have a internal ROM have such kind of code, that make
+ JZ4740 can boot from USB
+
+ usbboot.S can downloads user program from the USB port to internal
+ SRAM and branches to the internal SRAM to execute the program
+
+Signed-off-by: Xiangfu <xiangfu@openmobilefree.net>
+---
+ board/qi/qi_lb60/Makefile | 1 +
+ board/qi/qi_lb60/qi_lb60-spl.c | 20 +
+ board/qi/qi_lb60/usbboot.S | 838 ++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 859 insertions(+)
+ create mode 100644 board/qi/qi_lb60/usbboot.S
+
+diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile
+index e399246..6dd8c6f 100644
+--- a/board/qi/qi_lb60/Makefile
++++ b/board/qi/qi_lb60/Makefile
+@@ -23,6 +23,7 @@ include $(TOPDIR)/config.mk
+ LIB = $(obj)lib$(BOARD).o
+
+ ifeq ($(CONFIG_SPL_BUILD),y)
++SOBJS := usbboot.o
+ COBJS := $(BOARD)-spl.o
+ else
+ COBJS := $(BOARD).o
+diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c
+index 3fe3fa3..aea459c 100644
+--- a/board/qi/qi_lb60/qi_lb60-spl.c
++++ b/board/qi/qi_lb60/qi_lb60-spl.c
+@@ -12,6 +12,24 @@
+ #include <asm/io.h>
+ #include <asm/jz4740.h>
+
++#define KEY_U_OUT (32 * 2 + 16)
++#define KEY_U_IN (32 * 3 + 19)
++
++extern void usb_boot(void);
++
++static void check_usb_boot(void)
++{
++ __gpio_as_input(KEY_U_IN);
++ __gpio_enable_pull(KEY_U_IN);
++ __gpio_as_output(KEY_U_OUT);
++ __gpio_clear_pin(KEY_U_OUT);
++
++ if (!__gpio_get_pin(KEY_U_IN)) {
++ puts("[U] pressed, goto USBBOOT mode\n");
++ usb_boot();
++ }
++}
++
+ void nand_spl_boot(void)
+ {
+ __gpio_as_sdram_16bit_4720();
+@@ -23,6 +41,8 @@ void nand_spl_boot(void)
+ pll_init();
+ sdram_init();
+
++ check_usb_boot();
++
+ nand_init();
+
+ puts("\nQi LB60 SPL: Starting U-Boot ...\n");
+diff --git a/board/qi/qi_lb60/usbboot.S b/board/qi/qi_lb60/usbboot.S
+new file mode 100644
+index 0000000..c872266
+--- /dev/null
++++ b/board/qi/qi_lb60/usbboot.S
+@@ -0,0 +1,838 @@
++/*
++ * for jz4740 usb boot
++ *
++ * Copyright (c) 2009 Author: <jlwei@ingenic.cn>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++ .set noreorder
++ .globl usb_boot
++ .text
++
++/*
++ * Both NAND and USB boot load data to D-Cache first, then transfer
++ * data from D-Cache to I-Cache, and jump to execute the code in I-Cache.
++ * So init caches first and then dispatch to a proper boot routine.
++ */
++
++.macro load_addr reg addr
++ li \reg, 0x80000000
++ addiu \reg, \reg, \addr
++ la $2, usbboot_begin
++ subu \reg, \reg, $2
++.endm
++
++usb_boot:
++ /* Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. */
++ la $9, 0xB0000000 /* CPCCR: Clock Control Register */
++ la $8, 0x42041110 /* I:S:M:P=1:2:2:2 */
++ sw $8, 0($9)
++
++ la $9, 0xB0000010 /* CPPCR: PLL Control Register */
++ la $8, 0x06000120 /* M=12 N=0 D=0 CLK=12*(M+2)/(N+2) */
++ sw $8, 0($9)
++
++ mtc0 $0, $26 /* CP0_ERRCTL, restore WST reset state */
++ nop
++
++ mtc0 $0, $16 /* CP0_CONFIG */
++ nop
++
++ /* Relocate code to beginning of the ram */
++
++ la $2, usbboot_begin
++ la $3, usbboot_end
++ li $4, 0x80000000
++
++1:
++ lw $5, 0($2)
++ sw $5, 0($4)
++ addiu $2, $2, 4
++ bne $2, $3, 1b
++ addiu $4, $4, 4
++
++ li $2, 0x80000000
++ ori $3, $2, 0
++ addiu $3, $3, usbboot_end
++ la $4, usbboot_begin
++ subu $3, $3, $4
++
++
++2:
++ cache 0x0, 0($2) /* Index_Invalidate_I */
++ cache 0x1, 0($2) /* Index_Writeback_Inv_D */
++ addiu $2, $2, 32
++ subu $4, $3, $2
++ bgtz $4, 2b
++ nop
++
++ load_addr $3, usb_boot_return
++
++ jr $3
++
++usbboot_begin:
++
++init_caches:
++ li $2, 3 /* cacheable for kseg0 access */
++ mtc0 $2, $16 /* CP0_CONFIG */
++ nop
++
++ li $2, 0x20000000 /* enable idx-store-data cache insn */
++ mtc0 $2, $26 /* CP0_ERRCTL */
++
++ ori $2, $28, 0 /* start address */
++ ori $3, $2, 0x3fe0 /* end address, total 16KB */
++ mtc0 $0, $28, 0 /* CP0_TAGLO */
++ mtc0 $0, $28, 1 /* CP0_DATALO */
++cache_clear_a_line:
++ cache 0x8, 0($2) /* Index_Store_Tag_I */
++ cache 0x9, 0($2) /* Index_Store_Tag_D */
++ bne $2, $3, cache_clear_a_line
++ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
++
++ ori $2, $28, 0 /* start address */
++ ori $3, $2, 0x3fe0 /* end address, total 16KB */
++ la $4, 0x1ffff000 /* physical address and 4KB page mask */
++cache_alloc_a_line:
++ and $5, $2, $4
++ ori $5, $5, 1 /* V bit of the physical tag */
++ mtc0 $5, $28, 0 /* CP0_TAGLO */
++ cache 0x8, 0($2) /* Index_Store_Tag_I */
++ cache 0x9, 0($2) /* Index_Store_Tag_D */
++ bne $2, $3, cache_alloc_a_line
++ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
++
++ nop
++ nop
++ nop
++ /*
++ * Transfer data from dcache to icache, then jump to icache.
++ * Input parameters:
++ * $19: data length in bytes
++ * $20: jump target address
++ */
++xfer_d2i:
++
++ ori $8, $20, 0
++ addu $9, $8, $19 /* total 16KB */
++
++1:
++ cache 0x0, 0($8) /* Index_Invalidate_I */
++ cache 0x1, 0($8) /* Index_Writeback_Inv_D */
++ bne $8, $9, 1b
++ addiu $8, $8, 32
++
++ /* flush write-buffer */
++ sync
++
++ /* Invalidate BTB */
++ mfc0 $8, $16, 7 /* CP0_CONFIG */
++ nop
++ ori $8, 2
++ mtc0 $8, $16, 7
++ nop
++
++ /* Overwrite config to disable ram initalisation */
++ li $2, 0xff
++ sb $2, 20($20)
++
++ jalr $20
++ nop
++
++icache_return:
++ /* User code can return to here after executing itself in
++ icache, by jumping to $31. */
++ b usb_boot_return
++ nop
++
++
++usb_boot_return:
++ /* Enable the USB PHY */
++ la $9, 0xB0000024 /* CPM_SCR */
++ lw $8, 0($9)
++ ori $8, 0x40 /* USBPHY_ENABLE */
++ sw $8, 0($9)
++
++ /* Initialize USB registers */
++ la $27, 0xb3040000 /* USB registers base address */
++
++ sb $0, 0x0b($27) /* INTRUSBE: disable common USB interrupts */
++ sh $0, 0x06($27) /* INTRINE: disable EPIN interrutps */
++ sh $0, 0x08($27) /* INTROUTE: disable EPOUT interrutps */
++
++ li $9, 0x61
++ sb $9, 0x01($27) /* POWER: HSENAB | SUSPENDM | SOFTCONN */
++
++ /* Initialize USB states */
++ li $22, 0 /* set EP0 to IDLE state */
++ li $23, 1 /* no data stage */
++
++ /* Main loop of polling the usb commands */
++usb_command_loop:
++ lbu $9, 0x0a($27) /* read INTRUSB */
++ andi $9, 0x04 /* check USB_INTR_RESET */
++ beqz $9, check_intr_ep0in
++ nop
++
++ /* 1. Handle USB reset interrupt */
++handle_reset_intr:
++ lbu $9, 0x01($27) /* read POWER */
++ andi $9, 0x10 /* test HS_MODE */
++ bnez $9, _usb_set_maxpktsize
++ li $9, 512 /* max packet size of HS mode */
++ li $9, 64 /* max packet size of FS mode */
++
++_usb_set_maxpktsize:
++ li $8, 1
++ sb $8, 0x0e($27) /* set INDEX 1 */
++
++ sh $9, 0x10($27) /* INMAXP */
++ sb $0, 0x13($27) /* INCSRH */
++ sh $9, 0x14($27) /* OUTMAXP */
++ sb $0, 0x17($27) /* OUTCSRH */
++
++_usb_flush_fifo:
++ li $8, 0x48 /* INCSR_CDT && INCSR_FF */
++ sb $8, 0x12($27) /* INCSR */
++ li $8, 0x90 /* OUTCSR_CDT && OUTCSR_FF */
++ sb $8, 0x16($27) /* OUTCSR */
++
++ li $22, 0 /* set EP0 to IDLE state */
++ li $23, 1 /* no data stage */
++
++ /* 2. Check and handle EP0 interrupt */
++check_intr_ep0in:
++ lhu $10, 0x02($27) /* read INTRIN */
++ andi $9, $10, 0x1 /* check EP0 interrupt */
++ beqz $9, check_intr_ep1in
++ nop
++
++handle_ep0_intr:
++ sb $0, 0x0e($27) /* set INDEX 0 */
++ lbu $11, 0x12($27) /* read CSR0 */
++
++ andi $9, $11, 0x04 /* check SENTSTALL */
++ beqz $9, _ep0_setupend
++ nop
++
++_ep0_sentstall:
++ andi $9, $11, 0xdb
++ sb $9, 0x12($27) /* clear SENDSTALL and SENTSTALL */
++ li $22, 0 /* set EP0 to IDLE state */
++
++_ep0_setupend:
++ andi $9, $11, 0x10 /* check SETUPEND */
++ beqz $9, ep0_idle_state
++ nop
++
++ ori $9, $11, 0x80
++ sb $9, 0x12($27) /* set SVDSETUPEND */
++ li $22, 0 /* set EP0 to IDLE state */
++
++ep0_idle_state:
++ bnez $22, ep0_tx_state
++ nop
++
++ /* 2.1 Handle EP0 IDLE state interrupt */
++ andi $9, $11, 0x01 /* check OUTPKTRDY */
++ beqz $9, check_intr_ep1in
++ nop
++
++ /* Read 8-bytes setup packet from the FIFO */
++ lw $25, 0x20($27) /* first word of setup packet */
++ lw $26, 0x20($27) /* second word of setup packet */
++
++ andi $9, $25, 0x60 /* bRequestType & USB_TYPE_MASK */
++ beqz $9, _ep0_std_req
++ nop
++
++ /* 2.1.1 Vendor-specific setup request */
++_ep0_vend_req:
++ li $22, 0 /* set EP0 to IDLE state */
++ li $23, 1 /* NoData = 1 */
++
++ andi $9, $25, 0xff00 /* check bRequest */
++ srl $9, $9, 8
++ beqz $9, __ep0_get_cpu_info
++ sub $8, $9, 0x1
++ beqz $8, __ep0_set_data_address
++ sub $8, $9, 0x2
++ beqz $8, __ep0_set_data_length
++ sub $8, $9, 0x3
++ beqz $8, __ep0_flush_caches
++ sub $8, $9, 0x4
++ beqz $8, __ep0_prog_start1
++ sub $8, $9, 0x5
++ beqz $8, __ep0_prog_start2
++ nop
++ b _ep0_idle_state_fini /* invalid request */
++ nop
++
++__ep0_get_cpu_info:
++ load_addr $20, cpu_info_data /* data pointer to transfer */
++ li $21, 8 /* bytes left to transfer */
++ li $22, 1 /* set EP0 to TX state */
++ li $23, 0 /* NoData = 0 */
++
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_set_data_address:
++ li $9, 0xffff0000
++ and $9, $25, $9
++ andi $8, $26, 0xffff
++ or $20, $9, $8 /* data address of next transfer */
++
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_set_data_length:
++ li $9, 0xffff0000
++ and $9, $25, $9
++ andi $8, $26, 0xffff
++ or $21, $9, $8 /* data length of next transfer */
++
++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
++ sb $9, 0x12($27) /* CSR0 */
++
++ /* We must write packet to FIFO before EP1-IN interrupt here. */
++ b handle_epin1_intr
++ nop
++
++__ep0_flush_caches:
++ /* Flush dcache and invalidate icache. */
++ li $8, 0x80000000
++ addi $9, $8, 0x3fe0 /* total 16KB */
++
++1:
++ cache 0x0, 0($8) /* Index_Invalidate_I */
++ cache 0x1, 0($8) /* Index_Writeback_Inv_D */
++ bne $8, $9, 1b
++ addiu $8, $8, 32
++
++ /* flush write-buffer */
++ sync
++
++ /* Invalidate BTB */
++ mfc0 $8, $16, 7 /* CP0_CONFIG */
++ nop
++ ori $8, 2
++ mtc0 $8, $16, 7
++ nop
++
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_prog_start1:
++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
++ sb $9, 0x12($27) /* CSR0 */
++
++ li $9, 0xffff0000
++ and $9, $25, $9
++ andi $8, $26, 0xffff
++ or $20, $9, $8 /* target address */
++
++ b xfer_d2i
++ li $19, 0x2000 /* 16KB data length */
++
++__ep0_prog_start2:
++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
++ sb $9, 0x12($27) /* CSR0 */
++
++ li $9, 0xffff0000
++ and $9, $25, $9
++ andi $8, $26, 0xffff
++ or $20, $9, $8 /* target address */
++
++ jalr $20 /* jump, and place the return address in $31 */
++ nop
++
++__ep0_prog_start2_return:
++/* User code can return to here after executing itself, by jumping to $31 */
++ b usb_boot_return
++ nop
++
++ /* 2.1.2 Standard setup request */
++_ep0_std_req:
++ andi $12, $25, 0xff00 /* check bRequest */
++ srl $12, $12, 8
++ sub $9, $12, 0x05 /* check USB_REQ_SET_ADDRESS */
++ bnez $9, __ep0_req_set_config
++ nop
++
++ /* Handle USB_REQ_SET_ADDRESS */
++__ep0_req_set_addr:
++ srl $9, $25, 16 /* get wValue */
++ sb $9, 0x0($27) /* set FADDR */
++ li $23, 1 /* NoData = 1 */
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_req_set_config:
++ sub $9, $12, 0x09 /* check USB_REQ_SET_CONFIGURATION */
++ bnez $9, __ep0_req_get_desc
++ nop
++
++ /* Handle USB_REQ_SET_CONFIGURATION */
++ li $23, 1 /* NoData = 1 */
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_req_get_desc:
++ sub $9, $12, 0x06 /* check USB_REQ_GET_DESCRIPTOR */
++ bnez $9, _ep0_idle_state_fini
++ li $23, 1 /* NoData = 1 */
++
++ /* Handle USB_REQ_GET_DESCRIPTOR */
++ li $23, 0 /* NoData = 0 */
++
++ srl $9, $25, 24 /* wValue >> 8 */
++ sub $8, $9, 0x01 /* check USB_DT_DEVICE */
++ beqz $8, ___ep0_get_dev_desc
++ srl $21, $26, 16 /* get wLength */
++ sub $8, $9, 0x02 /* check USB_DT_CONFIG */
++ beqz $8, ___ep0_get_conf_desc
++ sub $8, $9, 0x03 /* check USB_DT_STRING */
++ beqz $8, ___ep0_get_string_desc
++ sub $8, $9, 0x06 /* check USB_DT_DEVICE_QUALIFIER */
++ beqz $8, ___ep0_get_dev_qualifier
++ nop
++ b _ep0_idle_state_fini
++ nop
++
++___ep0_get_dev_desc:
++ load_addr $20, device_desc /* data pointer */
++ li $22, 1 /* set EP0 to TX state */
++ sub $8, $21, 18
++ blez $8, _ep0_idle_state_fini /* wLength <= 18 */
++ nop
++ li $21, 18 /* max length of device_desc */
++ b _ep0_idle_state_fini
++ nop
++
++___ep0_get_dev_qualifier:
++ load_addr $20, dev_qualifier /* data pointer */
++ li $22, 1 /* set EP0 to TX state */
++ sub $8, $21, 10
++ blez $8, _ep0_idle_state_fini /* wLength <= 10 */
++ nop
++ li $21, 10 /* max length of dev_qualifier */
++ b _ep0_idle_state_fini
++ nop
++
++___ep0_get_conf_desc:
++ load_addr $20, config_desc_fs /* data pointer of FS mode */
++ lbu $8, 0x01($27) /* read POWER */
++ andi $8, 0x10 /* test HS_MODE */
++ beqz $8, ___ep0_get_conf_desc2
++ nop
++ load_addr $20, config_desc_hs /* data pointer of HS mode */
++
++___ep0_get_conf_desc2:
++ li $22, 1 /* set EP0 to TX state */
++ sub $8, $21, 32
++ blez $8, _ep0_idle_state_fini /* wLength <= 32 */
++ nop
++ li $21, 32 /* max length of config_desc */
++ b _ep0_idle_state_fini
++ nop
++
++___ep0_get_string_desc:
++ li $22, 1 /* set EP0 to TX state */
++
++ srl $9, $25, 16 /* wValue & 0xff */
++ andi $9, 0xff
++
++ sub $8, $9, 1
++ beqz $8, ___ep0_get_string_manufacture
++ sub $8, $9, 2
++ beqz $8, ___ep0_get_string_product
++ nop
++
++___ep0_get_string_lang_ids:
++ load_addr $20, string_lang_ids /* data pointer */
++ b _ep0_idle_state_fini
++ li $21, 4 /* data length */
++
++___ep0_get_string_manufacture:
++ load_addr $20, string_manufacture /* data pointer */
++ b _ep0_idle_state_fini
++ li $21, 16 /* data length */
++
++___ep0_get_string_product:
++ load_addr $20, string_product /* data pointer */
++ b _ep0_idle_state_fini
++ li $21, 46 /* data length */
++
++_ep0_idle_state_fini:
++ li $9, 0x40 /* SVDOUTPKTRDY */
++ beqz $23, _ep0_idle_state_fini2
++ nop
++ ori $9, $9, 0x08 /* DATAEND */
++_ep0_idle_state_fini2:
++ sb $9, 0x12($27) /* CSR0 */
++ beqz $22, check_intr_ep1in
++ nop
++
++ /* 2.2 Handle EP0 TX state interrupt */
++ep0_tx_state:
++ sub $9, $22, 1
++ bnez $9, check_intr_ep1in
++ nop
++
++ sub $9, $21, 64 /* max packetsize */
++ blez $9, _ep0_tx_state2 /* data count <= 64 */
++ ori $19, $21, 0
++ li $19, 64
++
++_ep0_tx_state2:
++ beqz $19, _ep0_tx_state3 /* send ZLP */
++ ori $18, $19, 0 /* record bytes to be transferred */
++ sub $21, $21, $19 /* decrement data count */
++
++_ep0_fifo_write_loop:
++ lbu $9, 0($20) /* read data */
++ sb $9, 0x20($27) /* load FIFO */
++ sub $19, $19, 1 /* decrement counter */
++ bnez $19, _ep0_fifo_write_loop
++ addi $20, $20, 1 /* increment data pointer */
++
++ sub $9, $18, 64 /* max packetsize */
++ beqz $9, _ep0_tx_state4
++ nop
++
++_ep0_tx_state3:
++ /* transferred bytes < max packetsize */
++ li $9, 0x0a /* set INPKTRDY and DATAEND */
++ sb $9, 0x12($27) /* CSR0 */
++ li $22, 0 /* set EP0 to IDLE state */
++ b check_intr_ep1in
++ nop
++
++_ep0_tx_state4:
++ /* transferred bytes == max packetsize */
++ li $9, 0x02 /* set INPKTRDY */
++ sb $9, 0x12($27) /* CSR0 */
++ b check_intr_ep1in
++ nop
++
++ /* 3. Check and handle EP1 BULK-IN interrupt */
++check_intr_ep1in:
++ andi $9, $10, 0x2 /* check EP1 IN interrupt */
++ beqz $9, check_intr_ep1out
++ nop
++
++handle_epin1_intr:
++ li $9, 1
++ sb $9, 0x0e($27) /* set INDEX 1 */
++ lbu $9, 0x12($27) /* read INCSR */
++
++ andi $8, $9, 0x2 /* check INCSR_FFNOTEMPT */
++ bnez $8, _epin1_tx_state4
++ nop
++
++_epin1_write_fifo:
++ lhu $9, 0x10($27) /* get INMAXP */
++ sub $8, $21, $9
++ blez $8, _epin1_tx_state1 /* bytes left <= INMAXP */
++ ori $19, $21, 0
++ ori $19, $9, 0
++
++_epin1_tx_state1:
++ beqz $19, _epin1_tx_state4 /* No data */
++ nop
++
++ sub $21, $21, $19 /* decrement data count */
++
++ srl $5, $19, 2 /* # of word */
++ andi $6, $19, 0x3 /* # of byte */
++ beqz $5, _epin1_tx_state2
++ nop
++
++_epin1_fifo_write_word:
++ lw $9, 0($20) /* read data from source address */
++ sw $9, 0x24($27) /* write FIFO */
++ sub $5, $5, 1 /* decrement counter */
++ bnez $5, _epin1_fifo_write_word
++ addiu $20, $20, 4 /* increment dest address */
++
++_epin1_tx_state2:
++ beqz $6, _epin1_tx_state3
++ nop
++
++_epin1_fifo_write_byte:
++ lbu $9, 0($20) /* read data from source address */
++ sb $9, 0x24($27) /* write FIFO */
++ sub $6, $6, 1 /* decrement counter */
++ bnez $6, _epin1_fifo_write_byte
++ addiu $20, $20, 1 /* increment dest address */
++
++_epin1_tx_state3:
++ li $9, 0x1
++ sb $9, 0x12($27) /* INCSR, set INPKTRDY */
++
++_epin1_tx_state4:
++ /* 4. Check and handle EP1 BULK-OUT interrupt */
++check_intr_ep1out:
++ lhu $9, 0x04($27) /* read INTROUT */
++ andi $9, 0x2
++ beqz $9, check_status_next
++ nop
++
++handle_epout1_intr:
++ li $9, 1
++ sb $9, 0x0e($27) /* set INDEX 1 */
++
++ lbu $9, 0x16($27) /* read OUTCSR */
++ andi $9, 0x1 /* check OUTPKTRDY */
++ beqz $9, check_status_next
++ nop
++
++_epout1_read_fifo:
++ lhu $19, 0x18($27) /* read OUTCOUNT */
++ srl $5, $19, 2 /* # of word */
++ andi $6, $19, 0x3 /* # of byte */
++ beqz $5, _epout1_rx_state1
++ nop
++
++_epout1_fifo_read_word:
++ lw $9, 0x24($27) /* read FIFO */
++ sw $9, 0($20) /* store to dest address */
++ sub $5, $5, 1 /* decrement counter */
++ bnez $5, _epout1_fifo_read_word
++ addiu $20, $20, 4 /* increment dest address */
++
++_epout1_rx_state1:
++ beqz $6, _epout1_rx_state2
++ nop
++
++_epout1_fifo_read_byte:
++ lbu $9, 0x24($27) /* read FIFO */
++ sb $9, 0($20) /* store to dest address */
++ sub $6, $6, 1 /* decrement counter */
++ bnez $6, _epout1_fifo_read_byte
++ addiu $20, $20, 1 /* increment dest address */
++
++_epout1_rx_state2:
++ sb $0, 0x16($27) /* clear OUTPKTRDY */
++
++check_status_next:
++ b usb_command_loop
++ nop
++
++/* Device/Configuration/Interface/Endpoint/String Descriptors */
++
++ .align 2
++device_desc:
++ .byte 0x12 /* bLength */
++ .byte 0x01 /* bDescriptorType */
++ .byte 0x00 /* bcdUSB */
++ .byte 0x02 /* bcdUSB */
++ .byte 0x00 /* bDeviceClass */
++ .byte 0x00 /* bDeviceSubClass */
++ .byte 0x00 /* bDeviceProtocol */
++ .byte 0x40 /* bMaxPacketSize0 */
++ .byte 0x1a /* idVendor */
++ .byte 0x60 /* idVendor */
++ .byte 0x40 /* idProduct */
++ .byte 0x47 /* idProduct */
++ .byte 0x00 /* bcdDevice */
++ .byte 0x01 /* bcdDevice */
++ .byte 0x01 /* iManufacturer */
++ .byte 0x02 /* iProduct */
++ .byte 0x00 /* iSerialNumber */
++ .byte 0x01 /* bNumConfigurations */
++
++ .align 2
++dev_qualifier:
++ .byte 0x0a /* bLength */
++ .byte 0x06 /* bDescriptorType */
++ .byte 0x00 /* bcdUSB */
++ .byte 0x02 /* bcdUSB */
++ .byte 0x00 /* bDeviceClass */
++ .byte 0x00 /* bDeviceSubClass */
++ .byte 0x00 /* bDeviceProtocol */
++ .byte 0x40 /* bMaxPacketSize0 */
++ .byte 0x01 /* bNumConfigurations */
++ .byte 0x00 /* bRESERVED */
++
++ .align 2
++config_desc_hs:
++ .byte 0x09 /* bLength */
++ .byte 0x02 /* bDescriptorType */
++ .byte 0x20 /* wTotalLength */
++ .byte 0x00 /* wTotalLength */
++ .byte 0x01 /* bNumInterfaces */
++ .byte 0x01 /* bConfigurationValue */
++ .byte 0x00 /* iConfiguration */
++ .byte 0xc0 /* bmAttributes */
++ .byte 0x01 /* MaxPower */
++intf_desc_hs:
++ .byte 0x09 /* bLength */
++ .byte 0x04 /* bDescriptorType */
++ .byte 0x00 /* bInterfaceNumber */
++ .byte 0x00 /* bAlternateSetting */
++ .byte 0x02 /* bNumEndpoints */
++ .byte 0xff /* bInterfaceClass */
++ .byte 0x00 /* bInterfaceSubClass */
++ .byte 0x50 /* bInterfaceProtocol */
++ .byte 0x00 /* iInterface */
++ep1_desc_hs:
++ .byte 0x07 /* bLength */
++ .byte 0x05 /* bDescriptorType */
++ .byte 0x01 /* bEndpointAddress */
++ .byte 0x02 /* bmAttributes */
++ .byte 0x00 /* wMaxPacketSize */
++ .byte 0x02 /* wMaxPacketSize */
++ .byte 0x00 /* bInterval */
++ep2_desc_hs:
++ .byte 0x07 /* bLength */
++ .byte 0x05 /* bDescriptorType */
++ .byte 0x81 /* bEndpointAddress */
++ .byte 0x02 /* bmAttributes */
++ .byte 0x00 /* wMaxPacketSize */
++ .byte 0x02 /* wMaxPacketSize */
++ .byte 0x00 /* bInterval */
++
++ .align 2
++config_desc_fs:
++ .byte 0x09 /* bLength */
++ .byte 0x02 /* bDescriptorType */
++ .byte 0x20 /* wTotalLength */
++ .byte 0x00 /* wTotalLength */
++ .byte 0x01 /* bNumInterfaces */
++ .byte 0x01 /* bConfigurationValue */
++ .byte 0x00 /* iConfiguration */
++ .byte 0xc0 /* bmAttributes */
++ .byte 0x01 /* MaxPower */
++intf_desc_fs:
++ .byte 0x09 /* bLength */
++ .byte 0x04 /* bDescriptorType */
++ .byte 0x00 /* bInterfaceNumber */
++ .byte 0x00 /* bAlternateSetting */
++ .byte 0x02 /* bNumEndpoints */
++ .byte 0xff /* bInterfaceClass */
++ .byte 0x00 /* bInterfaceSubClass */
++ .byte 0x50 /* bInterfaceProtocol */
++ .byte 0x00 /* iInterface */
++ep1_desc_fs:
++ .byte 0x07 /* bLength */
++ .byte 0x05 /* bDescriptorType */
++ .byte 0x01 /* bEndpointAddress */
++ .byte 0x02 /* bmAttributes */
++ .byte 0x40 /* wMaxPacketSize */
++ .byte 0x00 /* wMaxPacketSize */
++ .byte 0x00 /* bInterval */
++ep2_desc_fs:
++ .byte 0x07 /* bLength */
++ .byte 0x05 /* bDescriptorType */
++ .byte 0x81 /* bEndpointAddress */
++ .byte 0x02 /* bmAttributes */
++ .byte 0x40 /* wMaxPacketSize */
++ .byte 0x00 /* wMaxPacketSize */
++ .byte 0x00 /* bInterval */
++
++ .align 2
++string_lang_ids:
++ .byte 0x04
++ .byte 0x03
++ .byte 0x09
++ .byte 0x04
++
++ .align 2
++string_manufacture:
++ .byte 0x10
++ .byte 0x03
++ .byte 0x49
++ .byte 0x00
++ .byte 0x6e
++ .byte 0x00
++ .byte 0x67
++ .byte 0x00
++ .byte 0x65
++ .byte 0x00
++ .byte 0x6e
++ .byte 0x00
++ .byte 0x69
++ .byte 0x00
++ .byte 0x63
++ .byte 0x00
++
++ .align 2
++string_product:
++ .byte 0x2e
++ .byte 0x03
++ .byte 0x4a
++ .byte 0x00
++ .byte 0x5a
++ .byte 0x00
++ .byte 0x34
++ .byte 0x00
++ .byte 0x37
++ .byte 0x00
++ .byte 0x34
++ .byte 0x00
++ .byte 0x30
++ .byte 0x00
++ .byte 0x20
++ .byte 0x00
++ .byte 0x55
++ .byte 0x00
++ .byte 0x53
++ .byte 0x00
++ .byte 0x42
++ .byte 0x00
++ .byte 0x20
++ .byte 0x00
++ .byte 0x42
++ .byte 0x00
++ .byte 0x6f
++ .byte 0x00
++ .byte 0x6f
++ .byte 0x00
++ .byte 0x74
++ .byte 0x00
++ .byte 0x20
++ .byte 0x00
++ .byte 0x44
++ .byte 0x00
++ .byte 0x65
++ .byte 0x00
++ .byte 0x76
++ .byte 0x00
++ .byte 0x69
++ .byte 0x00
++ .byte 0x63
++ .byte 0x00
++ .byte 0x65
++ .byte 0x00
++
++ .align 2
++cpu_info_data:
++ .byte 0x4a
++ .byte 0x5a
++ .byte 0x34
++ .byte 0x37
++ .byte 0x34
++ .byte 0x30
++ .byte 0x56
++ .byte 0x31
++usbboot_end:
++
++ .set reorder
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0003-add-mmc-support.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0003-add-mmc-support.patch.svn-base
new file mode 100644
index 0000000..e9baa7c
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/.svn/text-base/0003-add-mmc-support.patch.svn-base
@@ -0,0 +1,1664 @@
+From bd36739e77669e8df45c38f6acfe2cea511534d9 Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Wed, 10 Oct 2012 18:19:41 +0800
+Subject: [PATCH 3/6] add mmc support
+
+---
+ arch/mips/include/asm/jz4740.h | 166 ++++++
+ board/qi/qi_lb60/qi_lb60.c | 9 +-
+ drivers/mmc/Makefile | 1 +
+ drivers/mmc/jz_mmc.c | 1179 ++++++++++++++++++++++++++++++++++++++++
+ drivers/mmc/jz_mmc.h | 176 ++++++
+ include/configs/qi_lb60.h | 9 +
+ include/mmc.h | 40 ++
+ 7 files changed, 1578 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/mmc/jz_mmc.c
+ create mode 100644 drivers/mmc/jz_mmc.h
+
+diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h
+index 7a7cfff..68287fb 100644
+--- a/arch/mips/include/asm/jz4740.h
++++ b/arch/mips/include/asm/jz4740.h
+@@ -1146,5 +1146,171 @@ extern void sdram_init(void);
+ extern void calc_clocks(void);
+ extern void rtc_init(void);
+
++/*************************************************************************
++ * MSC
++ *************************************************************************/
++#define REG8(addr) *((volatile u8 *)(addr))
++#define REG16(addr) *((volatile u16 *)(addr))
++#define REG32(addr) *((volatile u32 *)(addr))
++
++#define CPM_BASE 0xB0000000
++#define CPM_CPCCR (CPM_BASE+0x00)
++#define CPM_MSCCDR (CPM_BASE+0x68)
++#define REG_CPM_MSCCDR REG32(CPM_MSCCDR)
++#define REG_CPM_CPCCR REG32(CPM_CPCCR)
++
++#define MSC_BASE 0xB0021000
++
++#define MSC_STRPCL (MSC_BASE + 0x000)
++#define MSC_STAT (MSC_BASE + 0x004)
++#define MSC_CLKRT (MSC_BASE + 0x008)
++#define MSC_CMDAT (MSC_BASE + 0x00C)
++#define MSC_RESTO (MSC_BASE + 0x010)
++#define MSC_RDTO (MSC_BASE + 0x014)
++#define MSC_BLKLEN (MSC_BASE + 0x018)
++#define MSC_NOB (MSC_BASE + 0x01C)
++#define MSC_SNOB (MSC_BASE + 0x020)
++#define MSC_IMASK (MSC_BASE + 0x024)
++#define MSC_IREG (MSC_BASE + 0x028)
++#define MSC_CMD (MSC_BASE + 0x02C)
++#define MSC_ARG (MSC_BASE + 0x030)
++#define MSC_RES (MSC_BASE + 0x034)
++#define MSC_RXFIFO (MSC_BASE + 0x038)
++#define MSC_TXFIFO (MSC_BASE + 0x03C)
++
++#define REG_MSC_STRPCL REG16(MSC_STRPCL)
++#define REG_MSC_STAT REG32(MSC_STAT)
++#define REG_MSC_CLKRT REG16(MSC_CLKRT)
++#define REG_MSC_CMDAT REG32(MSC_CMDAT)
++#define REG_MSC_RESTO REG16(MSC_RESTO)
++#define REG_MSC_RDTO REG16(MSC_RDTO)
++#define REG_MSC_BLKLEN REG16(MSC_BLKLEN)
++#define REG_MSC_NOB REG16(MSC_NOB)
++#define REG_MSC_SNOB REG16(MSC_SNOB)
++#define REG_MSC_IMASK REG16(MSC_IMASK)
++#define REG_MSC_IREG REG16(MSC_IREG)
++#define REG_MSC_CMD REG8(MSC_CMD)
++#define REG_MSC_ARG REG32(MSC_ARG)
++#define REG_MSC_RES REG16(MSC_RES)
++#define REG_MSC_RXFIFO REG32(MSC_RXFIFO)
++#define REG_MSC_TXFIFO REG32(MSC_TXFIFO)
++
++/* MSC Clock and Control Register (MSC_STRPCL) */
++
++#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7)
++#define MSC_STRPCL_EXIT_TRANSFER (1 << 6)
++#define MSC_STRPCL_START_READWAIT (1 << 5)
++#define MSC_STRPCL_STOP_READWAIT (1 << 4)
++#define MSC_STRPCL_RESET (1 << 3)
++#define MSC_STRPCL_START_OP (1 << 2)
++#define MSC_STRPCL_CLOCK_CONTROL_BIT 0
++#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT)
++ #define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */
++ #define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */
++
++/* MSC Status Register (MSC_STAT) */
++
++#define MSC_STAT_IS_RESETTING (1 << 15)
++#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14)
++#define MSC_STAT_PRG_DONE (1 << 13)
++#define MSC_STAT_DATA_TRAN_DONE (1 << 12)
++#define MSC_STAT_END_CMD_RES (1 << 11)
++#define MSC_STAT_DATA_FIFO_AFULL (1 << 10)
++#define MSC_STAT_IS_READWAIT (1 << 9)
++#define MSC_STAT_CLK_EN (1 << 8)
++#define MSC_STAT_DATA_FIFO_FULL (1 << 7)
++#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6)
++#define MSC_STAT_CRC_RES_ERR (1 << 5)
++#define MSC_STAT_CRC_READ_ERROR (1 << 4)
++#define MSC_STAT_CRC_WRITE_ERROR_BIT 2
++#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT)
++ #define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */
++ #define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */
++ #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */
++#define MSC_STAT_TIME_OUT_RES (1 << 1)
++#define MSC_STAT_TIME_OUT_READ (1 << 0)
++
++/* MSC Bus Clock Control Register (MSC_CLKRT) */
++
++#define MSC_CLKRT_CLK_RATE_BIT 0
++#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT)
++ #define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */
++
++/* MSC Command Sequence Control Register (MSC_CMDAT) */
++
++#define MSC_CMDAT_IO_ABORT (1 << 11)
++#define MSC_CMDAT_BUS_WIDTH_BIT 9
++#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT)
++#define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT)
++#define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT)
++#define MSC_CMDAT_DMA_EN (1 << 8)
++#define MSC_CMDAT_INIT (1 << 7)
++#define MSC_CMDAT_BUSY (1 << 6)
++#define MSC_CMDAT_STREAM_BLOCK (1 << 5)
++#define MSC_CMDAT_WRITE (1 << 4)
++#define MSC_CMDAT_READ (0 << 4)
++#define MSC_CMDAT_DATA_EN (1 << 3)
++#define MSC_CMDAT_RESPONSE_BIT 0
++#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT)
++
++/* MSC Interrupts Mask Register (MSC_IMASK) */
++#define MSC_IMASK_SDIO (1 << 7)
++#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6)
++#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5)
++#define MSC_IMASK_END_CMD_RES (1 << 2)
++#define MSC_IMASK_PRG_DONE (1 << 1)
++#define MSC_IMASK_DATA_TRAN_DONE (1 << 0)
++
++
++/* MSC Interrupts Status Register (MSC_IREG) */
++#define MSC_IREG_SDIO (1 << 7)
++#define MSC_IREG_TXFIFO_WR_REQ (1 << 6)
++#define MSC_IREG_RXFIFO_RD_REQ (1 << 5)
++#define MSC_IREG_END_CMD_RES (1 << 2)
++#define MSC_IREG_PRG_DONE (1 << 1)
++#define MSC_IREG_DATA_TRAN_DONE (1 << 0)
++
++static __inline__ unsigned int __cpm_get_pllout2(void)
++{
++ if (REG_CPM_CPCCR & CPM_CPCCR_PCS)
++ return __cpm_get_pllout();
++ else
++ return __cpm_get_pllout()/2;
++}
++
++static inline void __cpm_select_msc_clk(int sd)
++{
++ unsigned int pllout2 = __cpm_get_pllout2();
++ unsigned int div = 0;
++
++ if (sd) {
++ div = pllout2 / 24000000;
++ }
++ else {
++ div = pllout2 / 16000000;
++ }
++
++ REG_CPM_MSCCDR = div - 1;
++}
++#define __msc_reset() \
++do { \
++ REG_MSC_STRPCL = MSC_STRPCL_RESET; \
++ while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \
++} while (0)
++
+ #endif /* !__ASSEMBLY__ */
+ #endif /* __JZ4740_H__ */
+diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
+index 3bd4e2f..a2ba648 100644
+--- a/board/qi/qi_lb60/qi_lb60.c
++++ b/board/qi/qi_lb60/qi_lb60.c
+@@ -40,8 +40,13 @@ static void gpio_init(void)
+ __gpio_clear_pin(GPIO_KEYOUT_BASE + i);
+ }
+
+- __gpio_as_input(GPIO_KEYIN_8);
+- __gpio_enable_pull(GPIO_KEYIN_8);
++ if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){
++ printf("[S] pressed, enable UART0\n");
++ __gpio_as_uart0();
++ } else {
++ __gpio_as_input(GPIO_KEYIN_8);
++ __gpio_enable_pull(GPIO_KEYIN_8);
++ }
+
+ /* enable the TP4, TP5 as UART0 */
+ __gpio_jtag_to_uart0();
+diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
+index 565ba6a..3c717b1 100644
+--- a/drivers/mmc/Makefile
++++ b/drivers/mmc/Makefile
+@@ -47,6 +47,7 @@ COBJS-$(CONFIG_SDHCI) += sdhci.o
+ COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
+ COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
+ COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
++COBJS-$(CONFIG_JZ4740_MMC) += jz_mmc.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
+new file mode 100644
+index 0000000..642cecc
+--- /dev/null
++++ b/drivers/mmc/jz_mmc.c
+@@ -0,0 +1,1179 @@
++/*
++ * (C) Copyright 2003
++ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <common.h>
++#include <part.h>
++#include <mmc.h>
++
++#include <asm/io.h>
++#include <asm/jz4740.h>
++#include "jz_mmc.h"
++
++static int sd2_0 = 0;
++static int mmc_ready = 0;
++static int use_4bit; /* Use 4-bit data bus */
++/*
++ * MMC Events
++ */
++#define MMC_EVENT_NONE 0x00 /* No events */
++#define MMC_EVENT_RX_DATA_DONE 0x01 /* Rx data done */
++#define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */
++#define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */
++
++
++#define MMC_IRQ_MASK() \
++do { \
++ REG_MSC_IMASK = 0xffff; \
++ REG_MSC_IREG = 0xffff; \
++} while (0)
++
++/*
++ * GPIO definition
++ */
++#if defined(CONFIG_SAKC)
++
++#define __msc_init_io() \
++do { \
++ __gpio_as_input(GPIO_SD_CD_N); \
++} while (0)
++
++#else
++#define __msc_init_io() \
++do { \
++ __gpio_as_output(GPIO_SD_VCC_EN_N); \
++ __gpio_as_input(GPIO_SD_CD_N); \
++} while (0)
++
++#define __msc_enable_power() \
++do { \
++ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \
++} while (0)
++
++#define __msc_disable_power() \
++do { \
++ __gpio_set_pin(GPIO_SD_VCC_EN_N); \
++} while (0)
++
++#endif /* CONFIG_SAKE */
++
++#define __msc_card_detected() \
++({ \
++ int detected = 1; \
++ __gpio_as_input(GPIO_SD_CD_N); \
++ __gpio_disable_pull(GPIO_SD_CD_N); \
++ if (!__gpio_get_pin(GPIO_SD_CD_N)) \
++ detected = 0; \
++ detected; \
++})
++
++/*
++ * Local functions
++ */
++
++extern int
++fat_register_device(block_dev_desc_t *dev_desc, int part_no);
++
++static block_dev_desc_t mmc_dev;
++
++block_dev_desc_t * mmc_get_dev(int dev)
++{
++ return ((block_dev_desc_t *)&mmc_dev);
++}
++
++/* Stop the MMC clock and wait while it happens */
++static inline int jz_mmc_stop_clock(void)
++{
++ int timeout = 1000;
++
++ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP;
++
++ while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) {
++ timeout--;
++ if (timeout == 0)
++ return MMC_ERROR_TIMEOUT;
++ udelay(1);
++ }
++ return MMC_NO_ERROR;
++}
++
++/* Start the MMC clock and operation */
++static inline int jz_mmc_start_clock(void)
++{
++ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP;
++ return MMC_NO_ERROR;
++}
++
++static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate)
++{
++ u32 clkrt = 0;
++ u32 clk_src = is_sd ? 24000000 : 16000000;
++
++ while (rate < clk_src) {
++ clkrt ++;
++ clk_src >>= 1;
++ }
++
++ return clkrt;
++}
++
++/* Set the MMC clock frequency */
++void jz_mmc_set_clock(int sd, u32 rate)
++{
++ jz_mmc_stop_clock();
++
++ /* Select clock source of MSC */
++ __cpm_select_msc_clk(sd);
++
++ /* Set clock dividor of MSC */
++ REG_MSC_CLKRT = jz_mmc_calc_clkrt(sd, rate);
++}
++
++static int jz_mmc_check_status(struct mmc_request *request)
++{
++ u32 status = REG_MSC_STAT;
++
++ /* Checking for response or data timeout */
++ if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) {
++ printf("MMC/SD timeout, MMC_STAT 0x%x CMD %d\n", status, request->cmd);
++ return MMC_ERROR_TIMEOUT;
++ }
++
++ /* Checking for CRC error */
++ if (status & (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_RES_ERR)) {
++ printf("MMC/CD CRC error, MMC_STAT 0x%x\n", status);
++ return MMC_ERROR_CRC;
++ }
++
++ return MMC_NO_ERROR;
++}
++
++/* Obtain response to the command and store it to response buffer */
++static void jz_mmc_get_response(struct mmc_request *request)
++{
++ int i;
++ u8 *buf;
++ u32 data;
++
++ debug("fetch response for request %d, cmd %d\n",
++ request->rtype, request->cmd);
++
++ buf = request->response;
++ request->result = MMC_NO_ERROR;
++
++ switch (request->rtype) {
++ case RESPONSE_R1: case RESPONSE_R1B: case RESPONSE_R6:
++ case RESPONSE_R3: case RESPONSE_R4: case RESPONSE_R5:
++ {
++ data = REG_MSC_RES;
++ buf[0] = (data >> 8) & 0xff;
++ buf[1] = data & 0xff;
++ data = REG_MSC_RES;
++ buf[2] = (data >> 8) & 0xff;
++ buf[3] = data & 0xff;
++ data = REG_MSC_RES;
++ buf[4] = data & 0xff;
++
++ debug("request %d, response [%02x %02x %02x %02x %02x]\n",
++ request->rtype, buf[0], buf[1], buf[2], buf[3], buf[4]);
++ break;
++ }
++ case RESPONSE_R2_CID: case RESPONSE_R2_CSD:
++ {
++ for (i = 0; i < 16; i += 2) {
++ data = REG_MSC_RES;
++ buf[i] = (data >> 8) & 0xff;
++ buf[i+1] = data & 0xff;
++ }
++ debug("request %d, response [", request->rtype);
++#if CONFIG_MMC_DEBUG_VERBOSE > 2
++ if (g_mmc_debug >= 3) {
++ int n;
++ for (n = 0; n < 17; n++)
++ printk("%02x ", buf[n]);
++ printk("]\n");
++ }
++#endif
++ break;
++ }
++ case RESPONSE_NONE:
++ debug("No response\n");
++ break;
++
++ default:
++ debug("unhandled response type for request %d\n", request->rtype);
++ break;
++ }
++}
++
++static int jz_mmc_receive_data(struct mmc_request *req)
++{
++ u32 stat, timeout, data, cnt;
++ u8 *buf = req->buffer;
++ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
++
++ timeout = 0x3ffffff;
++
++ while (timeout) {
++ timeout--;
++ stat = REG_MSC_STAT;
++
++ if (stat & MSC_STAT_TIME_OUT_READ)
++ return MMC_ERROR_TIMEOUT;
++ else if (stat & MSC_STAT_CRC_READ_ERROR)
++ return MMC_ERROR_CRC;
++ else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY)
++ || (stat & MSC_STAT_DATA_FIFO_AFULL)) {
++ /* Ready to read data */
++ break;
++ }
++ udelay(1);
++ }
++ if (!timeout)
++ return MMC_ERROR_TIMEOUT;
++
++ /* Read data from RXFIFO. It could be FULL or PARTIAL FULL */
++ cnt = wblocklen;
++ while (cnt) {
++ data = REG_MSC_RXFIFO;
++ {
++ *buf++ = (u8)(data >> 0);
++ *buf++ = (u8)(data >> 8);
++ *buf++ = (u8)(data >> 16);
++ *buf++ = (u8)(data >> 24);
++ }
++ cnt --;
++ while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY))
++ ;
++ }
++ return MMC_NO_ERROR;
++}
++
++static int jz_mmc_transmit_data(struct mmc_request *req)
++{
++#if 0
++ u32 nob = req->nob;
++ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
++ u8 *buf = req->buffer;
++ u32 *wbuf = (u32 *)buf;
++ u32 waligned = (((u32)buf & 0x3) == 0); /* word aligned ? */
++ u32 stat, timeout, data, cnt;
++
++ for (nob; nob >= 1; nob--) {
++ timeout = 0x3FFFFFF;
++
++ while (timeout) {
++ timeout--;
++ stat = REG_MSC_STAT;
++
++ if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS))
++ return MMC_ERROR_CRC;
++ else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) {
++ /* Ready to write data */
++ break;
++ }
++
++ udelay(1);
++ }
++
++ if (!timeout)
++ return MMC_ERROR_TIMEOUT;
++
++ /* Write data to TXFIFO */
++ cnt = wblocklen;
++ while (cnt) {
++ while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL)
++ ;
++
++ if (waligned) {
++ REG_MSC_TXFIFO = *wbuf++;
++ }
++ else {
++ data = *buf++ | (*buf++ << 8) | (*buf++ << 16) | (*buf++ << 24);
++ REG_MSC_TXFIFO = data;
++ }
++
++ cnt--;
++ }
++ }
++#endif
++ return MMC_NO_ERROR;
++}
++
++
++/*
++ * Name: int jz_mmc_exec_cmd()
++ * Function: send command to the card, and get a response
++ * Input: struct mmc_request *req : MMC/SD request
++ * Output: 0: right >0: error code
++ */
++int jz_mmc_exec_cmd(struct mmc_request *request)
++{
++ u32 cmdat = 0, events = 0;
++ int retval, timeout = 0x3fffff;
++
++ /* Indicate we have no result yet */
++ request->result = MMC_NO_RESPONSE;
++ if (request->cmd == MMC_CIM_RESET) {
++ /* On reset, 1-bit bus width */
++ use_4bit = 0;
++
++ /* Reset MMC/SD controller */
++ __msc_reset();
++
++ /* On reset, drop MMC clock down */
++ jz_mmc_set_clock(0, MMC_CLOCK_SLOW);
++
++ /* On reset, stop MMC clock */
++ jz_mmc_stop_clock();
++ }
++ if (request->cmd == MMC_CMD_SEND_OP_COND) {
++ debug("Have an MMC card\n");
++ /* always use 1bit for MMC */
++ use_4bit = 0;
++ }
++ if (request->cmd == SET_BUS_WIDTH) {
++ if (request->arg == 0x2) {
++ printf("Use 4-bit bus width\n");
++ use_4bit = 1;
++ } else {
++ printf("Use 1-bit bus width\n");
++ use_4bit = 0;
++ }
++ }
++
++ /* stop clock */
++ jz_mmc_stop_clock();
++
++ /* mask all interrupts */
++ REG_MSC_IMASK = 0xffff;
++
++ /* clear status */
++ REG_MSC_IREG = 0xffff;
++
++ /* use 4-bit bus width when possible */
++ if (use_4bit)
++ cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT;
++
++ /* Set command type and events */
++ switch (request->cmd) {
++ /* MMC core extra command */
++ case MMC_CIM_RESET:
++ cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
++ break;
++
++ /* bc - broadcast - no response */
++ case MMC_CMD_GO_IDLE_STATE:
++ case MMC_CMD_SET_DSR:
++ break;
++
++ /* bcr - broadcast with response */
++ case MMC_CMD_SEND_OP_COND:
++ case MMC_CMD_ALL_SEND_CID:
++ case MMC_GO_IRQ_STATE:
++ break;
++
++ /* adtc - addressed with data transfer */
++ case MMC_READ_DAT_UNTIL_STOP:
++ case MMC_CMD_READ_SINGLE_BLOCK:
++ case MMC_CMD_READ_MULTIPLE_BLOCK:
++ case SD_CMD_APP_SEND_SCR:
++ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_READ;
++ events = MMC_EVENT_RX_DATA_DONE;
++ break;
++
++ case MMC_WRITE_DAT_UNTIL_STOP:
++ case MMC_CMD_WRITE_SINGLE_BLOCK:
++ case MMC_CMD_WRITE_MULTIPLE_BLOCK:
++ case MMC_PROGRAM_CID:
++ case MMC_PROGRAM_CSD:
++ case MMC_SEND_WRITE_PROT:
++ case MMC_GEN_CMD:
++ case MMC_LOCK_UNLOCK:
++ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE;
++ events = MMC_EVENT_TX_DATA_DONE | MMC_EVENT_PROG_DONE;
++
++ break;
++
++ case MMC_CMD_STOP_TRANSMISSION:
++ events = MMC_EVENT_PROG_DONE;
++ break;
++
++ /* ac - no data transfer */
++ default:
++ break;
++ }
++
++ /* Set response type */
++ switch (request->rtype) {
++ case RESPONSE_NONE:
++ break;
++
++ case RESPONSE_R1B:
++ cmdat |= MSC_CMDAT_BUSY;
++ /*FALLTHRU*/
++ case RESPONSE_R1:
++ cmdat |= MSC_CMDAT_RESPONSE_R1;
++ break;
++ case RESPONSE_R2_CID:
++ case RESPONSE_R2_CSD:
++ cmdat |= MSC_CMDAT_RESPONSE_R2;
++ break;
++ case RESPONSE_R3:
++ cmdat |= MSC_CMDAT_RESPONSE_R3;
++ break;
++ case RESPONSE_R4:
++ cmdat |= MSC_CMDAT_RESPONSE_R4;
++ break;
++ case RESPONSE_R5:
++ cmdat |= MSC_CMDAT_RESPONSE_R5;
++ break;
++ case RESPONSE_R6:
++ cmdat |= MSC_CMDAT_RESPONSE_R6;
++ break;
++ default:
++ break;
++ }
++
++ /* Set command index */
++ if (request->cmd == MMC_CIM_RESET) {
++ REG_MSC_CMD = MMC_CMD_GO_IDLE_STATE;
++ } else {
++ REG_MSC_CMD = request->cmd;
++ }
++
++ /* Set argument */
++ REG_MSC_ARG = request->arg;
++
++ /* Set block length and nob */
++ if (request->cmd == SD_CMD_APP_SEND_SCR) { /* get SCR from DataFIFO */
++ REG_MSC_BLKLEN = 8;
++ REG_MSC_NOB = 1;
++ } else {
++ REG_MSC_BLKLEN = request->block_len;
++ REG_MSC_NOB = request->nob;
++ }
++
++ /* Set command */
++ REG_MSC_CMDAT = cmdat;
++
++ debug("Send cmd %d cmdat: %x arg: %x resp %d\n", request->cmd,
++ cmdat, request->arg, request->rtype);
++
++ /* Start MMC/SD clock and send command to card */
++ jz_mmc_start_clock();
++
++ /* Wait for command completion */
++ while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES))
++ ;
++
++ if (timeout == 0)
++ return MMC_ERROR_TIMEOUT;
++
++ REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear flag */
++
++ /* Check for status */
++ retval = jz_mmc_check_status(request);
++ if (retval) {
++ return retval;
++ }
++
++ /* Complete command with no response */
++ if (request->rtype == RESPONSE_NONE) {
++ return MMC_NO_ERROR;
++ }
++
++ /* Get response */
++ jz_mmc_get_response(request);
++
++ /* Start data operation */
++ if (events & (MMC_EVENT_RX_DATA_DONE | MMC_EVENT_TX_DATA_DONE)) {
++ if (events & MMC_EVENT_RX_DATA_DONE) {
++ if (request->cmd == SD_CMD_APP_SEND_SCR) {
++ /* SD card returns SCR register as data.
++ MMC core expect it in the response buffer,
++ after normal response. */
++ request->buffer = (u8 *)((u32)request->response + 5);
++ }
++ jz_mmc_receive_data(request);
++ }
++
++ if (events & MMC_EVENT_TX_DATA_DONE) {
++ jz_mmc_transmit_data(request);
++ }
++
++ /* Wait for Data Done */
++ while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE))
++ ;
++ REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */
++ }
++
++ /* Wait for Prog Done event */
++ if (events & MMC_EVENT_PROG_DONE) {
++ while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE))
++ ;
++ REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */
++ }
++
++ /* Command completed */
++
++ return MMC_NO_ERROR; /* return successfully */
++}
++
++int mmc_block_read(u8 *dst, ulong src, ulong len)
++{
++
++ struct mmc_request request;
++ struct mmc_response_r1 r1;
++ int retval = 0;
++
++ if (len == 0)
++ goto exit;
++
++ mmc_simple_cmd(&request, MMC_CMD_SEND_STATUS, mmcinfo.rca, RESPONSE_R1);
++ retval = mmc_unpack_r1(&request, &r1, 0);
++ if (retval && (retval != MMC_ERROR_STATE_MISMATCH))
++ goto exit;
++
++ mmc_simple_cmd(&request, MMC_CMD_SET_BLOCKLEN, len, RESPONSE_R1);
++ if (retval = mmc_unpack_r1(&request, &r1, 0))
++ goto exit;
++
++ if (!sd2_0)
++ src *= mmcinfo.block_len;
++
++ mmc_send_cmd(&request, MMC_CMD_READ_SINGLE_BLOCK, src, 1, len, RESPONSE_R1, dst);
++ if (retval = mmc_unpack_r1(&request, &r1, 0))
++ goto exit;
++
++exit:
++ return retval;
++}
++
++ulong mmc_bread(int dev_num, ulong blkstart, ulong blkcnt, ulong *dst)
++{
++ if (!mmc_ready) {
++ printf("Please initial the MMC first\n");
++ return -1;
++ }
++
++ int i = 0;
++ ulong dst_tmp = dst;
++
++ for (i = 0; i < blkcnt; i++) {
++ if ((mmc_block_read((uchar *)(dst_tmp), blkstart, mmcinfo.block_len)) < 0)
++ return -1;
++
++ dst_tmp += mmcinfo.block_len;
++ blkstart++;
++ }
++
++ return i;
++}
++
++int mmc_select_card(void)
++{
++ struct mmc_request request;
++ struct mmc_response_r1 r1;
++ int retval;
++
++ mmc_simple_cmd(&request, MMC_CMD_SELECT_CARD, mmcinfo.rca, RESPONSE_R1B);
++ retval = mmc_unpack_r1(&request, &r1, 0);
++ if (retval) {
++ return retval;
++ }
++
++ if (mmcinfo.sd) {
++ mmc_simple_cmd(&request, MMC_CMD_APP_CMD, mmcinfo.rca, RESPONSE_R1);
++ retval = mmc_unpack_r1(&request,&r1,0);
++ if (retval) {
++ return retval;
++ }
++#if defined(MMC_BUS_WIDTH_1BIT)
++ mmc_simple_cmd(&request, SET_BUS_WIDTH, 1, RESPONSE_R1);
++#else
++ mmc_simple_cmd(&request, SET_BUS_WIDTH, 2, RESPONSE_R1);
++#endif
++ retval = mmc_unpack_r1(&request,&r1,0);
++ if (retval) {
++ return retval;
++ }
++ }
++ return 0;
++}
++
++/*
++ * Configure card
++ */
++static void mmc_configure_card(void)
++{
++ u32 rate;
++
++ /* Get card info */
++ if (sd2_0)
++ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) << 10;
++ else
++ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) * (1 << (mmcinfo.csd.c_size_mult + 2));
++
++ mmcinfo.block_len = 1 << mmcinfo.csd.read_bl_len;
++
++ mmc_dev.if_type = IF_TYPE_SD;
++ mmc_dev.part_type = PART_TYPE_DOS;
++ mmc_dev.dev = 0;
++ mmc_dev.lun = 0;
++ mmc_dev.type = 0;
++ mmc_dev.blksz = mmcinfo.block_len;
++ mmc_dev.lba = mmcinfo.block_num;
++ mmc_dev.removable = 0;
++
++ printf("%s Detected: %lu blocks of %lu bytes\n",
++ sd2_0 == 1 ? "SDHC" : "SD",
++ mmc_dev.lba,
++ mmc_dev.blksz);
++
++ /* Fix the clock rate */
++ rate = mmc_tran_speed(mmcinfo.csd.tran_speed);
++ if (rate < MMC_CLOCK_SLOW)
++ rate = MMC_CLOCK_SLOW;
++ if ((mmcinfo.sd == 0) && (rate > MMC_CLOCK_FAST))
++ rate = MMC_CLOCK_FAST;
++ if ((mmcinfo.sd) && (rate > SD_CLOCK_FAST))
++ rate = SD_CLOCK_FAST;
++
++ debug("%s: block_len=%d block_num=%d rate=%d\n",
++ __func__, mmcinfo.block_len, mmcinfo.block_num, rate);
++
++ jz_mmc_set_clock(mmcinfo.sd, rate);
++}
++
++/*
++ * State machine routines to initialize card(s)
++ */
++
++/*
++ CIM_SINGLE_CARD_ACQ (frequency at 400 kHz)
++ --- Must enter from GO_IDLE_STATE ---
++ 1. SD_SEND_OP_COND (SD Card) [CMD55] + [CMD41]
++ 2. SEND_OP_COND (Full Range) [CMD1] {optional}
++ 3. SEND_OP_COND (Set Range ) [CMD1]
++ If busy, delay and repeat step 2
++ 4. ALL_SEND_CID [CMD2]
++ If timeout, set an error (no cards found)
++ 5. SET_RELATIVE_ADDR [CMD3]
++ 6. SEND_CSD [CMD9]
++ 7. SET_DSR [CMD4] Only call this if (csd.dsr_imp).
++ 8. Set clock frequency (check available in csd.tran_speed)
++ */
++
++#define MMC_INIT_DOING 0
++#define MMC_INIT_PASSED 1
++#define MMC_INIT_FAILED 2
++
++static int mmc_init_card_state(struct mmc_request *request)
++{
++ struct mmc_response_r1 r1;
++ struct mmc_response_r3 r3;
++ int retval;
++ int ocr = 0x40300000;
++ int limit_41 = 0;
++
++ switch (request->cmd) {
++ case MMC_CMD_GO_IDLE_STATE: /* No response to parse */
++ if (mmcinfo.sd)
++ mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1);
++ else
++ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
++ break;
++
++ case 8:
++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
++ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
++ break;
++
++ case MMC_CMD_APP_CMD:
++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
++ if (retval & (limit_41 < 100)) {
++ debug("%s: unable to MMC_APP_CMD error=%d (%s)\n",
++ __func__, retval, mmc_result_to_string(retval));
++ limit_41++;
++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
++ } else if (limit_41 < 100) {
++ limit_41++;
++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
++ } else{
++ /* reset the card to idle*/
++ mmc_simple_cmd(request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
++ mmcinfo.sd = 0;
++ }
++ break;
++
++ case SD_CMD_APP_SEND_OP_COND:
++ retval = mmc_unpack_r3(request, &r3);
++ if (retval) {
++ debug("%s: try MMC card\n", __func__);
++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
++ break;
++ }
++
++ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
++
++ if(!(r3.ocr & MMC_CARD_BUSY || ocr == 0)){
++ udelay(50000);
++ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
++ } else {
++ mmcinfo.sd = 1; /* SD Card ready */
++ mmcinfo.state = CARD_STATE_READY;
++ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
++ }
++ break;
++
++ case MMC_CMD_SEND_OP_COND:
++ retval = mmc_unpack_r3(request, &r3);
++ if (retval) {
++ debug("%s: failed SEND_OP_COND error=%d (%s)\n",
++ __func__, retval, mmc_result_to_string(retval));
++ return MMC_INIT_FAILED;
++ }
++
++ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
++ if (!(r3.ocr & MMC_CARD_BUSY)) {
++ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
++ } else {
++ mmcinfo.sd = 0; /* MMC Card ready */
++ mmcinfo.state = CARD_STATE_READY;
++ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
++ }
++ break;
++
++ case MMC_CMD_ALL_SEND_CID:
++ retval = mmc_unpack_cid( request, &mmcinfo.cid );
++ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
++ if ( retval && (retval != MMC_ERROR_CRC)) {
++ debug("mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n",
++ retval, mmc_result_to_string(retval));
++ return MMC_INIT_FAILED;
++ }
++ mmcinfo.state = CARD_STATE_IDENT;
++ if(mmcinfo.sd)
++ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, 0, RESPONSE_R6);
++ else
++ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, ID_TO_RCA(mmcinfo.id) << 16, RESPONSE_R1);
++ break;
++
++ case MMC_CMD_SET_RELATIVE_ADDR:
++ if (mmcinfo.sd) {
++ retval = mmc_unpack_r6(request, &r1, mmcinfo.state, &mmcinfo.rca);
++ mmcinfo.rca = mmcinfo.rca << 16;
++ debug("%s: Get RCA from SD: 0x%04x Status: %x\n",
++ __func__, mmcinfo.rca, r1.status);
++ } else {
++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
++ mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16;
++ }
++ if (retval) {
++ debug("%s: unable to SET_RELATIVE_ADDR error=%d (%s)\n",
++ __func__, retval, mmc_result_to_string(retval));
++ return MMC_INIT_FAILED;
++ }
++
++ mmcinfo.state = CARD_STATE_STBY;
++ mmc_simple_cmd(request, MMC_CMD_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD);
++
++ break;
++
++ case MMC_CMD_SEND_CSD:
++ retval = mmc_unpack_csd(request, &mmcinfo.csd);
++ mmc_ready = 1;
++ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
++ if (retval && (retval != MMC_ERROR_CRC)) {
++ debug("%s: unable to SEND_CSD error=%d (%s)\n",
++ __func__, retval, mmc_result_to_string(retval));
++ return MMC_INIT_FAILED;
++ }
++ if (mmcinfo.csd.dsr_imp) {
++ debug("%s: driver doesn't support setting DSR\n", __func__);
++ }
++ mmc_configure_card();
++ return MMC_INIT_PASSED;
++
++ default:
++ debug("%s: error! Illegal last cmd %d\n", __func__, request->cmd);
++ return MMC_INIT_FAILED;
++ }
++
++ return MMC_INIT_DOING;
++}
++
++int mmc_init_card(void)
++{
++ struct mmc_request request;
++ int retval;
++
++ mmc_simple_cmd(&request, MMC_CIM_RESET, 0, RESPONSE_NONE); /* reset card */
++ mmc_simple_cmd(&request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
++ mmcinfo.sd = 1; /* assuming a SD card */
++
++ while ((retval = mmc_init_card_state(&request)) == MMC_INIT_DOING)
++ ;
++
++ if (retval == MMC_INIT_PASSED)
++ return MMC_NO_ERROR;
++ else
++ return MMC_NO_RESPONSE;
++}
++
++int mmc_legacy_init(int verbose)
++{
++ if (!__msc_card_detected())
++ return 1;
++
++ /* Step-1: init GPIO */
++ __gpio_as_msc();
++ __msc_init_io();
++
++ /* Step-2: turn on power of card */
++#if !defined(CONFIG_SAKC)
++ __msc_enable_power();
++#endif
++
++ /* Step-3: Reset MSC Controller. */
++ __msc_reset();
++
++ /* Step-3: mask all IRQs. */
++ MMC_IRQ_MASK();
++
++ /* Step-4: stop MMC/SD clock */
++ jz_mmc_stop_clock();
++ mmc_init_card();
++ mmc_select_card();
++
++ mmc_dev.block_read = mmc_bread;
++ fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
++
++ return 0;
++}
++
++/*
++ * Debugging functions
++ */
++static char * mmc_result_strings[] = {
++ "NO_RESPONSE",
++ "NO_ERROR",
++ "ERROR_OUT_OF_RANGE",
++ "ERROR_ADDRESS",
++ "ERROR_BLOCK_LEN",
++ "ERROR_ERASE_SEQ",
++ "ERROR_ERASE_PARAM",
++ "ERROR_WP_VIOLATION",
++ "ERROR_CARD_IS_LOCKED",
++ "ERROR_LOCK_UNLOCK_FAILED",
++ "ERROR_COM_CRC",
++ "ERROR_ILLEGAL_COMMAND",
++ "ERROR_CARD_ECC_FAILED",
++ "ERROR_CC",
++ "ERROR_GENERAL",
++ "ERROR_UNDERRUN",
++ "ERROR_OVERRUN",
++ "ERROR_CID_CSD_OVERWRITE",
++ "ERROR_STATE_MISMATCH",
++ "ERROR_HEADER_MISMATCH",
++ "ERROR_TIMEOUT",
++ "ERROR_CRC",
++ "ERROR_DRIVER_FAILURE",
++};
++
++char * mmc_result_to_string(int i)
++{
++ return mmc_result_strings[i+1];
++}
++
++static char * card_state_strings[] = {
++ "empty",
++ "idle",
++ "ready",
++ "ident",
++ "stby",
++ "tran",
++ "data",
++ "rcv",
++ "prg",
++ "dis",
++};
++
++static inline char * card_state_to_string(int i)
++{
++ return card_state_strings[i+1];
++}
++
++/*
++ * Utility functions
++ */
++
++#define PARSE_U32(_buf,_index) \
++ (((u32)_buf[_index]) << 24) | (((u32)_buf[_index+1]) << 16) | \
++ (((u32)_buf[_index+2]) << 8) | ((u32)_buf[_index+3]);
++
++#define PARSE_U16(_buf,_index) \
++ (((u16)_buf[_index]) << 8) | ((u16)_buf[_index+1]);
++
++int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd)
++{
++ u8 *buf = request->response;
++ int num = 0;
++
++ if (request->result)
++ return request->result;
++
++ if (buf[0] != 0x3f)
++ return MMC_ERROR_HEADER_MISMATCH;
++
++ csd->csd_structure = (buf[1] & 0xc0) >> 6;
++ if (csd->csd_structure)
++ sd2_0 = 1;
++ else
++ sd2_0 = 0;
++
++ switch (csd->csd_structure) {
++ case 0 :/* Version 1.01-1.10
++ * Version 2.00/Standard Capacity */
++ csd->taac = buf[2];
++ csd->nsac = buf[3];
++ csd->tran_speed = buf[4];
++ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
++ csd->read_bl_len = buf[6] & 0x0f;
++ /* for support 2GB card*/
++ if (csd->read_bl_len >= 10)
++ {
++ num = csd->read_bl_len - 9;
++ csd->read_bl_len = 9;
++ }
++
++ csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0;
++ csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0;
++ csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0;
++ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
++ csd->c_size = ((((u16)buf[7]) & 0x03) << 10) | (((u16)buf[8]) << 2) | (((u16)buf[9]) & 0xc0) >> 6;
++
++ if (num)
++ csd->c_size = csd->c_size << num;
++
++
++ csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3;
++ csd->vdd_r_curr_max = buf[9] & 0x07;
++ csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5;
++ csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2;
++ csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7);
++ csd->sector_size = (buf[11] & 0x7c) >> 2;
++ csd->erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5);
++ csd->wp_grp_size = buf[12] & 0x1f;
++ csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0;
++ csd->default_ecc = (buf[13] & 0x60) >> 5;
++ csd->r2w_factor = (buf[13] & 0x1c) >> 2;
++ csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6);
++ if (csd->write_bl_len >= 10)
++ csd->write_bl_len = 9;
++
++ csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0;
++ csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0;
++ csd->copy = (buf[15] & 0x40) ? 1 : 0;
++ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
++ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
++ csd->file_format = (buf[15] & 0x0c) >> 2;
++ csd->ecc = buf[15] & 0x03;
++ break;
++ case 1 : /* Version 2.00/High Capacity */
++ csd->taac = 0;
++ csd->nsac = 0;
++ csd->tran_speed = buf[4];
++ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
++
++ csd->read_bl_len = 9;
++ csd->read_bl_partial = 0;
++ csd->write_blk_misalign = 0;
++ csd->read_blk_misalign = 0;
++ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
++ csd->c_size = ((((u16)buf[8]) & 0x3f) << 16) | (((u16)buf[9]) << 8) | ((u16)buf[10]) ;
++ csd->sector_size = 0x7f;
++ csd->erase_grp_size = 0;
++ csd->wp_grp_size = 0;
++ csd->wp_grp_enable = 0;
++ csd->default_ecc = (buf[13] & 0x60) >> 5;
++ csd->r2w_factor = 4;/* Unused */
++ csd->write_bl_len = 9;
++
++ csd->write_bl_partial = 0;
++ csd->file_format_grp = 0;
++ csd->copy = (buf[15] & 0x40) ? 1 : 0;
++ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
++ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
++ csd->file_format = 0;
++ csd->ecc = buf[15] & 0x03;
++ }
++
++ return 0;
++}
++
++int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state)
++{
++ u8 *buf = request->response;
++
++ if (request->result)
++ return request->result;
++
++ r1->cmd = buf[0];
++ r1->status = PARSE_U32(buf,1);
++
++ debug("mmc_unpack_r1: cmd=%d status=%08x\n", r1->cmd, r1->status);
++
++ if (R1_STATUS(r1->status)) {
++ if (r1->status & R1_OUT_OF_RANGE) return MMC_ERROR_OUT_OF_RANGE;
++ if (r1->status & R1_ADDRESS_ERROR) return MMC_ERROR_ADDRESS;
++ if (r1->status & R1_BLOCK_LEN_ERROR) return MMC_ERROR_BLOCK_LEN;
++ if (r1->status & R1_ERASE_SEQ_ERROR) return MMC_ERROR_ERASE_SEQ;
++ if (r1->status & R1_ERASE_PARAM) return MMC_ERROR_ERASE_PARAM;
++ if (r1->status & R1_WP_VIOLATION) return MMC_ERROR_WP_VIOLATION;
++ /*if (r1->status & R1_CARD_IS_LOCKED) return MMC_ERROR_CARD_IS_LOCKED; */
++ if (r1->status & R1_LOCK_UNLOCK_FAILED) return MMC_ERROR_LOCK_UNLOCK_FAILED;
++ if (r1->status & R1_COM_CRC_ERROR) return MMC_ERROR_COM_CRC;
++ if (r1->status & R1_ILLEGAL_COMMAND) return MMC_ERROR_ILLEGAL_COMMAND;
++ if (r1->status & R1_CARD_ECC_FAILED) return MMC_ERROR_CARD_ECC_FAILED;
++ if (r1->status & R1_CC_ERROR) return MMC_ERROR_CC;
++ if (r1->status & R1_ERROR) return MMC_ERROR_GENERAL;
++ if (r1->status & R1_UNDERRUN) return MMC_ERROR_UNDERRUN;
++ if (r1->status & R1_OVERRUN) return MMC_ERROR_OVERRUN;
++ if (r1->status & R1_CID_CSD_OVERWRITE) return MMC_ERROR_CID_CSD_OVERWRITE;
++ }
++
++ if (buf[0] != request->cmd)
++ return MMC_ERROR_HEADER_MISMATCH;
++
++ /* This should be last - it's the least dangerous error */
++
++ return 0;
++}
++
++int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr)
++{
++ u8 *buf = request->response;
++ if (request->result)
++ return request->result;
++
++ *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */
++ return mmc_unpack_r1(request, r1, state);
++
++}
++
++int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca)
++{
++ u8 *buf = request->response;
++
++ if (request->result)
++ return request->result;
++
++ *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */
++
++ *(buf+1) = 0;
++ *(buf+2) = 0;
++
++ return mmc_unpack_r1(request, r1, state);
++}
++
++int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid)
++{
++ int i;
++ u8 *buf = request->response;
++
++ if (request->result)
++ return request->result;
++
++ cid->mid = buf[1];
++ cid->oid = PARSE_U16(buf,2);
++ for (i = 0 ; i < 5 ; i++)
++ cid->pnm[i] = buf[4+i];
++ cid->pnm[6] = 0;
++ cid->prv = buf[10];
++ cid->psn = PARSE_U32(buf,10);
++ cid->mdt = buf[15];
++
++ printf("Man %02x OEM 0x%04x \"%s\" %d.%d 0x%08x "
++ "Date %02u/%04u\n",
++ cid->mid,
++ cid->oid,
++ cid->pnm,
++ cid->prv >> 4,
++ cid->prv & 0xf,
++ cid->psn,
++ cid->mdt & 0xf,
++ (cid->mdt >> 4) + 2000);
++
++ if (buf[0] != 0x3f)
++ return MMC_ERROR_HEADER_MISMATCH;
++ return 0;
++}
++
++int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3)
++{
++ u8 *buf = request->response;
++
++ if (request->result)
++ return request->result;
++
++ r3->ocr = PARSE_U32(buf,1);
++ debug("mmc_unpack_r3: ocr=%08x\n", r3->ocr);
++
++ if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
++ return 0;
++}
++
++#define KBPS 1
++#define MBPS 1000
++
++static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 };
++static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000,
++ 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 };
++
++u32 mmc_tran_speed(u8 ts)
++{
++ u32 rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3];
++
++ if (rate <= 0) {
++ debug("%s: error - unrecognized speed 0x%02x\n", __func__, ts);
++ return 1;
++ }
++
++ return rate;
++}
++
++void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
++ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer)
++{
++ request->cmd = cmd;
++ request->arg = arg;
++ request->rtype = rtype;
++ request->nob = nob;
++ request->block_len = block_len;
++ request->buffer = buffer;
++ request->cnt = nob * block_len;
++
++ jz_mmc_exec_cmd(request);
++}
+diff --git a/drivers/mmc/jz_mmc.h b/drivers/mmc/jz_mmc.h
+new file mode 100644
+index 0000000..936c514
+--- /dev/null
++++ b/drivers/mmc/jz_mmc.h
+@@ -0,0 +1,176 @@
++/*
++ * linux/drivers/mmc/jz_mmc.h
++ *
++ * Author: Vladimir Shebordaev, Igor Oblakov
++ * Copyright: MontaVista Software Inc.
++ *
++ * $Id: jz_mmc.h,v 1.3 2007-06-15 08:04:20 jlwei Exp $
++ *
++ * 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 __MMC_JZMMC_H__
++#define __MMC_JZMMC_H__
++
++#define ID_TO_RCA(x) ((x)+1)
++#define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */
++
++/* Standard MMC/SD clock speeds */
++#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */
++#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */
++#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
++
++/* Use negative numbers to disambiguate */
++#define MMC_CIM_RESET -1
++#define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
++
++#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
++#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
++#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
++#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
++#define R1_ERASE_PARAM (1 << 27) /* ex, c */
++#define R1_WP_VIOLATION (1 << 26) /* erx, c */
++#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
++#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
++#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
++#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
++#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
++#define R1_CC_ERROR (1 << 20) /* erx, c */
++#define R1_ERROR (1 << 19) /* erx, c */
++#define R1_UNDERRUN (1 << 18) /* ex, c */
++#define R1_OVERRUN (1 << 17) /* ex, c */
++#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
++#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
++#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
++#define R1_ERASE_RESET (1 << 13) /* sr, c */
++#define R1_STATUS(x) (x & 0xFFFFE000)
++
++#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
++
++#define MMC_PROGRAM_CID 26 /* adtc R1 */
++#define MMC_PROGRAM_CSD 27 /* adtc R1 */
++
++#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
++#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */
++#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
++#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
++#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
++#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
++
++
++enum mmc_result_t {
++ MMC_NO_RESPONSE = -1,
++ MMC_NO_ERROR = 0,
++ MMC_ERROR_OUT_OF_RANGE,
++ MMC_ERROR_ADDRESS,
++ MMC_ERROR_BLOCK_LEN,
++ MMC_ERROR_ERASE_SEQ,
++ MMC_ERROR_ERASE_PARAM,
++ MMC_ERROR_WP_VIOLATION,
++ MMC_ERROR_CARD_IS_LOCKED,
++ MMC_ERROR_LOCK_UNLOCK_FAILED,
++ MMC_ERROR_COM_CRC,
++ MMC_ERROR_ILLEGAL_COMMAND,
++ MMC_ERROR_CARD_ECC_FAILED,
++ MMC_ERROR_CC,
++ MMC_ERROR_GENERAL,
++ MMC_ERROR_UNDERRUN,
++ MMC_ERROR_OVERRUN,
++ MMC_ERROR_CID_CSD_OVERWRITE,
++ MMC_ERROR_STATE_MISMATCH,
++ MMC_ERROR_HEADER_MISMATCH,
++ MMC_ERROR_TIMEOUT,
++ MMC_ERROR_CRC,
++ MMC_ERROR_DRIVER_FAILURE,
++};
++
++enum card_state {
++ CARD_STATE_EMPTY = -1,
++ CARD_STATE_IDLE = 0,
++ CARD_STATE_READY = 1,
++ CARD_STATE_IDENT = 2,
++ CARD_STATE_STBY = 3,
++ CARD_STATE_TRAN = 4,
++ CARD_STATE_DATA = 5,
++ CARD_STATE_RCV = 6,
++ CARD_STATE_PRG = 7,
++ CARD_STATE_DIS = 8,
++};
++
++enum mmc_rsp_t {
++ RESPONSE_NONE = 0,
++ RESPONSE_R1 = 1,
++ RESPONSE_R1B = 2,
++ RESPONSE_R2_CID = 3,
++ RESPONSE_R2_CSD = 4,
++ RESPONSE_R3 = 5,
++ RESPONSE_R4 = 6,
++ RESPONSE_R5 = 7,
++ RESPONSE_R6 = 8,
++};
++
++struct mmc_response_r1 {
++ u8 cmd;
++ u32 status;
++};
++
++struct mmc_response_r3 {
++ u32 ocr;
++};
++
++/* the information structure of MMC/SD Card */
++struct mmc_info {
++ int id; /* Card index */
++ int sd; /* MMC or SD card */
++ int rca; /* RCA */
++ u32 scr; /* SCR 63:32*/
++ int flags; /* Ejected, inserted */
++ enum card_state state; /* empty, ident, ready, whatever */
++
++ /* Card specific information */
++ struct mmc_cid cid;
++ struct mmc_csd csd;
++ u32 block_num;
++ u32 block_len;
++ u32 erase_unit;
++};
++
++struct mmc_info mmcinfo;
++
++struct mmc_request {
++ int index; /* Slot index - used for CS lines */
++ int cmd; /* Command to send */
++ u32 arg; /* Argument to send */
++ enum mmc_rsp_t rtype; /* Response type expected */
++
++ /* Data transfer (these may be modified at the low level) */
++ u16 nob; /* Number of blocks to transfer*/
++ u16 block_len; /* Block length */
++ u8 *buffer; /* Data buffer */
++ u32 cnt; /* Data length, for PIO */
++
++ /* Results */
++ u8 response[18]; /* Buffer to store response - CRC is optional */
++ enum mmc_result_t result;
++};
++
++char * mmc_result_to_string(int);
++int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd);
++int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state);
++int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca);
++int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr);
++int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid);
++int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3);
++
++void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
++ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer);
++u32 mmc_tran_speed(u8 ts);
++void jz_mmc_set_clock(int sd, u32 rate);
++
++static inline void mmc_simple_cmd(struct mmc_request *request, int cmd, u32 arg, enum mmc_rsp_t rtype)
++{
++ mmc_send_cmd( request, cmd, arg, 0, 0, rtype, 0);
++}
++
++#endif /* __MMC_JZMMC_H__ */
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index 7bff444..7b33be0 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -31,6 +31,15 @@
+ /*
+ * Miscellaneous configurable options
+ */
++#define CONFIG_JZ4740_MMC
++#define CONFIG_MMC 1
++#define CONFIG_FAT 1
++#define CONFIG_DOS_PARTITION 1
++#define CONFIG_CMD_MMC
++#define CONFIG_CMD_FAT
++#define CONFIG_CMD_EXT2
++
++
+ #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
+ #define CONFIG_SYS_INIT_SP_OFFSET 0x400000
+ #define CONFIG_SYS_LOAD_ADDR 0x80600000
+diff --git a/include/mmc.h b/include/mmc.h
+index a13e2bd..3c4761c 100644
+--- a/include/mmc.h
++++ b/include/mmc.h
+@@ -283,4 +283,44 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
+ int mmc_legacy_init(int verbose);
+ #endif
+
++struct mmc_csd
++{
++ u8 csd_structure:2,
++ spec_vers:4,
++ rsvd1:2;
++ u8 taac;
++ u8 nsac;
++ u8 tran_speed;
++ u16 ccc:12,
++ read_bl_len:4;
++ u32 c_size:22;
++ u64 read_bl_partial:1,
++ write_blk_misalign:1,
++ read_blk_misalign:1,
++ dsr_imp:1,
++ rsvd2:2,
++ vdd_r_curr_min:3,
++ vdd_r_curr_max:3,
++ vdd_w_curr_min:3,
++ vdd_w_curr_max:3,
++ c_size_mult:3,
++ sector_size:5,
++ erase_grp_size:5,
++ wp_grp_size:5,
++ wp_grp_enable:1,
++ default_ecc:2,
++ r2w_factor:3,
++ write_bl_len:4,
++ write_bl_partial:1,
++ rsvd3:5;
++ u8 file_format_grp:1,
++ copy:1,
++ perm_write_protect:1,
++ tmp_write_protect:1,
++ file_format:2,
++ ecc:2;
++ u8 crc:7;
++ u8 one:1;
++};
++
+ #endif /* _MMC_H_ */
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch.svn-base
new file mode 100644
index 0000000..73e0324
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/.svn/text-base/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch.svn-base
@@ -0,0 +1,200 @@
+From c52b6168979d03fc31205444c3278c537787472a Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Wed, 10 Oct 2012 18:39:55 +0800
+Subject: [PATCH 4/6] add more boot options(F1/F2/F3/F4/M/S)
+
+---
+ arch/mips/include/asm/global_data.h | 3 +++
+ arch/mips/lib/bootm.c | 17 ++++++++++++++++-
+ board/qi/qi_lb60/qi_lb60.c | 26 +++++++++++++++++++++++---
+ common/main.c | 21 +++++++++++++++++++--
+ include/configs/qi_lb60.h | 32 ++++++++++++++++++++++++++++++++
+ 5 files changed, 93 insertions(+), 6 deletions(-)
+
+diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
+index 6e2cdc7..cd03d7e 100644
+--- a/arch/mips/include/asm/global_data.h
++++ b/arch/mips/include/asm/global_data.h
+@@ -59,6 +59,9 @@ typedef struct global_data {
+ unsigned long env_valid; /* Checksum of Environment valid? */
+ void **jt; /* jump table */
+ char env_buf[32]; /* buffer for getenv() before reloc. */
++#if defined(CONFIG_NANONOTE)
++ unsigned long boot_option;
++#endif
+ } gd_t;
+
+ #include <asm-generic/global_data_flags.h>
+diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
+index 608c1a7..e00416b 100644
+--- a/arch/mips/lib/bootm.c
++++ b/arch/mips/lib/bootm.c
+@@ -47,10 +47,25 @@ int do_bootm_linux(int flag, int argc, char * const argv[],
+ bootm_headers_t *images)
+ {
+ void (*theKernel) (int, char **, char **, int *);
+- char *commandline = getenv("bootargs");
++ char *commandline;
+ char env_buf[12];
+ char *cp;
+
++#if defined(CONFIG_NANONOTE)
++ if (gd->boot_option & BOOT_FROM_MEMCARD)
++ commandline = getenv ("bootargsfromsd");
++ else if (gd->boot_option & BOOT_WITH_F1)
++ commandline = getenv ("bootargsf1");
++ else if (gd->boot_option & BOOT_WITH_F2)
++ commandline = getenv ("bootargsf2");
++ else if (gd->boot_option & BOOT_WITH_F3)
++ commandline = getenv ("bootargsf3");
++ else if (gd->boot_option & BOOT_WITH_F4)
++ commandline = getenv ("bootargsf4");
++ else
++#endif
++ commandline = getenv ("bootargs");
++
+ if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
+ return 1;
+
+diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
+index a2ba648..d622219 100644
+--- a/board/qi/qi_lb60/qi_lb60.c
++++ b/board/qi/qi_lb60/qi_lb60.c
+@@ -15,7 +15,7 @@ DECLARE_GLOBAL_DATA_PTR;
+
+ static void gpio_init(void)
+ {
+- unsigned int i;
++ unsigned int i, j;
+
+ /* Initialize NAND Flash Pins */
+ __gpio_as_nand();
+@@ -42,14 +42,34 @@ static void gpio_init(void)
+
+ if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){
+ printf("[S] pressed, enable UART0\n");
++ gd->boot_option |= BOOT_WITH_ENABLE_UART;
+ __gpio_as_uart0();
+ } else {
+ __gpio_as_input(GPIO_KEYIN_8);
+ __gpio_enable_pull(GPIO_KEYIN_8);
+ }
+
+- /* enable the TP4, TP5 as UART0 */
+- __gpio_jtag_to_uart0();
++ if (__gpio_get_pin(GPIO_KEYIN_BASE + 3) == 0) {
++ printf("[M] pressed, boot from memory card\n");
++ gd->boot_option |= BOOT_FROM_MEMCARD;
++ __gpio_jtag_to_uart0();
++ }
++
++ for (j = 0; j < 4; j++) {
++ for (i = 0; i < 4; i++)
++ __gpio_set_pin(GPIO_KEYOUT_BASE + i);
++
++ __gpio_clear_pin(GPIO_KEYOUT_BASE + j);
++
++ if (__gpio_get_pin(GPIO_KEYIN_BASE) == 0) {
++ printf("[F%d] pressed", (j + 1));
++ gd->boot_option |= (1 << (j + 2));
++ /* BOOT_WITH_F1 (1 << 2) */
++ /* BOOT_WITH_F2 (1 << 3) */
++ /* BOOT_WITH_F3 (1 << 4) */
++ /* BOOT_WITH_F4 (1 << 5) */
++ }
++ }
+
+ __gpio_as_output(GPIO_AUDIO_POP);
+ __gpio_set_pin(GPIO_AUDIO_POP);
+diff --git a/common/main.c b/common/main.c
+index 9507cec..dbfb7ca 100644
+--- a/common/main.c
++++ b/common/main.c
+@@ -355,7 +355,11 @@ void main_loop (void)
+ #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+ s = getenv ("bootdelay");
+ bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
+-
++#if defined(CONFIG_NANONOTE)
++ DECLARE_GLOBAL_DATA_PTR;
++ if (gd->boot_option & BOOT_WITH_ENABLE_UART)
++ bootdelay = 3;
++# endif
+ debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
+
+ #if defined(CONFIG_MENU_SHOW)
+@@ -379,7 +383,20 @@ void main_loop (void)
+ }
+ else
+ #endif /* CONFIG_BOOTCOUNT_LIMIT */
+- s = getenv ("bootcmd");
++#if defined(CONFIG_NANONOTE)
++ if (gd->boot_option & BOOT_FROM_MEMCARD)
++ s = getenv ("bootcmdfromsd");
++ else if (gd->boot_option & BOOT_WITH_F1)
++ s = getenv ("bootcmdf1");
++ else if (gd->boot_option & BOOT_WITH_F2)
++ s = getenv ("bootcmdf2");
++ else if (gd->boot_option & BOOT_WITH_F3)
++ s = getenv ("bootcmdf3");
++ else if (gd->boot_option & BOOT_WITH_F4)
++ s = getenv ("bootcmdf4");
++ else
++#endif
++ s = getenv ("bootcmd");
+
+ debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
+
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index 7b33be0..52b370c 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -31,6 +31,7 @@
+ /*
+ * Miscellaneous configurable options
+ */
++#define CONFIG_NANONOTE
+ #define CONFIG_JZ4740_MMC
+ #define CONFIG_MMC 1
+ #define CONFIG_FAT 1
+@@ -39,6 +40,37 @@
+ #define CONFIG_CMD_FAT
+ #define CONFIG_CMD_EXT2
+
++#define CONFIG_CMD_UBIFS
++#define CONFIG_CMD_UBI
++#define CONFIG_MTD_PARTITIONS
++#define CONFIG_MTD_DEVICE
++#define CONFIG_CMD_MTDPARTS
++#define CONFIG_CMD_UBI
++#define CONFIG_CMD_UBIFS
++#define CONFIG_LZO
++#define CONFIG_RBTREE
++
++#define MTDIDS_DEFAULT "nand0=jz4740-nand"
++#define MTDPARTS_DEFAULT "mtdparts=jz4740-nand:4M@0(uboot)ro,4M@4M(kernel)ro,512M@8M(rootfs)ro,-(data)ro"
++
++#define BOOT_FROM_MEMCARD 1
++#define BOOT_WITH_ENABLE_UART (1 << 1) /* Vaule for global_data.h gd->boot_option */
++#define BOOT_WITH_F1 (1 << 2)
++#define BOOT_WITH_F2 (1 << 3)
++#define BOOT_WITH_F3 (1 << 4)
++#define BOOT_WITH_F4 (1 << 5)
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ "bootcmdfromsd=mmc init; ext2load mmc 0 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsfromsd=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \
++ "bootcmdf1=mmc init; ext2load mmc 0:1 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsf1=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \
++ "bootcmdf2=mmc init; ext2load mmc 0:2 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsf2=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p2 rw rootwait\0" \
++ "bootcmdf3=mmc init; ext2load mmc 0:3 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsf3=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p3 rw rootwait\0" \
++ "bootcmdf4=mtdparts default;ubi part rootfs;ubifsmount rootfs;ubifsload 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsf4=mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
+
+ #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
+ #define CONFIG_SYS_INIT_SP_OFFSET 0x400000
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0005-add-nanonote-lcd-support.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0005-add-nanonote-lcd-support.patch.svn-base
new file mode 100644
index 0000000..2c550f7
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/.svn/text-base/0005-add-nanonote-lcd-support.patch.svn-base
@@ -0,0 +1,847 @@
+From ca8c5216cfd3ad3fda9867ed2d157ae5a209834b Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Wed, 10 Oct 2012 22:05:27 +0800
+Subject: [PATCH 5/6] add nanonote lcd support
+
+---
+ arch/mips/include/asm/global_data.h | 1 +
+ arch/mips/include/asm/jz4740.h | 90 ++++++++
+ arch/mips/lib/board.c | 6 +
+ common/lcd.c | 9 +-
+ drivers/video/Makefile | 1 +
+ drivers/video/nanonote_gpm940b0.c | 400 +++++++++++++++++++++++++++++++++++
+ drivers/video/nanonote_gpm940b0.h | 135 ++++++++++++
+ include/configs/qi_lb60.h | 7 +
+ include/lcd.h | 52 ++++-
+ 9 files changed, 697 insertions(+), 4 deletions(-)
+ create mode 100644 drivers/video/nanonote_gpm940b0.c
+ create mode 100644 drivers/video/nanonote_gpm940b0.h
+
+diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
+index cd03d7e..7cec2de 100644
+--- a/arch/mips/include/asm/global_data.h
++++ b/arch/mips/include/asm/global_data.h
+@@ -44,6 +44,7 @@ typedef struct global_data {
+ unsigned long per_clk; /* Peripheral bus clock */
+ unsigned long mem_clk; /* Memory bus clock */
+ unsigned long dev_clk; /* Device clock */
++ unsigned long fb_base; /* base address of framebuffer */
+ /* "static data" needed by most of timer.c */
+ unsigned long tbl;
+ unsigned long lastinc;
+diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h
+index 68287fb..13724a2 100644
+--- a/arch/mips/include/asm/jz4740.h
++++ b/arch/mips/include/asm/jz4740.h
+@@ -1312,5 +1312,95 @@ do { \
+ while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \
+ } while (0)
+
++/*************************************************************************
++ * LCD (LCD Controller)
++ *************************************************************************/
++#define REG32(addr) *((volatile u32 *)(addr))
++
++#define CPM_BASE 0xB0000000
++#define CPM_CPCCR (CPM_BASE+0x00)
++#define REG_CPM_CPCCR REG32(CPM_CPCCR)
++
++#define LCD_BASE 0xB3050000
++#define LCD_CFG (LCD_BASE + 0x00) /* LCD Configure Register */
++#define LCD_VSYNC (LCD_BASE + 0x04) /* Vertical Synchronize Register */
++#define LCD_HSYNC (LCD_BASE + 0x08) /* Horizontal Synchronize Register */
++#define LCD_VAT (LCD_BASE + 0x0c) /* Virtual Area Setting Register */
++#define LCD_DAH (LCD_BASE + 0x10) /* Display Area Horizontal Start/End Point */
++#define LCD_DAV (LCD_BASE + 0x14) /* Display Area Vertical Start/End Point */
++#define LCD_PS (LCD_BASE + 0x18) /* PS Signal Setting */
++#define LCD_CLS (LCD_BASE + 0x1c) /* CLS Signal Setting */
++#define LCD_SPL (LCD_BASE + 0x20) /* SPL Signal Setting */
++#define LCD_REV (LCD_BASE + 0x24) /* REV Signal Setting */
++#define LCD_CTRL (LCD_BASE + 0x30) /* LCD Control Register */
++#define LCD_STATE (LCD_BASE + 0x34) /* LCD Status Register */
++#define LCD_IID (LCD_BASE + 0x38) /* Interrupt ID Register */
++#define LCD_DA0 (LCD_BASE + 0x40) /* Descriptor Address Register 0 */
++#define LCD_SA0 (LCD_BASE + 0x44) /* Source Address Register 0 */
++#define LCD_FID0 (LCD_BASE + 0x48) /* Frame ID Register 0 */
++#define LCD_CMD0 (LCD_BASE + 0x4c) /* DMA Command Register 0 */
++#define LCD_DA1 (LCD_BASE + 0x50) /* Descriptor Address Register 1 */
++#define LCD_SA1 (LCD_BASE + 0x54) /* Source Address Register 1 */
++#define LCD_FID1 (LCD_BASE + 0x58) /* Frame ID Register 1 */
++#define LCD_CMD1 (LCD_BASE + 0x5c) /* DMA Command Register 1 */
++
++#define REG_LCD_CFG REG32(LCD_CFG)
++#define REG_LCD_VSYNC REG32(LCD_VSYNC)
++#define REG_LCD_HSYNC REG32(LCD_HSYNC)
++#define REG_LCD_VAT REG32(LCD_VAT)
++#define REG_LCD_DAH REG32(LCD_DAH)
++#define REG_LCD_DAV REG32(LCD_DAV)
++#define REG_LCD_PS REG32(LCD_PS)
++#define REG_LCD_CLS REG32(LCD_CLS)
++#define REG_LCD_SPL REG32(LCD_SPL)
++#define REG_LCD_REV REG32(LCD_REV)
++#define REG_LCD_CTRL REG32(LCD_CTRL)
++#define REG_LCD_STATE REG32(LCD_STATE)
++#define REG_LCD_IID REG32(LCD_IID)
++#define REG_LCD_DA0 REG32(LCD_DA0)
++#define REG_LCD_SA0 REG32(LCD_SA0)
++#define REG_LCD_FID0 REG32(LCD_FID0)
++#define REG_LCD_CMD0 REG32(LCD_CMD0)
++#define REG_LCD_DA1 REG32(LCD_DA1)
++#define REG_LCD_SA1 REG32(LCD_SA1)
++#define REG_LCD_FID1 REG32(LCD_FID1)
++#define REG_LCD_CMD1 REG32(LCD_CMD1)
++
++#define LCD_CTRL_BPP_BIT 0 /* Bits Per Pixel */
++#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT)
++ #define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT) /* 1 bpp */
++ #define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT) /* 2 bpp */
++ #define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT) /* 4 bpp */
++ #define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT) /* 8 bpp */
++ #define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT) /* 15/16 bpp */
++ #define LCD_CTRL_BPP_18_24 (5 << LCD_CTRL_BPP_BIT) /* 18/24/32 bpp */
++
++#define LCD_CTRL_BST_BIT 28 /* Burst Length Selection */
++#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT)
++ #define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT) /* 4-word */
++ #define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT) /* 8-word */
++ #define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT) /* 16-word */
++#define LCD_CTRL_RGB565 (0 << 27) /* RGB565 mode */
++#define LCD_CTRL_RGB555 (1 << 27) /* RGB555 mode */
++#define LCD_CTRL_OFUP (1 << 26) /* Output FIFO underrun protection enable */
++#define LCD_CTRL_FRC_BIT 24 /* STN FRC Algorithm Selection */
++#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT)
++ #define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT) /* 16 grayscale */
++ #define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT) /* 4 grayscale */
++ #define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT) /* 2 grayscale */
++
++#define CPM_LPCDR (CPM_BASE+0x64)
++#define CPM_CLKGR (CPM_BASE+0x20)
++#define REG_CPM_LPCDR REG32(CPM_LPCDR)
++#define REG_CPM_CLKGR REG32(CPM_CLKGR)
++
++#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU)
++#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD)
++#define __cpm_set_pixdiv(v) \
++ (REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT)))
++#define __cpm_set_ldiv(v) \
++ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT)))
++#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD)
++
+ #endif /* !__ASSEMBLY__ */
+ #endif /* __JZ4740_H__ */
+diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c
+index b14b33e..c2e64d9 100644
+--- a/arch/mips/lib/board.c
++++ b/arch/mips/lib/board.c
+@@ -172,6 +172,12 @@ void board_init_f(ulong bootflag)
+ addr &= ~(4096 - 1);
+ debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
+
++#ifdef CONFIG_LCD
++ /* reserve memory for LCD display (always full pages) */
++ addr = lcd_setmem (addr);
++ gd->fb_base = addr;
++#endif /* CONFIG_LCD */
++
+ /* Reserve memory for U-Boot code, data & bss
+ * round down to next 16 kB limit
+ */
+diff --git a/common/lcd.c b/common/lcd.c
+index b6be800..af1281a 100644
+--- a/common/lcd.c
++++ b/common/lcd.c
+@@ -263,6 +263,13 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
+ lcd_color_fg : lcd_color_bg;
+ bits <<= 1;
+ }
++#elif LCD_BPP == LCD_COLOR32
++ uint *m = (uint *)d;
++ for (c=0; c<32; ++c) {
++ *m++ = (bits & 0x80) ?
++ lcd_color_fg : lcd_color_bg;
++ bits <<= 1;
++ }
+ #endif
+ }
+ #if LCD_BPP == LCD_MONOCHROME
+@@ -509,7 +516,7 @@ static inline ushort *configuration_get_cmap(void)
+ return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]);
+ #elif defined(CONFIG_ATMEL_LCD)
+ return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0));
+-#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB)
++#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) && !defined(CONFIG_VIDEO_GPM940B0)
+ return panel_info.cmap;
+ #else
+ #if defined(CONFIG_LCD_LOGO)
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index ebb6da8..03625bc 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -50,6 +50,7 @@ COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o
+ COBJS-$(CONFIG_VIDEO_SM501) += sm501.o
+ COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
+ COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
++COBJS-$(CONFIG_VIDEO_GPM940B0) += nanonote_gpm940b0.o
+
+ COBJS := $(sort $(COBJS-y))
+ SRCS := $(COBJS:.o=.c)
+diff --git a/drivers/video/nanonote_gpm940b0.c b/drivers/video/nanonote_gpm940b0.c
+new file mode 100644
+index 0000000..11efb72
+--- /dev/null
++++ b/drivers/video/nanonote_gpm940b0.c
+@@ -0,0 +1,400 @@
++/*
++ * JzRISC lcd controller
++ *
++ * Xiangfu Liu <xiangfu@sharism.cc>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <common.h>
++#include <lcd.h>
++
++#include <asm/io.h> /* virt_to_phys() */
++#include <asm/jz4740.h>
++
++#include "nanonote_gpm940b0.h"
++
++#define align2(n) (n)=((((n)+1)>>1)<<1)
++#define align4(n) (n)=((((n)+3)>>2)<<2)
++#define align8(n) (n)=((((n)+7)>>3)<<3)
++
++struct jzfb_info {
++ unsigned int cfg; /* panel mode and pin usage etc. */
++ unsigned int w;
++ unsigned int h;
++ unsigned int bpp; /* bit per pixel */
++ unsigned int fclk; /* frame clk */
++ unsigned int hsw; /* hsync width, in pclk */
++ unsigned int vsw; /* vsync width, in line count */
++ unsigned int elw; /* end of line, in pclk */
++ unsigned int blw; /* begin of line, in pclk */
++ unsigned int efw; /* end of frame, in line count */
++ unsigned int bfw; /* begin of frame, in line count */
++};
++
++static struct jzfb_info jzfb = {
++ MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N,
++ 320, 240, 32, 70, 1, 1, 273, 140, 1, 20
++};
++
++vidinfo_t panel_info = {
++ 320, 240, LCD_BPP,
++};
++
++void *lcd_base;
++void *lcd_console_address;
++int lcd_line_length;
++int lcd_color_fg;
++int lcd_color_bg;
++short console_col;
++short console_row;
++
++static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid)
++{
++ u_long palette_mem_size;
++ struct jz_fb_info *fbi = &vid->jz_fb;
++ int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8;
++
++ fbi->screen = (u_long)lcdbase;
++ fbi->palette_size = 256;
++ palette_mem_size = fbi->palette_size * sizeof(u16);
++
++ debug("jz_lcd.c palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
++ /* locate palette and descs at end of page following fb */
++ fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
++
++ return 0;
++}
++
++static void jz_lcd_desc_init(vidinfo_t *vid)
++{
++ struct jz_fb_info * fbi;
++ fbi = &vid->jz_fb;
++ fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 3*16);
++ fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 2*16);
++ fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 1*16);
++
++ #define BYTES_PER_PANEL (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8)
++
++ /* populate descriptors */
++ fbi->dmadesc_fblow->fdadr = virt_to_phys(fbi->dmadesc_fblow);
++ fbi->dmadesc_fblow->fsadr = virt_to_phys((void *)(fbi->screen + BYTES_PER_PANEL));
++ fbi->dmadesc_fblow->fidr = 0;
++ fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL / 4 ;
++
++ fbi->fdadr1 = virt_to_phys(fbi->dmadesc_fblow); /* only used in dual-panel mode */
++
++ fbi->dmadesc_fbhigh->fsadr = virt_to_phys((void *)fbi->screen);
++ fbi->dmadesc_fbhigh->fidr = 0;
++ fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL / 4; /* length in word */
++
++ fbi->dmadesc_palette->fsadr = virt_to_phys((void *)fbi->palette);
++ fbi->dmadesc_palette->fidr = 0;
++ fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2)/4 | (1<<28);
++
++ if(NBITS(vid->vl_bpix) < 12) {
++ /* assume any mode with <12 bpp is palette driven */
++ fbi->dmadesc_palette->fdadr = virt_to_phys(fbi->dmadesc_fbhigh);
++ fbi->dmadesc_fbhigh->fdadr = virt_to_phys(fbi->dmadesc_palette);
++ /* flips back and forth between pal and fbhigh */
++ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_palette);
++ } else {
++ /* palette shouldn't be loaded in true-color mode */
++ fbi->dmadesc_fbhigh->fdadr = virt_to_phys((void *)fbi->dmadesc_fbhigh);
++ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_fbhigh); /* no pal just fbhigh */
++ }
++}
++
++static int jz_lcd_hw_init(vidinfo_t *vid)
++{
++ struct jz_fb_info *fbi = &vid->jz_fb;
++ unsigned int val = 0;
++ unsigned int pclk;
++ unsigned int stnH;
++ int pll_div;
++
++ /* Setting Control register */
++ switch (jzfb.bpp) {
++ case 1:
++ val |= LCD_CTRL_BPP_1;
++ break;
++ case 2:
++ val |= LCD_CTRL_BPP_2;
++ break;
++ case 4:
++ val |= LCD_CTRL_BPP_4;
++ break;
++ case 8:
++ val |= LCD_CTRL_BPP_8;
++ break;
++ case 15:
++ val |= LCD_CTRL_RGB555;
++ case 16:
++ val |= LCD_CTRL_BPP_16;
++ break;
++ case 17 ... 32:
++ val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */
++ break;
++
++ default:
++ printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp);
++ val |= LCD_CTRL_BPP_16;
++ break;
++ }
++
++ switch (jzfb.cfg & MODE_MASK) {
++ case MODE_STN_MONO_DUAL:
++ case MODE_STN_COLOR_DUAL:
++ case MODE_STN_MONO_SINGLE:
++ case MODE_STN_COLOR_SINGLE:
++ switch (jzfb.bpp) {
++ case 1:
++ /* val |= LCD_CTRL_PEDN; */
++ case 2:
++ val |= LCD_CTRL_FRC_2;
++ break;
++ case 4:
++ val |= LCD_CTRL_FRC_4;
++ break;
++ case 8:
++ default:
++ val |= LCD_CTRL_FRC_16;
++ break;
++ }
++ break;
++ }
++
++ val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */
++ val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */
++
++ switch (jzfb.cfg & MODE_MASK) {
++ case MODE_STN_MONO_DUAL:
++ case MODE_STN_COLOR_DUAL:
++ case MODE_STN_MONO_SINGLE:
++ case MODE_STN_COLOR_SINGLE:
++ switch (jzfb.cfg & STN_DAT_PINMASK) {
++ case STN_DAT_PIN1:
++ /* Do not adjust the hori-param value. */
++ break;
++ case STN_DAT_PIN2:
++ align2(jzfb.hsw);
++ align2(jzfb.elw);
++ align2(jzfb.blw);
++ break;
++ case STN_DAT_PIN4:
++ align4(jzfb.hsw);
++ align4(jzfb.elw);
++ align4(jzfb.blw);
++ break;
++ case STN_DAT_PIN8:
++ align8(jzfb.hsw);
++ align8(jzfb.elw);
++ align8(jzfb.blw);
++ break;
++ }
++ break;
++ }
++
++ REG_LCD_CTRL = val;
++
++ switch (jzfb.cfg & MODE_MASK) {
++ case MODE_STN_MONO_DUAL:
++ case MODE_STN_COLOR_DUAL:
++ case MODE_STN_MONO_SINGLE:
++ case MODE_STN_COLOR_SINGLE:
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
++ stnH = jzfb.h >> 1;
++ else
++ stnH = jzfb.h;
++
++ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
++ REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw);
++
++ /* Screen setting */
++ REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw);
++ REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w);
++ REG_LCD_DAV = (0 << 16) | (stnH);
++
++ /* AC BIAs signal */
++ REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw);
++
++ break;
++
++ case MODE_TFT_GEN:
++ case MODE_TFT_SHARP:
++ case MODE_TFT_CASIO:
++ case MODE_TFT_SAMSUNG:
++ case MODE_8BIT_SERIAL_TFT:
++ case MODE_TFT_18BIT:
++ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
++ REG_LCD_HSYNC = (0 << 16) | jzfb.hsw;
++ REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h);
++ REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w );
++ REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \
++ | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw);
++ break;
++ }
++
++ switch (jzfb.cfg & MODE_MASK) {
++ case MODE_TFT_SAMSUNG:
++ {
++ unsigned int total, tp_s, tp_e, ckv_s, ckv_e;
++ unsigned int rev_s, rev_e, inv_s, inv_e;
++
++ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
++
++ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
++ tp_s = jzfb.blw + jzfb.w + 1;
++ tp_e = tp_s + 1;
++ ckv_s = tp_s - pclk/(1000000000/4100);
++ ckv_e = tp_s + total;
++ rev_s = tp_s - 11; /* -11.5 clk */
++ rev_e = rev_s + total;
++ inv_s = tp_s;
++ inv_e = inv_s + total;
++ REG_LCD_CLS = (tp_s << 16) | tp_e;
++ REG_LCD_PS = (ckv_s << 16) | ckv_e;
++ REG_LCD_SPL = (rev_s << 16) | rev_e;
++ REG_LCD_REV = (inv_s << 16) | inv_e;
++ jzfb.cfg |= STFT_REVHI | STFT_SPLHI;
++ break;
++ }
++ case MODE_TFT_SHARP:
++ {
++ unsigned int total, cls_s, cls_e, ps_s, ps_e;
++ unsigned int spl_s, spl_e, rev_s, rev_e;
++ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
++ spl_s = 1;
++ spl_e = spl_s + 1;
++ cls_s = 0;
++ cls_e = total - 60; /* > 4us (pclk = 80ns) */
++ ps_s = cls_s;
++ ps_e = cls_e;
++ rev_s = total - 40; /* > 3us (pclk = 80ns) */
++ rev_e = rev_s + total;
++ jzfb.cfg |= STFT_PSHI;
++ REG_LCD_SPL = (spl_s << 16) | spl_e;
++ REG_LCD_CLS = (cls_s << 16) | cls_e;
++ REG_LCD_PS = (ps_s << 16) | ps_e;
++ REG_LCD_REV = (rev_s << 16) | rev_e;
++ break;
++ }
++ case MODE_TFT_CASIO:
++ break;
++ }
++
++ /* Configure the LCD panel */
++ REG_LCD_CFG = jzfb.cfg;
++
++ /* Timing setting */
++ __cpm_stop_lcd();
++
++ val = jzfb.fclk; /* frame clk */
++ if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) {
++ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
++ } else {
++ /* serial mode: Hsync period = 3*Width_Pixel */
++ pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) *
++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
++ }
++
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
++ pclk = (pclk * 3);
++
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
++ pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4);
++
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
++ pclk >>= 1;
++
++ pll_div = (REG_CPM_CPCCR & CPM_CPCCR_PCS); /* clock source,0:pllout/2 1: pllout */
++ pll_div = pll_div ? 1 : 2;
++ val = (__cpm_get_pllout() / pll_div) / pclk;
++ val--;
++ if (val > 0x1ff) {
++ printf("CPM_LPCDR too large, set it to 0x1ff\n");
++ val = 0x1ff;
++ }
++ __cpm_set_pixdiv(val);
++
++ val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
++ if (val > 150000000) {
++ printf("Warning: LCDClock=%d\n, LCDClock must less or equal to 150MHz.\n", val);
++ printf("Change LCDClock to 150MHz\n");
++ val = 150000000;
++ }
++ val = (__cpm_get_pllout() / pll_div) / val;
++ val--;
++ if (val > 0x1f) {
++ printf("CPM_CPCCR.LDIV too large, set it to 0x1f\n");
++ val = 0x1f;
++ }
++ __cpm_set_ldiv( val );
++ REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */
++
++ __cpm_start_lcd();
++ udelay(1000);
++
++ REG_LCD_DA0 = fbi->fdadr0; /* frame descripter*/
++
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
++ REG_LCD_DA1 = fbi->fdadr1; /* frame descripter*/
++
++ return 0;
++}
++
++void lcd_ctrl_init (void *lcdbase)
++{
++ __lcd_display_pin_init();
++ __lcd_display_on() ;
++
++ jz_lcd_init_mem(lcdbase, &panel_info);
++ jz_lcd_desc_init(&panel_info);
++ jz_lcd_hw_init(&panel_info);
++
++}
++
++/*
++ * Before enabled lcd controller, lcd registers should be configured correctly.
++ */
++void lcd_enable (void)
++{
++ REG_LCD_CTRL &= ~(1<<4); /* LCDCTRL.DIS */
++ REG_LCD_CTRL |= 1<<3; /* LCDCTRL.ENA*/
++}
++
++void lcd_disable (void)
++{
++ REG_LCD_CTRL |= (1<<4);
++}
++
++void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
++{
++}
++
++void lcd_initcolregs (void)
++{
++}
+diff --git a/drivers/video/nanonote_gpm940b0.h b/drivers/video/nanonote_gpm940b0.h
+new file mode 100644
+index 0000000..efe491e
+--- /dev/null
++++ b/drivers/video/nanonote_gpm940b0.h
+@@ -0,0 +1,135 @@
++/*
++ * JzRISC lcd controller
++ *
++ * Xiangfu Liu <xiangfu@sharism.cc>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __QI_LB60_GPM940B0_H__
++#define __QI_LB60_GPM940B0_H__
++
++struct lcd_desc{
++ unsigned int next_desc; /* LCDDAx */
++ unsigned int databuf; /* LCDSAx */
++ unsigned int frame_id; /* LCDFIDx */
++ unsigned int cmd; /* LCDCMDx */
++};
++
++#define MODE_MASK 0x0f
++#define MODE_TFT_GEN 0x00
++#define MODE_TFT_SHARP 0x01
++#define MODE_TFT_CASIO 0x02
++#define MODE_TFT_SAMSUNG 0x03
++#define MODE_CCIR656_NONINT 0x04
++#define MODE_CCIR656_INT 0x05
++#define MODE_STN_COLOR_SINGLE 0x08
++#define MODE_STN_MONO_SINGLE 0x09
++#define MODE_STN_COLOR_DUAL 0x0a
++#define MODE_STN_MONO_DUAL 0x0b
++#define MODE_8BIT_SERIAL_TFT 0x0c
++
++#define MODE_TFT_18BIT (1<<7)
++
++#define STN_DAT_PIN1 (0x00 << 4)
++#define STN_DAT_PIN2 (0x01 << 4)
++#define STN_DAT_PIN4 (0x02 << 4)
++#define STN_DAT_PIN8 (0x03 << 4)
++#define STN_DAT_PINMASK STN_DAT_PIN8
++
++#define STFT_PSHI (1 << 15)
++#define STFT_CLSHI (1 << 14)
++#define STFT_SPLHI (1 << 13)
++#define STFT_REVHI (1 << 12)
++
++#define SYNC_MASTER (0 << 16)
++#define SYNC_SLAVE (1 << 16)
++
++#define DE_P (0 << 9)
++#define DE_N (1 << 9)
++
++#define PCLK_P (0 << 10)
++#define PCLK_N (1 << 10)
++
++#define HSYNC_P (0 << 11)
++#define HSYNC_N (1 << 11)
++
++#define VSYNC_P (0 << 8)
++#define VSYNC_N (1 << 8)
++
++#define DATA_NORMAL (0 << 17)
++#define DATA_INVERSE (1 << 17)
++
++
++/* Jz LCDFB supported I/O controls. */
++#define FBIOSETBACKLIGHT 0x4688
++#define FBIODISPON 0x4689
++#define FBIODISPOFF 0x468a
++#define FBIORESET 0x468b
++#define FBIOPRINT_REG 0x468c
++
++/*
++ * LCD panel specific definition
++ */
++#define MODE (0xc9) /* 8bit serial RGB */
++
++#define __spi_write_reg1(reg, val) \
++do { \
++ unsigned char no; \
++ unsigned short value; \
++ unsigned char a=reg; \
++ unsigned char b=val; \
++ __gpio_set_pin(SPEN); \
++ __gpio_set_pin(SPCK); \
++ __gpio_clear_pin(SPDA); \
++ __gpio_clear_pin(SPEN); \
++ value=((a<<8)|(b&0xFF)); \
++ for(no=0;no<16;no++) \
++ { \
++ __gpio_clear_pin(SPCK); \
++ if((value&0x8000)==0x8000) \
++ __gpio_set_pin(SPDA); \
++ else \
++ __gpio_clear_pin(SPDA); \
++ __gpio_set_pin(SPCK); \
++ value=(value<<1); \
++ } \
++ __gpio_set_pin(SPEN); \
++} while (0)
++
++#define __lcd_display_pin_init() \
++do { \
++ __cpm_start_tcu(); \
++ __gpio_as_output(SPEN); /* use SPDA */ \
++ __gpio_as_output(SPCK); /* use SPCK */ \
++ __gpio_as_output(SPDA); /* use SPDA */ \
++} while (0)
++
++#define __lcd_display_on() \
++do { \
++ __spi_write_reg1(0x05, 0x1e); \
++ __spi_write_reg1(0x05, 0x5e); \
++ __spi_write_reg1(0x07, 0x8d); \
++ __spi_write_reg1(0x13, 0x01); \
++ __spi_write_reg1(0x05, 0x5f); \
++} while (0)
++
++#define __lcd_display_off() \
++do { \
++ __spi_write_reg1(0x05, 0x5e); \
++} while (0)
++
++#endif /* __QI_LB60_GPM940B0_H__ */
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index 52b370c..d3e78ad 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -32,6 +32,13 @@
+ * Miscellaneous configurable options
+ */
+ #define CONFIG_NANONOTE
++
++#define CONFIG_LCD
++#define CONFIG_SYS_WHITE_ON_BLACK
++#define LCD_BPP LCD_COLOR32
++#define CONFIG_VIDEO_GPM940B0
++
++
+ #define CONFIG_JZ4740_MMC
+ #define CONFIG_MMC 1
+ #define CONFIG_FAT 1
+diff --git a/include/lcd.h b/include/lcd.h
+index 42070d7..6de5482 100644
+--- a/include/lcd.h
++++ b/include/lcd.h
+@@ -263,8 +263,44 @@ typedef struct vidinfo {
+
+ void init_panel_info(vidinfo_t *vid);
+
+-#else
++#elif defined(CONFIG_JZSOC)
++/*
++ * LCD controller stucture for JZSOC: JZ4740
++ */
++struct jz_fb_dma_descriptor {
++ u_long fdadr; /* Frame descriptor address register */
++ u_long fsadr; /* Frame source address register */
++ u_long fidr; /* Frame ID register */
++ u_long ldcmd; /* Command register */
++};
++
++/*
++ * Jz LCD info
++ */
++struct jz_fb_info {
++
++ u_long fdadr0; /* physical address of frame/palette descriptor */
++ u_long fdadr1; /* physical address of frame descriptor */
++
++ /* DMA descriptors */
++ struct jz_fb_dma_descriptor * dmadesc_fblow;
++ struct jz_fb_dma_descriptor * dmadesc_fbhigh;
++ struct jz_fb_dma_descriptor * dmadesc_palette;
++ u_long screen; /* address of frame buffer */
++ u_long palette; /* address of palette memory */
++ u_int palette_size;
++};
++typedef struct vidinfo {
++ ushort vl_col; /* Number of columns (i.e. 640) */
++ ushort vl_row; /* Number of rows (i.e. 480) */
++ u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8 */
++
++ struct jz_fb_info jz_fb;
++} vidinfo_t;
++
++extern vidinfo_t panel_info;
+
++#else
+ typedef struct vidinfo {
+ ushort vl_col; /* Number of columns (i.e. 160) */
+ ushort vl_row; /* Number of rows (i.e. 100) */
+@@ -318,6 +354,7 @@ void lcd_show_board_info(void);
+ #define LCD_COLOR4 2
+ #define LCD_COLOR8 3
+ #define LCD_COLOR16 4
++#define LCD_COLOR32 5
+
+ /*----------------------------------------------------------------------*/
+ #if defined(CONFIG_LCD_INFO_BELOW_LOGO)
+@@ -369,7 +406,7 @@ void lcd_show_board_info(void);
+ # define CONSOLE_COLOR_GREY 14
+ # define CONSOLE_COLOR_WHITE 15 /* Must remain last / highest */
+
+-#else
++#elif LCD_BPP == LCD_COLOR16
+
+ /*
+ * 16bpp color definitions
+@@ -377,6 +414,15 @@ void lcd_show_board_info(void);
+ # define CONSOLE_COLOR_BLACK 0x0000
+ # define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */
+
++#elif LCD_BPP == LCD_COLOR32
++/*
++ * 18,24,32 bpp color definitions
++ */
++# define CONSOLE_COLOR_BLACK 0x00000000
++# define CONSOLE_COLOR_WHITE 0xffffffff /* Must remain last / highest */
++
++#else
++
+ #endif /* color definitions */
+
+ /************************************************************************/
+@@ -406,7 +452,7 @@ void lcd_show_board_info(void);
+ #if LCD_BPP == LCD_MONOCHROME
+ # define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \
+ (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
+-#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16)
++#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || (LCD_BPP == LCD_COLOR32)
+ # define COLOR_MASK(c) (c)
+ #else
+ # error Unsupported LCD BPP.
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0006-enable-silent-console.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0006-enable-silent-console.patch.svn-base
new file mode 100644
index 0000000..ebd6a6a
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/.svn/text-base/0006-enable-silent-console.patch.svn-base
@@ -0,0 +1,60 @@
+From 5eb4d4c598f2806bd1b3d1140e917bfead7851ad Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Wed, 10 Oct 2012 23:51:26 +0800
+Subject: [PATCH 6/6] enable silent console
+
+---
+ common/console.c | 16 ++++++++++++++++
+ include/configs/qi_lb60.h | 2 ++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/common/console.c b/common/console.c
+index 1177f7d..e8a2078 100644
+--- a/common/console.c
++++ b/common/console.c
+@@ -685,6 +685,14 @@ done:
+
+ gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+
++#ifdef CONFIG_SILENT_CONSOLE
++ /* Check one more time the contents of the silent environment
++ * variable, because if the environment is loaded from NAND it was
++ * not available when console_init_f() was called */
++ if (getenv("silent") != NULL)
++ gd->flags |= GD_FLG_SILENT;
++#endif
++
+ stdio_print_current_devices();
+
+ #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
+@@ -760,6 +768,14 @@ int console_init_r(void)
+
+ gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+
++#ifdef CONFIG_SILENT_CONSOLE
++ /* Check one more time the contents of the silent environment
++ * variable, because if the environment is loaded from NAND it was
++ * not available when console_init_f() was called */
++ if (getenv("silent") != NULL)
++ gd->flags |= GD_FLG_SILENT;
++#endif
++
+ stdio_print_current_devices();
+
+ /* Setting environment variables */
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index d3e78ad..a3534ff 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -102,6 +102,8 @@
+ #define CONFIG_SYS_NO_FLASH
+ #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */
+
++#define CONFIG_SILENT_CONSOLE 1 /* Enable silent console */
++
+ /*
+ * Command line configuration
+ */
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch b/package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch
new file mode 100644
index 0000000..e770243
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch
@@ -0,0 +1,894 @@
+From 0329cf7965956a5a7044827e0ce88ae8d5150e54 Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Fri, 12 Oct 2012 09:46:58 +0800
+Subject: [PATCH 1/6] qi_lb60: add nand spl support
+
+ The JZ4740 CPU can load 8KB from two different addresses:
+ 1. the normal area up to 8KB starting from NAND flash address 0x00000000
+ 2. the backup area up to 8KB starting from NAND flash address 0x00002000
+
+Signed-off-by: Xiangfu <xiangfu@openmobilefree.net>
+---
+ Makefile | 12 +++
+ arch/mips/cpu/xburst/Makefile | 7 +-
+ arch/mips/cpu/xburst/cpu.c | 4 +
+ arch/mips/cpu/xburst/jz4740.c | 82 +++++++----------
+ arch/mips/cpu/xburst/spl/Makefile | 47 ++++++++++
+ arch/mips/cpu/xburst/spl/start.S | 63 +++++++++++++
+ board/qi/qi_lb60/Makefile | 4 +
+ board/qi/qi_lb60/qi_lb60-spl.c | 30 +++++++
+ board/qi/qi_lb60/qi_lb60.c | 8 +-
+ board/qi/qi_lb60/u-boot-spl.lds | 61 +++++++++++++
+ drivers/mtd/nand/jz4740_nand.c | 39 ++++++++-
+ include/configs/qi_lb60.h | 175 ++++++++++++++++++-------------------
+ 12 files changed, 386 insertions(+), 146 deletions(-)
+ create mode 100644 arch/mips/cpu/xburst/spl/Makefile
+ create mode 100644 arch/mips/cpu/xburst/spl/start.S
+ create mode 100644 board/qi/qi_lb60/qi_lb60-spl.c
+ create mode 100644 board/qi/qi_lb60/u-boot-spl.lds
+
+diff --git a/Makefile b/Makefile
+index 34d9075..a22778e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -393,6 +393,10 @@ ALL-y += $(obj)u-boot-nodtb-tegra.bin
+ endif
+ endif
+
++ifeq ($(CPU),xburst)
++ALL-y += $(obj)u-boot-xburst.bin
++endif
++
+ all: $(ALL-y) $(SUBDIR_EXAMPLES)
+
+ $(obj)u-boot.dtb: $(obj)u-boot
+@@ -506,6 +510,14 @@ $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
+ endif
+ endif
+
++ifeq ($(CPU),xburst)
++$(obj)u-boot-xburst.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
++ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync bs=8192 count=1
++ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=8192 count=1
++ tr '\0' '\377' < /dev/zero | dd of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=16384 count=1
++ cat $(obj)spl/u-boot-pad.bin u-boot.bin > $@
++endif
++
+ ifeq ($(CONFIG_SANDBOX),y)
+ GEN_UBOOT = \
+ cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
+diff --git a/arch/mips/cpu/xburst/Makefile b/arch/mips/cpu/xburst/Makefile
+index b1f2ae4..ec35e55 100644
+--- a/arch/mips/cpu/xburst/Makefile
++++ b/arch/mips/cpu/xburst/Makefile
+@@ -24,9 +24,12 @@ include $(TOPDIR)/config.mk
+
+ LIB = $(obj)lib$(CPU).o
+
++COBJS-y = cpu.o jz_serial.o
++
++ifneq ($(CONFIG_SPL_BUILD),y)
+ START = start.o
+-SOBJS-y =
+-COBJS-y = cpu.o timer.o jz_serial.o
++COBJS-y += timer.o
++endif
+
+ COBJS-$(CONFIG_JZ4740) += jz4740.o
+
+diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c
+index ddcbfaa..1432838 100644
+--- a/arch/mips/cpu/xburst/cpu.c
++++ b/arch/mips/cpu/xburst/cpu.c
+@@ -42,6 +42,8 @@
+ : \
+ : "i" (op), "R" (*(unsigned char *)(addr)))
+
++#ifndef CONFIG_SPL_BUILD
++
+ void __attribute__((weak)) _machine_restart(void)
+ {
+ struct jz4740_wdt *wdt = (struct jz4740_wdt *)JZ4740_WDT_BASE;
+@@ -109,6 +111,8 @@ void invalidate_dcache_range(ulong start_addr, ulong stop)
+ cache_op(Hit_Invalidate_D, addr);
+ }
+
++#endif
++
+ void flush_icache_all(void)
+ {
+ u32 addr, t = 0;
+diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c
+index c0b9817..8816aa3 100644
+--- a/arch/mips/cpu/xburst/jz4740.c
++++ b/arch/mips/cpu/xburst/jz4740.c
+@@ -32,31 +32,19 @@ int disable_interrupts(void)
+ return 0;
+ }
+
+-/*
+- * PLL output clock = EXTAL * NF / (NR * NO)
+- * NF = FD + 2, NR = RD + 2
+- * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
+- */
+ void pll_init(void)
+ {
+ struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE;
+
+- register unsigned int cfcr, plcr1;
+- int n2FR[33] = {
+- 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
+- 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
+- 9
+- };
+- int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
+- int nf, pllout2;
++ register unsigned int cfcr, plcr;
++ unsigned int nf, pllout2;
+
+ cfcr = CPM_CPCCR_CLKOEN |
+- CPM_CPCCR_PCS |
+- (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
+- (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
+- (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
+- (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
+- (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
++ (0 << CPM_CPCCR_CDIV_BIT) |
++ (2 << CPM_CPCCR_HDIV_BIT) |
++ (2 << CPM_CPCCR_PDIV_BIT) |
++ (2 << CPM_CPCCR_MDIV_BIT) |
++ (2 << CPM_CPCCR_LDIV_BIT);
+
+ pllout2 = (cfcr & CPM_CPCCR_PCS) ?
+ CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2);
+@@ -65,15 +53,18 @@ void pll_init(void)
+ writel(pllout2 / 48000000 - 1, &cpm->uhccdr);
+
+ nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL;
+- plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
++ plcr = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
+ (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
+ (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
+- (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
++ (0x32 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
+ CPM_CPPCR_PLLEN; /* enable PLL */
+
+ /* init PLL */
+ writel(cfcr, &cpm->cpccr);
+- writel(plcr1, &cpm->cppcr);
++ writel(plcr, &cpm->cppcr);
++
++ while (!(readl(&cpm->cppcr) & CPM_CPPCR_PLLS))
++ ;
+ }
+
+ void sdram_init(void)
+@@ -92,26 +83,12 @@ void sdram_init(void)
+ 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
+ };
+
+- int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
+-
+ cpu_clk = CONFIG_SYS_CPU_SPEED;
+- mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
++ mem_clk = 84000000;
+
+ writel(0, &emc->bcr); /* Disable bus release */
+ writew(0, &emc->rtcsr); /* Disable clock for counting */
+
+- /* Fault DMCR value for mode register setting*/
+-#define SDRAM_ROW0 11
+-#define SDRAM_COL0 8
+-#define SDRAM_BANK40 0
+-
+- dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) |
+- ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) |
+- (SDRAM_BANK40 << EMC_DMCR_BA_BIT) |
+- (SDRAM_BW16 << EMC_DMCR_BW_BIT) |
+- EMC_DMCR_EPIN |
+- cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
+-
+ /* Basic DMCR value */
+ dmcr = ((SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) |
+ ((SDRAM_COL - 8) << EMC_DMCR_CA_BIT) |
+@@ -128,31 +105,31 @@ void sdram_init(void)
+ if (tmp > 11)
+ tmp = 11;
+ dmcr |= (tmp - 4) << EMC_DMCR_TRAS_BIT;
+- tmp = SDRAM_RCD / ns;
+
++ tmp = SDRAM_RCD / ns;
+ if (tmp > 3)
+ tmp = 3;
+ dmcr |= tmp << EMC_DMCR_RCD_BIT;
+- tmp = SDRAM_TPC / ns;
+
++ tmp = SDRAM_TPC / ns;
+ if (tmp > 7)
+ tmp = 7;
+ dmcr |= tmp << EMC_DMCR_TPC_BIT;
+- tmp = SDRAM_TRWL / ns;
+
++ tmp = SDRAM_TRWL / ns;
+ if (tmp > 3)
+ tmp = 3;
+ dmcr |= tmp << EMC_DMCR_TRWL_BIT;
+- tmp = (SDRAM_TRAS + SDRAM_TPC) / ns;
+
++ tmp = (SDRAM_TRAS + SDRAM_TPC) / ns;
+ if (tmp > 14)
+ tmp = 14;
+ dmcr |= ((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT;
+
+ /* SDRAM mode value */
+- sdmode = EMC_SDMR_BT_SEQ |
+- EMC_SDMR_OM_NORMAL |
+- EMC_SDMR_BL_4 |
++ sdmode = EMC_SDMR_BT_SEQ |
++ EMC_SDMR_OM_NORMAL |
++ EMC_SDMR_BL_4 |
+ cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
+
+ /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
+@@ -172,8 +149,8 @@ void sdram_init(void)
+ if (tmp > 0xff)
+ tmp = 0xff;
+ writew(tmp, &emc->rtcor);
++
+ writew(0, &emc->rtcnt);
+- /* Divisor is 64, CKO/64 */
+ writew(EMC_RTCSR_CKS_64, &emc->rtcsr);
+
+ /* Wait for number of auto-refresh cycles */
+@@ -182,13 +159,17 @@ void sdram_init(void)
+ ;
+
+ /* Stage 3. Mode Register Set */
++ dmcr0 = (11 << EMC_DMCR_RA_BIT) |
++ (8 << EMC_DMCR_CA_BIT) |
++ (0 << EMC_DMCR_BA_BIT) |
++ EMC_DMCR_EPIN |
++ (SDRAM_BW16 << EMC_DMCR_BW_BIT) |
++ cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
+ writel(dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr);
+ writeb(0, JZ4740_EMC_SDMR0 | sdmode);
+
+ /* Set back to basic DMCR value */
+ writel(dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr);
+-
+- /* everything is ok now */
+ }
+
+ DECLARE_GLOBAL_DATA_PTR;
+@@ -232,9 +213,10 @@ void rtc_init(void)
+ phys_size_t initdram(int board_type)
+ {
+ struct jz4740_emc *emc = (struct jz4740_emc *)JZ4740_EMC_BASE;
+- u32 dmcr;
+- u32 rows, cols, dw, banks;
+- ulong size;
++
++ unsigned int dmcr;
++ unsigned int rows, cols, dw, banks;
++ unsigned long size;
+
+ dmcr = readl(&emc->dmcr);
+ rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT);
+diff --git a/arch/mips/cpu/xburst/spl/Makefile b/arch/mips/cpu/xburst/spl/Makefile
+new file mode 100644
+index 0000000..f45e8c8
+--- /dev/null
++++ b/arch/mips/cpu/xburst/spl/Makefile
+@@ -0,0 +1,47 @@
++#
++# Copyright (C) 2011 Xiangfu Liu <xiangfu@openmobilefree.net>
++#
++# See file CREDITS for list of people who contributed to this
++# project.
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of the GNU General Public License as
++# published by the Free Software Foundation; either version 2 of
++# the License, or (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++# MA 02111-1307 USA
++#
++
++include $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(CPU).o
++
++START = start.o
++SOBJS-y =
++COBJS-y =
++
++SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
++OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
++START := $(addprefix $(obj),$(START))
++
++all: $(obj).depend $(START) $(LIB)
++
++$(LIB): $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+diff --git a/arch/mips/cpu/xburst/spl/start.S b/arch/mips/cpu/xburst/spl/start.S
+new file mode 100644
+index 0000000..e31c4c8
+--- /dev/null
++++ b/arch/mips/cpu/xburst/spl/start.S
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (c) 2010 Xiangfu Liu <xiangfu@openmobilefree.net>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 3 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <version.h>
++#include <asm/regdef.h>
++#include <asm/mipsregs.h>
++#include <asm/addrspace.h>
++#include <asm/cacheops.h>
++
++#include <asm/jz4740.h>
++
++ .set noreorder
++
++ .globl _start
++ .text
++_start:
++ .word JZ4740_NANDBOOT_CFG /* fetched during NAND Boot */
++reset:
++ /*
++ * STATUS register
++ * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
++ */
++ li t0, 0x0040FC04
++ mtc0 t0, CP0_STATUS
++ /*
++ * CAUSE register
++ * IV=1, use the specical interrupt vector (0x200)
++ */
++ li t1, 0x00800000
++ mtc0 t1, CP0_CAUSE
++
++ bal 1f
++ nop
++ .word _GLOBAL_OFFSET_TABLE_
++1:
++ move gp, ra
++ lw t1, 0(ra)
++ move gp, t1
++
++ la sp, 0x80004000
++ la t9, nand_spl_boot
++ j t9
++ nop
+diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile
+index 5dae11b..e399246 100644
+--- a/board/qi/qi_lb60/Makefile
++++ b/board/qi/qi_lb60/Makefile
+@@ -22,7 +22,11 @@ include $(TOPDIR)/config.mk
+
+ LIB = $(obj)lib$(BOARD).o
+
++ifeq ($(CONFIG_SPL_BUILD),y)
++COBJS := $(BOARD)-spl.o
++else
+ COBJS := $(BOARD).o
++endif
+
+ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c
+new file mode 100644
+index 0000000..3fe3fa3
+--- /dev/null
++++ b/board/qi/qi_lb60/qi_lb60-spl.c
+@@ -0,0 +1,30 @@
++/*
++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.cc>
++ *
++ * 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
++ * 3 of the License, or (at your option) any later version.
++ */
++
++#include <common.h>
++#include <nand.h>
++#include <asm/io.h>
++#include <asm/jz4740.h>
++
++void nand_spl_boot(void)
++{
++ __gpio_as_sdram_16bit_4720();
++ __gpio_as_uart0();
++ __gpio_jtag_to_uart0();
++
++ serial_init();
++
++ pll_init();
++ sdram_init();
++
++ nand_init();
++
++ puts("\nQi LB60 SPL: Starting U-Boot ...\n");
++ nand_boot();
++}
+diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
+index d975209..3bd4e2f 100644
+--- a/board/qi/qi_lb60/qi_lb60.c
++++ b/board/qi/qi_lb60/qi_lb60.c
+@@ -1,5 +1,5 @@
+ /*
+- * Authors: Xiangfu Liu <xiangfu@sharism.cc>
++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+@@ -97,8 +97,10 @@ int board_early_init_f(void)
+ /* U-Boot common routines */
+ int checkboard(void)
+ {
+- printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC, Speed %ld MHz)\n",
+- gd->cpu_clk / 1000000);
++ printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC)\n");
++ printf(" CPU: %ld\n", gd->cpu_clk);
++ printf(" MEM: %ld\n", gd->mem_clk);
++ printf(" DEV: %ld\n", gd->dev_clk);
+
+ return 0;
+ }
+diff --git a/board/qi/qi_lb60/u-boot-spl.lds b/board/qi/qi_lb60/u-boot-spl.lds
+new file mode 100644
+index 0000000..930537f
+--- /dev/null
++++ b/board/qi/qi_lb60/u-boot-spl.lds
+@@ -0,0 +1,61 @@
++/*
++ * (C) Copyright 2012 Xiangfu Liu <xiangfu@openmobilefree.net>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
++
++OUTPUT_ARCH(mips)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x80000000;
++ . = ALIGN(4);
++ .text :
++ {
++ *(.text)
++ }
++
++ . = ALIGN(4);
++ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
++
++ . = ALIGN(4);
++ .data : { *(.data) }
++
++ . = ALIGN(4);
++ .sdata : { *(.sdata) }
++
++ _gp = ALIGN(16);
++
++ __got_start = .;
++ .got : { *(.got) }
++ __got_end = .;
++
++ . = .;
++ __u_boot_cmd_start = .;
++ .u_boot_cmd : { *(.u_boot_cmd) }
++ __u_boot_cmd_end = .;
++
++ uboot_end_data = .;
++ num_got_entries = (__got_end - __got_start) >> 2;
++
++ . = ALIGN(4);
++ .sbss : { *(.sbss) }
++ .bss : { *(.bss) }
++ uboot_end = .;
++}
++ASSERT(uboot_end <= 0x80002000, "NAND bootstrap too big");
+diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
+index 3ec34f3..24a4921 100644
+--- a/drivers/mtd/nand/jz4740_nand.c
++++ b/drivers/mtd/nand/jz4740_nand.c
+@@ -15,6 +15,9 @@
+ #include <asm/io.h>
+ #include <asm/jz4740.h>
+
++#ifdef CONFIG_SPL_BUILD
++#define printf(s) puts(s)
++#endif
+ #define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000)
+ #define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000)
+ #define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000)
+@@ -176,7 +179,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+ for (k = 0; k < 9; k++)
+ writeb(read_ecc[k], &emc->nfpar[k]);
+ }
+- /* Set PRDY */
++
+ writel(readl(&emc->nfecr) | EMC_NFECR_PRDY, &emc->nfecr);
+
+ /* Wait for completion */
+@@ -184,7 +187,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+ status = readl(&emc->nfints);
+ } while (!(status & EMC_NFINTS_DECF));
+
+- /* disable ecc */
++ /* Disable ECC */
+ writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr);
+
+ /* Check decoding */
+@@ -192,7 +195,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+ return 0;
+
+ if (status & EMC_NFINTS_UNCOR) {
+- printf("uncorrectable ecc\n");
++ printf("JZ4740 uncorrectable ECC\n");
+ return -1;
+ }
+
+@@ -230,6 +233,32 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+ return errcnt;
+ }
+
++#ifdef CONFIG_SPL_BUILD
++static void jz_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
++{
++ int i;
++ struct nand_chip *this = mtd->priv;
++
++#if (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R3) || \
++ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R2)
++ for (i = 0; i < len; i += 2)
++ buf[i] = readw(this->IO_ADDR_R);
++#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R3) || \
++ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R2)
++ for (i = 0; i < len; i++)
++ buf[i] = readb(this->IO_ADDR_R);
++#else
++ #error JZ4740_NANDBOOT_CFG not defined or wrong
++#endif
++}
++
++static uint8_t jz_nand_read_byte(struct mtd_info *mtd)
++{
++ struct nand_chip *this = mtd->priv;
++ return readb(this->IO_ADDR_R);
++}
++#endif
++
+ /*
+ * Main initialization routine
+ */
+@@ -254,6 +283,10 @@ int board_nand_init(struct nand_chip *nand)
+ nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
+ nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
+ nand->ecc.layout = &qi_lb60_ecclayout_2gb;
++#ifdef CONFIG_SPL_BUILD
++ nand->read_byte = jz_nand_read_byte;
++ nand->read_buf = jz_nand_read_buf;
++#endif
+ nand->chip_delay = 50;
+ nand->options = NAND_USE_FLASH_BBT;
+
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index 4bb5bbc..7bff444 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -1,5 +1,5 @@
+ /*
+- * Authors: Xiangfu Liu <xiangfu.z@gmail.com>
++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+@@ -14,7 +14,6 @@
+ #define CONFIG_SYS_LITTLE_ENDIAN
+ #define CONFIG_JZSOC /* Jz SoC */
+ #define CONFIG_JZ4740 /* Jz4740 SoC */
+-#define CONFIG_NAND_JZ4740
+
+ #define CONFIG_SYS_CPU_SPEED 336000000 /* CPU clock: 336 MHz */
+ #define CONFIG_SYS_EXTAL 12000000 /* EXTAL freq: 12 MHz */
+@@ -24,24 +23,43 @@
+ #define CONFIG_SYS_UART_BASE JZ4740_UART0_BASE /* Base of the UART channel */
+ #define CONFIG_BAUDRATE 57600
+
++#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL)
++#define CONFIG_BOOTDELAY 0
++#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
++#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x280000;bootm"
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
++#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
++#define CONFIG_SYS_LOAD_ADDR 0x80600000
++#define CONFIG_SYS_MEMTEST_START 0x80100000
++#define CONFIG_SYS_MEMTEST_END 0x80A00000
++#define CONFIG_SYS_TEXT_BASE 0x80100000
++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
++
++#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024)
++#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)
++
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
++
++#define CONFIG_SYS_LONGHELP
++#define CONFIG_SYS_MAXARGS 16
++#define CONFIG_SYS_PROMPT "NanoNote# "
++
+ #define CONFIG_SKIP_LOWLEVEL_INIT
+ #define CONFIG_BOARD_EARLY_INIT_F
+ #define CONFIG_SYS_NO_FLASH
+ #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */
+-#define CONFIG_ENV_OVERWRITE
+-
+-#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL)
+-#define CONFIG_BOOTDELAY 0
+-#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
+-#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x200000;bootm"
+
+ /*
+- * Command line configuration.
++ * Command line configuration
+ */
+ #define CONFIG_CMD_BOOTD /* bootd */
+ #define CONFIG_CMD_CONSOLE /* coninfo */
+ #define CONFIG_CMD_ECHO /* echo arguments */
+-
+ #define CONFIG_CMD_LOADB /* loadb */
+ #define CONFIG_CMD_LOADS /* loads */
+ #define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop mtest */
+@@ -58,45 +76,16 @@
+ #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
+
+ /*
+- * Miscellaneous configurable options
+- */
+-#define CONFIG_SYS_MAXARGS 16
+-#define CONFIG_SYS_LONGHELP
+-#define CONFIG_SYS_PROMPT "NanoNote# "
+-#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
+-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+-
+-#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024)
+-#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)
+-
+-#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
+-#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
+-#define CONFIG_SYS_LOAD_ADDR 0x80600000
+-#define CONFIG_SYS_MEMTEST_START 0x80100000
+-#define CONFIG_SYS_MEMTEST_END 0x80800000
+-
+-/*
+- * Environment
++ * NAND driver configuration
+ */
+-#define CONFIG_ENV_IS_IN_NAND /* use NAND for environment vars */
+-
+-#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+-/*
+- * if board nand flash is 1GB, set to 1
+- * if board nand flash is 2GB, set to 2
+- * for change the PAGE_SIZE and BLOCK_SIZE
+- * will delete when there is no 1GB flash
+- */
+-#define NANONOTE_NAND_SIZE 2
+-
+-#define CONFIG_SYS_NAND_PAGE_SIZE (2048 * NANONOTE_NAND_SIZE)
+-#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * NANONOTE_NAND_SIZE << 10)
+-/* nand bad block was marked at this page in a block, start from 0 */
++#define CONFIG_NAND_JZ4740
++#define CONFIG_SYS_NAND_PAGE_SIZE 4096
++#define CONFIG_SYS_NAND_BLOCK_SIZE (512 << 10)
++/* NAND bad block was marked at this page in a block, start from 0 */
+ #define CONFIG_SYS_NAND_BADBLOCK_PAGE 127
+ #define CONFIG_SYS_NAND_PAGE_COUNT 128
+ #define CONFIG_SYS_NAND_BAD_BLOCK_POS 0
+-/* ECC offset position in oob area, default value is 6 if it isn't defined */
+-#define CONFIG_SYS_NAND_ECC_POS (6 * NANONOTE_NAND_SIZE)
++#define CONFIG_SYS_NAND_ECC_POS 12
+ #define CONFIG_SYS_NAND_ECCSIZE 512
+ #define CONFIG_SYS_NAND_ECCBYTES 9
+ #define CONFIG_SYS_NAND_ECCPOS \
+@@ -115,10 +104,9 @@
+ #define CONFIG_SYS_ONENAND_BASE CONFIG_SYS_NAND_BASE
+ #define CONFIG_SYS_MAX_NAND_DEVICE 1
+ #define CONFIG_SYS_NAND_SELECT_DEVICE 1 /* nand driver supports mutipl.*/
+-#define CONFIG_NAND_SPL_TEXT_BASE 0x80000000
+
+ /*
+- * IPL (Initial Program Loader, integrated inside CPU)
++ * IPL (Initial Program Loader, integrated inside Ingenic Xburst JZ4740 CPU)
+ * Will load first 8k from NAND (SPL) into cache and execute it from there.
+ *
+ * SPL (Secondary Program Loader)
+@@ -130,77 +118,88 @@
+ * NUB (NAND U-Boot)
+ * This NAND U-Boot (NUB) is a special U-Boot version which can be started
+ * from RAM. Therefore it mustn't (re-)configure the SDRAM controller.
+- *
+ */
++
++/*
++ * NAND SPL configuration
++ */
++#define CONFIG_SPL
++#define CONFIG_SPL_LIBGENERIC_SUPPORT
++#define CONFIG_SPL_LIBCOMMON_SUPPORT
++#define CONFIG_SPL_NAND_LOAD
++#define CONFIG_SPL_NAND_SIMPLE
++#define CONFIG_SPL_NAND_SUPPORT
++#define CONFIG_SPL_TEXT_BASE 0x80000000
++#define CONFIG_SPL_START_S_PATH "arch/mips/cpu/xburst/spl"
++
++#define CONFIG_SYS_NAND_5_ADDR_CYCLE
++#define CONFIG_SYS_NAND_HW_ECC_OOBFIRST
++#define JZ4740_NANDBOOT_CFG JZ4740_NANDBOOT_B8R3
++
+ #define CONFIG_SYS_NAND_U_BOOT_DST 0x80100000 /* Load NUB to this addr */
+ #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST
+-/* Start NUB from this addr*/
++ /* Start NUB from this addr */
++#define CONFIG_SYS_NAND_U_BOOT_OFFS (32 << 10) /* Offset of NUB */
++#define CONFIG_SYS_NAND_U_BOOT_SIZE (256 << 10) /* Size of NUB */
+
+ /*
+- * Define the partitioning of the NAND chip (only RAM U-Boot is needed here)
++ * Environment configuration
+ */
+-#define CONFIG_SYS_NAND_U_BOOT_OFFS (256 << 10) /* Offset to RAM U-Boot image */
+-#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 << 10) /* Size of RAM U-Boot image */
+-
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_IS_IN_NAND
+ #define CONFIG_ENV_SIZE (4 << 10)
+ #define CONFIG_ENV_OFFSET \
+ (CONFIG_SYS_NAND_BLOCK_SIZE + CONFIG_SYS_NAND_U_BOOT_SIZE)
+ #define CONFIG_ENV_OFFSET_REDUND \
+ (CONFIG_ENV_OFFSET + CONFIG_SYS_NAND_BLOCK_SIZE)
+
+-#define CONFIG_SYS_TEXT_BASE 0x80100000
+-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+-
+ /*
+- * SDRAM Info.
++ * CPU cache configuration
+ */
+-#define CONFIG_NR_DRAM_BANKS 1
++#define CONFIG_SYS_DCACHE_SIZE 16384
++#define CONFIG_SYS_ICACHE_SIZE 16384
++#define CONFIG_SYS_CACHELINE_SIZE 32
+
+ /*
+- * Cache Configuration
++ * SDRAM configuration
+ */
+-#define CONFIG_SYS_DCACHE_SIZE 16384
+-#define CONFIG_SYS_ICACHE_SIZE 16384
+-#define CONFIG_SYS_CACHELINE_SIZE 32
++#define CONFIG_NR_DRAM_BANKS 1
++
++#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */
++#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
++#define SDRAM_ROW 13 /* Row address: 11 to 13 */
++#define SDRAM_COL 9 /* Column address: 8 to 12 */
++#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */
++#define SDRAM_TRAS 45 /* RAS# Active Time */
++#define SDRAM_RCD 20 /* RAS# to CAS# Delay */
++#define SDRAM_TPC 20 /* RAS# Precharge Time */
++#define SDRAM_TRWL 7 /* Write Latency Time */
++#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */
+
+ /*
+- * GPIO definition
++ * GPIO configuration
+ */
+-#define GPIO_LCD_CS (2 * 32 + 21)
+-#define GPIO_AMP_EN (3 * 32 + 4)
++#define GPIO_LCD_CS (2 * 32 + 21)
++#define GPIO_AMP_EN (3 * 32 + 4)
+
+-#define GPIO_SDPW_EN (3 * 32 + 2)
+-#define GPIO_SD_DETECT (3 * 32 + 0)
++#define GPIO_SDPW_EN (3 * 32 + 2)
++#define GPIO_SD_DETECT (3 * 32 + 0)
+
+-#define GPIO_BUZZ_PWM (3 * 32 + 27)
+-#define GPIO_USB_DETECT (3 * 32 + 28)
++#define GPIO_BUZZ_PWM (3 * 32 + 27)
++#define GPIO_USB_DETECT (3 * 32 + 28)
+
+-#define GPIO_AUDIO_POP (1 * 32 + 29)
+-#define GPIO_COB_TEST (1 * 32 + 30)
++#define GPIO_AUDIO_POP (1 * 32 + 29)
++#define GPIO_COB_TEST (1 * 32 + 30)
+
+ #define GPIO_KEYOUT_BASE (2 * 32 + 10)
+-#define GPIO_KEYIN_BASE (3 * 32 + 18)
+-#define GPIO_KEYIN_8 (3 * 32 + 26)
++#define GPIO_KEYIN_BASE (3 * 32 + 18)
++#define GPIO_KEYIN_8 (3 * 32 + 26)
+
+-#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */
++#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */
+ #define GPIO_SD_VCC_EN_N GPIO_SDPW_EN /* SD Card Power Enable */
+
+ #define SPEN GPIO_LCD_CS /* LCDCS :Serial command enable */
+ #define SPDA (2 * 32 + 22) /* LCDSCL:Serial command clock input */
+ #define SPCK (2 * 32 + 23) /* LCDSDA:Serial command data input */
+
+-/* SDRAM paramters */
+-#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */
+-#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
+-#define SDRAM_ROW 13 /* Row address: 11 to 13 */
+-#define SDRAM_COL 9 /* Column address: 8 to 12 */
+-#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */
+-
+-/* SDRAM Timings, unit: ns */
+-#define SDRAM_TRAS 45 /* RAS# Active Time */
+-#define SDRAM_RCD 20 /* RAS# to CAS# Delay */
+-#define SDRAM_TPC 20 /* RAS# Precharge Time */
+-#define SDRAM_TRWL 7 /* Write Latency Time */
+-#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */
+-
+ #endif
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch b/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch
new file mode 100644
index 0000000..feaf297
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch
@@ -0,0 +1,916 @@
+From fa51192b912d296b8eec10f7d44c6c17eb1dd368 Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Fri, 12 Oct 2012 09:47:39 +0800
+Subject: [PATCH 2/6] qi_lb60: add software usbboot support
+
+ JZ4740 CPU have a internal ROM have such kind of code, that make
+ JZ4740 can boot from USB
+
+ usbboot.S can downloads user program from the USB port to internal
+ SRAM and branches to the internal SRAM to execute the program
+
+Signed-off-by: Xiangfu <xiangfu@openmobilefree.net>
+---
+ board/qi/qi_lb60/Makefile | 1 +
+ board/qi/qi_lb60/qi_lb60-spl.c | 20 +
+ board/qi/qi_lb60/usbboot.S | 838 ++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 859 insertions(+)
+ create mode 100644 board/qi/qi_lb60/usbboot.S
+
+diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile
+index e399246..6dd8c6f 100644
+--- a/board/qi/qi_lb60/Makefile
++++ b/board/qi/qi_lb60/Makefile
+@@ -23,6 +23,7 @@ include $(TOPDIR)/config.mk
+ LIB = $(obj)lib$(BOARD).o
+
+ ifeq ($(CONFIG_SPL_BUILD),y)
++SOBJS := usbboot.o
+ COBJS := $(BOARD)-spl.o
+ else
+ COBJS := $(BOARD).o
+diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c
+index 3fe3fa3..aea459c 100644
+--- a/board/qi/qi_lb60/qi_lb60-spl.c
++++ b/board/qi/qi_lb60/qi_lb60-spl.c
+@@ -12,6 +12,24 @@
+ #include <asm/io.h>
+ #include <asm/jz4740.h>
+
++#define KEY_U_OUT (32 * 2 + 16)
++#define KEY_U_IN (32 * 3 + 19)
++
++extern void usb_boot(void);
++
++static void check_usb_boot(void)
++{
++ __gpio_as_input(KEY_U_IN);
++ __gpio_enable_pull(KEY_U_IN);
++ __gpio_as_output(KEY_U_OUT);
++ __gpio_clear_pin(KEY_U_OUT);
++
++ if (!__gpio_get_pin(KEY_U_IN)) {
++ puts("[U] pressed, goto USBBOOT mode\n");
++ usb_boot();
++ }
++}
++
+ void nand_spl_boot(void)
+ {
+ __gpio_as_sdram_16bit_4720();
+@@ -23,6 +41,8 @@ void nand_spl_boot(void)
+ pll_init();
+ sdram_init();
+
++ check_usb_boot();
++
+ nand_init();
+
+ puts("\nQi LB60 SPL: Starting U-Boot ...\n");
+diff --git a/board/qi/qi_lb60/usbboot.S b/board/qi/qi_lb60/usbboot.S
+new file mode 100644
+index 0000000..c872266
+--- /dev/null
++++ b/board/qi/qi_lb60/usbboot.S
+@@ -0,0 +1,838 @@
++/*
++ * for jz4740 usb boot
++ *
++ * Copyright (c) 2009 Author: <jlwei@ingenic.cn>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++ .set noreorder
++ .globl usb_boot
++ .text
++
++/*
++ * Both NAND and USB boot load data to D-Cache first, then transfer
++ * data from D-Cache to I-Cache, and jump to execute the code in I-Cache.
++ * So init caches first and then dispatch to a proper boot routine.
++ */
++
++.macro load_addr reg addr
++ li \reg, 0x80000000
++ addiu \reg, \reg, \addr
++ la $2, usbboot_begin
++ subu \reg, \reg, $2
++.endm
++
++usb_boot:
++ /* Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. */
++ la $9, 0xB0000000 /* CPCCR: Clock Control Register */
++ la $8, 0x42041110 /* I:S:M:P=1:2:2:2 */
++ sw $8, 0($9)
++
++ la $9, 0xB0000010 /* CPPCR: PLL Control Register */
++ la $8, 0x06000120 /* M=12 N=0 D=0 CLK=12*(M+2)/(N+2) */
++ sw $8, 0($9)
++
++ mtc0 $0, $26 /* CP0_ERRCTL, restore WST reset state */
++ nop
++
++ mtc0 $0, $16 /* CP0_CONFIG */
++ nop
++
++ /* Relocate code to beginning of the ram */
++
++ la $2, usbboot_begin
++ la $3, usbboot_end
++ li $4, 0x80000000
++
++1:
++ lw $5, 0($2)
++ sw $5, 0($4)
++ addiu $2, $2, 4
++ bne $2, $3, 1b
++ addiu $4, $4, 4
++
++ li $2, 0x80000000
++ ori $3, $2, 0
++ addiu $3, $3, usbboot_end
++ la $4, usbboot_begin
++ subu $3, $3, $4
++
++
++2:
++ cache 0x0, 0($2) /* Index_Invalidate_I */
++ cache 0x1, 0($2) /* Index_Writeback_Inv_D */
++ addiu $2, $2, 32
++ subu $4, $3, $2
++ bgtz $4, 2b
++ nop
++
++ load_addr $3, usb_boot_return
++
++ jr $3
++
++usbboot_begin:
++
++init_caches:
++ li $2, 3 /* cacheable for kseg0 access */
++ mtc0 $2, $16 /* CP0_CONFIG */
++ nop
++
++ li $2, 0x20000000 /* enable idx-store-data cache insn */
++ mtc0 $2, $26 /* CP0_ERRCTL */
++
++ ori $2, $28, 0 /* start address */
++ ori $3, $2, 0x3fe0 /* end address, total 16KB */
++ mtc0 $0, $28, 0 /* CP0_TAGLO */
++ mtc0 $0, $28, 1 /* CP0_DATALO */
++cache_clear_a_line:
++ cache 0x8, 0($2) /* Index_Store_Tag_I */
++ cache 0x9, 0($2) /* Index_Store_Tag_D */
++ bne $2, $3, cache_clear_a_line
++ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
++
++ ori $2, $28, 0 /* start address */
++ ori $3, $2, 0x3fe0 /* end address, total 16KB */
++ la $4, 0x1ffff000 /* physical address and 4KB page mask */
++cache_alloc_a_line:
++ and $5, $2, $4
++ ori $5, $5, 1 /* V bit of the physical tag */
++ mtc0 $5, $28, 0 /* CP0_TAGLO */
++ cache 0x8, 0($2) /* Index_Store_Tag_I */
++ cache 0x9, 0($2) /* Index_Store_Tag_D */
++ bne $2, $3, cache_alloc_a_line
++ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
++
++ nop
++ nop
++ nop
++ /*
++ * Transfer data from dcache to icache, then jump to icache.
++ * Input parameters:
++ * $19: data length in bytes
++ * $20: jump target address
++ */
++xfer_d2i:
++
++ ori $8, $20, 0
++ addu $9, $8, $19 /* total 16KB */
++
++1:
++ cache 0x0, 0($8) /* Index_Invalidate_I */
++ cache 0x1, 0($8) /* Index_Writeback_Inv_D */
++ bne $8, $9, 1b
++ addiu $8, $8, 32
++
++ /* flush write-buffer */
++ sync
++
++ /* Invalidate BTB */
++ mfc0 $8, $16, 7 /* CP0_CONFIG */
++ nop
++ ori $8, 2
++ mtc0 $8, $16, 7
++ nop
++
++ /* Overwrite config to disable ram initalisation */
++ li $2, 0xff
++ sb $2, 20($20)
++
++ jalr $20
++ nop
++
++icache_return:
++ /* User code can return to here after executing itself in
++ icache, by jumping to $31. */
++ b usb_boot_return
++ nop
++
++
++usb_boot_return:
++ /* Enable the USB PHY */
++ la $9, 0xB0000024 /* CPM_SCR */
++ lw $8, 0($9)
++ ori $8, 0x40 /* USBPHY_ENABLE */
++ sw $8, 0($9)
++
++ /* Initialize USB registers */
++ la $27, 0xb3040000 /* USB registers base address */
++
++ sb $0, 0x0b($27) /* INTRUSBE: disable common USB interrupts */
++ sh $0, 0x06($27) /* INTRINE: disable EPIN interrutps */
++ sh $0, 0x08($27) /* INTROUTE: disable EPOUT interrutps */
++
++ li $9, 0x61
++ sb $9, 0x01($27) /* POWER: HSENAB | SUSPENDM | SOFTCONN */
++
++ /* Initialize USB states */
++ li $22, 0 /* set EP0 to IDLE state */
++ li $23, 1 /* no data stage */
++
++ /* Main loop of polling the usb commands */
++usb_command_loop:
++ lbu $9, 0x0a($27) /* read INTRUSB */
++ andi $9, 0x04 /* check USB_INTR_RESET */
++ beqz $9, check_intr_ep0in
++ nop
++
++ /* 1. Handle USB reset interrupt */
++handle_reset_intr:
++ lbu $9, 0x01($27) /* read POWER */
++ andi $9, 0x10 /* test HS_MODE */
++ bnez $9, _usb_set_maxpktsize
++ li $9, 512 /* max packet size of HS mode */
++ li $9, 64 /* max packet size of FS mode */
++
++_usb_set_maxpktsize:
++ li $8, 1
++ sb $8, 0x0e($27) /* set INDEX 1 */
++
++ sh $9, 0x10($27) /* INMAXP */
++ sb $0, 0x13($27) /* INCSRH */
++ sh $9, 0x14($27) /* OUTMAXP */
++ sb $0, 0x17($27) /* OUTCSRH */
++
++_usb_flush_fifo:
++ li $8, 0x48 /* INCSR_CDT && INCSR_FF */
++ sb $8, 0x12($27) /* INCSR */
++ li $8, 0x90 /* OUTCSR_CDT && OUTCSR_FF */
++ sb $8, 0x16($27) /* OUTCSR */
++
++ li $22, 0 /* set EP0 to IDLE state */
++ li $23, 1 /* no data stage */
++
++ /* 2. Check and handle EP0 interrupt */
++check_intr_ep0in:
++ lhu $10, 0x02($27) /* read INTRIN */
++ andi $9, $10, 0x1 /* check EP0 interrupt */
++ beqz $9, check_intr_ep1in
++ nop
++
++handle_ep0_intr:
++ sb $0, 0x0e($27) /* set INDEX 0 */
++ lbu $11, 0x12($27) /* read CSR0 */
++
++ andi $9, $11, 0x04 /* check SENTSTALL */
++ beqz $9, _ep0_setupend
++ nop
++
++_ep0_sentstall:
++ andi $9, $11, 0xdb
++ sb $9, 0x12($27) /* clear SENDSTALL and SENTSTALL */
++ li $22, 0 /* set EP0 to IDLE state */
++
++_ep0_setupend:
++ andi $9, $11, 0x10 /* check SETUPEND */
++ beqz $9, ep0_idle_state
++ nop
++
++ ori $9, $11, 0x80
++ sb $9, 0x12($27) /* set SVDSETUPEND */
++ li $22, 0 /* set EP0 to IDLE state */
++
++ep0_idle_state:
++ bnez $22, ep0_tx_state
++ nop
++
++ /* 2.1 Handle EP0 IDLE state interrupt */
++ andi $9, $11, 0x01 /* check OUTPKTRDY */
++ beqz $9, check_intr_ep1in
++ nop
++
++ /* Read 8-bytes setup packet from the FIFO */
++ lw $25, 0x20($27) /* first word of setup packet */
++ lw $26, 0x20($27) /* second word of setup packet */
++
++ andi $9, $25, 0x60 /* bRequestType & USB_TYPE_MASK */
++ beqz $9, _ep0_std_req
++ nop
++
++ /* 2.1.1 Vendor-specific setup request */
++_ep0_vend_req:
++ li $22, 0 /* set EP0 to IDLE state */
++ li $23, 1 /* NoData = 1 */
++
++ andi $9, $25, 0xff00 /* check bRequest */
++ srl $9, $9, 8
++ beqz $9, __ep0_get_cpu_info
++ sub $8, $9, 0x1
++ beqz $8, __ep0_set_data_address
++ sub $8, $9, 0x2
++ beqz $8, __ep0_set_data_length
++ sub $8, $9, 0x3
++ beqz $8, __ep0_flush_caches
++ sub $8, $9, 0x4
++ beqz $8, __ep0_prog_start1
++ sub $8, $9, 0x5
++ beqz $8, __ep0_prog_start2
++ nop
++ b _ep0_idle_state_fini /* invalid request */
++ nop
++
++__ep0_get_cpu_info:
++ load_addr $20, cpu_info_data /* data pointer to transfer */
++ li $21, 8 /* bytes left to transfer */
++ li $22, 1 /* set EP0 to TX state */
++ li $23, 0 /* NoData = 0 */
++
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_set_data_address:
++ li $9, 0xffff0000
++ and $9, $25, $9
++ andi $8, $26, 0xffff
++ or $20, $9, $8 /* data address of next transfer */
++
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_set_data_length:
++ li $9, 0xffff0000
++ and $9, $25, $9
++ andi $8, $26, 0xffff
++ or $21, $9, $8 /* data length of next transfer */
++
++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
++ sb $9, 0x12($27) /* CSR0 */
++
++ /* We must write packet to FIFO before EP1-IN interrupt here. */
++ b handle_epin1_intr
++ nop
++
++__ep0_flush_caches:
++ /* Flush dcache and invalidate icache. */
++ li $8, 0x80000000
++ addi $9, $8, 0x3fe0 /* total 16KB */
++
++1:
++ cache 0x0, 0($8) /* Index_Invalidate_I */
++ cache 0x1, 0($8) /* Index_Writeback_Inv_D */
++ bne $8, $9, 1b
++ addiu $8, $8, 32
++
++ /* flush write-buffer */
++ sync
++
++ /* Invalidate BTB */
++ mfc0 $8, $16, 7 /* CP0_CONFIG */
++ nop
++ ori $8, 2
++ mtc0 $8, $16, 7
++ nop
++
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_prog_start1:
++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
++ sb $9, 0x12($27) /* CSR0 */
++
++ li $9, 0xffff0000
++ and $9, $25, $9
++ andi $8, $26, 0xffff
++ or $20, $9, $8 /* target address */
++
++ b xfer_d2i
++ li $19, 0x2000 /* 16KB data length */
++
++__ep0_prog_start2:
++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
++ sb $9, 0x12($27) /* CSR0 */
++
++ li $9, 0xffff0000
++ and $9, $25, $9
++ andi $8, $26, 0xffff
++ or $20, $9, $8 /* target address */
++
++ jalr $20 /* jump, and place the return address in $31 */
++ nop
++
++__ep0_prog_start2_return:
++/* User code can return to here after executing itself, by jumping to $31 */
++ b usb_boot_return
++ nop
++
++ /* 2.1.2 Standard setup request */
++_ep0_std_req:
++ andi $12, $25, 0xff00 /* check bRequest */
++ srl $12, $12, 8
++ sub $9, $12, 0x05 /* check USB_REQ_SET_ADDRESS */
++ bnez $9, __ep0_req_set_config
++ nop
++
++ /* Handle USB_REQ_SET_ADDRESS */
++__ep0_req_set_addr:
++ srl $9, $25, 16 /* get wValue */
++ sb $9, 0x0($27) /* set FADDR */
++ li $23, 1 /* NoData = 1 */
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_req_set_config:
++ sub $9, $12, 0x09 /* check USB_REQ_SET_CONFIGURATION */
++ bnez $9, __ep0_req_get_desc
++ nop
++
++ /* Handle USB_REQ_SET_CONFIGURATION */
++ li $23, 1 /* NoData = 1 */
++ b _ep0_idle_state_fini
++ nop
++
++__ep0_req_get_desc:
++ sub $9, $12, 0x06 /* check USB_REQ_GET_DESCRIPTOR */
++ bnez $9, _ep0_idle_state_fini
++ li $23, 1 /* NoData = 1 */
++
++ /* Handle USB_REQ_GET_DESCRIPTOR */
++ li $23, 0 /* NoData = 0 */
++
++ srl $9, $25, 24 /* wValue >> 8 */
++ sub $8, $9, 0x01 /* check USB_DT_DEVICE */
++ beqz $8, ___ep0_get_dev_desc
++ srl $21, $26, 16 /* get wLength */
++ sub $8, $9, 0x02 /* check USB_DT_CONFIG */
++ beqz $8, ___ep0_get_conf_desc
++ sub $8, $9, 0x03 /* check USB_DT_STRING */
++ beqz $8, ___ep0_get_string_desc
++ sub $8, $9, 0x06 /* check USB_DT_DEVICE_QUALIFIER */
++ beqz $8, ___ep0_get_dev_qualifier
++ nop
++ b _ep0_idle_state_fini
++ nop
++
++___ep0_get_dev_desc:
++ load_addr $20, device_desc /* data pointer */
++ li $22, 1 /* set EP0 to TX state */
++ sub $8, $21, 18
++ blez $8, _ep0_idle_state_fini /* wLength <= 18 */
++ nop
++ li $21, 18 /* max length of device_desc */
++ b _ep0_idle_state_fini
++ nop
++
++___ep0_get_dev_qualifier:
++ load_addr $20, dev_qualifier /* data pointer */
++ li $22, 1 /* set EP0 to TX state */
++ sub $8, $21, 10
++ blez $8, _ep0_idle_state_fini /* wLength <= 10 */
++ nop
++ li $21, 10 /* max length of dev_qualifier */
++ b _ep0_idle_state_fini
++ nop
++
++___ep0_get_conf_desc:
++ load_addr $20, config_desc_fs /* data pointer of FS mode */
++ lbu $8, 0x01($27) /* read POWER */
++ andi $8, 0x10 /* test HS_MODE */
++ beqz $8, ___ep0_get_conf_desc2
++ nop
++ load_addr $20, config_desc_hs /* data pointer of HS mode */
++
++___ep0_get_conf_desc2:
++ li $22, 1 /* set EP0 to TX state */
++ sub $8, $21, 32
++ blez $8, _ep0_idle_state_fini /* wLength <= 32 */
++ nop
++ li $21, 32 /* max length of config_desc */
++ b _ep0_idle_state_fini
++ nop
++
++___ep0_get_string_desc:
++ li $22, 1 /* set EP0 to TX state */
++
++ srl $9, $25, 16 /* wValue & 0xff */
++ andi $9, 0xff
++
++ sub $8, $9, 1
++ beqz $8, ___ep0_get_string_manufacture
++ sub $8, $9, 2
++ beqz $8, ___ep0_get_string_product
++ nop
++
++___ep0_get_string_lang_ids:
++ load_addr $20, string_lang_ids /* data pointer */
++ b _ep0_idle_state_fini
++ li $21, 4 /* data length */
++
++___ep0_get_string_manufacture:
++ load_addr $20, string_manufacture /* data pointer */
++ b _ep0_idle_state_fini
++ li $21, 16 /* data length */
++
++___ep0_get_string_product:
++ load_addr $20, string_product /* data pointer */
++ b _ep0_idle_state_fini
++ li $21, 46 /* data length */
++
++_ep0_idle_state_fini:
++ li $9, 0x40 /* SVDOUTPKTRDY */
++ beqz $23, _ep0_idle_state_fini2
++ nop
++ ori $9, $9, 0x08 /* DATAEND */
++_ep0_idle_state_fini2:
++ sb $9, 0x12($27) /* CSR0 */
++ beqz $22, check_intr_ep1in
++ nop
++
++ /* 2.2 Handle EP0 TX state interrupt */
++ep0_tx_state:
++ sub $9, $22, 1
++ bnez $9, check_intr_ep1in
++ nop
++
++ sub $9, $21, 64 /* max packetsize */
++ blez $9, _ep0_tx_state2 /* data count <= 64 */
++ ori $19, $21, 0
++ li $19, 64
++
++_ep0_tx_state2:
++ beqz $19, _ep0_tx_state3 /* send ZLP */
++ ori $18, $19, 0 /* record bytes to be transferred */
++ sub $21, $21, $19 /* decrement data count */
++
++_ep0_fifo_write_loop:
++ lbu $9, 0($20) /* read data */
++ sb $9, 0x20($27) /* load FIFO */
++ sub $19, $19, 1 /* decrement counter */
++ bnez $19, _ep0_fifo_write_loop
++ addi $20, $20, 1 /* increment data pointer */
++
++ sub $9, $18, 64 /* max packetsize */
++ beqz $9, _ep0_tx_state4
++ nop
++
++_ep0_tx_state3:
++ /* transferred bytes < max packetsize */
++ li $9, 0x0a /* set INPKTRDY and DATAEND */
++ sb $9, 0x12($27) /* CSR0 */
++ li $22, 0 /* set EP0 to IDLE state */
++ b check_intr_ep1in
++ nop
++
++_ep0_tx_state4:
++ /* transferred bytes == max packetsize */
++ li $9, 0x02 /* set INPKTRDY */
++ sb $9, 0x12($27) /* CSR0 */
++ b check_intr_ep1in
++ nop
++
++ /* 3. Check and handle EP1 BULK-IN interrupt */
++check_intr_ep1in:
++ andi $9, $10, 0x2 /* check EP1 IN interrupt */
++ beqz $9, check_intr_ep1out
++ nop
++
++handle_epin1_intr:
++ li $9, 1
++ sb $9, 0x0e($27) /* set INDEX 1 */
++ lbu $9, 0x12($27) /* read INCSR */
++
++ andi $8, $9, 0x2 /* check INCSR_FFNOTEMPT */
++ bnez $8, _epin1_tx_state4
++ nop
++
++_epin1_write_fifo:
++ lhu $9, 0x10($27) /* get INMAXP */
++ sub $8, $21, $9
++ blez $8, _epin1_tx_state1 /* bytes left <= INMAXP */
++ ori $19, $21, 0
++ ori $19, $9, 0
++
++_epin1_tx_state1:
++ beqz $19, _epin1_tx_state4 /* No data */
++ nop
++
++ sub $21, $21, $19 /* decrement data count */
++
++ srl $5, $19, 2 /* # of word */
++ andi $6, $19, 0x3 /* # of byte */
++ beqz $5, _epin1_tx_state2
++ nop
++
++_epin1_fifo_write_word:
++ lw $9, 0($20) /* read data from source address */
++ sw $9, 0x24($27) /* write FIFO */
++ sub $5, $5, 1 /* decrement counter */
++ bnez $5, _epin1_fifo_write_word
++ addiu $20, $20, 4 /* increment dest address */
++
++_epin1_tx_state2:
++ beqz $6, _epin1_tx_state3
++ nop
++
++_epin1_fifo_write_byte:
++ lbu $9, 0($20) /* read data from source address */
++ sb $9, 0x24($27) /* write FIFO */
++ sub $6, $6, 1 /* decrement counter */
++ bnez $6, _epin1_fifo_write_byte
++ addiu $20, $20, 1 /* increment dest address */
++
++_epin1_tx_state3:
++ li $9, 0x1
++ sb $9, 0x12($27) /* INCSR, set INPKTRDY */
++
++_epin1_tx_state4:
++ /* 4. Check and handle EP1 BULK-OUT interrupt */
++check_intr_ep1out:
++ lhu $9, 0x04($27) /* read INTROUT */
++ andi $9, 0x2
++ beqz $9, check_status_next
++ nop
++
++handle_epout1_intr:
++ li $9, 1
++ sb $9, 0x0e($27) /* set INDEX 1 */
++
++ lbu $9, 0x16($27) /* read OUTCSR */
++ andi $9, 0x1 /* check OUTPKTRDY */
++ beqz $9, check_status_next
++ nop
++
++_epout1_read_fifo:
++ lhu $19, 0x18($27) /* read OUTCOUNT */
++ srl $5, $19, 2 /* # of word */
++ andi $6, $19, 0x3 /* # of byte */
++ beqz $5, _epout1_rx_state1
++ nop
++
++_epout1_fifo_read_word:
++ lw $9, 0x24($27) /* read FIFO */
++ sw $9, 0($20) /* store to dest address */
++ sub $5, $5, 1 /* decrement counter */
++ bnez $5, _epout1_fifo_read_word
++ addiu $20, $20, 4 /* increment dest address */
++
++_epout1_rx_state1:
++ beqz $6, _epout1_rx_state2
++ nop
++
++_epout1_fifo_read_byte:
++ lbu $9, 0x24($27) /* read FIFO */
++ sb $9, 0($20) /* store to dest address */
++ sub $6, $6, 1 /* decrement counter */
++ bnez $6, _epout1_fifo_read_byte
++ addiu $20, $20, 1 /* increment dest address */
++
++_epout1_rx_state2:
++ sb $0, 0x16($27) /* clear OUTPKTRDY */
++
++check_status_next:
++ b usb_command_loop
++ nop
++
++/* Device/Configuration/Interface/Endpoint/String Descriptors */
++
++ .align 2
++device_desc:
++ .byte 0x12 /* bLength */
++ .byte 0x01 /* bDescriptorType */
++ .byte 0x00 /* bcdUSB */
++ .byte 0x02 /* bcdUSB */
++ .byte 0x00 /* bDeviceClass */
++ .byte 0x00 /* bDeviceSubClass */
++ .byte 0x00 /* bDeviceProtocol */
++ .byte 0x40 /* bMaxPacketSize0 */
++ .byte 0x1a /* idVendor */
++ .byte 0x60 /* idVendor */
++ .byte 0x40 /* idProduct */
++ .byte 0x47 /* idProduct */
++ .byte 0x00 /* bcdDevice */
++ .byte 0x01 /* bcdDevice */
++ .byte 0x01 /* iManufacturer */
++ .byte 0x02 /* iProduct */
++ .byte 0x00 /* iSerialNumber */
++ .byte 0x01 /* bNumConfigurations */
++
++ .align 2
++dev_qualifier:
++ .byte 0x0a /* bLength */
++ .byte 0x06 /* bDescriptorType */
++ .byte 0x00 /* bcdUSB */
++ .byte 0x02 /* bcdUSB */
++ .byte 0x00 /* bDeviceClass */
++ .byte 0x00 /* bDeviceSubClass */
++ .byte 0x00 /* bDeviceProtocol */
++ .byte 0x40 /* bMaxPacketSize0 */
++ .byte 0x01 /* bNumConfigurations */
++ .byte 0x00 /* bRESERVED */
++
++ .align 2
++config_desc_hs:
++ .byte 0x09 /* bLength */
++ .byte 0x02 /* bDescriptorType */
++ .byte 0x20 /* wTotalLength */
++ .byte 0x00 /* wTotalLength */
++ .byte 0x01 /* bNumInterfaces */
++ .byte 0x01 /* bConfigurationValue */
++ .byte 0x00 /* iConfiguration */
++ .byte 0xc0 /* bmAttributes */
++ .byte 0x01 /* MaxPower */
++intf_desc_hs:
++ .byte 0x09 /* bLength */
++ .byte 0x04 /* bDescriptorType */
++ .byte 0x00 /* bInterfaceNumber */
++ .byte 0x00 /* bAlternateSetting */
++ .byte 0x02 /* bNumEndpoints */
++ .byte 0xff /* bInterfaceClass */
++ .byte 0x00 /* bInterfaceSubClass */
++ .byte 0x50 /* bInterfaceProtocol */
++ .byte 0x00 /* iInterface */
++ep1_desc_hs:
++ .byte 0x07 /* bLength */
++ .byte 0x05 /* bDescriptorType */
++ .byte 0x01 /* bEndpointAddress */
++ .byte 0x02 /* bmAttributes */
++ .byte 0x00 /* wMaxPacketSize */
++ .byte 0x02 /* wMaxPacketSize */
++ .byte 0x00 /* bInterval */
++ep2_desc_hs:
++ .byte 0x07 /* bLength */
++ .byte 0x05 /* bDescriptorType */
++ .byte 0x81 /* bEndpointAddress */
++ .byte 0x02 /* bmAttributes */
++ .byte 0x00 /* wMaxPacketSize */
++ .byte 0x02 /* wMaxPacketSize */
++ .byte 0x00 /* bInterval */
++
++ .align 2
++config_desc_fs:
++ .byte 0x09 /* bLength */
++ .byte 0x02 /* bDescriptorType */
++ .byte 0x20 /* wTotalLength */
++ .byte 0x00 /* wTotalLength */
++ .byte 0x01 /* bNumInterfaces */
++ .byte 0x01 /* bConfigurationValue */
++ .byte 0x00 /* iConfiguration */
++ .byte 0xc0 /* bmAttributes */
++ .byte 0x01 /* MaxPower */
++intf_desc_fs:
++ .byte 0x09 /* bLength */
++ .byte 0x04 /* bDescriptorType */
++ .byte 0x00 /* bInterfaceNumber */
++ .byte 0x00 /* bAlternateSetting */
++ .byte 0x02 /* bNumEndpoints */
++ .byte 0xff /* bInterfaceClass */
++ .byte 0x00 /* bInterfaceSubClass */
++ .byte 0x50 /* bInterfaceProtocol */
++ .byte 0x00 /* iInterface */
++ep1_desc_fs:
++ .byte 0x07 /* bLength */
++ .byte 0x05 /* bDescriptorType */
++ .byte 0x01 /* bEndpointAddress */
++ .byte 0x02 /* bmAttributes */
++ .byte 0x40 /* wMaxPacketSize */
++ .byte 0x00 /* wMaxPacketSize */
++ .byte 0x00 /* bInterval */
++ep2_desc_fs:
++ .byte 0x07 /* bLength */
++ .byte 0x05 /* bDescriptorType */
++ .byte 0x81 /* bEndpointAddress */
++ .byte 0x02 /* bmAttributes */
++ .byte 0x40 /* wMaxPacketSize */
++ .byte 0x00 /* wMaxPacketSize */
++ .byte 0x00 /* bInterval */
++
++ .align 2
++string_lang_ids:
++ .byte 0x04
++ .byte 0x03
++ .byte 0x09
++ .byte 0x04
++
++ .align 2
++string_manufacture:
++ .byte 0x10
++ .byte 0x03
++ .byte 0x49
++ .byte 0x00
++ .byte 0x6e
++ .byte 0x00
++ .byte 0x67
++ .byte 0x00
++ .byte 0x65
++ .byte 0x00
++ .byte 0x6e
++ .byte 0x00
++ .byte 0x69
++ .byte 0x00
++ .byte 0x63
++ .byte 0x00
++
++ .align 2
++string_product:
++ .byte 0x2e
++ .byte 0x03
++ .byte 0x4a
++ .byte 0x00
++ .byte 0x5a
++ .byte 0x00
++ .byte 0x34
++ .byte 0x00
++ .byte 0x37
++ .byte 0x00
++ .byte 0x34
++ .byte 0x00
++ .byte 0x30
++ .byte 0x00
++ .byte 0x20
++ .byte 0x00
++ .byte 0x55
++ .byte 0x00
++ .byte 0x53
++ .byte 0x00
++ .byte 0x42
++ .byte 0x00
++ .byte 0x20
++ .byte 0x00
++ .byte 0x42
++ .byte 0x00
++ .byte 0x6f
++ .byte 0x00
++ .byte 0x6f
++ .byte 0x00
++ .byte 0x74
++ .byte 0x00
++ .byte 0x20
++ .byte 0x00
++ .byte 0x44
++ .byte 0x00
++ .byte 0x65
++ .byte 0x00
++ .byte 0x76
++ .byte 0x00
++ .byte 0x69
++ .byte 0x00
++ .byte 0x63
++ .byte 0x00
++ .byte 0x65
++ .byte 0x00
++
++ .align 2
++cpu_info_data:
++ .byte 0x4a
++ .byte 0x5a
++ .byte 0x34
++ .byte 0x37
++ .byte 0x34
++ .byte 0x30
++ .byte 0x56
++ .byte 0x31
++usbboot_end:
++
++ .set reorder
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/0003-add-mmc-support.patch b/package/boot/uboot-xburst/patches/0003-add-mmc-support.patch
new file mode 100644
index 0000000..e9baa7c
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/0003-add-mmc-support.patch
@@ -0,0 +1,1664 @@
+From bd36739e77669e8df45c38f6acfe2cea511534d9 Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Wed, 10 Oct 2012 18:19:41 +0800
+Subject: [PATCH 3/6] add mmc support
+
+---
+ arch/mips/include/asm/jz4740.h | 166 ++++++
+ board/qi/qi_lb60/qi_lb60.c | 9 +-
+ drivers/mmc/Makefile | 1 +
+ drivers/mmc/jz_mmc.c | 1179 ++++++++++++++++++++++++++++++++++++++++
+ drivers/mmc/jz_mmc.h | 176 ++++++
+ include/configs/qi_lb60.h | 9 +
+ include/mmc.h | 40 ++
+ 7 files changed, 1578 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/mmc/jz_mmc.c
+ create mode 100644 drivers/mmc/jz_mmc.h
+
+diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h
+index 7a7cfff..68287fb 100644
+--- a/arch/mips/include/asm/jz4740.h
++++ b/arch/mips/include/asm/jz4740.h
+@@ -1146,5 +1146,171 @@ extern void sdram_init(void);
+ extern void calc_clocks(void);
+ extern void rtc_init(void);
+
++/*************************************************************************
++ * MSC
++ *************************************************************************/
++#define REG8(addr) *((volatile u8 *)(addr))
++#define REG16(addr) *((volatile u16 *)(addr))
++#define REG32(addr) *((volatile u32 *)(addr))
++
++#define CPM_BASE 0xB0000000
++#define CPM_CPCCR (CPM_BASE+0x00)
++#define CPM_MSCCDR (CPM_BASE+0x68)
++#define REG_CPM_MSCCDR REG32(CPM_MSCCDR)
++#define REG_CPM_CPCCR REG32(CPM_CPCCR)
++
++#define MSC_BASE 0xB0021000
++
++#define MSC_STRPCL (MSC_BASE + 0x000)
++#define MSC_STAT (MSC_BASE + 0x004)
++#define MSC_CLKRT (MSC_BASE + 0x008)
++#define MSC_CMDAT (MSC_BASE + 0x00C)
++#define MSC_RESTO (MSC_BASE + 0x010)
++#define MSC_RDTO (MSC_BASE + 0x014)
++#define MSC_BLKLEN (MSC_BASE + 0x018)
++#define MSC_NOB (MSC_BASE + 0x01C)
++#define MSC_SNOB (MSC_BASE + 0x020)
++#define MSC_IMASK (MSC_BASE + 0x024)
++#define MSC_IREG (MSC_BASE + 0x028)
++#define MSC_CMD (MSC_BASE + 0x02C)
++#define MSC_ARG (MSC_BASE + 0x030)
++#define MSC_RES (MSC_BASE + 0x034)
++#define MSC_RXFIFO (MSC_BASE + 0x038)
++#define MSC_TXFIFO (MSC_BASE + 0x03C)
++
++#define REG_MSC_STRPCL REG16(MSC_STRPCL)
++#define REG_MSC_STAT REG32(MSC_STAT)
++#define REG_MSC_CLKRT REG16(MSC_CLKRT)
++#define REG_MSC_CMDAT REG32(MSC_CMDAT)
++#define REG_MSC_RESTO REG16(MSC_RESTO)
++#define REG_MSC_RDTO REG16(MSC_RDTO)
++#define REG_MSC_BLKLEN REG16(MSC_BLKLEN)
++#define REG_MSC_NOB REG16(MSC_NOB)
++#define REG_MSC_SNOB REG16(MSC_SNOB)
++#define REG_MSC_IMASK REG16(MSC_IMASK)
++#define REG_MSC_IREG REG16(MSC_IREG)
++#define REG_MSC_CMD REG8(MSC_CMD)
++#define REG_MSC_ARG REG32(MSC_ARG)
++#define REG_MSC_RES REG16(MSC_RES)
++#define REG_MSC_RXFIFO REG32(MSC_RXFIFO)
++#define REG_MSC_TXFIFO REG32(MSC_TXFIFO)
++
++/* MSC Clock and Control Register (MSC_STRPCL) */
++
++#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7)
++#define MSC_STRPCL_EXIT_TRANSFER (1 << 6)
++#define MSC_STRPCL_START_READWAIT (1 << 5)
++#define MSC_STRPCL_STOP_READWAIT (1 << 4)
++#define MSC_STRPCL_RESET (1 << 3)
++#define MSC_STRPCL_START_OP (1 << 2)
++#define MSC_STRPCL_CLOCK_CONTROL_BIT 0
++#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT)
++ #define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */
++ #define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */
++
++/* MSC Status Register (MSC_STAT) */
++
++#define MSC_STAT_IS_RESETTING (1 << 15)
++#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14)
++#define MSC_STAT_PRG_DONE (1 << 13)
++#define MSC_STAT_DATA_TRAN_DONE (1 << 12)
++#define MSC_STAT_END_CMD_RES (1 << 11)
++#define MSC_STAT_DATA_FIFO_AFULL (1 << 10)
++#define MSC_STAT_IS_READWAIT (1 << 9)
++#define MSC_STAT_CLK_EN (1 << 8)
++#define MSC_STAT_DATA_FIFO_FULL (1 << 7)
++#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6)
++#define MSC_STAT_CRC_RES_ERR (1 << 5)
++#define MSC_STAT_CRC_READ_ERROR (1 << 4)
++#define MSC_STAT_CRC_WRITE_ERROR_BIT 2
++#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT)
++ #define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */
++ #define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */
++ #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */
++#define MSC_STAT_TIME_OUT_RES (1 << 1)
++#define MSC_STAT_TIME_OUT_READ (1 << 0)
++
++/* MSC Bus Clock Control Register (MSC_CLKRT) */
++
++#define MSC_CLKRT_CLK_RATE_BIT 0
++#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT)
++ #define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */
++ #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */
++
++/* MSC Command Sequence Control Register (MSC_CMDAT) */
++
++#define MSC_CMDAT_IO_ABORT (1 << 11)
++#define MSC_CMDAT_BUS_WIDTH_BIT 9
++#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT)
++#define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT)
++#define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT)
++#define MSC_CMDAT_DMA_EN (1 << 8)
++#define MSC_CMDAT_INIT (1 << 7)
++#define MSC_CMDAT_BUSY (1 << 6)
++#define MSC_CMDAT_STREAM_BLOCK (1 << 5)
++#define MSC_CMDAT_WRITE (1 << 4)
++#define MSC_CMDAT_READ (0 << 4)
++#define MSC_CMDAT_DATA_EN (1 << 3)
++#define MSC_CMDAT_RESPONSE_BIT 0
++#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT)
++#define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT)
++
++/* MSC Interrupts Mask Register (MSC_IMASK) */
++#define MSC_IMASK_SDIO (1 << 7)
++#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6)
++#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5)
++#define MSC_IMASK_END_CMD_RES (1 << 2)
++#define MSC_IMASK_PRG_DONE (1 << 1)
++#define MSC_IMASK_DATA_TRAN_DONE (1 << 0)
++
++
++/* MSC Interrupts Status Register (MSC_IREG) */
++#define MSC_IREG_SDIO (1 << 7)
++#define MSC_IREG_TXFIFO_WR_REQ (1 << 6)
++#define MSC_IREG_RXFIFO_RD_REQ (1 << 5)
++#define MSC_IREG_END_CMD_RES (1 << 2)
++#define MSC_IREG_PRG_DONE (1 << 1)
++#define MSC_IREG_DATA_TRAN_DONE (1 << 0)
++
++static __inline__ unsigned int __cpm_get_pllout2(void)
++{
++ if (REG_CPM_CPCCR & CPM_CPCCR_PCS)
++ return __cpm_get_pllout();
++ else
++ return __cpm_get_pllout()/2;
++}
++
++static inline void __cpm_select_msc_clk(int sd)
++{
++ unsigned int pllout2 = __cpm_get_pllout2();
++ unsigned int div = 0;
++
++ if (sd) {
++ div = pllout2 / 24000000;
++ }
++ else {
++ div = pllout2 / 16000000;
++ }
++
++ REG_CPM_MSCCDR = div - 1;
++}
++#define __msc_reset() \
++do { \
++ REG_MSC_STRPCL = MSC_STRPCL_RESET; \
++ while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \
++} while (0)
++
+ #endif /* !__ASSEMBLY__ */
+ #endif /* __JZ4740_H__ */
+diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
+index 3bd4e2f..a2ba648 100644
+--- a/board/qi/qi_lb60/qi_lb60.c
++++ b/board/qi/qi_lb60/qi_lb60.c
+@@ -40,8 +40,13 @@ static void gpio_init(void)
+ __gpio_clear_pin(GPIO_KEYOUT_BASE + i);
+ }
+
+- __gpio_as_input(GPIO_KEYIN_8);
+- __gpio_enable_pull(GPIO_KEYIN_8);
++ if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){
++ printf("[S] pressed, enable UART0\n");
++ __gpio_as_uart0();
++ } else {
++ __gpio_as_input(GPIO_KEYIN_8);
++ __gpio_enable_pull(GPIO_KEYIN_8);
++ }
+
+ /* enable the TP4, TP5 as UART0 */
+ __gpio_jtag_to_uart0();
+diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
+index 565ba6a..3c717b1 100644
+--- a/drivers/mmc/Makefile
++++ b/drivers/mmc/Makefile
+@@ -47,6 +47,7 @@ COBJS-$(CONFIG_SDHCI) += sdhci.o
+ COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
+ COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
+ COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
++COBJS-$(CONFIG_JZ4740_MMC) += jz_mmc.o
+
+ COBJS := $(COBJS-y)
+ SRCS := $(COBJS:.o=.c)
+diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
+new file mode 100644
+index 0000000..642cecc
+--- /dev/null
++++ b/drivers/mmc/jz_mmc.c
+@@ -0,0 +1,1179 @@
++/*
++ * (C) Copyright 2003
++ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <common.h>
++#include <part.h>
++#include <mmc.h>
++
++#include <asm/io.h>
++#include <asm/jz4740.h>
++#include "jz_mmc.h"
++
++static int sd2_0 = 0;
++static int mmc_ready = 0;
++static int use_4bit; /* Use 4-bit data bus */
++/*
++ * MMC Events
++ */
++#define MMC_EVENT_NONE 0x00 /* No events */
++#define MMC_EVENT_RX_DATA_DONE 0x01 /* Rx data done */
++#define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */
++#define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */
++
++
++#define MMC_IRQ_MASK() \
++do { \
++ REG_MSC_IMASK = 0xffff; \
++ REG_MSC_IREG = 0xffff; \
++} while (0)
++
++/*
++ * GPIO definition
++ */
++#if defined(CONFIG_SAKC)
++
++#define __msc_init_io() \
++do { \
++ __gpio_as_input(GPIO_SD_CD_N); \
++} while (0)
++
++#else
++#define __msc_init_io() \
++do { \
++ __gpio_as_output(GPIO_SD_VCC_EN_N); \
++ __gpio_as_input(GPIO_SD_CD_N); \
++} while (0)
++
++#define __msc_enable_power() \
++do { \
++ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \
++} while (0)
++
++#define __msc_disable_power() \
++do { \
++ __gpio_set_pin(GPIO_SD_VCC_EN_N); \
++} while (0)
++
++#endif /* CONFIG_SAKE */
++
++#define __msc_card_detected() \
++({ \
++ int detected = 1; \
++ __gpio_as_input(GPIO_SD_CD_N); \
++ __gpio_disable_pull(GPIO_SD_CD_N); \
++ if (!__gpio_get_pin(GPIO_SD_CD_N)) \
++ detected = 0; \
++ detected; \
++})
++
++/*
++ * Local functions
++ */
++
++extern int
++fat_register_device(block_dev_desc_t *dev_desc, int part_no);
++
++static block_dev_desc_t mmc_dev;
++
++block_dev_desc_t * mmc_get_dev(int dev)
++{
++ return ((block_dev_desc_t *)&mmc_dev);
++}
++
++/* Stop the MMC clock and wait while it happens */
++static inline int jz_mmc_stop_clock(void)
++{
++ int timeout = 1000;
++
++ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP;
++
++ while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) {
++ timeout--;
++ if (timeout == 0)
++ return MMC_ERROR_TIMEOUT;
++ udelay(1);
++ }
++ return MMC_NO_ERROR;
++}
++
++/* Start the MMC clock and operation */
++static inline int jz_mmc_start_clock(void)
++{
++ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP;
++ return MMC_NO_ERROR;
++}
++
++static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate)
++{
++ u32 clkrt = 0;
++ u32 clk_src = is_sd ? 24000000 : 16000000;
++
++ while (rate < clk_src) {
++ clkrt ++;
++ clk_src >>= 1;
++ }
++
++ return clkrt;
++}
++
++/* Set the MMC clock frequency */
++void jz_mmc_set_clock(int sd, u32 rate)
++{
++ jz_mmc_stop_clock();
++
++ /* Select clock source of MSC */
++ __cpm_select_msc_clk(sd);
++
++ /* Set clock dividor of MSC */
++ REG_MSC_CLKRT = jz_mmc_calc_clkrt(sd, rate);
++}
++
++static int jz_mmc_check_status(struct mmc_request *request)
++{
++ u32 status = REG_MSC_STAT;
++
++ /* Checking for response or data timeout */
++ if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) {
++ printf("MMC/SD timeout, MMC_STAT 0x%x CMD %d\n", status, request->cmd);
++ return MMC_ERROR_TIMEOUT;
++ }
++
++ /* Checking for CRC error */
++ if (status & (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_RES_ERR)) {
++ printf("MMC/CD CRC error, MMC_STAT 0x%x\n", status);
++ return MMC_ERROR_CRC;
++ }
++
++ return MMC_NO_ERROR;
++}
++
++/* Obtain response to the command and store it to response buffer */
++static void jz_mmc_get_response(struct mmc_request *request)
++{
++ int i;
++ u8 *buf;
++ u32 data;
++
++ debug("fetch response for request %d, cmd %d\n",
++ request->rtype, request->cmd);
++
++ buf = request->response;
++ request->result = MMC_NO_ERROR;
++
++ switch (request->rtype) {
++ case RESPONSE_R1: case RESPONSE_R1B: case RESPONSE_R6:
++ case RESPONSE_R3: case RESPONSE_R4: case RESPONSE_R5:
++ {
++ data = REG_MSC_RES;
++ buf[0] = (data >> 8) & 0xff;
++ buf[1] = data & 0xff;
++ data = REG_MSC_RES;
++ buf[2] = (data >> 8) & 0xff;
++ buf[3] = data & 0xff;
++ data = REG_MSC_RES;
++ buf[4] = data & 0xff;
++
++ debug("request %d, response [%02x %02x %02x %02x %02x]\n",
++ request->rtype, buf[0], buf[1], buf[2], buf[3], buf[4]);
++ break;
++ }
++ case RESPONSE_R2_CID: case RESPONSE_R2_CSD:
++ {
++ for (i = 0; i < 16; i += 2) {
++ data = REG_MSC_RES;
++ buf[i] = (data >> 8) & 0xff;
++ buf[i+1] = data & 0xff;
++ }
++ debug("request %d, response [", request->rtype);
++#if CONFIG_MMC_DEBUG_VERBOSE > 2
++ if (g_mmc_debug >= 3) {
++ int n;
++ for (n = 0; n < 17; n++)
++ printk("%02x ", buf[n]);
++ printk("]\n");
++ }
++#endif
++ break;
++ }
++ case RESPONSE_NONE:
++ debug("No response\n");
++ break;
++
++ default:
++ debug("unhandled response type for request %d\n", request->rtype);
++ break;
++ }
++}
++
++static int jz_mmc_receive_data(struct mmc_request *req)
++{
++ u32 stat, timeout, data, cnt;
++ u8 *buf = req->buffer;
++ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
++
++ timeout = 0x3ffffff;
++
++ while (timeout) {
++ timeout--;
++ stat = REG_MSC_STAT;
++
++ if (stat & MSC_STAT_TIME_OUT_READ)
++ return MMC_ERROR_TIMEOUT;
++ else if (stat & MSC_STAT_CRC_READ_ERROR)
++ return MMC_ERROR_CRC;
++ else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY)
++ || (stat & MSC_STAT_DATA_FIFO_AFULL)) {
++ /* Ready to read data */
++ break;
++ }
++ udelay(1);
++ }
++ if (!timeout)
++ return MMC_ERROR_TIMEOUT;
++
++ /* Read data from RXFIFO. It could be FULL or PARTIAL FULL */
++ cnt = wblocklen;
++ while (cnt) {
++ data = REG_MSC_RXFIFO;
++ {
++ *buf++ = (u8)(data >> 0);
++ *buf++ = (u8)(data >> 8);
++ *buf++ = (u8)(data >> 16);
++ *buf++ = (u8)(data >> 24);
++ }
++ cnt --;
++ while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY))
++ ;
++ }
++ return MMC_NO_ERROR;
++}
++
++static int jz_mmc_transmit_data(struct mmc_request *req)
++{
++#if 0
++ u32 nob = req->nob;
++ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
++ u8 *buf = req->buffer;
++ u32 *wbuf = (u32 *)buf;
++ u32 waligned = (((u32)buf & 0x3) == 0); /* word aligned ? */
++ u32 stat, timeout, data, cnt;
++
++ for (nob; nob >= 1; nob--) {
++ timeout = 0x3FFFFFF;
++
++ while (timeout) {
++ timeout--;
++ stat = REG_MSC_STAT;
++
++ if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS))
++ return MMC_ERROR_CRC;
++ else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) {
++ /* Ready to write data */
++ break;
++ }
++
++ udelay(1);
++ }
++
++ if (!timeout)
++ return MMC_ERROR_TIMEOUT;
++
++ /* Write data to TXFIFO */
++ cnt = wblocklen;
++ while (cnt) {
++ while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL)
++ ;
++
++ if (waligned) {
++ REG_MSC_TXFIFO = *wbuf++;
++ }
++ else {
++ data = *buf++ | (*buf++ << 8) | (*buf++ << 16) | (*buf++ << 24);
++ REG_MSC_TXFIFO = data;
++ }
++
++ cnt--;
++ }
++ }
++#endif
++ return MMC_NO_ERROR;
++}
++
++
++/*
++ * Name: int jz_mmc_exec_cmd()
++ * Function: send command to the card, and get a response
++ * Input: struct mmc_request *req : MMC/SD request
++ * Output: 0: right >0: error code
++ */
++int jz_mmc_exec_cmd(struct mmc_request *request)
++{
++ u32 cmdat = 0, events = 0;
++ int retval, timeout = 0x3fffff;
++
++ /* Indicate we have no result yet */
++ request->result = MMC_NO_RESPONSE;
++ if (request->cmd == MMC_CIM_RESET) {
++ /* On reset, 1-bit bus width */
++ use_4bit = 0;
++
++ /* Reset MMC/SD controller */
++ __msc_reset();
++
++ /* On reset, drop MMC clock down */
++ jz_mmc_set_clock(0, MMC_CLOCK_SLOW);
++
++ /* On reset, stop MMC clock */
++ jz_mmc_stop_clock();
++ }
++ if (request->cmd == MMC_CMD_SEND_OP_COND) {
++ debug("Have an MMC card\n");
++ /* always use 1bit for MMC */
++ use_4bit = 0;
++ }
++ if (request->cmd == SET_BUS_WIDTH) {
++ if (request->arg == 0x2) {
++ printf("Use 4-bit bus width\n");
++ use_4bit = 1;
++ } else {
++ printf("Use 1-bit bus width\n");
++ use_4bit = 0;
++ }
++ }
++
++ /* stop clock */
++ jz_mmc_stop_clock();
++
++ /* mask all interrupts */
++ REG_MSC_IMASK = 0xffff;
++
++ /* clear status */
++ REG_MSC_IREG = 0xffff;
++
++ /* use 4-bit bus width when possible */
++ if (use_4bit)
++ cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT;
++
++ /* Set command type and events */
++ switch (request->cmd) {
++ /* MMC core extra command */
++ case MMC_CIM_RESET:
++ cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
++ break;
++
++ /* bc - broadcast - no response */
++ case MMC_CMD_GO_IDLE_STATE:
++ case MMC_CMD_SET_DSR:
++ break;
++
++ /* bcr - broadcast with response */
++ case MMC_CMD_SEND_OP_COND:
++ case MMC_CMD_ALL_SEND_CID:
++ case MMC_GO_IRQ_STATE:
++ break;
++
++ /* adtc - addressed with data transfer */
++ case MMC_READ_DAT_UNTIL_STOP:
++ case MMC_CMD_READ_SINGLE_BLOCK:
++ case MMC_CMD_READ_MULTIPLE_BLOCK:
++ case SD_CMD_APP_SEND_SCR:
++ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_READ;
++ events = MMC_EVENT_RX_DATA_DONE;
++ break;
++
++ case MMC_WRITE_DAT_UNTIL_STOP:
++ case MMC_CMD_WRITE_SINGLE_BLOCK:
++ case MMC_CMD_WRITE_MULTIPLE_BLOCK:
++ case MMC_PROGRAM_CID:
++ case MMC_PROGRAM_CSD:
++ case MMC_SEND_WRITE_PROT:
++ case MMC_GEN_CMD:
++ case MMC_LOCK_UNLOCK:
++ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE;
++ events = MMC_EVENT_TX_DATA_DONE | MMC_EVENT_PROG_DONE;
++
++ break;
++
++ case MMC_CMD_STOP_TRANSMISSION:
++ events = MMC_EVENT_PROG_DONE;
++ break;
++
++ /* ac - no data transfer */
++ default:
++ break;
++ }
++
++ /* Set response type */
++ switch (request->rtype) {
++ case RESPONSE_NONE:
++ break;
++
++ case RESPONSE_R1B:
++ cmdat |= MSC_CMDAT_BUSY;
++ /*FALLTHRU*/
++ case RESPONSE_R1:
++ cmdat |= MSC_CMDAT_RESPONSE_R1;
++ break;
++ case RESPONSE_R2_CID:
++ case RESPONSE_R2_CSD:
++ cmdat |= MSC_CMDAT_RESPONSE_R2;
++ break;
++ case RESPONSE_R3:
++ cmdat |= MSC_CMDAT_RESPONSE_R3;
++ break;
++ case RESPONSE_R4:
++ cmdat |= MSC_CMDAT_RESPONSE_R4;
++ break;
++ case RESPONSE_R5:
++ cmdat |= MSC_CMDAT_RESPONSE_R5;
++ break;
++ case RESPONSE_R6:
++ cmdat |= MSC_CMDAT_RESPONSE_R6;
++ break;
++ default:
++ break;
++ }
++
++ /* Set command index */
++ if (request->cmd == MMC_CIM_RESET) {
++ REG_MSC_CMD = MMC_CMD_GO_IDLE_STATE;
++ } else {
++ REG_MSC_CMD = request->cmd;
++ }
++
++ /* Set argument */
++ REG_MSC_ARG = request->arg;
++
++ /* Set block length and nob */
++ if (request->cmd == SD_CMD_APP_SEND_SCR) { /* get SCR from DataFIFO */
++ REG_MSC_BLKLEN = 8;
++ REG_MSC_NOB = 1;
++ } else {
++ REG_MSC_BLKLEN = request->block_len;
++ REG_MSC_NOB = request->nob;
++ }
++
++ /* Set command */
++ REG_MSC_CMDAT = cmdat;
++
++ debug("Send cmd %d cmdat: %x arg: %x resp %d\n", request->cmd,
++ cmdat, request->arg, request->rtype);
++
++ /* Start MMC/SD clock and send command to card */
++ jz_mmc_start_clock();
++
++ /* Wait for command completion */
++ while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES))
++ ;
++
++ if (timeout == 0)
++ return MMC_ERROR_TIMEOUT;
++
++ REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear flag */
++
++ /* Check for status */
++ retval = jz_mmc_check_status(request);
++ if (retval) {
++ return retval;
++ }
++
++ /* Complete command with no response */
++ if (request->rtype == RESPONSE_NONE) {
++ return MMC_NO_ERROR;
++ }
++
++ /* Get response */
++ jz_mmc_get_response(request);
++
++ /* Start data operation */
++ if (events & (MMC_EVENT_RX_DATA_DONE | MMC_EVENT_TX_DATA_DONE)) {
++ if (events & MMC_EVENT_RX_DATA_DONE) {
++ if (request->cmd == SD_CMD_APP_SEND_SCR) {
++ /* SD card returns SCR register as data.
++ MMC core expect it in the response buffer,
++ after normal response. */
++ request->buffer = (u8 *)((u32)request->response + 5);
++ }
++ jz_mmc_receive_data(request);
++ }
++
++ if (events & MMC_EVENT_TX_DATA_DONE) {
++ jz_mmc_transmit_data(request);
++ }
++
++ /* Wait for Data Done */
++ while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE))
++ ;
++ REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */
++ }
++
++ /* Wait for Prog Done event */
++ if (events & MMC_EVENT_PROG_DONE) {
++ while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE))
++ ;
++ REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */
++ }
++
++ /* Command completed */
++
++ return MMC_NO_ERROR; /* return successfully */
++}
++
++int mmc_block_read(u8 *dst, ulong src, ulong len)
++{
++
++ struct mmc_request request;
++ struct mmc_response_r1 r1;
++ int retval = 0;
++
++ if (len == 0)
++ goto exit;
++
++ mmc_simple_cmd(&request, MMC_CMD_SEND_STATUS, mmcinfo.rca, RESPONSE_R1);
++ retval = mmc_unpack_r1(&request, &r1, 0);
++ if (retval && (retval != MMC_ERROR_STATE_MISMATCH))
++ goto exit;
++
++ mmc_simple_cmd(&request, MMC_CMD_SET_BLOCKLEN, len, RESPONSE_R1);
++ if (retval = mmc_unpack_r1(&request, &r1, 0))
++ goto exit;
++
++ if (!sd2_0)
++ src *= mmcinfo.block_len;
++
++ mmc_send_cmd(&request, MMC_CMD_READ_SINGLE_BLOCK, src, 1, len, RESPONSE_R1, dst);
++ if (retval = mmc_unpack_r1(&request, &r1, 0))
++ goto exit;
++
++exit:
++ return retval;
++}
++
++ulong mmc_bread(int dev_num, ulong blkstart, ulong blkcnt, ulong *dst)
++{
++ if (!mmc_ready) {
++ printf("Please initial the MMC first\n");
++ return -1;
++ }
++
++ int i = 0;
++ ulong dst_tmp = dst;
++
++ for (i = 0; i < blkcnt; i++) {
++ if ((mmc_block_read((uchar *)(dst_tmp), blkstart, mmcinfo.block_len)) < 0)
++ return -1;
++
++ dst_tmp += mmcinfo.block_len;
++ blkstart++;
++ }
++
++ return i;
++}
++
++int mmc_select_card(void)
++{
++ struct mmc_request request;
++ struct mmc_response_r1 r1;
++ int retval;
++
++ mmc_simple_cmd(&request, MMC_CMD_SELECT_CARD, mmcinfo.rca, RESPONSE_R1B);
++ retval = mmc_unpack_r1(&request, &r1, 0);
++ if (retval) {
++ return retval;
++ }
++
++ if (mmcinfo.sd) {
++ mmc_simple_cmd(&request, MMC_CMD_APP_CMD, mmcinfo.rca, RESPONSE_R1);
++ retval = mmc_unpack_r1(&request,&r1,0);
++ if (retval) {
++ return retval;
++ }
++#if defined(MMC_BUS_WIDTH_1BIT)
++ mmc_simple_cmd(&request, SET_BUS_WIDTH, 1, RESPONSE_R1);
++#else
++ mmc_simple_cmd(&request, SET_BUS_WIDTH, 2, RESPONSE_R1);
++#endif
++ retval = mmc_unpack_r1(&request,&r1,0);
++ if (retval) {
++ return retval;
++ }
++ }
++ return 0;
++}
++
++/*
++ * Configure card
++ */
++static void mmc_configure_card(void)
++{
++ u32 rate;
++
++ /* Get card info */
++ if (sd2_0)
++ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) << 10;
++ else
++ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) * (1 << (mmcinfo.csd.c_size_mult + 2));
++
++ mmcinfo.block_len = 1 << mmcinfo.csd.read_bl_len;
++
++ mmc_dev.if_type = IF_TYPE_SD;
++ mmc_dev.part_type = PART_TYPE_DOS;
++ mmc_dev.dev = 0;
++ mmc_dev.lun = 0;
++ mmc_dev.type = 0;
++ mmc_dev.blksz = mmcinfo.block_len;
++ mmc_dev.lba = mmcinfo.block_num;
++ mmc_dev.removable = 0;
++
++ printf("%s Detected: %lu blocks of %lu bytes\n",
++ sd2_0 == 1 ? "SDHC" : "SD",
++ mmc_dev.lba,
++ mmc_dev.blksz);
++
++ /* Fix the clock rate */
++ rate = mmc_tran_speed(mmcinfo.csd.tran_speed);
++ if (rate < MMC_CLOCK_SLOW)
++ rate = MMC_CLOCK_SLOW;
++ if ((mmcinfo.sd == 0) && (rate > MMC_CLOCK_FAST))
++ rate = MMC_CLOCK_FAST;
++ if ((mmcinfo.sd) && (rate > SD_CLOCK_FAST))
++ rate = SD_CLOCK_FAST;
++
++ debug("%s: block_len=%d block_num=%d rate=%d\n",
++ __func__, mmcinfo.block_len, mmcinfo.block_num, rate);
++
++ jz_mmc_set_clock(mmcinfo.sd, rate);
++}
++
++/*
++ * State machine routines to initialize card(s)
++ */
++
++/*
++ CIM_SINGLE_CARD_ACQ (frequency at 400 kHz)
++ --- Must enter from GO_IDLE_STATE ---
++ 1. SD_SEND_OP_COND (SD Card) [CMD55] + [CMD41]
++ 2. SEND_OP_COND (Full Range) [CMD1] {optional}
++ 3. SEND_OP_COND (Set Range ) [CMD1]
++ If busy, delay and repeat step 2
++ 4. ALL_SEND_CID [CMD2]
++ If timeout, set an error (no cards found)
++ 5. SET_RELATIVE_ADDR [CMD3]
++ 6. SEND_CSD [CMD9]
++ 7. SET_DSR [CMD4] Only call this if (csd.dsr_imp).
++ 8. Set clock frequency (check available in csd.tran_speed)
++ */
++
++#define MMC_INIT_DOING 0
++#define MMC_INIT_PASSED 1
++#define MMC_INIT_FAILED 2
++
++static int mmc_init_card_state(struct mmc_request *request)
++{
++ struct mmc_response_r1 r1;
++ struct mmc_response_r3 r3;
++ int retval;
++ int ocr = 0x40300000;
++ int limit_41 = 0;
++
++ switch (request->cmd) {
++ case MMC_CMD_GO_IDLE_STATE: /* No response to parse */
++ if (mmcinfo.sd)
++ mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1);
++ else
++ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
++ break;
++
++ case 8:
++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
++ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
++ break;
++
++ case MMC_CMD_APP_CMD:
++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
++ if (retval & (limit_41 < 100)) {
++ debug("%s: unable to MMC_APP_CMD error=%d (%s)\n",
++ __func__, retval, mmc_result_to_string(retval));
++ limit_41++;
++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
++ } else if (limit_41 < 100) {
++ limit_41++;
++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
++ } else{
++ /* reset the card to idle*/
++ mmc_simple_cmd(request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
++ mmcinfo.sd = 0;
++ }
++ break;
++
++ case SD_CMD_APP_SEND_OP_COND:
++ retval = mmc_unpack_r3(request, &r3);
++ if (retval) {
++ debug("%s: try MMC card\n", __func__);
++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
++ break;
++ }
++
++ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
++
++ if(!(r3.ocr & MMC_CARD_BUSY || ocr == 0)){
++ udelay(50000);
++ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
++ } else {
++ mmcinfo.sd = 1; /* SD Card ready */
++ mmcinfo.state = CARD_STATE_READY;
++ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
++ }
++ break;
++
++ case MMC_CMD_SEND_OP_COND:
++ retval = mmc_unpack_r3(request, &r3);
++ if (retval) {
++ debug("%s: failed SEND_OP_COND error=%d (%s)\n",
++ __func__, retval, mmc_result_to_string(retval));
++ return MMC_INIT_FAILED;
++ }
++
++ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
++ if (!(r3.ocr & MMC_CARD_BUSY)) {
++ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
++ } else {
++ mmcinfo.sd = 0; /* MMC Card ready */
++ mmcinfo.state = CARD_STATE_READY;
++ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
++ }
++ break;
++
++ case MMC_CMD_ALL_SEND_CID:
++ retval = mmc_unpack_cid( request, &mmcinfo.cid );
++ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
++ if ( retval && (retval != MMC_ERROR_CRC)) {
++ debug("mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n",
++ retval, mmc_result_to_string(retval));
++ return MMC_INIT_FAILED;
++ }
++ mmcinfo.state = CARD_STATE_IDENT;
++ if(mmcinfo.sd)
++ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, 0, RESPONSE_R6);
++ else
++ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, ID_TO_RCA(mmcinfo.id) << 16, RESPONSE_R1);
++ break;
++
++ case MMC_CMD_SET_RELATIVE_ADDR:
++ if (mmcinfo.sd) {
++ retval = mmc_unpack_r6(request, &r1, mmcinfo.state, &mmcinfo.rca);
++ mmcinfo.rca = mmcinfo.rca << 16;
++ debug("%s: Get RCA from SD: 0x%04x Status: %x\n",
++ __func__, mmcinfo.rca, r1.status);
++ } else {
++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
++ mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16;
++ }
++ if (retval) {
++ debug("%s: unable to SET_RELATIVE_ADDR error=%d (%s)\n",
++ __func__, retval, mmc_result_to_string(retval));
++ return MMC_INIT_FAILED;
++ }
++
++ mmcinfo.state = CARD_STATE_STBY;
++ mmc_simple_cmd(request, MMC_CMD_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD);
++
++ break;
++
++ case MMC_CMD_SEND_CSD:
++ retval = mmc_unpack_csd(request, &mmcinfo.csd);
++ mmc_ready = 1;
++ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
++ if (retval && (retval != MMC_ERROR_CRC)) {
++ debug("%s: unable to SEND_CSD error=%d (%s)\n",
++ __func__, retval, mmc_result_to_string(retval));
++ return MMC_INIT_FAILED;
++ }
++ if (mmcinfo.csd.dsr_imp) {
++ debug("%s: driver doesn't support setting DSR\n", __func__);
++ }
++ mmc_configure_card();
++ return MMC_INIT_PASSED;
++
++ default:
++ debug("%s: error! Illegal last cmd %d\n", __func__, request->cmd);
++ return MMC_INIT_FAILED;
++ }
++
++ return MMC_INIT_DOING;
++}
++
++int mmc_init_card(void)
++{
++ struct mmc_request request;
++ int retval;
++
++ mmc_simple_cmd(&request, MMC_CIM_RESET, 0, RESPONSE_NONE); /* reset card */
++ mmc_simple_cmd(&request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
++ mmcinfo.sd = 1; /* assuming a SD card */
++
++ while ((retval = mmc_init_card_state(&request)) == MMC_INIT_DOING)
++ ;
++
++ if (retval == MMC_INIT_PASSED)
++ return MMC_NO_ERROR;
++ else
++ return MMC_NO_RESPONSE;
++}
++
++int mmc_legacy_init(int verbose)
++{
++ if (!__msc_card_detected())
++ return 1;
++
++ /* Step-1: init GPIO */
++ __gpio_as_msc();
++ __msc_init_io();
++
++ /* Step-2: turn on power of card */
++#if !defined(CONFIG_SAKC)
++ __msc_enable_power();
++#endif
++
++ /* Step-3: Reset MSC Controller. */
++ __msc_reset();
++
++ /* Step-3: mask all IRQs. */
++ MMC_IRQ_MASK();
++
++ /* Step-4: stop MMC/SD clock */
++ jz_mmc_stop_clock();
++ mmc_init_card();
++ mmc_select_card();
++
++ mmc_dev.block_read = mmc_bread;
++ fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
++
++ return 0;
++}
++
++/*
++ * Debugging functions
++ */
++static char * mmc_result_strings[] = {
++ "NO_RESPONSE",
++ "NO_ERROR",
++ "ERROR_OUT_OF_RANGE",
++ "ERROR_ADDRESS",
++ "ERROR_BLOCK_LEN",
++ "ERROR_ERASE_SEQ",
++ "ERROR_ERASE_PARAM",
++ "ERROR_WP_VIOLATION",
++ "ERROR_CARD_IS_LOCKED",
++ "ERROR_LOCK_UNLOCK_FAILED",
++ "ERROR_COM_CRC",
++ "ERROR_ILLEGAL_COMMAND",
++ "ERROR_CARD_ECC_FAILED",
++ "ERROR_CC",
++ "ERROR_GENERAL",
++ "ERROR_UNDERRUN",
++ "ERROR_OVERRUN",
++ "ERROR_CID_CSD_OVERWRITE",
++ "ERROR_STATE_MISMATCH",
++ "ERROR_HEADER_MISMATCH",
++ "ERROR_TIMEOUT",
++ "ERROR_CRC",
++ "ERROR_DRIVER_FAILURE",
++};
++
++char * mmc_result_to_string(int i)
++{
++ return mmc_result_strings[i+1];
++}
++
++static char * card_state_strings[] = {
++ "empty",
++ "idle",
++ "ready",
++ "ident",
++ "stby",
++ "tran",
++ "data",
++ "rcv",
++ "prg",
++ "dis",
++};
++
++static inline char * card_state_to_string(int i)
++{
++ return card_state_strings[i+1];
++}
++
++/*
++ * Utility functions
++ */
++
++#define PARSE_U32(_buf,_index) \
++ (((u32)_buf[_index]) << 24) | (((u32)_buf[_index+1]) << 16) | \
++ (((u32)_buf[_index+2]) << 8) | ((u32)_buf[_index+3]);
++
++#define PARSE_U16(_buf,_index) \
++ (((u16)_buf[_index]) << 8) | ((u16)_buf[_index+1]);
++
++int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd)
++{
++ u8 *buf = request->response;
++ int num = 0;
++
++ if (request->result)
++ return request->result;
++
++ if (buf[0] != 0x3f)
++ return MMC_ERROR_HEADER_MISMATCH;
++
++ csd->csd_structure = (buf[1] & 0xc0) >> 6;
++ if (csd->csd_structure)
++ sd2_0 = 1;
++ else
++ sd2_0 = 0;
++
++ switch (csd->csd_structure) {
++ case 0 :/* Version 1.01-1.10
++ * Version 2.00/Standard Capacity */
++ csd->taac = buf[2];
++ csd->nsac = buf[3];
++ csd->tran_speed = buf[4];
++ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
++ csd->read_bl_len = buf[6] & 0x0f;
++ /* for support 2GB card*/
++ if (csd->read_bl_len >= 10)
++ {
++ num = csd->read_bl_len - 9;
++ csd->read_bl_len = 9;
++ }
++
++ csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0;
++ csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0;
++ csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0;
++ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
++ csd->c_size = ((((u16)buf[7]) & 0x03) << 10) | (((u16)buf[8]) << 2) | (((u16)buf[9]) & 0xc0) >> 6;
++
++ if (num)
++ csd->c_size = csd->c_size << num;
++
++
++ csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3;
++ csd->vdd_r_curr_max = buf[9] & 0x07;
++ csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5;
++ csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2;
++ csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7);
++ csd->sector_size = (buf[11] & 0x7c) >> 2;
++ csd->erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5);
++ csd->wp_grp_size = buf[12] & 0x1f;
++ csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0;
++ csd->default_ecc = (buf[13] & 0x60) >> 5;
++ csd->r2w_factor = (buf[13] & 0x1c) >> 2;
++ csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6);
++ if (csd->write_bl_len >= 10)
++ csd->write_bl_len = 9;
++
++ csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0;
++ csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0;
++ csd->copy = (buf[15] & 0x40) ? 1 : 0;
++ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
++ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
++ csd->file_format = (buf[15] & 0x0c) >> 2;
++ csd->ecc = buf[15] & 0x03;
++ break;
++ case 1 : /* Version 2.00/High Capacity */
++ csd->taac = 0;
++ csd->nsac = 0;
++ csd->tran_speed = buf[4];
++ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
++
++ csd->read_bl_len = 9;
++ csd->read_bl_partial = 0;
++ csd->write_blk_misalign = 0;
++ csd->read_blk_misalign = 0;
++ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
++ csd->c_size = ((((u16)buf[8]) & 0x3f) << 16) | (((u16)buf[9]) << 8) | ((u16)buf[10]) ;
++ csd->sector_size = 0x7f;
++ csd->erase_grp_size = 0;
++ csd->wp_grp_size = 0;
++ csd->wp_grp_enable = 0;
++ csd->default_ecc = (buf[13] & 0x60) >> 5;
++ csd->r2w_factor = 4;/* Unused */
++ csd->write_bl_len = 9;
++
++ csd->write_bl_partial = 0;
++ csd->file_format_grp = 0;
++ csd->copy = (buf[15] & 0x40) ? 1 : 0;
++ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
++ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
++ csd->file_format = 0;
++ csd->ecc = buf[15] & 0x03;
++ }
++
++ return 0;
++}
++
++int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state)
++{
++ u8 *buf = request->response;
++
++ if (request->result)
++ return request->result;
++
++ r1->cmd = buf[0];
++ r1->status = PARSE_U32(buf,1);
++
++ debug("mmc_unpack_r1: cmd=%d status=%08x\n", r1->cmd, r1->status);
++
++ if (R1_STATUS(r1->status)) {
++ if (r1->status & R1_OUT_OF_RANGE) return MMC_ERROR_OUT_OF_RANGE;
++ if (r1->status & R1_ADDRESS_ERROR) return MMC_ERROR_ADDRESS;
++ if (r1->status & R1_BLOCK_LEN_ERROR) return MMC_ERROR_BLOCK_LEN;
++ if (r1->status & R1_ERASE_SEQ_ERROR) return MMC_ERROR_ERASE_SEQ;
++ if (r1->status & R1_ERASE_PARAM) return MMC_ERROR_ERASE_PARAM;
++ if (r1->status & R1_WP_VIOLATION) return MMC_ERROR_WP_VIOLATION;
++ /*if (r1->status & R1_CARD_IS_LOCKED) return MMC_ERROR_CARD_IS_LOCKED; */
++ if (r1->status & R1_LOCK_UNLOCK_FAILED) return MMC_ERROR_LOCK_UNLOCK_FAILED;
++ if (r1->status & R1_COM_CRC_ERROR) return MMC_ERROR_COM_CRC;
++ if (r1->status & R1_ILLEGAL_COMMAND) return MMC_ERROR_ILLEGAL_COMMAND;
++ if (r1->status & R1_CARD_ECC_FAILED) return MMC_ERROR_CARD_ECC_FAILED;
++ if (r1->status & R1_CC_ERROR) return MMC_ERROR_CC;
++ if (r1->status & R1_ERROR) return MMC_ERROR_GENERAL;
++ if (r1->status & R1_UNDERRUN) return MMC_ERROR_UNDERRUN;
++ if (r1->status & R1_OVERRUN) return MMC_ERROR_OVERRUN;
++ if (r1->status & R1_CID_CSD_OVERWRITE) return MMC_ERROR_CID_CSD_OVERWRITE;
++ }
++
++ if (buf[0] != request->cmd)
++ return MMC_ERROR_HEADER_MISMATCH;
++
++ /* This should be last - it's the least dangerous error */
++
++ return 0;
++}
++
++int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr)
++{
++ u8 *buf = request->response;
++ if (request->result)
++ return request->result;
++
++ *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */
++ return mmc_unpack_r1(request, r1, state);
++
++}
++
++int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca)
++{
++ u8 *buf = request->response;
++
++ if (request->result)
++ return request->result;
++
++ *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */
++
++ *(buf+1) = 0;
++ *(buf+2) = 0;
++
++ return mmc_unpack_r1(request, r1, state);
++}
++
++int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid)
++{
++ int i;
++ u8 *buf = request->response;
++
++ if (request->result)
++ return request->result;
++
++ cid->mid = buf[1];
++ cid->oid = PARSE_U16(buf,2);
++ for (i = 0 ; i < 5 ; i++)
++ cid->pnm[i] = buf[4+i];
++ cid->pnm[6] = 0;
++ cid->prv = buf[10];
++ cid->psn = PARSE_U32(buf,10);
++ cid->mdt = buf[15];
++
++ printf("Man %02x OEM 0x%04x \"%s\" %d.%d 0x%08x "
++ "Date %02u/%04u\n",
++ cid->mid,
++ cid->oid,
++ cid->pnm,
++ cid->prv >> 4,
++ cid->prv & 0xf,
++ cid->psn,
++ cid->mdt & 0xf,
++ (cid->mdt >> 4) + 2000);
++
++ if (buf[0] != 0x3f)
++ return MMC_ERROR_HEADER_MISMATCH;
++ return 0;
++}
++
++int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3)
++{
++ u8 *buf = request->response;
++
++ if (request->result)
++ return request->result;
++
++ r3->ocr = PARSE_U32(buf,1);
++ debug("mmc_unpack_r3: ocr=%08x\n", r3->ocr);
++
++ if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
++ return 0;
++}
++
++#define KBPS 1
++#define MBPS 1000
++
++static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 };
++static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000,
++ 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 };
++
++u32 mmc_tran_speed(u8 ts)
++{
++ u32 rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3];
++
++ if (rate <= 0) {
++ debug("%s: error - unrecognized speed 0x%02x\n", __func__, ts);
++ return 1;
++ }
++
++ return rate;
++}
++
++void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
++ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer)
++{
++ request->cmd = cmd;
++ request->arg = arg;
++ request->rtype = rtype;
++ request->nob = nob;
++ request->block_len = block_len;
++ request->buffer = buffer;
++ request->cnt = nob * block_len;
++
++ jz_mmc_exec_cmd(request);
++}
+diff --git a/drivers/mmc/jz_mmc.h b/drivers/mmc/jz_mmc.h
+new file mode 100644
+index 0000000..936c514
+--- /dev/null
++++ b/drivers/mmc/jz_mmc.h
+@@ -0,0 +1,176 @@
++/*
++ * linux/drivers/mmc/jz_mmc.h
++ *
++ * Author: Vladimir Shebordaev, Igor Oblakov
++ * Copyright: MontaVista Software Inc.
++ *
++ * $Id: jz_mmc.h,v 1.3 2007-06-15 08:04:20 jlwei Exp $
++ *
++ * 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 __MMC_JZMMC_H__
++#define __MMC_JZMMC_H__
++
++#define ID_TO_RCA(x) ((x)+1)
++#define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */
++
++/* Standard MMC/SD clock speeds */
++#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */
++#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */
++#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
++
++/* Use negative numbers to disambiguate */
++#define MMC_CIM_RESET -1
++#define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
++
++#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
++#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
++#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
++#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
++#define R1_ERASE_PARAM (1 << 27) /* ex, c */
++#define R1_WP_VIOLATION (1 << 26) /* erx, c */
++#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
++#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
++#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
++#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
++#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
++#define R1_CC_ERROR (1 << 20) /* erx, c */
++#define R1_ERROR (1 << 19) /* erx, c */
++#define R1_UNDERRUN (1 << 18) /* ex, c */
++#define R1_OVERRUN (1 << 17) /* ex, c */
++#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
++#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
++#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
++#define R1_ERASE_RESET (1 << 13) /* sr, c */
++#define R1_STATUS(x) (x & 0xFFFFE000)
++
++#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
++
++#define MMC_PROGRAM_CID 26 /* adtc R1 */
++#define MMC_PROGRAM_CSD 27 /* adtc R1 */
++
++#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
++#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */
++#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
++#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
++#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
++#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
++
++
++enum mmc_result_t {
++ MMC_NO_RESPONSE = -1,
++ MMC_NO_ERROR = 0,
++ MMC_ERROR_OUT_OF_RANGE,
++ MMC_ERROR_ADDRESS,
++ MMC_ERROR_BLOCK_LEN,
++ MMC_ERROR_ERASE_SEQ,
++ MMC_ERROR_ERASE_PARAM,
++ MMC_ERROR_WP_VIOLATION,
++ MMC_ERROR_CARD_IS_LOCKED,
++ MMC_ERROR_LOCK_UNLOCK_FAILED,
++ MMC_ERROR_COM_CRC,
++ MMC_ERROR_ILLEGAL_COMMAND,
++ MMC_ERROR_CARD_ECC_FAILED,
++ MMC_ERROR_CC,
++ MMC_ERROR_GENERAL,
++ MMC_ERROR_UNDERRUN,
++ MMC_ERROR_OVERRUN,
++ MMC_ERROR_CID_CSD_OVERWRITE,
++ MMC_ERROR_STATE_MISMATCH,
++ MMC_ERROR_HEADER_MISMATCH,
++ MMC_ERROR_TIMEOUT,
++ MMC_ERROR_CRC,
++ MMC_ERROR_DRIVER_FAILURE,
++};
++
++enum card_state {
++ CARD_STATE_EMPTY = -1,
++ CARD_STATE_IDLE = 0,
++ CARD_STATE_READY = 1,
++ CARD_STATE_IDENT = 2,
++ CARD_STATE_STBY = 3,
++ CARD_STATE_TRAN = 4,
++ CARD_STATE_DATA = 5,
++ CARD_STATE_RCV = 6,
++ CARD_STATE_PRG = 7,
++ CARD_STATE_DIS = 8,
++};
++
++enum mmc_rsp_t {
++ RESPONSE_NONE = 0,
++ RESPONSE_R1 = 1,
++ RESPONSE_R1B = 2,
++ RESPONSE_R2_CID = 3,
++ RESPONSE_R2_CSD = 4,
++ RESPONSE_R3 = 5,
++ RESPONSE_R4 = 6,
++ RESPONSE_R5 = 7,
++ RESPONSE_R6 = 8,
++};
++
++struct mmc_response_r1 {
++ u8 cmd;
++ u32 status;
++};
++
++struct mmc_response_r3 {
++ u32 ocr;
++};
++
++/* the information structure of MMC/SD Card */
++struct mmc_info {
++ int id; /* Card index */
++ int sd; /* MMC or SD card */
++ int rca; /* RCA */
++ u32 scr; /* SCR 63:32*/
++ int flags; /* Ejected, inserted */
++ enum card_state state; /* empty, ident, ready, whatever */
++
++ /* Card specific information */
++ struct mmc_cid cid;
++ struct mmc_csd csd;
++ u32 block_num;
++ u32 block_len;
++ u32 erase_unit;
++};
++
++struct mmc_info mmcinfo;
++
++struct mmc_request {
++ int index; /* Slot index - used for CS lines */
++ int cmd; /* Command to send */
++ u32 arg; /* Argument to send */
++ enum mmc_rsp_t rtype; /* Response type expected */
++
++ /* Data transfer (these may be modified at the low level) */
++ u16 nob; /* Number of blocks to transfer*/
++ u16 block_len; /* Block length */
++ u8 *buffer; /* Data buffer */
++ u32 cnt; /* Data length, for PIO */
++
++ /* Results */
++ u8 response[18]; /* Buffer to store response - CRC is optional */
++ enum mmc_result_t result;
++};
++
++char * mmc_result_to_string(int);
++int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd);
++int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state);
++int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca);
++int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr);
++int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid);
++int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3);
++
++void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
++ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer);
++u32 mmc_tran_speed(u8 ts);
++void jz_mmc_set_clock(int sd, u32 rate);
++
++static inline void mmc_simple_cmd(struct mmc_request *request, int cmd, u32 arg, enum mmc_rsp_t rtype)
++{
++ mmc_send_cmd( request, cmd, arg, 0, 0, rtype, 0);
++}
++
++#endif /* __MMC_JZMMC_H__ */
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index 7bff444..7b33be0 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -31,6 +31,15 @@
+ /*
+ * Miscellaneous configurable options
+ */
++#define CONFIG_JZ4740_MMC
++#define CONFIG_MMC 1
++#define CONFIG_FAT 1
++#define CONFIG_DOS_PARTITION 1
++#define CONFIG_CMD_MMC
++#define CONFIG_CMD_FAT
++#define CONFIG_CMD_EXT2
++
++
+ #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
+ #define CONFIG_SYS_INIT_SP_OFFSET 0x400000
+ #define CONFIG_SYS_LOAD_ADDR 0x80600000
+diff --git a/include/mmc.h b/include/mmc.h
+index a13e2bd..3c4761c 100644
+--- a/include/mmc.h
++++ b/include/mmc.h
+@@ -283,4 +283,44 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
+ int mmc_legacy_init(int verbose);
+ #endif
+
++struct mmc_csd
++{
++ u8 csd_structure:2,
++ spec_vers:4,
++ rsvd1:2;
++ u8 taac;
++ u8 nsac;
++ u8 tran_speed;
++ u16 ccc:12,
++ read_bl_len:4;
++ u32 c_size:22;
++ u64 read_bl_partial:1,
++ write_blk_misalign:1,
++ read_blk_misalign:1,
++ dsr_imp:1,
++ rsvd2:2,
++ vdd_r_curr_min:3,
++ vdd_r_curr_max:3,
++ vdd_w_curr_min:3,
++ vdd_w_curr_max:3,
++ c_size_mult:3,
++ sector_size:5,
++ erase_grp_size:5,
++ wp_grp_size:5,
++ wp_grp_enable:1,
++ default_ecc:2,
++ r2w_factor:3,
++ write_bl_len:4,
++ write_bl_partial:1,
++ rsvd3:5;
++ u8 file_format_grp:1,
++ copy:1,
++ perm_write_protect:1,
++ tmp_write_protect:1,
++ file_format:2,
++ ecc:2;
++ u8 crc:7;
++ u8 one:1;
++};
++
+ #endif /* _MMC_H_ */
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch b/package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch
new file mode 100644
index 0000000..73e0324
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch
@@ -0,0 +1,200 @@
+From c52b6168979d03fc31205444c3278c537787472a Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Wed, 10 Oct 2012 18:39:55 +0800
+Subject: [PATCH 4/6] add more boot options(F1/F2/F3/F4/M/S)
+
+---
+ arch/mips/include/asm/global_data.h | 3 +++
+ arch/mips/lib/bootm.c | 17 ++++++++++++++++-
+ board/qi/qi_lb60/qi_lb60.c | 26 +++++++++++++++++++++++---
+ common/main.c | 21 +++++++++++++++++++--
+ include/configs/qi_lb60.h | 32 ++++++++++++++++++++++++++++++++
+ 5 files changed, 93 insertions(+), 6 deletions(-)
+
+diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
+index 6e2cdc7..cd03d7e 100644
+--- a/arch/mips/include/asm/global_data.h
++++ b/arch/mips/include/asm/global_data.h
+@@ -59,6 +59,9 @@ typedef struct global_data {
+ unsigned long env_valid; /* Checksum of Environment valid? */
+ void **jt; /* jump table */
+ char env_buf[32]; /* buffer for getenv() before reloc. */
++#if defined(CONFIG_NANONOTE)
++ unsigned long boot_option;
++#endif
+ } gd_t;
+
+ #include <asm-generic/global_data_flags.h>
+diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
+index 608c1a7..e00416b 100644
+--- a/arch/mips/lib/bootm.c
++++ b/arch/mips/lib/bootm.c
+@@ -47,10 +47,25 @@ int do_bootm_linux(int flag, int argc, char * const argv[],
+ bootm_headers_t *images)
+ {
+ void (*theKernel) (int, char **, char **, int *);
+- char *commandline = getenv("bootargs");
++ char *commandline;
+ char env_buf[12];
+ char *cp;
+
++#if defined(CONFIG_NANONOTE)
++ if (gd->boot_option & BOOT_FROM_MEMCARD)
++ commandline = getenv ("bootargsfromsd");
++ else if (gd->boot_option & BOOT_WITH_F1)
++ commandline = getenv ("bootargsf1");
++ else if (gd->boot_option & BOOT_WITH_F2)
++ commandline = getenv ("bootargsf2");
++ else if (gd->boot_option & BOOT_WITH_F3)
++ commandline = getenv ("bootargsf3");
++ else if (gd->boot_option & BOOT_WITH_F4)
++ commandline = getenv ("bootargsf4");
++ else
++#endif
++ commandline = getenv ("bootargs");
++
+ if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
+ return 1;
+
+diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
+index a2ba648..d622219 100644
+--- a/board/qi/qi_lb60/qi_lb60.c
++++ b/board/qi/qi_lb60/qi_lb60.c
+@@ -15,7 +15,7 @@ DECLARE_GLOBAL_DATA_PTR;
+
+ static void gpio_init(void)
+ {
+- unsigned int i;
++ unsigned int i, j;
+
+ /* Initialize NAND Flash Pins */
+ __gpio_as_nand();
+@@ -42,14 +42,34 @@ static void gpio_init(void)
+
+ if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){
+ printf("[S] pressed, enable UART0\n");
++ gd->boot_option |= BOOT_WITH_ENABLE_UART;
+ __gpio_as_uart0();
+ } else {
+ __gpio_as_input(GPIO_KEYIN_8);
+ __gpio_enable_pull(GPIO_KEYIN_8);
+ }
+
+- /* enable the TP4, TP5 as UART0 */
+- __gpio_jtag_to_uart0();
++ if (__gpio_get_pin(GPIO_KEYIN_BASE + 3) == 0) {
++ printf("[M] pressed, boot from memory card\n");
++ gd->boot_option |= BOOT_FROM_MEMCARD;
++ __gpio_jtag_to_uart0();
++ }
++
++ for (j = 0; j < 4; j++) {
++ for (i = 0; i < 4; i++)
++ __gpio_set_pin(GPIO_KEYOUT_BASE + i);
++
++ __gpio_clear_pin(GPIO_KEYOUT_BASE + j);
++
++ if (__gpio_get_pin(GPIO_KEYIN_BASE) == 0) {
++ printf("[F%d] pressed", (j + 1));
++ gd->boot_option |= (1 << (j + 2));
++ /* BOOT_WITH_F1 (1 << 2) */
++ /* BOOT_WITH_F2 (1 << 3) */
++ /* BOOT_WITH_F3 (1 << 4) */
++ /* BOOT_WITH_F4 (1 << 5) */
++ }
++ }
+
+ __gpio_as_output(GPIO_AUDIO_POP);
+ __gpio_set_pin(GPIO_AUDIO_POP);
+diff --git a/common/main.c b/common/main.c
+index 9507cec..dbfb7ca 100644
+--- a/common/main.c
++++ b/common/main.c
+@@ -355,7 +355,11 @@ void main_loop (void)
+ #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+ s = getenv ("bootdelay");
+ bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
+-
++#if defined(CONFIG_NANONOTE)
++ DECLARE_GLOBAL_DATA_PTR;
++ if (gd->boot_option & BOOT_WITH_ENABLE_UART)
++ bootdelay = 3;
++# endif
+ debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
+
+ #if defined(CONFIG_MENU_SHOW)
+@@ -379,7 +383,20 @@ void main_loop (void)
+ }
+ else
+ #endif /* CONFIG_BOOTCOUNT_LIMIT */
+- s = getenv ("bootcmd");
++#if defined(CONFIG_NANONOTE)
++ if (gd->boot_option & BOOT_FROM_MEMCARD)
++ s = getenv ("bootcmdfromsd");
++ else if (gd->boot_option & BOOT_WITH_F1)
++ s = getenv ("bootcmdf1");
++ else if (gd->boot_option & BOOT_WITH_F2)
++ s = getenv ("bootcmdf2");
++ else if (gd->boot_option & BOOT_WITH_F3)
++ s = getenv ("bootcmdf3");
++ else if (gd->boot_option & BOOT_WITH_F4)
++ s = getenv ("bootcmdf4");
++ else
++#endif
++ s = getenv ("bootcmd");
+
+ debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
+
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index 7b33be0..52b370c 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -31,6 +31,7 @@
+ /*
+ * Miscellaneous configurable options
+ */
++#define CONFIG_NANONOTE
+ #define CONFIG_JZ4740_MMC
+ #define CONFIG_MMC 1
+ #define CONFIG_FAT 1
+@@ -39,6 +40,37 @@
+ #define CONFIG_CMD_FAT
+ #define CONFIG_CMD_EXT2
+
++#define CONFIG_CMD_UBIFS
++#define CONFIG_CMD_UBI
++#define CONFIG_MTD_PARTITIONS
++#define CONFIG_MTD_DEVICE
++#define CONFIG_CMD_MTDPARTS
++#define CONFIG_CMD_UBI
++#define CONFIG_CMD_UBIFS
++#define CONFIG_LZO
++#define CONFIG_RBTREE
++
++#define MTDIDS_DEFAULT "nand0=jz4740-nand"
++#define MTDPARTS_DEFAULT "mtdparts=jz4740-nand:4M@0(uboot)ro,4M@4M(kernel)ro,512M@8M(rootfs)ro,-(data)ro"
++
++#define BOOT_FROM_MEMCARD 1
++#define BOOT_WITH_ENABLE_UART (1 << 1) /* Vaule for global_data.h gd->boot_option */
++#define BOOT_WITH_F1 (1 << 2)
++#define BOOT_WITH_F2 (1 << 3)
++#define BOOT_WITH_F3 (1 << 4)
++#define BOOT_WITH_F4 (1 << 5)
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ "bootcmdfromsd=mmc init; ext2load mmc 0 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsfromsd=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \
++ "bootcmdf1=mmc init; ext2load mmc 0:1 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsf1=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \
++ "bootcmdf2=mmc init; ext2load mmc 0:2 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsf2=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p2 rw rootwait\0" \
++ "bootcmdf3=mmc init; ext2load mmc 0:3 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsf3=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p3 rw rootwait\0" \
++ "bootcmdf4=mtdparts default;ubi part rootfs;ubifsmount rootfs;ubifsload 0x80600000 /boot/uImage; bootm;\0" \
++ "bootargsf4=mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
+
+ #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
+ #define CONFIG_SYS_INIT_SP_OFFSET 0x400000
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch b/package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch
new file mode 100644
index 0000000..2c550f7
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch
@@ -0,0 +1,847 @@
+From ca8c5216cfd3ad3fda9867ed2d157ae5a209834b Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Wed, 10 Oct 2012 22:05:27 +0800
+Subject: [PATCH 5/6] add nanonote lcd support
+
+---
+ arch/mips/include/asm/global_data.h | 1 +
+ arch/mips/include/asm/jz4740.h | 90 ++++++++
+ arch/mips/lib/board.c | 6 +
+ common/lcd.c | 9 +-
+ drivers/video/Makefile | 1 +
+ drivers/video/nanonote_gpm940b0.c | 400 +++++++++++++++++++++++++++++++++++
+ drivers/video/nanonote_gpm940b0.h | 135 ++++++++++++
+ include/configs/qi_lb60.h | 7 +
+ include/lcd.h | 52 ++++-
+ 9 files changed, 697 insertions(+), 4 deletions(-)
+ create mode 100644 drivers/video/nanonote_gpm940b0.c
+ create mode 100644 drivers/video/nanonote_gpm940b0.h
+
+diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
+index cd03d7e..7cec2de 100644
+--- a/arch/mips/include/asm/global_data.h
++++ b/arch/mips/include/asm/global_data.h
+@@ -44,6 +44,7 @@ typedef struct global_data {
+ unsigned long per_clk; /* Peripheral bus clock */
+ unsigned long mem_clk; /* Memory bus clock */
+ unsigned long dev_clk; /* Device clock */
++ unsigned long fb_base; /* base address of framebuffer */
+ /* "static data" needed by most of timer.c */
+ unsigned long tbl;
+ unsigned long lastinc;
+diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h
+index 68287fb..13724a2 100644
+--- a/arch/mips/include/asm/jz4740.h
++++ b/arch/mips/include/asm/jz4740.h
+@@ -1312,5 +1312,95 @@ do { \
+ while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \
+ } while (0)
+
++/*************************************************************************
++ * LCD (LCD Controller)
++ *************************************************************************/
++#define REG32(addr) *((volatile u32 *)(addr))
++
++#define CPM_BASE 0xB0000000
++#define CPM_CPCCR (CPM_BASE+0x00)
++#define REG_CPM_CPCCR REG32(CPM_CPCCR)
++
++#define LCD_BASE 0xB3050000
++#define LCD_CFG (LCD_BASE + 0x00) /* LCD Configure Register */
++#define LCD_VSYNC (LCD_BASE + 0x04) /* Vertical Synchronize Register */
++#define LCD_HSYNC (LCD_BASE + 0x08) /* Horizontal Synchronize Register */
++#define LCD_VAT (LCD_BASE + 0x0c) /* Virtual Area Setting Register */
++#define LCD_DAH (LCD_BASE + 0x10) /* Display Area Horizontal Start/End Point */
++#define LCD_DAV (LCD_BASE + 0x14) /* Display Area Vertical Start/End Point */
++#define LCD_PS (LCD_BASE + 0x18) /* PS Signal Setting */
++#define LCD_CLS (LCD_BASE + 0x1c) /* CLS Signal Setting */
++#define LCD_SPL (LCD_BASE + 0x20) /* SPL Signal Setting */
++#define LCD_REV (LCD_BASE + 0x24) /* REV Signal Setting */
++#define LCD_CTRL (LCD_BASE + 0x30) /* LCD Control Register */
++#define LCD_STATE (LCD_BASE + 0x34) /* LCD Status Register */
++#define LCD_IID (LCD_BASE + 0x38) /* Interrupt ID Register */
++#define LCD_DA0 (LCD_BASE + 0x40) /* Descriptor Address Register 0 */
++#define LCD_SA0 (LCD_BASE + 0x44) /* Source Address Register 0 */
++#define LCD_FID0 (LCD_BASE + 0x48) /* Frame ID Register 0 */
++#define LCD_CMD0 (LCD_BASE + 0x4c) /* DMA Command Register 0 */
++#define LCD_DA1 (LCD_BASE + 0x50) /* Descriptor Address Register 1 */
++#define LCD_SA1 (LCD_BASE + 0x54) /* Source Address Register 1 */
++#define LCD_FID1 (LCD_BASE + 0x58) /* Frame ID Register 1 */
++#define LCD_CMD1 (LCD_BASE + 0x5c) /* DMA Command Register 1 */
++
++#define REG_LCD_CFG REG32(LCD_CFG)
++#define REG_LCD_VSYNC REG32(LCD_VSYNC)
++#define REG_LCD_HSYNC REG32(LCD_HSYNC)
++#define REG_LCD_VAT REG32(LCD_VAT)
++#define REG_LCD_DAH REG32(LCD_DAH)
++#define REG_LCD_DAV REG32(LCD_DAV)
++#define REG_LCD_PS REG32(LCD_PS)
++#define REG_LCD_CLS REG32(LCD_CLS)
++#define REG_LCD_SPL REG32(LCD_SPL)
++#define REG_LCD_REV REG32(LCD_REV)
++#define REG_LCD_CTRL REG32(LCD_CTRL)
++#define REG_LCD_STATE REG32(LCD_STATE)
++#define REG_LCD_IID REG32(LCD_IID)
++#define REG_LCD_DA0 REG32(LCD_DA0)
++#define REG_LCD_SA0 REG32(LCD_SA0)
++#define REG_LCD_FID0 REG32(LCD_FID0)
++#define REG_LCD_CMD0 REG32(LCD_CMD0)
++#define REG_LCD_DA1 REG32(LCD_DA1)
++#define REG_LCD_SA1 REG32(LCD_SA1)
++#define REG_LCD_FID1 REG32(LCD_FID1)
++#define REG_LCD_CMD1 REG32(LCD_CMD1)
++
++#define LCD_CTRL_BPP_BIT 0 /* Bits Per Pixel */
++#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT)
++ #define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT) /* 1 bpp */
++ #define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT) /* 2 bpp */
++ #define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT) /* 4 bpp */
++ #define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT) /* 8 bpp */
++ #define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT) /* 15/16 bpp */
++ #define LCD_CTRL_BPP_18_24 (5 << LCD_CTRL_BPP_BIT) /* 18/24/32 bpp */
++
++#define LCD_CTRL_BST_BIT 28 /* Burst Length Selection */
++#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT)
++ #define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT) /* 4-word */
++ #define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT) /* 8-word */
++ #define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT) /* 16-word */
++#define LCD_CTRL_RGB565 (0 << 27) /* RGB565 mode */
++#define LCD_CTRL_RGB555 (1 << 27) /* RGB555 mode */
++#define LCD_CTRL_OFUP (1 << 26) /* Output FIFO underrun protection enable */
++#define LCD_CTRL_FRC_BIT 24 /* STN FRC Algorithm Selection */
++#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT)
++ #define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT) /* 16 grayscale */
++ #define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT) /* 4 grayscale */
++ #define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT) /* 2 grayscale */
++
++#define CPM_LPCDR (CPM_BASE+0x64)
++#define CPM_CLKGR (CPM_BASE+0x20)
++#define REG_CPM_LPCDR REG32(CPM_LPCDR)
++#define REG_CPM_CLKGR REG32(CPM_CLKGR)
++
++#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU)
++#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD)
++#define __cpm_set_pixdiv(v) \
++ (REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT)))
++#define __cpm_set_ldiv(v) \
++ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT)))
++#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD)
++
+ #endif /* !__ASSEMBLY__ */
+ #endif /* __JZ4740_H__ */
+diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c
+index b14b33e..c2e64d9 100644
+--- a/arch/mips/lib/board.c
++++ b/arch/mips/lib/board.c
+@@ -172,6 +172,12 @@ void board_init_f(ulong bootflag)
+ addr &= ~(4096 - 1);
+ debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
+
++#ifdef CONFIG_LCD
++ /* reserve memory for LCD display (always full pages) */
++ addr = lcd_setmem (addr);
++ gd->fb_base = addr;
++#endif /* CONFIG_LCD */
++
+ /* Reserve memory for U-Boot code, data & bss
+ * round down to next 16 kB limit
+ */
+diff --git a/common/lcd.c b/common/lcd.c
+index b6be800..af1281a 100644
+--- a/common/lcd.c
++++ b/common/lcd.c
+@@ -263,6 +263,13 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
+ lcd_color_fg : lcd_color_bg;
+ bits <<= 1;
+ }
++#elif LCD_BPP == LCD_COLOR32
++ uint *m = (uint *)d;
++ for (c=0; c<32; ++c) {
++ *m++ = (bits & 0x80) ?
++ lcd_color_fg : lcd_color_bg;
++ bits <<= 1;
++ }
+ #endif
+ }
+ #if LCD_BPP == LCD_MONOCHROME
+@@ -509,7 +516,7 @@ static inline ushort *configuration_get_cmap(void)
+ return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]);
+ #elif defined(CONFIG_ATMEL_LCD)
+ return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0));
+-#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB)
++#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) && !defined(CONFIG_VIDEO_GPM940B0)
+ return panel_info.cmap;
+ #else
+ #if defined(CONFIG_LCD_LOGO)
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index ebb6da8..03625bc 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -50,6 +50,7 @@ COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o
+ COBJS-$(CONFIG_VIDEO_SM501) += sm501.o
+ COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
+ COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
++COBJS-$(CONFIG_VIDEO_GPM940B0) += nanonote_gpm940b0.o
+
+ COBJS := $(sort $(COBJS-y))
+ SRCS := $(COBJS:.o=.c)
+diff --git a/drivers/video/nanonote_gpm940b0.c b/drivers/video/nanonote_gpm940b0.c
+new file mode 100644
+index 0000000..11efb72
+--- /dev/null
++++ b/drivers/video/nanonote_gpm940b0.c
+@@ -0,0 +1,400 @@
++/*
++ * JzRISC lcd controller
++ *
++ * Xiangfu Liu <xiangfu@sharism.cc>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <config.h>
++#include <common.h>
++#include <lcd.h>
++
++#include <asm/io.h> /* virt_to_phys() */
++#include <asm/jz4740.h>
++
++#include "nanonote_gpm940b0.h"
++
++#define align2(n) (n)=((((n)+1)>>1)<<1)
++#define align4(n) (n)=((((n)+3)>>2)<<2)
++#define align8(n) (n)=((((n)+7)>>3)<<3)
++
++struct jzfb_info {
++ unsigned int cfg; /* panel mode and pin usage etc. */
++ unsigned int w;
++ unsigned int h;
++ unsigned int bpp; /* bit per pixel */
++ unsigned int fclk; /* frame clk */
++ unsigned int hsw; /* hsync width, in pclk */
++ unsigned int vsw; /* vsync width, in line count */
++ unsigned int elw; /* end of line, in pclk */
++ unsigned int blw; /* begin of line, in pclk */
++ unsigned int efw; /* end of frame, in line count */
++ unsigned int bfw; /* begin of frame, in line count */
++};
++
++static struct jzfb_info jzfb = {
++ MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N,
++ 320, 240, 32, 70, 1, 1, 273, 140, 1, 20
++};
++
++vidinfo_t panel_info = {
++ 320, 240, LCD_BPP,
++};
++
++void *lcd_base;
++void *lcd_console_address;
++int lcd_line_length;
++int lcd_color_fg;
++int lcd_color_bg;
++short console_col;
++short console_row;
++
++static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid)
++{
++ u_long palette_mem_size;
++ struct jz_fb_info *fbi = &vid->jz_fb;
++ int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8;
++
++ fbi->screen = (u_long)lcdbase;
++ fbi->palette_size = 256;
++ palette_mem_size = fbi->palette_size * sizeof(u16);
++
++ debug("jz_lcd.c palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
++ /* locate palette and descs at end of page following fb */
++ fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
++
++ return 0;
++}
++
++static void jz_lcd_desc_init(vidinfo_t *vid)
++{
++ struct jz_fb_info * fbi;
++ fbi = &vid->jz_fb;
++ fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 3*16);
++ fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 2*16);
++ fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 1*16);
++
++ #define BYTES_PER_PANEL (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8)
++
++ /* populate descriptors */
++ fbi->dmadesc_fblow->fdadr = virt_to_phys(fbi->dmadesc_fblow);
++ fbi->dmadesc_fblow->fsadr = virt_to_phys((void *)(fbi->screen + BYTES_PER_PANEL));
++ fbi->dmadesc_fblow->fidr = 0;
++ fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL / 4 ;
++
++ fbi->fdadr1 = virt_to_phys(fbi->dmadesc_fblow); /* only used in dual-panel mode */
++
++ fbi->dmadesc_fbhigh->fsadr = virt_to_phys((void *)fbi->screen);
++ fbi->dmadesc_fbhigh->fidr = 0;
++ fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL / 4; /* length in word */
++
++ fbi->dmadesc_palette->fsadr = virt_to_phys((void *)fbi->palette);
++ fbi->dmadesc_palette->fidr = 0;
++ fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2)/4 | (1<<28);
++
++ if(NBITS(vid->vl_bpix) < 12) {
++ /* assume any mode with <12 bpp is palette driven */
++ fbi->dmadesc_palette->fdadr = virt_to_phys(fbi->dmadesc_fbhigh);
++ fbi->dmadesc_fbhigh->fdadr = virt_to_phys(fbi->dmadesc_palette);
++ /* flips back and forth between pal and fbhigh */
++ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_palette);
++ } else {
++ /* palette shouldn't be loaded in true-color mode */
++ fbi->dmadesc_fbhigh->fdadr = virt_to_phys((void *)fbi->dmadesc_fbhigh);
++ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_fbhigh); /* no pal just fbhigh */
++ }
++}
++
++static int jz_lcd_hw_init(vidinfo_t *vid)
++{
++ struct jz_fb_info *fbi = &vid->jz_fb;
++ unsigned int val = 0;
++ unsigned int pclk;
++ unsigned int stnH;
++ int pll_div;
++
++ /* Setting Control register */
++ switch (jzfb.bpp) {
++ case 1:
++ val |= LCD_CTRL_BPP_1;
++ break;
++ case 2:
++ val |= LCD_CTRL_BPP_2;
++ break;
++ case 4:
++ val |= LCD_CTRL_BPP_4;
++ break;
++ case 8:
++ val |= LCD_CTRL_BPP_8;
++ break;
++ case 15:
++ val |= LCD_CTRL_RGB555;
++ case 16:
++ val |= LCD_CTRL_BPP_16;
++ break;
++ case 17 ... 32:
++ val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */
++ break;
++
++ default:
++ printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp);
++ val |= LCD_CTRL_BPP_16;
++ break;
++ }
++
++ switch (jzfb.cfg & MODE_MASK) {
++ case MODE_STN_MONO_DUAL:
++ case MODE_STN_COLOR_DUAL:
++ case MODE_STN_MONO_SINGLE:
++ case MODE_STN_COLOR_SINGLE:
++ switch (jzfb.bpp) {
++ case 1:
++ /* val |= LCD_CTRL_PEDN; */
++ case 2:
++ val |= LCD_CTRL_FRC_2;
++ break;
++ case 4:
++ val |= LCD_CTRL_FRC_4;
++ break;
++ case 8:
++ default:
++ val |= LCD_CTRL_FRC_16;
++ break;
++ }
++ break;
++ }
++
++ val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */
++ val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */
++
++ switch (jzfb.cfg & MODE_MASK) {
++ case MODE_STN_MONO_DUAL:
++ case MODE_STN_COLOR_DUAL:
++ case MODE_STN_MONO_SINGLE:
++ case MODE_STN_COLOR_SINGLE:
++ switch (jzfb.cfg & STN_DAT_PINMASK) {
++ case STN_DAT_PIN1:
++ /* Do not adjust the hori-param value. */
++ break;
++ case STN_DAT_PIN2:
++ align2(jzfb.hsw);
++ align2(jzfb.elw);
++ align2(jzfb.blw);
++ break;
++ case STN_DAT_PIN4:
++ align4(jzfb.hsw);
++ align4(jzfb.elw);
++ align4(jzfb.blw);
++ break;
++ case STN_DAT_PIN8:
++ align8(jzfb.hsw);
++ align8(jzfb.elw);
++ align8(jzfb.blw);
++ break;
++ }
++ break;
++ }
++
++ REG_LCD_CTRL = val;
++
++ switch (jzfb.cfg & MODE_MASK) {
++ case MODE_STN_MONO_DUAL:
++ case MODE_STN_COLOR_DUAL:
++ case MODE_STN_MONO_SINGLE:
++ case MODE_STN_COLOR_SINGLE:
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
++ stnH = jzfb.h >> 1;
++ else
++ stnH = jzfb.h;
++
++ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
++ REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw);
++
++ /* Screen setting */
++ REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw);
++ REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w);
++ REG_LCD_DAV = (0 << 16) | (stnH);
++
++ /* AC BIAs signal */
++ REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw);
++
++ break;
++
++ case MODE_TFT_GEN:
++ case MODE_TFT_SHARP:
++ case MODE_TFT_CASIO:
++ case MODE_TFT_SAMSUNG:
++ case MODE_8BIT_SERIAL_TFT:
++ case MODE_TFT_18BIT:
++ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
++ REG_LCD_HSYNC = (0 << 16) | jzfb.hsw;
++ REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h);
++ REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w );
++ REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \
++ | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw);
++ break;
++ }
++
++ switch (jzfb.cfg & MODE_MASK) {
++ case MODE_TFT_SAMSUNG:
++ {
++ unsigned int total, tp_s, tp_e, ckv_s, ckv_e;
++ unsigned int rev_s, rev_e, inv_s, inv_e;
++
++ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
++
++ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
++ tp_s = jzfb.blw + jzfb.w + 1;
++ tp_e = tp_s + 1;
++ ckv_s = tp_s - pclk/(1000000000/4100);
++ ckv_e = tp_s + total;
++ rev_s = tp_s - 11; /* -11.5 clk */
++ rev_e = rev_s + total;
++ inv_s = tp_s;
++ inv_e = inv_s + total;
++ REG_LCD_CLS = (tp_s << 16) | tp_e;
++ REG_LCD_PS = (ckv_s << 16) | ckv_e;
++ REG_LCD_SPL = (rev_s << 16) | rev_e;
++ REG_LCD_REV = (inv_s << 16) | inv_e;
++ jzfb.cfg |= STFT_REVHI | STFT_SPLHI;
++ break;
++ }
++ case MODE_TFT_SHARP:
++ {
++ unsigned int total, cls_s, cls_e, ps_s, ps_e;
++ unsigned int spl_s, spl_e, rev_s, rev_e;
++ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
++ spl_s = 1;
++ spl_e = spl_s + 1;
++ cls_s = 0;
++ cls_e = total - 60; /* > 4us (pclk = 80ns) */
++ ps_s = cls_s;
++ ps_e = cls_e;
++ rev_s = total - 40; /* > 3us (pclk = 80ns) */
++ rev_e = rev_s + total;
++ jzfb.cfg |= STFT_PSHI;
++ REG_LCD_SPL = (spl_s << 16) | spl_e;
++ REG_LCD_CLS = (cls_s << 16) | cls_e;
++ REG_LCD_PS = (ps_s << 16) | ps_e;
++ REG_LCD_REV = (rev_s << 16) | rev_e;
++ break;
++ }
++ case MODE_TFT_CASIO:
++ break;
++ }
++
++ /* Configure the LCD panel */
++ REG_LCD_CFG = jzfb.cfg;
++
++ /* Timing setting */
++ __cpm_stop_lcd();
++
++ val = jzfb.fclk; /* frame clk */
++ if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) {
++ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
++ } else {
++ /* serial mode: Hsync period = 3*Width_Pixel */
++ pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) *
++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
++ }
++
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
++ pclk = (pclk * 3);
++
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
++ pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4);
++
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
++ pclk >>= 1;
++
++ pll_div = (REG_CPM_CPCCR & CPM_CPCCR_PCS); /* clock source,0:pllout/2 1: pllout */
++ pll_div = pll_div ? 1 : 2;
++ val = (__cpm_get_pllout() / pll_div) / pclk;
++ val--;
++ if (val > 0x1ff) {
++ printf("CPM_LPCDR too large, set it to 0x1ff\n");
++ val = 0x1ff;
++ }
++ __cpm_set_pixdiv(val);
++
++ val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
++ if (val > 150000000) {
++ printf("Warning: LCDClock=%d\n, LCDClock must less or equal to 150MHz.\n", val);
++ printf("Change LCDClock to 150MHz\n");
++ val = 150000000;
++ }
++ val = (__cpm_get_pllout() / pll_div) / val;
++ val--;
++ if (val > 0x1f) {
++ printf("CPM_CPCCR.LDIV too large, set it to 0x1f\n");
++ val = 0x1f;
++ }
++ __cpm_set_ldiv( val );
++ REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */
++
++ __cpm_start_lcd();
++ udelay(1000);
++
++ REG_LCD_DA0 = fbi->fdadr0; /* frame descripter*/
++
++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
++ REG_LCD_DA1 = fbi->fdadr1; /* frame descripter*/
++
++ return 0;
++}
++
++void lcd_ctrl_init (void *lcdbase)
++{
++ __lcd_display_pin_init();
++ __lcd_display_on() ;
++
++ jz_lcd_init_mem(lcdbase, &panel_info);
++ jz_lcd_desc_init(&panel_info);
++ jz_lcd_hw_init(&panel_info);
++
++}
++
++/*
++ * Before enabled lcd controller, lcd registers should be configured correctly.
++ */
++void lcd_enable (void)
++{
++ REG_LCD_CTRL &= ~(1<<4); /* LCDCTRL.DIS */
++ REG_LCD_CTRL |= 1<<3; /* LCDCTRL.ENA*/
++}
++
++void lcd_disable (void)
++{
++ REG_LCD_CTRL |= (1<<4);
++}
++
++void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
++{
++}
++
++void lcd_initcolregs (void)
++{
++}
+diff --git a/drivers/video/nanonote_gpm940b0.h b/drivers/video/nanonote_gpm940b0.h
+new file mode 100644
+index 0000000..efe491e
+--- /dev/null
++++ b/drivers/video/nanonote_gpm940b0.h
+@@ -0,0 +1,135 @@
++/*
++ * JzRISC lcd controller
++ *
++ * Xiangfu Liu <xiangfu@sharism.cc>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __QI_LB60_GPM940B0_H__
++#define __QI_LB60_GPM940B0_H__
++
++struct lcd_desc{
++ unsigned int next_desc; /* LCDDAx */
++ unsigned int databuf; /* LCDSAx */
++ unsigned int frame_id; /* LCDFIDx */
++ unsigned int cmd; /* LCDCMDx */
++};
++
++#define MODE_MASK 0x0f
++#define MODE_TFT_GEN 0x00
++#define MODE_TFT_SHARP 0x01
++#define MODE_TFT_CASIO 0x02
++#define MODE_TFT_SAMSUNG 0x03
++#define MODE_CCIR656_NONINT 0x04
++#define MODE_CCIR656_INT 0x05
++#define MODE_STN_COLOR_SINGLE 0x08
++#define MODE_STN_MONO_SINGLE 0x09
++#define MODE_STN_COLOR_DUAL 0x0a
++#define MODE_STN_MONO_DUAL 0x0b
++#define MODE_8BIT_SERIAL_TFT 0x0c
++
++#define MODE_TFT_18BIT (1<<7)
++
++#define STN_DAT_PIN1 (0x00 << 4)
++#define STN_DAT_PIN2 (0x01 << 4)
++#define STN_DAT_PIN4 (0x02 << 4)
++#define STN_DAT_PIN8 (0x03 << 4)
++#define STN_DAT_PINMASK STN_DAT_PIN8
++
++#define STFT_PSHI (1 << 15)
++#define STFT_CLSHI (1 << 14)
++#define STFT_SPLHI (1 << 13)
++#define STFT_REVHI (1 << 12)
++
++#define SYNC_MASTER (0 << 16)
++#define SYNC_SLAVE (1 << 16)
++
++#define DE_P (0 << 9)
++#define DE_N (1 << 9)
++
++#define PCLK_P (0 << 10)
++#define PCLK_N (1 << 10)
++
++#define HSYNC_P (0 << 11)
++#define HSYNC_N (1 << 11)
++
++#define VSYNC_P (0 << 8)
++#define VSYNC_N (1 << 8)
++
++#define DATA_NORMAL (0 << 17)
++#define DATA_INVERSE (1 << 17)
++
++
++/* Jz LCDFB supported I/O controls. */
++#define FBIOSETBACKLIGHT 0x4688
++#define FBIODISPON 0x4689
++#define FBIODISPOFF 0x468a
++#define FBIORESET 0x468b
++#define FBIOPRINT_REG 0x468c
++
++/*
++ * LCD panel specific definition
++ */
++#define MODE (0xc9) /* 8bit serial RGB */
++
++#define __spi_write_reg1(reg, val) \
++do { \
++ unsigned char no; \
++ unsigned short value; \
++ unsigned char a=reg; \
++ unsigned char b=val; \
++ __gpio_set_pin(SPEN); \
++ __gpio_set_pin(SPCK); \
++ __gpio_clear_pin(SPDA); \
++ __gpio_clear_pin(SPEN); \
++ value=((a<<8)|(b&0xFF)); \
++ for(no=0;no<16;no++) \
++ { \
++ __gpio_clear_pin(SPCK); \
++ if((value&0x8000)==0x8000) \
++ __gpio_set_pin(SPDA); \
++ else \
++ __gpio_clear_pin(SPDA); \
++ __gpio_set_pin(SPCK); \
++ value=(value<<1); \
++ } \
++ __gpio_set_pin(SPEN); \
++} while (0)
++
++#define __lcd_display_pin_init() \
++do { \
++ __cpm_start_tcu(); \
++ __gpio_as_output(SPEN); /* use SPDA */ \
++ __gpio_as_output(SPCK); /* use SPCK */ \
++ __gpio_as_output(SPDA); /* use SPDA */ \
++} while (0)
++
++#define __lcd_display_on() \
++do { \
++ __spi_write_reg1(0x05, 0x1e); \
++ __spi_write_reg1(0x05, 0x5e); \
++ __spi_write_reg1(0x07, 0x8d); \
++ __spi_write_reg1(0x13, 0x01); \
++ __spi_write_reg1(0x05, 0x5f); \
++} while (0)
++
++#define __lcd_display_off() \
++do { \
++ __spi_write_reg1(0x05, 0x5e); \
++} while (0)
++
++#endif /* __QI_LB60_GPM940B0_H__ */
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index 52b370c..d3e78ad 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -32,6 +32,13 @@
+ * Miscellaneous configurable options
+ */
+ #define CONFIG_NANONOTE
++
++#define CONFIG_LCD
++#define CONFIG_SYS_WHITE_ON_BLACK
++#define LCD_BPP LCD_COLOR32
++#define CONFIG_VIDEO_GPM940B0
++
++
+ #define CONFIG_JZ4740_MMC
+ #define CONFIG_MMC 1
+ #define CONFIG_FAT 1
+diff --git a/include/lcd.h b/include/lcd.h
+index 42070d7..6de5482 100644
+--- a/include/lcd.h
++++ b/include/lcd.h
+@@ -263,8 +263,44 @@ typedef struct vidinfo {
+
+ void init_panel_info(vidinfo_t *vid);
+
+-#else
++#elif defined(CONFIG_JZSOC)
++/*
++ * LCD controller stucture for JZSOC: JZ4740
++ */
++struct jz_fb_dma_descriptor {
++ u_long fdadr; /* Frame descriptor address register */
++ u_long fsadr; /* Frame source address register */
++ u_long fidr; /* Frame ID register */
++ u_long ldcmd; /* Command register */
++};
++
++/*
++ * Jz LCD info
++ */
++struct jz_fb_info {
++
++ u_long fdadr0; /* physical address of frame/palette descriptor */
++ u_long fdadr1; /* physical address of frame descriptor */
++
++ /* DMA descriptors */
++ struct jz_fb_dma_descriptor * dmadesc_fblow;
++ struct jz_fb_dma_descriptor * dmadesc_fbhigh;
++ struct jz_fb_dma_descriptor * dmadesc_palette;
++ u_long screen; /* address of frame buffer */
++ u_long palette; /* address of palette memory */
++ u_int palette_size;
++};
++typedef struct vidinfo {
++ ushort vl_col; /* Number of columns (i.e. 640) */
++ ushort vl_row; /* Number of rows (i.e. 480) */
++ u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8 */
++
++ struct jz_fb_info jz_fb;
++} vidinfo_t;
++
++extern vidinfo_t panel_info;
+
++#else
+ typedef struct vidinfo {
+ ushort vl_col; /* Number of columns (i.e. 160) */
+ ushort vl_row; /* Number of rows (i.e. 100) */
+@@ -318,6 +354,7 @@ void lcd_show_board_info(void);
+ #define LCD_COLOR4 2
+ #define LCD_COLOR8 3
+ #define LCD_COLOR16 4
++#define LCD_COLOR32 5
+
+ /*----------------------------------------------------------------------*/
+ #if defined(CONFIG_LCD_INFO_BELOW_LOGO)
+@@ -369,7 +406,7 @@ void lcd_show_board_info(void);
+ # define CONSOLE_COLOR_GREY 14
+ # define CONSOLE_COLOR_WHITE 15 /* Must remain last / highest */
+
+-#else
++#elif LCD_BPP == LCD_COLOR16
+
+ /*
+ * 16bpp color definitions
+@@ -377,6 +414,15 @@ void lcd_show_board_info(void);
+ # define CONSOLE_COLOR_BLACK 0x0000
+ # define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */
+
++#elif LCD_BPP == LCD_COLOR32
++/*
++ * 18,24,32 bpp color definitions
++ */
++# define CONSOLE_COLOR_BLACK 0x00000000
++# define CONSOLE_COLOR_WHITE 0xffffffff /* Must remain last / highest */
++
++#else
++
+ #endif /* color definitions */
+
+ /************************************************************************/
+@@ -406,7 +452,7 @@ void lcd_show_board_info(void);
+ #if LCD_BPP == LCD_MONOCHROME
+ # define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \
+ (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
+-#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16)
++#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || (LCD_BPP == LCD_COLOR32)
+ # define COLOR_MASK(c) (c)
+ #else
+ # error Unsupported LCD BPP.
+--
+1.7.9.5
+
diff --git a/package/boot/uboot-xburst/patches/0006-enable-silent-console.patch b/package/boot/uboot-xburst/patches/0006-enable-silent-console.patch
new file mode 100644
index 0000000..ebd6a6a
--- /dev/null
+++ b/package/boot/uboot-xburst/patches/0006-enable-silent-console.patch
@@ -0,0 +1,60 @@
+From 5eb4d4c598f2806bd1b3d1140e917bfead7851ad Mon Sep 17 00:00:00 2001
+From: Xiangfu <xiangfu@openmobilefree.net>
+Date: Wed, 10 Oct 2012 23:51:26 +0800
+Subject: [PATCH 6/6] enable silent console
+
+---
+ common/console.c | 16 ++++++++++++++++
+ include/configs/qi_lb60.h | 2 ++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/common/console.c b/common/console.c
+index 1177f7d..e8a2078 100644
+--- a/common/console.c
++++ b/common/console.c
+@@ -685,6 +685,14 @@ done:
+
+ gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+
++#ifdef CONFIG_SILENT_CONSOLE
++ /* Check one more time the contents of the silent environment
++ * variable, because if the environment is loaded from NAND it was
++ * not available when console_init_f() was called */
++ if (getenv("silent") != NULL)
++ gd->flags |= GD_FLG_SILENT;
++#endif
++
+ stdio_print_current_devices();
+
+ #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
+@@ -760,6 +768,14 @@ int console_init_r(void)
+
+ gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
+
++#ifdef CONFIG_SILENT_CONSOLE
++ /* Check one more time the contents of the silent environment
++ * variable, because if the environment is loaded from NAND it was
++ * not available when console_init_f() was called */
++ if (getenv("silent") != NULL)
++ gd->flags |= GD_FLG_SILENT;
++#endif
++
+ stdio_print_current_devices();
+
+ /* Setting environment variables */
+diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
+index d3e78ad..a3534ff 100644
+--- a/include/configs/qi_lb60.h
++++ b/include/configs/qi_lb60.h
+@@ -102,6 +102,8 @@
+ #define CONFIG_SYS_NO_FLASH
+ #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */
+
++#define CONFIG_SILENT_CONSOLE 1 /* Enable silent console */
++
+ /*
+ * Command line configuration
+ */
+--
+1.7.9.5
+
diff --git a/package/boot/yamonenv/.svn/entries b/package/boot/yamonenv/.svn/entries
new file mode 100644
index 0000000..3b96508
--- /dev/null
+++ b/package/boot/yamonenv/.svn/entries
@@ -0,0 +1,65 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/yamonenv
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+patches
+dir
+
+Makefile
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+6c2b050e03080e465cf30e3b809c68cd
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+897
+
diff --git a/package/boot/yamonenv/.svn/prop-base/Makefile.svn-base b/package/boot/yamonenv/.svn/prop-base/Makefile.svn-base
new file mode 100644
index 0000000..8e522ae
--- /dev/null
+++ b/package/boot/yamonenv/.svn/prop-base/Makefile.svn-base
@@ -0,0 +1,9 @@
+K 13
+svn:copyright
+V 30
+Copyright (C) 2006 OpenWrt.org
+K 13
+svn:eol-style
+V 6
+native
+END
diff --git a/package/boot/yamonenv/.svn/text-base/Makefile.svn-base b/package/boot/yamonenv/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..e1d2a4b
--- /dev/null
+++ b/package/boot/yamonenv/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,39 @@
+#
+# 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
+
+PKG_NAME:=yamonenv
+PKG_VERSION:=20051022
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)_gruen.4g__$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/
+PKG_MD5SUM:=a3e4f24155aa3ba5aa502bc63fdaa6ad
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/yamonenv
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=@TARGET_au1000
+ TITLE:=YAMON configuration utility
+ URL:=http://meshcube.org/nylon/stable/sources/
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+endef
+
+define Build/Configure
+endef
+
+define Package/yamonenv/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_BUILD_DIR)/src/$(PKG_NAME) $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,yamonenv))
diff --git a/package/boot/yamonenv/Makefile b/package/boot/yamonenv/Makefile
new file mode 100644
index 0000000..e1d2a4b
--- /dev/null
+++ b/package/boot/yamonenv/Makefile
@@ -0,0 +1,39 @@
+#
+# 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
+
+PKG_NAME:=yamonenv
+PKG_VERSION:=20051022
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)_gruen.4g__$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/
+PKG_MD5SUM:=a3e4f24155aa3ba5aa502bc63fdaa6ad
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/yamonenv
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=@TARGET_au1000
+ TITLE:=YAMON configuration utility
+ URL:=http://meshcube.org/nylon/stable/sources/
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+endef
+
+define Build/Configure
+endef
+
+define Package/yamonenv/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_BUILD_DIR)/src/$(PKG_NAME) $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,yamonenv))
diff --git a/package/boot/yamonenv/patches/.svn/entries b/package/boot/yamonenv/patches/.svn/entries
new file mode 100644
index 0000000..fe61910
--- /dev/null
+++ b/package/boot/yamonenv/patches/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+36060
+svn://svn.openwrt.org/openwrt/trunk/package/boot/yamonenv/patches
+svn://svn.openwrt.org/openwrt
+
+
+
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3c298f89-4303-0410-b956-a3cf2f4a3e73
+
+001-yamonenv_mtd_partition.patch
+file
+
+
+
+
+2013-03-17T12:13:21.000000Z
+a53d173ddfcc4d3ff0b51638431afcff
+2012-10-16T13:44:25.630275Z
+33781
+blogic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+230
+
diff --git a/package/boot/yamonenv/patches/.svn/text-base/001-yamonenv_mtd_partition.patch.svn-base b/package/boot/yamonenv/patches/.svn/text-base/001-yamonenv_mtd_partition.patch.svn-base
new file mode 100644
index 0000000..e1def28
--- /dev/null
+++ b/package/boot/yamonenv/patches/.svn/text-base/001-yamonenv_mtd_partition.patch.svn-base
@@ -0,0 +1,11 @@
+--- a/src/yamonenv.c
++++ b/src/yamonenv.c
+@@ -12,7 +12,7 @@
+ #include <fcntl.h>
+ #include <unistd.h>
+
+-#define DEFAULT_YAMON_ENV_FILE "/dev/mtd/3"
++#define DEFAULT_YAMON_ENV_FILE "/dev/mtd3"
+
+
+ // control byte definitions:
diff --git a/package/boot/yamonenv/patches/001-yamonenv_mtd_partition.patch b/package/boot/yamonenv/patches/001-yamonenv_mtd_partition.patch
new file mode 100644
index 0000000..e1def28
--- /dev/null
+++ b/package/boot/yamonenv/patches/001-yamonenv_mtd_partition.patch
@@ -0,0 +1,11 @@
+--- a/src/yamonenv.c
++++ b/src/yamonenv.c
+@@ -12,7 +12,7 @@
+ #include <fcntl.h>
+ #include <unistd.h>
+
+-#define DEFAULT_YAMON_ENV_FILE "/dev/mtd/3"
++#define DEFAULT_YAMON_ENV_FILE "/dev/mtd3"
+
+
+ // control byte definitions: