From 716ca530e1c4515d8683c9d5be3d56b301758b66 Mon Sep 17 00:00:00 2001 From: James <> Date: Wed, 4 Nov 2015 11:49:21 +0000 Subject: trunk-47381 --- package/boot/apex/Makefile | 62 + package/boot/apex/patches/001-compile_fix.patch | 20 + .../patches/100-openwrt_nslu2_armeb_config.patch | 23 + .../120-openwrt_nslu2_16mb_armeb_config.patch | 23 + .../patches/140-openwrt_fsg3_armeb_config.patch | 23 + .../boot/apex/patches/150-limit_ram_to_64mb.patch | 22 + .../patches/160-openwrt_nas100d_armeb_config.patch | 20 + package/boot/fconfig/Makefile | 45 + package/boot/grub2/Makefile | 82 + .../boot/grub2/patches/100-grub_setup_root.patch | 118 + package/boot/grub2/patches/100-musl-compat.patch | 26 + .../boot/grub2/patches/200-fix-gets-removal.patch | 16 + .../boot/grub2/patches/210-fix_serial_rtscts.patch | 14 + package/boot/imx-bootlets/Makefile | 42 + .../patches/001-skip_sb_generation.patch | 18 + .../patches/002-set_elftosb_config.patch | 17 + .../imx-bootlets/patches/003-add-olinuxino.patch | 150 + package/boot/kexec-tools/Config.in | 31 + package/boot/kexec-tools/Makefile | 87 + .../patches/0001-Fix-zlib-lzma-decompression.patch | 171 + ...c-apply-necessary-quotes-to-result-of-mac.patch | 52 + ...mpiler-warning-on-printing-64-bit-integer.patch | 35 + .../patches/0004-mips-remove-unused-variable.patch | 30 + ...ix-warning-about-implicit-type-conversion.patch | 30 + package/boot/kobs-ng/Makefile | 45 + .../boot/kobs-ng/patches/001-fix-mtd-defines.patch | 76 + .../kobs-ng/patches/002-add-init-size-param.patch | 42 + .../boot/kobs-ng/patches/003-missing_include.patch | 20 + package/boot/kobs-ng/patches/004-gnu_source.patch | 10 + package/boot/rbcfg/Makefile | 49 + package/boot/rbcfg/src/Makefile | 14 + package/boot/rbcfg/src/cyg_crc.h | 109 + package/boot/rbcfg/src/cyg_crc32.c | 172 + package/boot/rbcfg/src/main.c | 791 ++ package/boot/rbcfg/src/rbcfg.h | 75 + package/boot/uboot-ar71xx/Makefile | 95 + .../files/board/zyxel/nbg460n/Makefile | 46 + .../files/board/zyxel/nbg460n/config.mk | 1 + .../files/board/zyxel/nbg460n/lowlevel_init.S | 39 + .../files/board/zyxel/nbg460n/nbg460n.c | 96 + .../files/board/zyxel/nbg460n/u-boot.lds | 42 + .../uboot-ar71xx/files/cpu/mips/ar71xx_serial.c | 177 + .../boot/uboot-ar71xx/files/drivers/net/ag71xx.c | 809 ++ .../boot/uboot-ar71xx/files/drivers/net/ag71xx.h | 374 + .../uboot-ar71xx/files/drivers/net/phy/rtl8366.h | 188 + .../files/drivers/net/phy/rtl8366_mii.c | 786 ++ .../uboot-ar71xx/files/drivers/spi/ar71xx_spi.c | 191 + .../uboot-ar71xx/files/include/asm-mips/ar71xx.h | 515 ++ .../files/include/asm-mips/ar71xx_gpio.h | 65 + .../uboot-ar71xx/files/include/configs/nbg460n.h | 136 + package/boot/uboot-ar71xx/patches/001-ar71xx.patch | 28 + .../boot/uboot-ar71xx/patches/002-ar71xx-spi.patch | 11 + .../uboot-ar71xx/patches/010-enet-ag71xx.patch | 22 + .../patches/011-switch-rtl8366sr.patch | 28 + .../uboot-ar71xx/patches/020-freebsd-compat.patch | 11 + .../uboot-ar71xx/patches/021-darwin_compat.patch | 23 + .../patches/022-getline_backport.patch | 21 + .../uboot-ar71xx/patches/030-no_examples.patch | 13 + .../patches/040-no_extern_inline.patch | 112 + .../uboot-ar71xx/patches/041-no_weak_alias.patch | 12 + package/boot/uboot-envtools/Config.in | 9 + package/boot/uboot-envtools/Makefile | 112 + package/boot/uboot-envtools/files/ar71xx | 55 + package/boot/uboot-envtools/files/cns3xxx | 28 + package/boot/uboot-envtools/files/imx6 | 36 + package/boot/uboot-envtools/files/kirkwood | 33 + package/boot/uboot-envtools/files/lantiq | 31 + package/boot/uboot-envtools/files/mvebu | 28 + package/boot/uboot-envtools/files/mxs | 26 + package/boot/uboot-envtools/files/oxnas | 27 + package/boot/uboot-envtools/files/ramips | 33 + .../boot/uboot-envtools/files/uboot-envtools.sh | 36 + .../boot/uboot-envtools/patches/001-compile.patch | 13 + .../uboot-envtools/patches/200-fw_env_no_aes.patch | 38 + .../300-support-env-in-ubivol-chardev.patch | 163 + package/boot/uboot-imx6/Makefile | 132 + .../patches/100-wandboard-enable-fit.patch | 10 + .../patches/110-wandboard-owrt-env.patch | 89 + package/boot/uboot-kirkwood/Makefile | 145 + ...irkwood-style-fixes-in-kwbimage.cfg-files.patch | 96 + ...efine-empty-CONFIG_MVGBE_PORTS-by-default.patch | 32 + ...-kirkwood-fix-cpu-info-for-6282-device-id.patch | 45 + ...b62x0-add-CONFIG_SYS_GENERIC_BOARD-define.patch | 27 + ...ckstar-add-CONFIG_SYS_GENERIC_BOARD-defin.patch | 23 + ...flexhome-add-CONFIG_SYS_GENERIC_BOARD-def.patch | 23 + ...onnect-add-CONFIG_SYS_GENERIC_BOARD-defin.patch | 23 + ...go_e02-add-CONFIG_SYS_GENERIC_BOARD-defin.patch | 23 + ...eevaplug-add-CONFIG_SYS_GENERIC_BOARD-def.patch | 23 + .../boot/uboot-kirkwood/patches/110-dockstar.patch | 129 + .../boot/uboot-kirkwood/patches/120-iconnect.patch | 47 + .../boot/uboot-kirkwood/patches/130-ib62x0.patch | 21 + .../uboot-kirkwood/patches/140-pogoplug_e02.patch | 48 + .../patches/200-openwrt-config.patch | 110 + package/boot/uboot-lantiq/Makefile | 383 + package/boot/uboot-lantiq/README | 6 + ...of-order-calls-for-spi_claim_bus-and-spi_.patch | 170 + ...ntly-use-debug-for-warning-error-messages.patch | 49 + ...ve-malloc-of-spi_flash-to-spi_flash_probe.patch | 110 + .../0004-sf-add-slim-probe-funtions-for-SPL.patch | 80 + ...culatiom-of-address-bytes-completely-conf.patch | 134 + ...0006-sf-add-support-for-4-byte-addressing.patch | 160 + .../0007-sf-add-support-for-EN25QH256.patch | 17 + ...or-layout-of-S25FL256S_256K-and-S25FL512S.patch | 21 + ...ib-add-framework-for-ethernet-switch-driv.patch | 244 + ...ib-add-driver-for-Lantiq-PSB697X-switch-f.patch | 161 + ...ib-add-driver-for-Lantiq-ADM6996I-switch-.patch | 157 + ...t-switchlib-add-driver-for-Atheros-AR8216.patch | 157 + ...-switchlib-add-driver-for-REALTEK-RTL8306.patch | 375 + ...014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch | 9339 ++++++++++++++++++++ ...-add-support-for-Lantiq-XWAY-ARX100-SoC-f.patch | 1228 +++ ...-add-driver-for-Lantiq-XWAY-ARX100-switch.patch | 546 ++ ...ols-add-some-helper-tools-for-Lantiq-SoCs.patch | 477 + .../0018-tools-lantiq-add-NAND-SPL-support.patch | 223 + .../0019-Makefile-add-Lantiq-NAND-SPL-images.patch | 46 + .../0020-MIPS-lantiq-add-NAND-SPL-support.patch | 165 + .../0021-MIPS-vrx200-add-NAND-SPL-support.patch | 30 + ...lantiq-easy80920-add-support-for-NAND-SPL.patch | 61 + ...23-MIPS-lantiq-add-default-openwrt-config.patch | 50 + ...tiq-easy50712-add-openwrt-lantiq-common.h.patch | 26 + ...tiq-easy80920-add-openwrt-lantiq-common.h.patch | 26 + ...PS-add-board-support-for-Arcadyan-ARV4519.patch | 242 + ...PS-add-board-support-for-Arcadyan-ARV7518.patch | 242 + ...S-add-board-support-for-AudioCodes-MP-252.patch | 248 + ...S-add-board-support-for-AVM-FritzBox-3370.patch | 354 + ...-MIPS-add-board-support-for-Gigaset-SX76X.patch | 247 + ...MIPS-add-board-support-for-ZTE-ZXHN-H367N.patch | 307 + ...IPS-add-board-support-for-ZTE-ZXV10-H201L.patch | 251 + ...S-add-board-support-for-ZyXEL-P-661HNU-Fx.patch | 304 + ...S-add-board-support-for-ZyXEL-P-2601HN-Fx.patch | 242 + ...-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch | 301 + ...dd-board-support-for-Arcadyan-Easybox-904.patch | 277 + ...-add-board-support-for-Arcadyan-ARV752DPW.patch | 242 + ...dd-board-support-for-Arcadyan-ARV752DPW22.patch | 244 + ...PS-add-board-support-for-Arcadyan-ARV7510.patch | 269 + ...dd-board-support-for-Arcadyan-ARV7510PW22.patch | 238 + ...e-prepare-u-boot-lantiq-v2013.10-openwrt4.patch | 18 + .../uboot-lantiq/patches/0041-lzma-fixup.patch | 44 + .../patches/0042-arx100-cgu-fixes.patch | 148 + ...dd-board-support-for-Arcadyan-VGV7510KW22.patch | 346 + ...dd-board-support-for-Arcadyan-ARV8539PW22.patch | 240 + package/boot/uboot-mxs/Makefile | 96 + .../uboot-mxs/patches/001-add-i2se-duckbill.patch | 581 ++ package/boot/uboot-omap/Makefile | 103 + .../uboot-omap/patches/001-switch_omap4_ext4.patch | 11 + .../boot/uboot-omap/patches/002-fix_jffs2.patch | 34 + .../uboot-omap/patches/003-fix_findfdt_C4.patch | 11 + package/boot/uboot-oxnas/Makefile | 102 + .../files/arch/arm/cpu/arm1136/nas782x/Makefile | 13 + .../files/arch/arm/cpu/arm1136/nas782x/clock.c | 97 + .../files/arch/arm/cpu/arm1136/nas782x/pinmux.c | 43 + .../files/arch/arm/cpu/arm1136/nas782x/reset.c | 91 + .../files/arch/arm/cpu/arm1136/nas782x/timer.c | 129 + .../arch/arm/include/asm/arch-nas782x/clock.h | 84 + .../files/arch/arm/include/asm/arch-nas782x/cpu.h | 26 + .../arch/arm/include/asm/arch-nas782x/hardware.h | 30 + .../arch/arm/include/asm/arch-nas782x/pinmux.h | 46 + .../files/arch/arm/include/asm/arch-nas782x/spl.h | 6 + .../arch/arm/include/asm/arch-nas782x/sysctl.h | 125 + .../arch/arm/include/asm/arch-nas782x/timer.h | 23 + package/boot/uboot-oxnas/files/board/ox820/Kconfig | 15 + .../boot/uboot-oxnas/files/board/ox820/MAINTAINERS | 6 + .../boot/uboot-oxnas/files/board/ox820/Makefile | 15 + package/boot/uboot-oxnas/files/board/ox820/ddr.c | 477 + package/boot/uboot-oxnas/files/board/ox820/ddr.h | 148 + .../uboot-oxnas/files/board/ox820/lowlevel_init.S | 20 + package/boot/uboot-oxnas/files/board/ox820/ox820.c | 374 + .../boot/uboot-oxnas/files/board/ox820/spl_start.S | 21 + .../uboot-oxnas/files/board/ox820/u-boot-spl.lds | 101 + package/boot/uboot-oxnas/files/common/env_ext4.c | 116 + .../boot/uboot-oxnas/files/common/spl/spl_block.c | 236 + .../boot/uboot-oxnas/files/configs/ox820_defconfig | 3 + .../uboot-oxnas/files/drivers/block/plxsata_ide.c | 1170 +++ .../files/drivers/usb/host/ehci-oxnas.c | 105 + .../boot/uboot-oxnas/files/include/configs/ox820.h | 383 + package/boot/uboot-oxnas/files/tools/mkox820crc.c | 123 + .../patches/010-capacity-is-unsigned.patch | 42 + .../boot/uboot-oxnas/patches/150-spl-block.patch | 54 + .../boot/uboot-oxnas/patches/200-icplus-phy.patch | 142 + .../uboot-oxnas/patches/300-oxnas-target.patch | 101 + .../patches/800-fix-bootm-assertion.patch | 11 + package/boot/uboot-pxa/Makefile | 92 + .../patches/001-squashfs_rootfstype_cmdline.patch | 13 + package/boot/uboot-sunxi/Makefile | 166 + .../patches/001-use-dtc-in-kernel.patch | 12 + .../uboot-sunxi/patches/002-add-lamobo-r1.diff | 277 + .../patches/003-add-olimex-a13-som.diff | 19 + ...et-transfer-timeout-according-to-byte_cnt.patch | 42 + package/boot/uboot-sunxi/uEnv.txt | 6 + package/boot/uboot-xburst/Makefile | 88 + .../0001-qi_lb60-add-nand-spl-support.patch | 894 ++ ...0002-qi_lb60-add-software-usbboot-support.patch | 916 ++ .../patches/0003-add-mmc-support.patch | 1664 ++++ ...004-add-more-boot-options-F1-F2-F3-F4-M-S.patch | 200 + .../patches/0005-add-nanonote-lcd-support.patch | 847 ++ .../patches/0006-enable-silent-console.patch | 60 + package/boot/yamonenv/Makefile | 39 + .../patches/001-yamonenv_mtd_partition.patch | 11 + 197 files changed, 38020 insertions(+) create mode 100644 package/boot/apex/Makefile create mode 100644 package/boot/apex/patches/001-compile_fix.patch create mode 100644 package/boot/apex/patches/100-openwrt_nslu2_armeb_config.patch create mode 100644 package/boot/apex/patches/120-openwrt_nslu2_16mb_armeb_config.patch create mode 100644 package/boot/apex/patches/140-openwrt_fsg3_armeb_config.patch create mode 100644 package/boot/apex/patches/150-limit_ram_to_64mb.patch create mode 100644 package/boot/apex/patches/160-openwrt_nas100d_armeb_config.patch create mode 100644 package/boot/fconfig/Makefile create mode 100644 package/boot/grub2/Makefile create mode 100644 package/boot/grub2/patches/100-grub_setup_root.patch create mode 100644 package/boot/grub2/patches/100-musl-compat.patch create mode 100644 package/boot/grub2/patches/200-fix-gets-removal.patch create mode 100644 package/boot/grub2/patches/210-fix_serial_rtscts.patch create mode 100644 package/boot/imx-bootlets/Makefile create mode 100644 package/boot/imx-bootlets/patches/001-skip_sb_generation.patch create mode 100644 package/boot/imx-bootlets/patches/002-set_elftosb_config.patch create mode 100644 package/boot/imx-bootlets/patches/003-add-olinuxino.patch create mode 100644 package/boot/kexec-tools/Config.in create mode 100644 package/boot/kexec-tools/Makefile create mode 100644 package/boot/kexec-tools/patches/0001-Fix-zlib-lzma-decompression.patch create mode 100644 package/boot/kexec-tools/patches/0002-configure.ac-apply-necessary-quotes-to-result-of-mac.patch create mode 100644 package/boot/kexec-tools/patches/0003-mips-fix-compiler-warning-on-printing-64-bit-integer.patch create mode 100644 package/boot/kexec-tools/patches/0004-mips-remove-unused-variable.patch create mode 100644 package/boot/kexec-tools/patches/0005-mips-fix-warning-about-implicit-type-conversion.patch create mode 100644 package/boot/kobs-ng/Makefile create mode 100644 package/boot/kobs-ng/patches/001-fix-mtd-defines.patch create mode 100644 package/boot/kobs-ng/patches/002-add-init-size-param.patch create mode 100644 package/boot/kobs-ng/patches/003-missing_include.patch create mode 100644 package/boot/kobs-ng/patches/004-gnu_source.patch create mode 100644 package/boot/rbcfg/Makefile create mode 100644 package/boot/rbcfg/src/Makefile create mode 100644 package/boot/rbcfg/src/cyg_crc.h create mode 100644 package/boot/rbcfg/src/cyg_crc32.c create mode 100644 package/boot/rbcfg/src/main.c create mode 100644 package/boot/rbcfg/src/rbcfg.h create mode 100644 package/boot/uboot-ar71xx/Makefile create mode 100644 package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile create mode 100644 package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk create mode 100644 package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S create mode 100644 package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c create mode 100644 package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds create mode 100644 package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c create mode 100644 package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c create mode 100644 package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h create mode 100644 package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h create mode 100644 package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366_mii.c create mode 100644 package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c create mode 100644 package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h create mode 100644 package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h create mode 100644 package/boot/uboot-ar71xx/files/include/configs/nbg460n.h create mode 100644 package/boot/uboot-ar71xx/patches/001-ar71xx.patch create mode 100644 package/boot/uboot-ar71xx/patches/002-ar71xx-spi.patch create mode 100644 package/boot/uboot-ar71xx/patches/010-enet-ag71xx.patch create mode 100644 package/boot/uboot-ar71xx/patches/011-switch-rtl8366sr.patch create mode 100644 package/boot/uboot-ar71xx/patches/020-freebsd-compat.patch create mode 100644 package/boot/uboot-ar71xx/patches/021-darwin_compat.patch create mode 100644 package/boot/uboot-ar71xx/patches/022-getline_backport.patch create mode 100644 package/boot/uboot-ar71xx/patches/030-no_examples.patch create mode 100644 package/boot/uboot-ar71xx/patches/040-no_extern_inline.patch create mode 100644 package/boot/uboot-ar71xx/patches/041-no_weak_alias.patch create mode 100644 package/boot/uboot-envtools/Config.in create mode 100644 package/boot/uboot-envtools/Makefile create mode 100644 package/boot/uboot-envtools/files/ar71xx create mode 100644 package/boot/uboot-envtools/files/cns3xxx create mode 100644 package/boot/uboot-envtools/files/imx6 create mode 100644 package/boot/uboot-envtools/files/kirkwood create mode 100644 package/boot/uboot-envtools/files/lantiq create mode 100644 package/boot/uboot-envtools/files/mvebu create mode 100644 package/boot/uboot-envtools/files/mxs create mode 100644 package/boot/uboot-envtools/files/oxnas create mode 100644 package/boot/uboot-envtools/files/ramips create mode 100644 package/boot/uboot-envtools/files/uboot-envtools.sh create mode 100644 package/boot/uboot-envtools/patches/001-compile.patch create mode 100644 package/boot/uboot-envtools/patches/200-fw_env_no_aes.patch create mode 100644 package/boot/uboot-envtools/patches/300-support-env-in-ubivol-chardev.patch create mode 100644 package/boot/uboot-imx6/Makefile create mode 100644 package/boot/uboot-imx6/patches/100-wandboard-enable-fit.patch create mode 100644 package/boot/uboot-imx6/patches/110-wandboard-owrt-env.patch create mode 100644 package/boot/uboot-kirkwood/Makefile create mode 100644 package/boot/uboot-kirkwood/patches/0001-cosmetic-kirkwood-style-fixes-in-kwbimage.cfg-files.patch create mode 100644 package/boot/uboot-kirkwood/patches/0002-kirkwood-define-empty-CONFIG_MVGBE_PORTS-by-default.patch create mode 100644 package/boot/uboot-kirkwood/patches/0003-ARM-kirkwood-fix-cpu-info-for-6282-device-id.patch create mode 100644 package/boot/uboot-kirkwood/patches/0004-kirkwood-ib62x0-add-CONFIG_SYS_GENERIC_BOARD-define.patch create mode 100644 package/boot/uboot-kirkwood/patches/0005-kirkwood-dockstar-add-CONFIG_SYS_GENERIC_BOARD-defin.patch create mode 100644 package/boot/uboot-kirkwood/patches/0006-kirkwood-goflexhome-add-CONFIG_SYS_GENERIC_BOARD-def.patch create mode 100644 package/boot/uboot-kirkwood/patches/0007-kirkwood-iconnect-add-CONFIG_SYS_GENERIC_BOARD-defin.patch create mode 100644 package/boot/uboot-kirkwood/patches/0008-kirkwood-pogo_e02-add-CONFIG_SYS_GENERIC_BOARD-defin.patch create mode 100644 package/boot/uboot-kirkwood/patches/0009-kirkwood-sheevaplug-add-CONFIG_SYS_GENERIC_BOARD-def.patch create mode 100644 package/boot/uboot-kirkwood/patches/110-dockstar.patch create mode 100644 package/boot/uboot-kirkwood/patches/120-iconnect.patch create mode 100644 package/boot/uboot-kirkwood/patches/130-ib62x0.patch create mode 100644 package/boot/uboot-kirkwood/patches/140-pogoplug_e02.patch create mode 100644 package/boot/uboot-kirkwood/patches/200-openwrt-config.patch create mode 100644 package/boot/uboot-lantiq/Makefile create mode 100644 package/boot/uboot-lantiq/README create mode 100644 package/boot/uboot-lantiq/patches/0001-sf-fix-out-of-order-calls-for-spi_claim_bus-and-spi_.patch create mode 100644 package/boot/uboot-lantiq/patches/0002-sf-consistently-use-debug-for-warning-error-messages.patch create mode 100644 package/boot/uboot-lantiq/patches/0003-sf-move-malloc-of-spi_flash-to-spi_flash_probe.patch create mode 100644 package/boot/uboot-lantiq/patches/0004-sf-add-slim-probe-funtions-for-SPL.patch create mode 100644 package/boot/uboot-lantiq/patches/0005-sf-make-calculatiom-of-address-bytes-completely-conf.patch create mode 100644 package/boot/uboot-lantiq/patches/0006-sf-add-support-for-4-byte-addressing.patch create mode 100644 package/boot/uboot-lantiq/patches/0007-sf-add-support-for-EN25QH256.patch create mode 100644 package/boot/uboot-lantiq/patches/0008-sf-fix-sector-layout-of-S25FL256S_256K-and-S25FL512S.patch create mode 100644 package/boot/uboot-lantiq/patches/0009-net-switchlib-add-framework-for-ethernet-switch-driv.patch create mode 100644 package/boot/uboot-lantiq/patches/0010-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch create mode 100644 package/boot/uboot-lantiq/patches/0011-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch create mode 100644 package/boot/uboot-lantiq/patches/0012-net-switchlib-add-driver-for-Atheros-AR8216.patch create mode 100644 package/boot/uboot-lantiq/patches/0013-net-switchlib-add-driver-for-REALTEK-RTL8306.patch create mode 100644 package/boot/uboot-lantiq/patches/0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch create mode 100644 package/boot/uboot-lantiq/patches/0015-MIPS-lantiq-add-support-for-Lantiq-XWAY-ARX100-SoC-f.patch create mode 100644 package/boot/uboot-lantiq/patches/0016-net-add-driver-for-Lantiq-XWAY-ARX100-switch.patch create mode 100644 package/boot/uboot-lantiq/patches/0017-tools-add-some-helper-tools-for-Lantiq-SoCs.patch create mode 100644 package/boot/uboot-lantiq/patches/0018-tools-lantiq-add-NAND-SPL-support.patch create mode 100644 package/boot/uboot-lantiq/patches/0019-Makefile-add-Lantiq-NAND-SPL-images.patch create mode 100644 package/boot/uboot-lantiq/patches/0020-MIPS-lantiq-add-NAND-SPL-support.patch create mode 100644 package/boot/uboot-lantiq/patches/0021-MIPS-vrx200-add-NAND-SPL-support.patch create mode 100644 package/boot/uboot-lantiq/patches/0022-MIPS-lantiq-easy80920-add-support-for-NAND-SPL.patch create mode 100644 package/boot/uboot-lantiq/patches/0023-MIPS-lantiq-add-default-openwrt-config.patch create mode 100644 package/boot/uboot-lantiq/patches/0024-MIPS-lantiq-easy50712-add-openwrt-lantiq-common.h.patch create mode 100644 package/boot/uboot-lantiq/patches/0025-MIPS-lantiq-easy80920-add-openwrt-lantiq-common.h.patch create mode 100644 package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Arcadyan-ARV4519.patch create mode 100644 package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch create mode 100644 package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-AudioCodes-MP-252.patch create mode 100644 package/boot/uboot-lantiq/patches/0029-MIPS-add-board-support-for-AVM-FritzBox-3370.patch create mode 100644 package/boot/uboot-lantiq/patches/0030-MIPS-add-board-support-for-Gigaset-SX76X.patch create mode 100644 package/boot/uboot-lantiq/patches/0031-MIPS-add-board-support-for-ZTE-ZXHN-H367N.patch create mode 100644 package/boot/uboot-lantiq/patches/0032-MIPS-add-board-support-for-ZTE-ZXV10-H201L.patch create mode 100644 package/boot/uboot-lantiq/patches/0033-MIPS-add-board-support-for-ZyXEL-P-661HNU-Fx.patch create mode 100644 package/boot/uboot-lantiq/patches/0034-MIPS-add-board-support-for-ZyXEL-P-2601HN-Fx.patch create mode 100644 package/boot/uboot-lantiq/patches/0035-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch create mode 100644 package/boot/uboot-lantiq/patches/0036-MIPS-add-board-support-for-Arcadyan-Easybox-904.patch create mode 100644 package/boot/uboot-lantiq/patches/0037-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch create mode 100644 package/boot/uboot-lantiq/patches/0038-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch create mode 100644 package/boot/uboot-lantiq/patches/0039-MIPS-add-board-support-for-Arcadyan-ARV7510.patch create mode 100644 package/boot/uboot-lantiq/patches/0041-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch create mode 100644 package/boot/uboot-lantiq/patches/0041-Makefile-prepare-u-boot-lantiq-v2013.10-openwrt4.patch create mode 100644 package/boot/uboot-lantiq/patches/0041-lzma-fixup.patch create mode 100644 package/boot/uboot-lantiq/patches/0042-arx100-cgu-fixes.patch create mode 100644 package/boot/uboot-lantiq/patches/0043-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch create mode 100644 package/boot/uboot-lantiq/patches/0044-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch create mode 100644 package/boot/uboot-mxs/Makefile create mode 100644 package/boot/uboot-mxs/patches/001-add-i2se-duckbill.patch create mode 100644 package/boot/uboot-omap/Makefile create mode 100644 package/boot/uboot-omap/patches/001-switch_omap4_ext4.patch create mode 100644 package/boot/uboot-omap/patches/002-fix_jffs2.patch create mode 100644 package/boot/uboot-omap/patches/003-fix_findfdt_C4.patch create mode 100644 package/boot/uboot-oxnas/Makefile create mode 100644 package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/Makefile create mode 100644 package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/clock.c create mode 100644 package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/pinmux.c create mode 100644 package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/reset.c create mode 100644 package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/timer.c create mode 100644 package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/clock.h create mode 100644 package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/cpu.h create mode 100644 package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/hardware.h create mode 100644 package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/pinmux.h create mode 100644 package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/spl.h create mode 100644 package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/sysctl.h create mode 100644 package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/timer.h create mode 100644 package/boot/uboot-oxnas/files/board/ox820/Kconfig create mode 100644 package/boot/uboot-oxnas/files/board/ox820/MAINTAINERS create mode 100644 package/boot/uboot-oxnas/files/board/ox820/Makefile create mode 100755 package/boot/uboot-oxnas/files/board/ox820/ddr.c create mode 100644 package/boot/uboot-oxnas/files/board/ox820/ddr.h create mode 100644 package/boot/uboot-oxnas/files/board/ox820/lowlevel_init.S create mode 100644 package/boot/uboot-oxnas/files/board/ox820/ox820.c create mode 100644 package/boot/uboot-oxnas/files/board/ox820/spl_start.S create mode 100644 package/boot/uboot-oxnas/files/board/ox820/u-boot-spl.lds create mode 100644 package/boot/uboot-oxnas/files/common/env_ext4.c create mode 100644 package/boot/uboot-oxnas/files/common/spl/spl_block.c create mode 100644 package/boot/uboot-oxnas/files/configs/ox820_defconfig create mode 100644 package/boot/uboot-oxnas/files/drivers/block/plxsata_ide.c create mode 100644 package/boot/uboot-oxnas/files/drivers/usb/host/ehci-oxnas.c create mode 100644 package/boot/uboot-oxnas/files/include/configs/ox820.h create mode 100644 package/boot/uboot-oxnas/files/tools/mkox820crc.c create mode 100644 package/boot/uboot-oxnas/patches/010-capacity-is-unsigned.patch create mode 100644 package/boot/uboot-oxnas/patches/150-spl-block.patch create mode 100644 package/boot/uboot-oxnas/patches/200-icplus-phy.patch create mode 100644 package/boot/uboot-oxnas/patches/300-oxnas-target.patch create mode 100644 package/boot/uboot-oxnas/patches/800-fix-bootm-assertion.patch create mode 100644 package/boot/uboot-pxa/Makefile create mode 100644 package/boot/uboot-pxa/patches/001-squashfs_rootfstype_cmdline.patch create mode 100644 package/boot/uboot-sunxi/Makefile create mode 100644 package/boot/uboot-sunxi/patches/001-use-dtc-in-kernel.patch create mode 100644 package/boot/uboot-sunxi/patches/002-add-lamobo-r1.diff create mode 100644 package/boot/uboot-sunxi/patches/003-add-olimex-a13-som.diff create mode 100644 package/boot/uboot-sunxi/patches/004-sunxi-mmc-set-transfer-timeout-according-to-byte_cnt.patch create mode 100644 package/boot/uboot-sunxi/uEnv.txt create mode 100644 package/boot/uboot-xburst/Makefile create mode 100644 package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch create mode 100644 package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch create mode 100644 package/boot/uboot-xburst/patches/0003-add-mmc-support.patch create mode 100644 package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch create mode 100644 package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch create mode 100644 package/boot/uboot-xburst/patches/0006-enable-silent-console.patch create mode 100644 package/boot/yamonenv/Makefile create mode 100644 package/boot/yamonenv/patches/001-yamonenv_mtd_partition.patch (limited to 'package/boot') diff --git a/package/boot/apex/Makefile b/package/boot/apex/Makefile new file mode 100644 index 0000000..f154f96 --- /dev/null +++ b/package/boot/apex/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (C) 2006-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:=apex +PKG_VERSION:=1.6.9 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/ +PKG_MD5SUM:=9606cf2e3fd2c9a86fe0b61388509a30 +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +export GCC_HONOUR_COPTS=s + +define Package/apex + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_ixp4xx + DEFAULT:=y + TITLE:=Boot loader for NSLU2, FSG3, NAS100D and others + URL:=http://wiki.buici.com/wiki/Apex_Bootloader +endef + +define build_apex + $(MAKE) -C $(PKG_BUILD_DIR) \ + ARCH=arm \ + $(1)_config + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) \ + KBUILD_HAVE_NLS=no \ + ARCH=arm \ + clean all + $(INSTALL_BIN) $(PKG_BUILD_DIR)/apex.bin $(PKG_BUILD_DIR)/out/apex-$(2).bin +endef + +define Build/Compile + $(INSTALL_DIR) $(PKG_BUILD_DIR)/out + $(call build_apex,slugos-nslu2-armeb,nslu2-armeb) + $(call build_apex,slugos-nslu2-16mb-armeb,nslu2-16mb-armeb) + $(call build_apex,slugos-fsg3-armeb,fsg3-armeb) + $(call build_apex,slugos-nas100d-armeb,nas100d-armeb) +endef + +define Package/apex/install + $(INSTALL_DIR) $(STAGING_DIR)/apex + $(CP) $(PKG_BUILD_DIR)/out/*.bin $(1)/ +endef + +define Build/InstallDev + $(CP) $(PKG_BUILD_DIR)/out/*.bin $(KERNEL_BUILD_DIR) +endef + +$(eval $(call BuildPackage,apex)) diff --git a/package/boot/apex/patches/001-compile_fix.patch b/package/boot/apex/patches/001-compile_fix.patch new file mode 100644 index 0000000..8a25de6 --- /dev/null +++ b/package/boot/apex/patches/001-compile_fix.patch @@ -0,0 +1,20 @@ +--- a/Makefile ++++ b/Makefile +@@ -444,7 +444,7 @@ ifeq ($(config-targets),1) + include $(srctree)/src/arch-$(SRCARCH)/Makefile + export KBUILD_DEFCONFIG + +-config %config: scripts_basic outputmakefile FORCE ++%config: scripts_basic outputmakefile FORCE + $(Q)mkdir -p include/linux include/config + $(Q)$(MAKE) $(build)=scripts/kconfig $@ + +@@ -1585,7 +1585,7 @@ endif + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) + + # Modules +-/ %/: prepare scripts FORCE ++%/: prepare scripts FORCE + $(cmd_crmodverdir) + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ + $(build)=$(build-dir) diff --git a/package/boot/apex/patches/100-openwrt_nslu2_armeb_config.patch b/package/boot/apex/patches/100-openwrt_nslu2_armeb_config.patch new file mode 100644 index 0000000..d598ff3 --- /dev/null +++ b/package/boot/apex/patches/100-openwrt_nslu2_armeb_config.patch @@ -0,0 +1,23 @@ +--- a/src/mach-ixp42x/slugos-nslu2-armeb_config ++++ b/src/mach-ixp42x/slugos-nslu2-armeb_config +@@ -19,7 +19,7 @@ CONFIG_EXPERIMENTAL=y + # + # General Setup + # +-CONFIG_TARGET_DESCRIPTION="SlugOS NSLU2 (bigendian)" ++CONFIG_TARGET_DESCRIPTION="OpenWrt NSLU2 (8MiB Flash)" + CONFIG_CROSS_COMPILE="" + CONFIG_AEABI=y + # CONFIG_DRIVER_LONG_LONG_SIZE is not set +@@ -163,9 +163,9 @@ CONFIG_ENV_REGION_KERNEL_ALT="fis://kern + # Overrides + # + CONFIG_ENV_DEFAULT_CMDLINE_OVERRIDE=y +-CONFIG_ENV_DEFAULT_CMDLINE="root=/dev/mtdblock4 rootfstype=jffs2 console=ttyS0,115200 init=/linuxrc" ++CONFIG_ENV_DEFAULT_CMDLINE="root=/dev/mtdblock4 rootfstype=squashfs,jffs2 console=ttyS0,115200 init=/etc/preinit noinitrd" + CONFIG_ENV_DEFAULT_CMDLINE_ALT_P=y +-CONFIG_ENV_DEFAULT_CMDLINE_ALT="root=/dev/mtdblock4 rootfstype=jffs2 console=ttyS0,115200 init=/linuxrc" ++CONFIG_ENV_DEFAULT_CMDLINE_ALT="root=/dev/mtdblock4 rootfstype=squashfs,jffs2 console=ttyS0,115200 init=/etc/preinit noinitrd" + # CONFIG_ENV_DEFAULT_STARTUP_OVERRIDE is not set + # CONFIG_ENV_DEFAULT_STARTUP_ALT_P is not set + CONFIG_USES_NOR_BOOTFLASH=y diff --git a/package/boot/apex/patches/120-openwrt_nslu2_16mb_armeb_config.patch b/package/boot/apex/patches/120-openwrt_nslu2_16mb_armeb_config.patch new file mode 100644 index 0000000..5e7ecee --- /dev/null +++ b/package/boot/apex/patches/120-openwrt_nslu2_16mb_armeb_config.patch @@ -0,0 +1,23 @@ +--- a/src/mach-ixp42x/slugos-nslu2-16mb-armeb_config ++++ b/src/mach-ixp42x/slugos-nslu2-16mb-armeb_config +@@ -19,7 +19,7 @@ CONFIG_EXPERIMENTAL=y + # + # General Setup + # +-CONFIG_TARGET_DESCRIPTION="SlugOS NSLU2/BE (16MiB Flash)" ++CONFIG_TARGET_DESCRIPTION="OpenWrt NSLU2 (16MiB Flash)" + CONFIG_CROSS_COMPILE="" + CONFIG_AEABI=y + # CONFIG_DRIVER_LONG_LONG_SIZE is not set +@@ -163,9 +163,9 @@ CONFIG_ENV_REGION_KERNEL_ALT="fis://kern + # Overrides + # + CONFIG_ENV_DEFAULT_CMDLINE_OVERRIDE=y +-CONFIG_ENV_DEFAULT_CMDLINE="root=/dev/mtdblock4 rootfstype=jffs2 console=ttyS0,115200 init=/linuxrc" ++CONFIG_ENV_DEFAULT_CMDLINE="root=/dev/mtdblock4 rootfstype=squashfs,jffs2 console=ttyS0,115200 init=/etc/preinit noinitrd" + CONFIG_ENV_DEFAULT_CMDLINE_ALT_P=y +-CONFIG_ENV_DEFAULT_CMDLINE_ALT="root=/dev/mtdblock4 rootfstype=jffs2 console=ttyS0,115200 init=/linuxrc" ++CONFIG_ENV_DEFAULT_CMDLINE_ALT="root=/dev/mtdblock4 rootfstype=squashfs,jffs2 console=ttyS0,115200 init=/etc/preinit noinitrd" + # CONFIG_ENV_DEFAULT_STARTUP_OVERRIDE is not set + # CONFIG_ENV_DEFAULT_STARTUP_ALT_P is not set + CONFIG_USES_NOR_BOOTFLASH=y diff --git a/package/boot/apex/patches/140-openwrt_fsg3_armeb_config.patch b/package/boot/apex/patches/140-openwrt_fsg3_armeb_config.patch new file mode 100644 index 0000000..fc0e8b9 --- /dev/null +++ b/package/boot/apex/patches/140-openwrt_fsg3_armeb_config.patch @@ -0,0 +1,23 @@ +--- a/src/mach-ixp42x/slugos-fsg3-armeb_config ++++ b/src/mach-ixp42x/slugos-fsg3-armeb_config +@@ -17,7 +17,7 @@ CONFIG_EXPERIMENTAL=y + # + # General Setup + # +-CONFIG_TARGET_DESCRIPTION="SlugOS FSG3/BE" ++CONFIG_TARGET_DESCRIPTION="OpenWrt FSG3" + CONFIG_CROSS_COMPILE="" + CONFIG_AEABI=y + CONFIG_CC_OPTIMIZE_FOR_SIZE=y +@@ -148,9 +148,9 @@ CONFIG_ENV_REGION_KERNEL_ALT="fis://kern + # Overrides + # + CONFIG_ENV_DEFAULT_CMDLINE_OVERRIDE=y +-CONFIG_ENV_DEFAULT_CMDLINE="root=/dev/sda1 rootdelay=10 console=ttyS0,115200" ++CONFIG_ENV_DEFAULT_CMDLINE="root=/dev/sda1 rootdelay=10 console=ttyS0,115200 init=/etc/preinit noinitrd" + CONFIG_ENV_DEFAULT_CMDLINE_ALT_P=y +-CONFIG_ENV_DEFAULT_CMDLINE_ALT="root=/dev/sda2 rootdelay=10 console=ttyS0,115200" ++CONFIG_ENV_DEFAULT_CMDLINE_ALT="root=/dev/mtdblock2 rootfstype=squashfs console=ttyS0,115200 init=/etc/preinit noinitrd" + # CONFIG_ENV_DEFAULT_STARTUP_OVERRIDE is not set + # CONFIG_ENV_DEFAULT_STARTUP_ALT_P is not set + CONFIG_USES_NOR_BOOTFLASH=y diff --git a/package/boot/apex/patches/150-limit_ram_to_64mb.patch b/package/boot/apex/patches/150-limit_ram_to_64mb.patch new file mode 100644 index 0000000..3e17816 --- /dev/null +++ b/package/boot/apex/patches/150-limit_ram_to_64mb.patch @@ -0,0 +1,22 @@ +--- a/src/mach-ixp42x/slugos-nslu2-armeb_config ++++ b/src/mach-ixp42x/slugos-nslu2-armeb_config +@@ -137,7 +137,7 @@ CONFIG_AUTOBOOT_DELAY=10 + CONFIG_ENV_STARTUP_KERNEL_COPY=y + # CONFIG_ENV_REGION_KERNEL_SWAP is not set + CONFIG_ENV_STARTUP_PREFIX_P=y +-CONFIG_ENV_STARTUP_PREFIX="sdram-init; memscan -u 0+256m" ++CONFIG_ENV_STARTUP_PREFIX="sdram-init; memscan -u 0+64m" + + # + # Regions +--- a/src/mach-ixp42x/slugos-nslu2-16mb-armeb_config ++++ b/src/mach-ixp42x/slugos-nslu2-16mb-armeb_config +@@ -137,7 +137,7 @@ CONFIG_AUTOBOOT_DELAY=10 + CONFIG_ENV_STARTUP_KERNEL_COPY=y + # CONFIG_ENV_REGION_KERNEL_SWAP is not set + CONFIG_ENV_STARTUP_PREFIX_P=y +-CONFIG_ENV_STARTUP_PREFIX="sdram-init; memscan -u 0+256m" ++CONFIG_ENV_STARTUP_PREFIX="sdram-init; memscan -u 0+64m" + + # + # Regions diff --git a/package/boot/apex/patches/160-openwrt_nas100d_armeb_config.patch b/package/boot/apex/patches/160-openwrt_nas100d_armeb_config.patch new file mode 100644 index 0000000..e190964 --- /dev/null +++ b/package/boot/apex/patches/160-openwrt_nas100d_armeb_config.patch @@ -0,0 +1,20 @@ +--- a/src/mach-ixp42x/slugos-nas100d-armeb_config ++++ b/src/mach-ixp42x/slugos-nas100d-armeb_config +@@ -19,7 +19,7 @@ CONFIG_EXPERIMENTAL=y + # + # General Setup + # +-CONFIG_TARGET_DESCRIPTION="SlugOS NAS100D/BE" ++CONFIG_TARGET_DESCRIPTION="OpenWrt NAS100D" + CONFIG_CROSS_COMPILE="" + CONFIG_AEABI=y + # CONFIG_DRIVER_LONG_LONG_SIZE is not set +@@ -158,7 +158,7 @@ CONFIG_ENV_REGION_KERNEL="fis://kernel" + # Overrides + # + CONFIG_ENV_DEFAULT_CMDLINE_OVERRIDE=y +-CONFIG_ENV_DEFAULT_CMDLINE="root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS0,115200 init=/linuxrc" ++CONFIG_ENV_DEFAULT_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 console=ttyS0,115200 init=/etc/preinit noinitrd" + # CONFIG_ENV_DEFAULT_STARTUP_OVERRIDE is not set + CONFIG_USES_NOR_BOOTFLASH=y + CONFIG_RELOCATE_SIMPLE=y 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/Makefile b/package/boot/grub2/Makefile new file mode 100644 index 0000000..3601dd8 --- /dev/null +++ b/package/boot/grub2/Makefile @@ -0,0 +1,82 @@ +# +# Copyright (C) 2006-2015 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.02~beta2 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=http://alpha.gnu.org/gnu/grub \ + http://gnualpha.uib.no/grub/ \ + http://mirrors.fe.up.pt/pub/gnu-alpha/grub/ \ + http://www.nic.funet.fi/pub/gnu/alpha/gnu/grub/ +PKG_MD5SUM:=be62932eade308a364ea4bbc91295930 + +HOST_BUILD_PARALLEL:=1 +PKG_BUILD_DEPENDS:=grub2/host + +PKG_SSP:=0 + +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||TARGET_x86_64 +endef + +define Package/grub2-editenv + CATEGORY:=Utilities + SECTION:=utils + TITLE:=Grub2 Environment editor + URL:=http://www.gnu.org/software/grub/ + DEPENDS:=@TARGET_x86||TARGET_x86_64 +endef + +define Package/grub2-editenv/description + Edit grub2 environment files. +endef + +CONFIGURE_ARGS += \ + --target=$(REAL_GNU_TARGET_NAME) \ + --disable-werror \ + --disable-nls \ + --disable-device-mapper \ + --disable-libzfs \ + --disable-grub-mkfont + +HOST_CONFIGURE_ARGS += \ + --target=$(REAL_GNU_TARGET_NAME) \ + --sbindir="$(STAGING_DIR_HOST)/bin" \ + --disable-werror \ + --disable-libzfs \ + --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 + +define Package/grub2-editenv/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-editenv $(1)/usr/sbin/ +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,grub2)) +$(eval $(call BuildPackage,grub2-editenv)) 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..9619c41 --- /dev/null +++ b/package/boot/grub2/patches/100-grub_setup_root.patch @@ -0,0 +1,118 @@ +--- a/util/grub-setup.c ++++ b/util/grub-setup.c +@@ -87,6 +87,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 +@@ -130,6 +132,7 @@ struct arguments + char *core_file; + char *dir; + char *dev_map; ++ char *root_dev; + int force; + int fs_probe; + int allow_floppy; +@@ -178,6 +181,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; +@@ -313,7 +323,7 @@ main (int argc, char *argv[]) + GRUB_SETUP_FUNC (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, + arguments.add_rs_codes); + +--- a/util/setup.c ++++ b/util/setup.c +@@ -247,13 +247,12 @@ identify_partmap (grub_disk_t disk __att + 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, + int add_rs_codes __attribute__ ((unused))) /* unused on sparc64 */ + { + char *core_path; + char *boot_img, *core_img, *boot_path; +- char *root = 0; + size_t boot_size, core_size; + #ifdef GRUB_SETUP_BIOS + grub_uint16_t core_sectors; +@@ -307,7 +306,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; +@@ -317,6 +319,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; +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -182,13 +182,13 @@ grub_install_get_image_target (const cha + void + grub_util_bios_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, + int add_rs_codes); + void + grub_util_sparc_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, + int add_rs_codes); + +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -1660,7 +1660,7 @@ main (int argc, char *argv[]) + /* Now perform the installation. */ + if (install_bootsector) + grub_util_bios_setup (platdir, "boot.img", "core.img", +- install_drive, force, ++ NULL, install_drive, force, + fs_probe, allow_floppy, add_rs_codes); + break; + } +@@ -1686,7 +1686,7 @@ main (int argc, char *argv[]) + /* Now perform the installation. */ + if (install_bootsector) + grub_util_sparc_setup (platdir, "boot.img", "core.img", +- install_device, force, ++ NULL, install_device, force, + fs_probe, allow_floppy, + 0 /* unused */ ); + break; diff --git a/package/boot/grub2/patches/100-musl-compat.patch b/package/boot/grub2/patches/100-musl-compat.patch new file mode 100644 index 0000000..e3b12be --- /dev/null +++ b/package/boot/grub2/patches/100-musl-compat.patch @@ -0,0 +1,26 @@ +--- a/grub-core/osdep/unix/hostdisk.c ++++ b/grub-core/osdep/unix/hostdisk.c +@@ -48,11 +48,10 @@ + #ifdef __linux__ + # include /* ioctl */ + # include +-# if !defined(__GLIBC__) || \ +- ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) ++# if defined(__UCLIBC__) + /* Maybe libc doesn't have large file support. */ + # include /* _llseek */ +-# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */ ++# endif /* __UCLIBC__ */ + #endif /* __linux__ */ + + grub_uint64_t +@@ -79,8 +78,7 @@ grub_util_get_fd_size (grub_util_fd_t fd + return st.st_size; + } + +-#if defined(__linux__) && (!defined(__GLIBC__) || \ +- ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) ++#if defined(__linux__) && defined(__UCLIBC__) + /* Maybe libc doesn't have large file support. */ + int + grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off) 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..737fb97 --- /dev/null +++ b/package/boot/grub2/patches/200-fix-gets-removal.patch @@ -0,0 +1,16 @@ +--- a/grub-core/gnulib/stdio.in.h ++++ b/grub-core/gnulib/stdio.in.h +@@ -695,13 +695,6 @@ _GL_WARN_ON_USE (getline, "getline is un + # endif + #endif + +-/* It is very rare that the developer ever has full control of stdin, +- so any use of gets warrants an unconditional warning; besides, C11 +- removed it. */ +-#undef gets +-#if HAVE_RAW_DECL_GETS +-#endif +- + + #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ + struct obstack; diff --git a/package/boot/grub2/patches/210-fix_serial_rtscts.patch b/package/boot/grub2/patches/210-fix_serial_rtscts.patch new file mode 100644 index 0000000..d60471c --- /dev/null +++ b/package/boot/grub2/patches/210-fix_serial_rtscts.patch @@ -0,0 +1,14 @@ +--- a/grub-core/term/serial.c ++++ b/grub-core/term/serial.c +@@ -241,9 +241,9 @@ grub_cmd_serial (grub_extcmd_context_t c + + if (state[OPTION_RTSCTS].set) + { +- if (grub_strcmp (state[OPTION_PARITY].arg, "on") == 0) ++ if (grub_strcmp (state[OPTION_RTSCTS].arg, "on") == 0) + config.rtscts = 1; +- if (grub_strcmp (state[OPTION_PARITY].arg, "off") == 0) ++ else if (grub_strcmp (state[OPTION_RTSCTS].arg, "off") == 0) + config.rtscts = 0; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, diff --git a/package/boot/imx-bootlets/Makefile b/package/boot/imx-bootlets/Makefile new file mode 100644 index 0000000..c6f041c --- /dev/null +++ b/package/boot/imx-bootlets/Makefile @@ -0,0 +1,42 @@ +# +# 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:=imx-bootlets +PKG_VERSION:=10.05.02 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://trabant.uid0.hu/openwrt/ +PKG_MD5SUM:=82e375193b66ca643023c1656d536282 + +include $(INCLUDE_DIR)/package.mk + +define Package/imx-bootlets + SECTION:=boot + CATEGORY:=Boot Loaders + TITLE:=i.MX23/i.MX28 bootlets + DEPENDS:=@TARGET_mxs +endef + +define Package/imx-bootlets/description + i.MX23/i.MX28 bootlets (for oLinuxino) +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" +endef + +define Package/imx-bootlets/install + @echo Copying boot_prep and power_prep into staging - $(STAGING_DIR) + $(INSTALL_BIN) $(PKG_BUILD_DIR)/boot_prep/boot_prep $(STAGING_DIR)/boot_prep + $(INSTALL_BIN) $(PKG_BUILD_DIR)/linux_prep/output-target/linux_prep $(STAGING_DIR)/linux_prep + $(INSTALL_BIN) $(PKG_BUILD_DIR)/power_prep/power_prep $(STAGING_DIR)/power_prep + $(INSTALL_BIN) $(PKG_BUILD_DIR)/linux_prebuilt.db $(STAGING_DIR)/linux_prebuilt.db +endef + +$(eval $(call BuildPackage,imx-bootlets)) + diff --git a/package/boot/imx-bootlets/patches/001-skip_sb_generation.patch b/package/boot/imx-bootlets/patches/001-skip_sb_generation.patch new file mode 100644 index 0000000..7267dff --- /dev/null +++ b/package/boot/imx-bootlets/patches/001-skip_sb_generation.patch @@ -0,0 +1,18 @@ +--- imx-bootlets-src-10.05.02.orig/Makefile 2010-05-14 06:56:28.000000000 +0200 ++++ imx-bootlets-src-10.05.02/Makefile 2012-10-24 21:41:44.000000000 +0200 +@@ -32,10 +32,11 @@ + sed -i 's,[^ *]image.*;,\timage="$(DFT_UBOOT)";,' uboot.db + elftosb2 -z -c ./uboot.db -o i$(ARCH)_uboot.sb + else +- @echo "by using the pre-built kernel" +- elftosb2 -z -c ./linux_prebuilt.db -o i$(ARCH)_linux.sb +- @echo "generating U-Boot boot stream image" +- elftosb2 -z -c ./uboot_prebuilt.db -o i$(ARCH)_uboot.sb ++ @echo "... not generating any image for now." ++ #@echo "by using the pre-built kernel" ++ #elftosb2 -z -c ./linux_prebuilt.db -o i$(ARCH)_linux.sb ++ #@echo "generating U-Boot boot stream image" ++ #elftosb2 -z -c ./uboot_prebuilt.db -o i$(ARCH)_uboot.sb + endif + #@echo "generating kernel bootstream file sd_mmc_bootstream.raw" + #Please use cfimager to burn xxx_linux.sb. The below way will no diff --git a/package/boot/imx-bootlets/patches/002-set_elftosb_config.patch b/package/boot/imx-bootlets/patches/002-set_elftosb_config.patch new file mode 100644 index 0000000..88b904e --- /dev/null +++ b/package/boot/imx-bootlets/patches/002-set_elftosb_config.patch @@ -0,0 +1,17 @@ +--- imx-bootlets-10.05.02.orig/linux_prebuilt.db 2010-05-14 06:56:28.000000000 +0200 ++++ imx-bootlets-10.05.02/linux_prebuilt.db 2012-10-24 22:04:37.000000000 +0200 +@@ -4,10 +4,10 @@ + flags = 0x01; + } + sources { +- power_prep="./power_prep/power_prep"; +- sdram_prep="./boot_prep/boot_prep"; +- linux_prep="./linux_prep/output-target/linux_prep"; +- zImage = "./zImage"; ++ power_prep="./power_prep"; ++ sdram_prep="./boot_prep"; ++ linux_prep="./linux_prep"; ++ zImage = "./zImage_dtb"; + } + + section (0) { diff --git a/package/boot/imx-bootlets/patches/003-add-olinuxino.patch b/package/boot/imx-bootlets/patches/003-add-olinuxino.patch new file mode 100644 index 0000000..ddc25bc --- /dev/null +++ b/package/boot/imx-bootlets/patches/003-add-olinuxino.patch @@ -0,0 +1,150 @@ +diff -ruN imx-bootlets-10.05.02.orig/linux_prep/board/imx23_olinuxino_dev.c imx-bootlets-10.05.02/linux_prep/board/imx23_olinuxino_dev.c +--- imx-bootlets-10.05.02.orig/linux_prep/board/imx23_olinuxino_dev.c 1970-01-01 01:00:00.000000000 +0100 ++++ imx-bootlets-10.05.02/linux_prep/board/imx23_olinuxino_dev.c 2013-05-19 00:11:40.000000000 +0200 +@@ -0,0 +1,54 @@ ++/* ++ * Platform specific data for the IMX23_OLINUXINO development board ++ * ++ * Fadil Berisha ++ * ++ * Copyright 2008 SigmaTel, Inc ++ * Copyright 2008 Embedded Alley Solutions, Inc ++ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++#include ++#include ++#include ++ ++/************************************************ ++ * LRADC keyboard data * ++ ************************************************/ ++int lradc_keypad_ch = LRADC_CH0; ++int lradc_vddio_ch = LRADC_CH6; ++ ++struct lradc_keycode lradc_keycodes[] = { ++ { 100, KEY4 }, ++ { 306, KEY5 }, ++ { 601, KEY6 }, ++ { 932, KEY7 }, ++ { 1260, KEY8 }, ++ { 1424, KEY9 }, ++ { 1707, KEY10 }, ++ { 2207, KEY11 }, ++ { 2525, KEY12 }, ++ { 2831, KEY13 }, ++ { 3134, KEY14 }, ++ { -1, 0 }, ++}; ++ ++/************************************************ ++ * Magic key combinations for Armadillo * ++ ************************************************/ ++u32 magic_keys[MAGIC_KEY_NR] = { ++ [MAGIC_KEY1] = KEY4, ++ [MAGIC_KEY2] = KEY6, ++ [MAGIC_KEY3] = KEY10, ++}; ++ ++/************************************************ ++ * Default command line * ++ ************************************************/ ++char cmdline_def[] = "console=ttyAMA0,115200"; +diff -ruN imx-bootlets-10.05.02.orig/linux_prep/cmdlines/imx23_olinuxino_dev.txt imx-bootlets-10.05.02/linux_prep/cmdlines/imx23_olinuxino_dev.txt +--- imx-bootlets-10.05.02.orig/linux_prep/cmdlines/imx23_olinuxino_dev.txt 1970-01-01 01:00:00.000000000 +0100 ++++ imx-bootlets-10.05.02/linux_prep/cmdlines/imx23_olinuxino_dev.txt 2013-05-19 00:12:56.000000000 +0200 +@@ -0,0 +1 @@ ++noinitrd console=ttyAMA0,115200 root=/dev/mmcblk0p2 rw rootwait ssp1=mmc +diff -ruN imx-bootlets-10.05.02.orig/linux_prep/core/setup.c imx-bootlets-10.05.02/linux_prep/core/setup.c +--- imx-bootlets-10.05.02.orig/linux_prep/core/setup.c 2010-05-14 06:56:28.000000000 +0200 ++++ imx-bootlets-10.05.02/linux_prep/core/setup.c 2013-05-19 00:11:40.000000000 +0200 +@@ -84,6 +84,8 @@ + #include "../../mach-mx28/includes/registers/regsrtc.h" + #elif defined(STMP378X) + #include "../../mach-mx23/includes/registers/regsrtc.h" ++#elif defined(IMX23_OLINUXINO) ++#include "../../mach-mx23/includes/registers/regsrtc.h" + #endif + + #define NAND_SECONDARY_BOOT 0x00000002 +diff -ruN imx-bootlets-10.05.02.orig/linux_prep/include/mx23/platform.h imx-bootlets-10.05.02/linux_prep/include/mx23/platform.h +--- imx-bootlets-10.05.02.orig/linux_prep/include/mx23/platform.h 2010-05-14 06:56:28.000000000 +0200 ++++ imx-bootlets-10.05.02/linux_prep/include/mx23/platform.h 2013-05-19 00:11:40.000000000 +0200 +@@ -19,6 +19,10 @@ + + #if defined (BOARD_STMP378X_DEV) + #define MACHINE_ID 0xa45 ++ ++#elif defined (BOARD_IMX23_OLINUXINO_DEV) ++#define MACHINE_ID 0x1009 ++ + #else + #error "Allocate a machine ID for your board" + #endif +diff -ruN imx-bootlets-10.05.02.orig/linux_prep/Makefile imx-bootlets-10.05.02/linux_prep/Makefile +--- imx-bootlets-10.05.02.orig/linux_prep/Makefile 2010-05-14 06:56:28.000000000 +0200 ++++ imx-bootlets-10.05.02/linux_prep/Makefile 2013-05-19 00:11:40.000000000 +0200 +@@ -69,6 +69,11 @@ + HW_OBJS = $(LRADC_OBJS) + CFLAGS += -DMX28 -DBOARD_MX28_EVK + endif ++ifeq ($(BOARD), imx23_olinuxino_dev) ++ARCH = mx23 ++HW_OBJS = $(LRADC_OBJS) ++CFLAGS += -DIMX23_OLINUXINO -DBOARD_IMX23_OLINUXINO_DEV ++endif + + # Generic code + CORE_OBJS = entry.o resume.o cmdlines.o setup.o keys.o +diff -ruN imx-bootlets-10.05.02.orig/Makefile imx-bootlets-10.05.02/Makefile +--- imx-bootlets-10.05.02.orig/Makefile 2010-05-14 06:56:28.000000000 +0200 ++++ imx-bootlets-10.05.02/Makefile 2013-05-19 00:15:02.000000000 +0200 +@@ -3,9 +3,9 @@ + export MEM_TYPE + + DFT_IMAGE=$(DEV_IMAGE)/boot/zImage +-DFT_UBOOT=$(DEV_IMAGE)/boot/u-boot ++DFT_UBOOT=../boot/u-boot + +-BOARD ?= stmp378x_dev ++BOARD ?= imx23_olinuxino_dev + + ifeq ($(BOARD), stmp37xx_dev) + ARCH = 37xx +@@ -16,6 +16,9 @@ + ifeq ($(BOARD), iMX28_EVK) + ARCH = mx28 + endif ++ifeq ($(BOARD), imx23_olinuxino_dev) ++ARCH = mx23 ++endif + + all: build_prep gen_bootstream + +@@ -93,6 +96,8 @@ + clean: + -rm -rf *.sb + rm -f sd_mmc_bootstream.raw ++ rm -f linux_prep/board/*.o ++ rm -f power_prep/*.o + $(MAKE) -C linux_prep clean ARCH=$(ARCH) + $(MAKE) -C boot_prep clean ARCH=$(ARCH) + $(MAKE) -C power_prep clean ARCH=$(ARCH) +diff -ruN imx-bootlets-10.05.02.orig/uboot.db imx-bootlets-10.05.02/uboot.db +--- imx-bootlets-10.05.02.orig/uboot.db 2010-05-14 06:56:28.000000000 +0200 ++++ imx-bootlets-10.05.02/uboot.db 2013-05-19 00:11:40.000000000 +0200 +@@ -3,7 +3,7 @@ + sources { + power_prep="./power_prep/power_prep"; + sdram_prep="./boot_prep/boot_prep"; +- image="/home/b18647/repos/ltib_latest/rootfs/boot/u-boot"; ++ image="../boot/u-boot"; + } + + section (0) { diff --git a/package/boot/kexec-tools/Config.in b/package/boot/kexec-tools/Config.in new file mode 100644 index 0000000..6c7558f --- /dev/null +++ b/package/boot/kexec-tools/Config.in @@ -0,0 +1,31 @@ +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. + +config KEXEC_ZLIB + bool + prompt "zlib support" + default y + +config KEXEC_LZMA + bool + prompt "lzma support" + default n + +endmenu diff --git a/package/boot/kexec-tools/Makefile b/package/boot/kexec-tools/Makefile new file mode 100644 index 0000000..6f04bce --- /dev/null +++ b/package/boot/kexec-tools/Makefile @@ -0,0 +1,87 @@ +# +# 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.9 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=@KERNEL/linux/utils/kernel/kexec +PKG_MD5SUM:=6681319934e22e74c532bd392ccb1bbb + +PKG_FIXUP:=autoreconf + +PKG_CONFIG_DEPENDS := CONFIG_KEXEC_ZLIB CONFIG_KEXEC_LZMA + +include $(INCLUDE_DIR)/package.mk + +define Package/kexec-tools + SECTION:=utils + CATEGORY:=Utilities + DEPENDS:=@KERNEL_KEXEC @armeb||@arm||@i386||@powerpc64||@mipsel||@mips +KEXEC_ZLIB:zlib +KEXEC_LZMA:liblzma + TITLE:=Kernel boots kernel + URL:=http://kernel.org/pub/linux/kernel/people/horms/kexec-tools/ + MAINTAINER:=Florian Fainelli + 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 \ + $(if $(CONFIG_KEXEC_ZLIB),--with,--without)-zlib \ + $(if $(CONFIG_KEXEC_LZMA),--with,--without)-lzma + +TARGET_CFLAGS += -ffunction-sections -fdata-sections +TARGET_LDFLAGS += -Wl,--gc-sections + +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) ../usr/sbin/kexec $(1)/sbin/kexec +endef + +$(eval $(call BuildPackage,kexec-tools)) diff --git a/package/boot/kexec-tools/patches/0001-Fix-zlib-lzma-decompression.patch b/package/boot/kexec-tools/patches/0001-Fix-zlib-lzma-decompression.patch new file mode 100644 index 0000000..06c11ec --- /dev/null +++ b/package/boot/kexec-tools/patches/0001-Fix-zlib-lzma-decompression.patch @@ -0,0 +1,171 @@ +From d606837b56d46eb7f815b5d85f07fcc3f1555d00 Mon Sep 17 00:00:00 2001 +From: Yousong Zhou +Date: Sun, 1 Feb 2015 00:10:07 +0800 +Subject: [PATCH 1/5] Fix zlib/lzma decompression. + +Let {zlib,lzma}_decompress_file() return NULL if anything wrong happened +to allow the other method to have a chance to run. + +Signed-off-by: Yousong Zhou +Signed-off-by: Simon Horman +--- + kexec/lzma.c | 33 ++++++++++++++++++++++----------- + kexec/zlib.c | 57 +++++++++++++++++++++++++++++++++++---------------------- + 2 files changed, 57 insertions(+), 33 deletions(-) + +diff --git a/kexec/lzma.c b/kexec/lzma.c +index 939aeb3..5bfccb7 100644 +--- a/kexec/lzma.c ++++ b/kexec/lzma.c +@@ -162,13 +162,16 @@ char *lzma_decompress_file(const char *filename, off_t *r_size) + off_t size, allocated; + ssize_t result; + +- if (!filename) { +- *r_size = 0; +- return 0; +- } ++ dbgprintf("Try LZMA decompression.\n"); ++ ++ *r_size = 0; ++ if (!filename) ++ return NULL; ++ + fp = lzopen(filename, "rb"); + if (fp == 0) { +- die("Cannot open `%s'\n", filename); ++ dbgprintf("Cannot open `%s'\n", filename); ++ return NULL; + } + size = 0; + allocated = 65536; +@@ -183,17 +186,25 @@ char *lzma_decompress_file(const char *filename, off_t *r_size) + if ((errno == EINTR) || (errno == EAGAIN)) + continue; + +- die ("read on %s of %ld bytes failed\n", +- filename, (allocated - size) + 0UL); ++ dbgprintf("%s: read on %s of %ld bytes failed\n", ++ __func__, filename, (allocated - size) + 0UL); ++ break; + } + size += result; +- } while(result > 0); +- result = lzclose(fp); +- if (result != LZMA_OK) { +- die ("Close of %s failed\n", filename); ++ } while (result > 0); ++ ++ if (lzclose(fp) != LZMA_OK) { ++ dbgprintf("%s: Close of %s failed\n", __func__, filename); ++ goto fail; + } ++ if (result < 0) ++ goto fail; ++ + *r_size = size; + return buf; ++fail: ++ free(buf); ++ return NULL; + } + #else + char *lzma_decompress_file(const char *UNUSED(filename), off_t *UNUSED(r_size)) +diff --git a/kexec/zlib.c b/kexec/zlib.c +index d44df12..7170ac3 100644 +--- a/kexec/zlib.c ++++ b/kexec/zlib.c +@@ -15,29 +15,39 @@ + #include + #include + ++static void _gzerror(gzFile fp, int *errnum, const char **errmsg) ++{ ++ *errmsg = gzerror(fp, errnum); ++ if (*errnum == Z_ERRNO) { ++ *errmsg = strerror(*errnum); ++ } ++} ++ + char *zlib_decompress_file(const char *filename, off_t *r_size) + { + gzFile fp; + int errnum; + const char *msg; + char *buf; +- off_t size, allocated; ++ off_t size = 0, allocated; + ssize_t result; + ++ dbgprintf("Try gzip decompression.\n"); ++ ++ *r_size = 0; + if (!filename) { +- *r_size = 0; +- return 0; ++ return NULL; + } + fp = gzopen(filename, "rb"); + if (fp == 0) { +- msg = gzerror(fp, &errnum); +- if (errnum == Z_ERRNO) { +- msg = strerror(errno); +- } +- fprintf(stderr, "Cannot open `%s': %s\n", filename, msg); ++ _gzerror(fp, &errnum, &msg); ++ dbgprintf("Cannot open `%s': %s\n", filename, msg); ++ return NULL; ++ } ++ if (gzdirect(fp)) { ++ /* It's not in gzip format */ + return NULL; + } +- size = 0; + allocated = 65536; + buf = xmalloc(allocated); + do { +@@ -49,25 +59,28 @@ char *zlib_decompress_file(const char *filename, off_t *r_size) + if (result < 0) { + if ((errno == EINTR) || (errno == EAGAIN)) + continue; +- +- msg = gzerror(fp, &errnum); +- if (errnum == Z_ERRNO) { +- msg = strerror(errno); +- } +- die ("read on %s of %ld bytes failed: %s\n", +- filename, (allocated - size) + 0UL, msg); ++ _gzerror(fp, &errnum, &msg); ++ dbgprintf("Read on %s of %ld bytes failed: %s\n", ++ filename, (allocated - size) + 0UL, msg); ++ size = 0; ++ goto fail; + } + size += result; + } while(result > 0); ++ ++fail: + result = gzclose(fp); + if (result != Z_OK) { +- msg = gzerror(fp, &errnum); +- if (errnum == Z_ERRNO) { +- msg = strerror(errno); +- } +- die ("Close of %s failed: %s\n", filename, msg); ++ _gzerror(fp, &errnum, &msg); ++ dbgprintf(" Close of %s failed: %s\n", filename, msg); ++ } ++ ++ if (size > 0) { ++ *r_size = size; ++ } else { ++ free(buf); ++ buf = NULL; + } +- *r_size = size; + return buf; + } + #else +-- +1.7.10.4 + diff --git a/package/boot/kexec-tools/patches/0002-configure.ac-apply-necessary-quotes-to-result-of-mac.patch b/package/boot/kexec-tools/patches/0002-configure.ac-apply-necessary-quotes-to-result-of-mac.patch new file mode 100644 index 0000000..aba8af7 --- /dev/null +++ b/package/boot/kexec-tools/patches/0002-configure.ac-apply-necessary-quotes-to-result-of-mac.patch @@ -0,0 +1,52 @@ +From eb20884c9bbc42bdf1ccace4444f3ce72657d7d8 Mon Sep 17 00:00:00 2001 +From: Yousong Zhou +Date: Tue, 9 Sep 2014 20:15:16 +0800 +Subject: [PATCH 2/5] configure.ac: apply necessary quotes to result of macro + expansion. + +This can fix the following error when searching for lzma support and +while at it also apply the practice to other uses of the same pattern. + + checking for lzma_code in -llzma... ./configure: line 4756: ac_fn_c_try_link: command not found + +Signed-off-by: Yousong Zhou +--- + configure.ac | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/configure.ac b/configure.ac +index db93331..c410e90 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -152,22 +152,22 @@ AC_CHECK_PROG([DIRNAME], dirname, dirname, "no", [$PATH]) + dnl See if I have a usable copy of zlib available + if test "$with_zlib" = yes ; then + AC_CHECK_HEADER(zlib.h, +- AC_CHECK_LIB(z, inflateInit_, , +- AC_MSG_NOTICE([zlib support disabled]))) ++ [AC_CHECK_LIB(z, inflateInit_, , ++ AC_MSG_NOTICE([zlib support disabled]))]) + fi + + dnl See if I have a usable copy of lzma available + if test "$with_lzma" = yes ; then + AC_CHECK_HEADER(lzma.h, +- AC_CHECK_LIB(lzma, lzma_code, , +- AC_MSG_NOTICE([lzma support disabled]))) ++ [AC_CHECK_LIB(lzma, lzma_code, , ++ AC_MSG_NOTICE([lzma support disabled]))]) + fi + + dnl find Xen control stack libraries + if test "$with_xen" = yes ; then + AC_CHECK_HEADER(xenctrl.h, +- AC_CHECK_LIB(xenctrl, xc_kexec_load, , +- AC_MSG_NOTICE([Xen support disabled]))) ++ [AC_CHECK_LIB(xenctrl, xc_kexec_load, , ++ AC_MSG_NOTICE([Xen support disabled]))]) + fi + + dnl ---Sanity checks +-- +1.7.10.4 + diff --git a/package/boot/kexec-tools/patches/0003-mips-fix-compiler-warning-on-printing-64-bit-integer.patch b/package/boot/kexec-tools/patches/0003-mips-fix-compiler-warning-on-printing-64-bit-integer.patch new file mode 100644 index 0000000..f4762e9 --- /dev/null +++ b/package/boot/kexec-tools/patches/0003-mips-fix-compiler-warning-on-printing-64-bit-integer.patch @@ -0,0 +1,35 @@ +From 89d455d785190203b1d3a8766c8babb8c1688fc3 Mon Sep 17 00:00:00 2001 +From: Yousong Zhou +Date: Mon, 9 Feb 2015 19:51:25 +0800 +Subject: [PATCH 3/5] mips: fix compiler warning on printing 64-bit integer. + + +Signed-off-by: Yousong Zhou +--- + kexec/arch/mips/crashdump-mips.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kexec/arch/mips/crashdump-mips.c b/kexec/arch/mips/crashdump-mips.c +index e7840e0..98c9f7c 100644 +--- a/kexec/arch/mips/crashdump-mips.c ++++ b/kexec/arch/mips/crashdump-mips.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -52,7 +53,7 @@ static int get_kernel_paddr(struct crash_elf_info *elf_info) + + if (parse_iomem_single("Kernel code\n", &start, NULL) == 0) { + elf_info->kern_paddr_start = start; +- dbgprintf("kernel load physical addr start = 0x%lx\n", start); ++ dbgprintf("kernel load physical addr start = 0x%" PRIu64 "\n", start); + return 0; + } + +-- +1.7.10.4 + diff --git a/package/boot/kexec-tools/patches/0004-mips-remove-unused-variable.patch b/package/boot/kexec-tools/patches/0004-mips-remove-unused-variable.patch new file mode 100644 index 0000000..8626c41 --- /dev/null +++ b/package/boot/kexec-tools/patches/0004-mips-remove-unused-variable.patch @@ -0,0 +1,30 @@ +From 904e9ae892b0592c916a013869e3be3d830e0155 Mon Sep 17 00:00:00 2001 +From: Yousong Zhou +Date: Mon, 9 Feb 2015 20:11:04 +0800 +Subject: [PATCH 4/5] mips: remove unused variable. + +Fixes the following compilation warning. + + kexec/arch/mips/crashdump-mips.c:151:6: warning: unused variable 'i' [-Wunused-variable] + +Signed-off-by: Yousong Zhou +--- + kexec/arch/mips/crashdump-mips.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kexec/arch/mips/crashdump-mips.c b/kexec/arch/mips/crashdump-mips.c +index 98c9f7c..dc68cb4 100644 +--- a/kexec/arch/mips/crashdump-mips.c ++++ b/kexec/arch/mips/crashdump-mips.c +@@ -148,7 +148,7 @@ static int exclude_crash_reserve_region(int *nr_ranges) + static int get_crash_memory_ranges(struct memory_range **range, int *ranges) + { + const char iomem[] = "/proc/iomem"; +- int i, memory_ranges = 0; ++ int memory_ranges = 0; + char line[MAX_LINE]; + FILE *fp; + unsigned long long start, end; +-- +1.7.10.4 + diff --git a/package/boot/kexec-tools/patches/0005-mips-fix-warning-about-implicit-type-conversion.patch b/package/boot/kexec-tools/patches/0005-mips-fix-warning-about-implicit-type-conversion.patch new file mode 100644 index 0000000..008a62d --- /dev/null +++ b/package/boot/kexec-tools/patches/0005-mips-fix-warning-about-implicit-type-conversion.patch @@ -0,0 +1,30 @@ +From 00e75179b3b4b80e6e58d29a2bd948f97682fd00 Mon Sep 17 00:00:00 2001 +From: Yousong Zhou +Date: Mon, 9 Feb 2015 20:28:14 +0800 +Subject: [PATCH 5/5] mips: fix warning about implicit type conversion. + +Fixes the following warning. + + kexec/arch/mips/kexec-elf-mips.c:161:16: warning: assignment makes integer from pointer without a cast [enabled by default] + +Signed-off-by: Yousong Zhou +--- + kexec/arch/mips/kexec-elf-mips.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kexec/arch/mips/kexec-elf-mips.c b/kexec/arch/mips/kexec-elf-mips.c +index a27d986..8a6419a 100644 +--- a/kexec/arch/mips/kexec-elf-mips.c ++++ b/kexec/arch/mips/kexec-elf-mips.c +@@ -158,7 +158,7 @@ int elf_mips_load(int argc, char **argv, const char *buf, off_t len, + if (info->kexec_flags & KEXEC_ON_CRASH) + /* In case of crashdump segment[0] is kernel. + * Put cmdline just after it. */ +- cmdline_addr = info->segment[0].mem + ++ cmdline_addr = (unsigned long)info->segment[0].mem + + info->segment[0].memsz; + else + cmdline_addr = 0; +-- +1.7.10.4 + diff --git a/package/boot/kobs-ng/Makefile b/package/boot/kobs-ng/Makefile new file mode 100644 index 0000000..c43fa19 --- /dev/null +++ b/package/boot/kobs-ng/Makefile @@ -0,0 +1,45 @@ +# +# Copyright (C) 2013-2014 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:=kobs-ng +PKG_VERSION:=3.0.35-4.0.0 +PKG_RELEASE:=2 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://repository.timesys.com/buildsources/k/kobs-ng/kobs-ng-$(PKG_VERSION)/ +PKG_MD5SUM:=26104c577f59a6b81782a5bd16aadd82 + +PKG_LICENSE:=GPLv2 +PKG_LICENSE_FILES:=COPYING + +include $(INCLUDE_DIR)/package.mk + +define Package/kobs-ng + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Application for writing bootstreams to NAND flash + DEPENDS:=@TARGET_imx6 +endef + +define Package/kobs-ng/description + The kobs-ng application writes a bootstream to NAND flash with the proper + FCB/DBBT headers and replicated streams. +endef + +define Build/Prepare + $(call Build/Prepare/Default) + echo "const char* git_sha = \"$(PKG_VERSION)\";" > $(PKG_BUILD_DIR)/autoversion.h +endef + +define Package/kobs-ng/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/kobs-ng $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,kobs-ng)) diff --git a/package/boot/kobs-ng/patches/001-fix-mtd-defines.patch b/package/boot/kobs-ng/patches/001-fix-mtd-defines.patch new file mode 100644 index 0000000..6fdc735 --- /dev/null +++ b/package/boot/kobs-ng/patches/001-fix-mtd-defines.patch @@ -0,0 +1,76 @@ +From: Paul B. Henson + +Newer kernel headers renamed mtd mode defines and no longer support +MEMSETOOBSEL. Allow code to work with both older and newer kernel +versions. + +Signed-off-by: Paul B. Henson +--- + +http://git.buildroot.net/buildroot/plain/package/kobs-ng/kobs-ng-fix-mtd-defines.patch + +--- a/src/mtd.c ++++ b/src/mtd.c +@@ -852,8 +852,11 @@ void mtd_close(struct mtd_data *md) + mp = &md->part[i]; + + if (mp->fd != -1) { ++/* Newer kernels dropped MEMSETOOBSEL */ ++#ifdef MEMSETOOBSEL + (void)ioctl(mp->fd, MEMSETOOBSEL, + &mp->old_oobinfo); ++#endif + close(mp->fd); + } + +@@ -896,6 +899,8 @@ int mtd_set_ecc_mode(struct mtd_data *md + continue; + } + ++/* Newer kernels dropped MEMSETOOBSEL */ ++#ifdef MEMSETOOBSEL + if (r == -ENOTTY) { + r = ioctl(mp->fd, MEMSETOOBSEL, &mp->old_oobinfo); + if (r != 0) { +@@ -904,6 +909,7 @@ int mtd_set_ecc_mode(struct mtd_data *md + } + mp->oobinfochanged = 0; + } ++#endif + } else { + r = ioctl(mp->fd, MTDFILEMODE, (void *)MTD_MODE_RAW); + if (r != 0 && r != -ENOTTY) { +@@ -911,6 +917,8 @@ int mtd_set_ecc_mode(struct mtd_data *md + continue; + } + ++/* Newer kernels dropped MEMSETOOBSEL */ ++#ifdef MEMSETOOBSEL + if (r == -ENOTTY) { + r = ioctl(mp->fd, MEMSETOOBSEL, &none_oobinfo); + if (r != 0) { +@@ -920,6 +928,7 @@ int mtd_set_ecc_mode(struct mtd_data *md + mp->oobinfochanged = 1; + } else + mp->oobinfochanged = 2; ++#endif + } + + mp->ecc = ecc; +--- a/src/mtd.h ++++ b/src/mtd.h +@@ -31,6 +31,14 @@ + #include "BootControlBlocks.h" + #include "rom_nand_hamming_code_ecc.h" + ++// Newer kernel headers renamed define ++#ifndef MTD_MODE_NORMAL ++#define MTD_MODE_NORMAL MTD_FILE_MODE_NORMAL ++#endif ++#ifndef MTD_MODE_RAW ++#define MTD_MODE_RAW MTD_FILE_MODE_RAW ++#endif ++ + //------------------------------------------------------------------------------ + // Re-definitions of true and false, because the standard ones aren't good + // enough? diff --git a/package/boot/kobs-ng/patches/002-add-init-size-param.patch b/package/boot/kobs-ng/patches/002-add-init-size-param.patch new file mode 100644 index 0000000..e0e89b2 --- /dev/null +++ b/package/boot/kobs-ng/patches/002-add-init-size-param.patch @@ -0,0 +1,42 @@ +--- a/src/main.c ++++ b/src/main.c +@@ -94,6 +94,7 @@ void usage(void) + " [KOBS] boot structures config options\n" + " --chip_0_device_path= .......... Device of boot (default /dev/mtd0)\n" + " --chip_1_device_path= .......... The second chip in case of multichip NAND\n" ++ " --chip_0_size= ................. Override size of chip_0 device\n" + " --search_exponent= ............ NCB field (default 2)\n" + " --data_setup_time= ............ NCB field (default 80)\n" + " --data_hold_time= ............. NCB field (default 60)\n" +--- a/src/mtd.c ++++ b/src/mtd.c +@@ -716,6 +716,11 @@ struct mtd_data *mtd_open(const struct m + goto out; + } + ++ /* override MTD size */ ++ if (md->cfg.chip_0_size) { ++ miu->size = md->cfg.chip_0_size; ++ } ++ + /* verify it's a nand */ + if (miu->type != MTD_NANDFLASH) { + fprintf(stderr, "mtd: device %s not NAND\n", mp->name); +@@ -2914,7 +2919,7 @@ static const struct { + } mtd_int_args[] = { + ARG_IGNORE(chip_count), + ARG_IGNORE(chip_0_offset), +- ARG_IGNORE(chip_0_size), ++ ARG(chip_0_size), + ARG_IGNORE(chip_1_offset), + ARG_IGNORE(chip_1_size), + ARG(search_exponent), +@@ -3107,7 +3112,7 @@ void mtd_cfg_dump(struct mtd_config *cfg + // Pd(chip_count); + Ps(chip_0_device_path); + // Pd(chip_0_offset); +-// Pd(chip_0_size); ++ Pd(chip_0_size); + Ps(chip_1_device_path); + // Pd(chip_1_offset); + // Pd(chip_1_size); diff --git a/package/boot/kobs-ng/patches/003-missing_include.patch b/package/boot/kobs-ng/patches/003-missing_include.patch new file mode 100644 index 0000000..b91c050 --- /dev/null +++ b/package/boot/kobs-ng/patches/003-missing_include.patch @@ -0,0 +1,20 @@ +--- a/src/mtd.c ++++ b/src/mtd.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + #include +--- a/src/mtd.h ++++ b/src/mtd.h +@@ -27,6 +27,7 @@ + + #include + #include ++#include + + #include "BootControlBlocks.h" + #include "rom_nand_hamming_code_ecc.h" diff --git a/package/boot/kobs-ng/patches/004-gnu_source.patch b/package/boot/kobs-ng/patches/004-gnu_source.patch new file mode 100644 index 0000000..3e94c92 --- /dev/null +++ b/package/boot/kobs-ng/patches/004-gnu_source.patch @@ -0,0 +1,10 @@ +--- a/src/plat_boot_config.c ++++ b/src/plat_boot_config.c +@@ -18,6 +18,7 @@ + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + ++#define _GNU_SOURCE + #include + #include + #include 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 +# +# 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/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 +#else +#include +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 +#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..b7cf79f --- /dev/null +++ b/package/boot/rbcfg/src/main.c @@ -0,0 +1,791 @@ +/* + * RouterBOOT configuration utility + * + * Copyright (C) 2010 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "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", " 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 \n" + "\t- get value of the configuration option ", + .flags = CMD_FLAG_USES_CFG, + .exec = rbcfg_cmd_get, + }, { + .command = "set", + .usage = "set \n" + "\t- set value of the configuration option to ", + .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 \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), "%s", 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 + * + * 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/Makefile b/package/boot/uboot-ar71xx/Makefile new file mode 100644 index 0000000..7c4bb6c --- /dev/null +++ b/package/boot/uboot-ar71xx/Makefile @@ -0,0 +1,95 @@ +# +# 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:= \ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:= +PKG_TARGETS:=bin + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +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_generic + 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/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 . + * + * 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 +#include +#include +#include +#include + + + +.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 . + * + * 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 +#include +#include +#include +#include +#include +#include + +#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/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 . + * + * 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 +#include +#include +#include + +#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/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 + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include +#include + +#include + +#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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include + +#include + +// 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/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 . + * + * 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<. + * + * 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 +#include +#include +#include +#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, ®Data)) { + 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, ®Data)) + 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, ®Data)) + 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, ®Data)) { + 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, ®Data)) + 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, ®Data)) + 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, ®Data)) { + 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, ®Data)) { + 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, ®Data)) + 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, ®Data); + 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/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 + * + * 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 +#include +#include + +#include +#include +#include + +/*----------------------------------------------------------------------- + * 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/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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include + +#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 . + * + * 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 +#include + +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/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 . + * + * 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 +#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 +#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/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 + # include +-#elif defined(__MACH__) ++#elif defined(__MACH__) || defined(__FreeBSD__) + # include + 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-ar71xx/patches/030-no_examples.patch b/package/boot/uboot-ar71xx/patches/030-no_examples.patch new file mode 100644 index 0000000..65e1289 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/030-no_examples.patch @@ -0,0 +1,13 @@ +--- a/Makefile ++++ b/Makefile +@@ -139,9 +139,7 @@ endif + + # The "tools" are needed early, so put this first + # Don't include stuff already done in $(LIBS) +-SUBDIRS = tools \ +- examples/standalone \ +- examples/api ++SUBDIRS = tools + + .PHONY : $(SUBDIRS) + diff --git a/package/boot/uboot-ar71xx/patches/040-no_extern_inline.patch b/package/boot/uboot-ar71xx/patches/040-no_extern_inline.patch new file mode 100644 index 0000000..5c01691 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/040-no_extern_inline.patch @@ -0,0 +1,112 @@ +--- a/include/asm-mips/io.h ++++ b/include/asm-mips/io.h +@@ -118,12 +118,12 @@ static inline void set_io_port_base(unsi + * Change virtual addresses to physical addresses and vv. + * These are trivial on the 1:1 Linux/MIPS mapping + */ +-extern inline phys_addr_t virt_to_phys(volatile void * address) ++static inline phys_addr_t virt_to_phys(volatile void * address) + { + return CPHYSADDR(address); + } + +-extern inline void * phys_to_virt(unsigned long address) ++static inline void * phys_to_virt(unsigned long address) + { + return (void *)KSEG0ADDR(address); + } +@@ -131,12 +131,12 @@ extern inline void * phys_to_virt(unsign + /* + * IO bus memory addresses are also 1:1 with the physical address + */ +-extern inline unsigned long virt_to_bus(volatile void * address) ++static inline unsigned long virt_to_bus(volatile void * address) + { + return CPHYSADDR(address); + } + +-extern inline void * bus_to_virt(unsigned long address) ++static inline void * bus_to_virt(unsigned long address) + { + return (void *)KSEG0ADDR(address); + } +@@ -150,12 +150,12 @@ extern unsigned long isa_slot_offset; + extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); + + #if 0 +-extern inline void *ioremap(unsigned long offset, unsigned long size) ++static inline void *ioremap(unsigned long offset, unsigned long size) + { + return __ioremap(offset, size, _CACHE_UNCACHED); + } + +-extern inline void *ioremap_nocache(unsigned long offset, unsigned long size) ++static inline void *ioremap_nocache(unsigned long offset, unsigned long size) + { + return __ioremap(offset, size, _CACHE_UNCACHED); + } +@@ -238,7 +238,7 @@ out: + */ + + #define __OUT1(s) \ +-extern inline void __out##s(unsigned int value, unsigned int port) { ++static inline void __out##s(unsigned int value, unsigned int port) { + + #define __OUT2(m) \ + __asm__ __volatile__ ("s" #m "\t%0,%1(%2)" +@@ -252,7 +252,7 @@ __OUT1(s##c_p) __OUT2(m) : : "r" (__iosw + SLOW_DOWN_IO; } + + #define __IN1(t,s) \ +-extern __inline__ t __in##s(unsigned int port) { t _v; ++static inline t __in##s(unsigned int port) { t _v; + + /* + * Required nops will be inserted by the assembler +@@ -267,7 +267,7 @@ __IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i + __IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return __ioswab##w(_v); } + + #define __INS1(s) \ +-extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) { ++static inline void __ins##s(unsigned int port, void * addr, unsigned long count) { + + #define __INS2(m) \ + if (count) \ +@@ -295,7 +295,7 @@ __INS1(s##c) __INS2(m) \ + : "$1");} + + #define __OUTS1(s) \ +-extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) { ++static inline void __outs##s(unsigned int port, const void * addr, unsigned long count) { + + #define __OUTS2(m) \ + if (count) \ +--- a/include/asm-mips/system.h ++++ b/include/asm-mips/system.h +@@ -23,7 +23,7 @@ + #include + #endif + +-extern __inline__ void ++static inline void + __sti(void) + { + __asm__ __volatile__( +@@ -47,7 +47,7 @@ __sti(void) + * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs + * no nops at all. + */ +-extern __inline__ void ++static inline void + __cli(void) + { + __asm__ __volatile__( +@@ -208,7 +208,7 @@ do { \ + * For 32 and 64 bit operands we can take advantage of ll and sc. + * FIXME: This doesn't work for R3000 machines. + */ +-extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) ++static inline unsigned long xchg_u32(volatile int * m, unsigned long val) + { + #ifdef CONFIG_CPU_HAS_LLSC + unsigned long dummy; diff --git a/package/boot/uboot-ar71xx/patches/041-no_weak_alias.patch b/package/boot/uboot-ar71xx/patches/041-no_weak_alias.patch new file mode 100644 index 0000000..b6f18ed --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/041-no_weak_alias.patch @@ -0,0 +1,12 @@ +--- a/common/main.c ++++ b/common/main.c +@@ -47,8 +47,7 @@ DECLARE_GLOBAL_DATA_PTR; + /* + * Board-specific Platform code can reimplement show_boot_progress () if needed + */ +-void inline __show_boot_progress (int val) {} +-void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress"))); ++void __attribute__((weak)) show_boot_progress(int val) {} + + #if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY) + extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* for do_reset() prototype */ diff --git a/package/boot/uboot-envtools/Config.in b/package/boot/uboot-envtools/Config.in new file mode 100644 index 0000000..8f0078f --- /dev/null +++ b/package/boot/uboot-envtools/Config.in @@ -0,0 +1,9 @@ +config UBOOT_ENVTOOLS_UBI + bool "Support environment in UBI volume" + depends on PACKAGE_uboot-envtools + default TARGET_oxnas + help + Add support for reading and writing U-Boot environment + stored in UBI volume(s). + + Increases binary size by about 8 kB diff --git a/package/boot/uboot-envtools/Makefile b/package/boot/uboot-envtools/Makefile new file mode 100644 index 0000000..54db0dd --- /dev/null +++ b/package/boot/uboot-envtools/Makefile @@ -0,0 +1,112 @@ +# +# Copyright (C) 2006-2014 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:=2015.10 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/u-boot-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=\ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=7c203b0fc3390a122d8e8b75f147eac5 + +PKG_BUILD_DEPENDS:=+fstools + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +PKG_BUILD_PARALLEL:=1 + +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 Package/uboot-envtools/config + source "$(SOURCE)/Config.in" +endef + +define Build/Configure + touch $(PKG_BUILD_DIR)/include/config.mk + touch $(PKG_BUILD_DIR)/include/config.h + mkdir $(PKG_BUILD_DIR)/include/generated + touch $(PKG_BUILD_DIR)/include/generated/autoconf.h +endef + +TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + TARGET_CFLAGS="$(TARGET_CFLAGS)" \ + UBI="$(CONFIG_UBOOT_ENVTOOLS_UBI)" \ + 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) 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_DATA) ./files/ar71xx $(1)/etc/uci-defaults/30_uboot-envtools +endif +ifneq ($(CONFIG_TARGET_cns3xxx),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_DATA) ./files/cns3xxx $(1)/etc/uci-defaults/30_uboot-envtools +endif +ifneq ($(CONFIG_TARGET_imx6),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_DATA) ./files/imx6 $(1)/etc/uci-defaults/30_uboot-envtools +endif +ifneq ($(CONFIG_TARGET_kirkwood),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_DATA) ./files/kirkwood $(1)/etc/uci-defaults/30_uboot-envtools +endif +ifneq ($(CONFIG_TARGET_lantiq),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_DATA) ./files/lantiq $(1)/etc/uci-defaults/30_uboot-envtools +endif +ifneq ($(CONFIG_TARGET_mvebu),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/mvebu $(1)/etc/uci-defaults/30_uboot-envtools +endif +ifneq ($(CONFIG_TARGET_mxs),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/mxs $(1)/etc/uci-defaults/30_uboot-envtools +endif +ifneq ($(CONFIG_TARGET_oxnas),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/oxnas $(1)/etc/uci-defaults/30_uboot-envtools +endif +ifneq ($(CONFIG_TARGET_ramips),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_DATA) ./files/ramips $(1)/etc/uci-defaults/30_uboot-envtools +endif +endef + +$(eval $(call BuildPackage,uboot-envtools)) diff --git a/package/boot/uboot-envtools/files/ar71xx b/package/boot/uboot-envtools/files/ar71xx new file mode 100644 index 0000000..0c81f32 --- /dev/null +++ b/package/boot/uboot-envtools/files/ar71xx @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (C) 2011-2014 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 | \ +carambola2 | \ +eap300v2 | \ +hornet-ub | \ +hornet-ub-x2 | \ +mr1750 | \ +mr600 | \ +mr600v2 | \ +mr900 | \ +mr900v2 | \ +nbg6716 | \ +om5p-an | \ +om5p | \ +tube2h | \ +wndr3700) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" + ;; +alfa-ap96 | \ +all0315n | \ +om2p | \ +om2pv2 | \ +om2p-hs | \ +om2p-hsv2 | \ +om2p-lc) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x40000" "0x40000" + ;; +wzr-hp-ag300h) + ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x10000" "0x10000" + ;; +qihoo-c301) + ubootenv_add_uci_config "/dev/mtd9" "0x0" "0x10000" "0x10000" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/cns3xxx b/package/boot/uboot-envtools/files/cns3xxx new file mode 100644 index 0000000..a56be15 --- /dev/null +++ b/package/boot/uboot-envtools/files/cns3xxx @@ -0,0 +1,28 @@ +#!/bin/sh +# +# Copyright (C) 2013 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/cns3xxx.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(cns3xxx_board_name) + +case "$board" in +laguna) + # Laguna uboot env size/erasesize vary depending on NOR vs SPI FLASH + size=$(grep mtd1 /proc/mtd | awk '{print $2}') + erasesize=$(grep mtd1 /proc/mtd | awk '{print $3}') + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x$size" "0x$erasesize" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/imx6 b/package/boot/uboot-envtools/files/imx6 new file mode 100644 index 0000000..d7412b2 --- /dev/null +++ b/package/boot/uboot-envtools/files/imx6 @@ -0,0 +1,36 @@ +#!/bin/sh +# +# Copyright (C) 2013-2014 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/imx6.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(imx6_board_name) + +case "$board" in +*gw5*) + if [ -c /dev/mtd1 ]; then + # board boots from NAND + ubootenv_add_uci_config /dev/mtd1 0x0 0x20000 0x40000 + ubootenv_add_uci_config /dev/mtd1 0x80000 0x20000 0x40000 + else + # board boots from microSD + ubootenv_add_uci_config /dev/mmcblk0 0xb1400 0x20000 0x20000 + ubootenv_add_uci_config /dev/mmcblk0 0xd1400 0x20000 0x20000 + fi + ;; +"wandboard") + ubootenv_add_uci_config "/dev/mmcblk0" "0x60000" "0x2000" "0x2000" + ;; +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..98f85da --- /dev/null +++ b/package/boot/uboot-envtools/files/kirkwood @@ -0,0 +1,33 @@ +#!/bin/sh +# +# Copyright (C) 2012-2014 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/kirkwood.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(kirkwood_board_name) + +case "$board" in +"ea3500") + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x4000" "0x20000" + ;; +"ea4500" | \ +"guruplug-server-plus" | \ +"ib62x0" | \ +"pogo_e02" | \ +"sheevaplug" | \ +"sheevaplug-esata" ) + 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..b152061 --- /dev/null +++ b/package/boot/uboot-envtools/files/lantiq @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Copyright (C) 2012 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/functions/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" + ;; +BTHOMEHUBV2B) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" "1" + ;; +P2812HNUF1) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x2000" "0x20000" "1" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/mvebu b/package/boot/uboot-envtools/files/mvebu new file mode 100644 index 0000000..2362bc3 --- /dev/null +++ b/package/boot/uboot-envtools/files/mvebu @@ -0,0 +1,28 @@ +#!/bin/sh +# +# Copyright (C) 2014-2015 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/mvebu.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(mvebu_board_name) + +case "$board" in +armada-385-linksys-caiman|armada-385-linksys-cobra|armada-385-linksys-shelby) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x40000" + ;; +armada-xp-linksys-mamba) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x40000" "0x20000" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/mxs b/package/boot/uboot-envtools/files/mxs new file mode 100644 index 0000000..ab8b4ef --- /dev/null +++ b/package/boot/uboot-envtools/files/mxs @@ -0,0 +1,26 @@ +#!/bin/sh +# +# Copyright (C) 2013 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/mxs.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(mxs_board_name) + +case "$board" in +duckbill) + ubootenv_add_uci_config "/dev/mmcblk0" "0x20000" "0x20000" + ubootenv_add_uci_config "/dev/mmcblk0" "0x40000" "0x20000" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/oxnas b/package/boot/uboot-envtools/files/oxnas new file mode 100644 index 0000000..063ffa0 --- /dev/null +++ b/package/boot/uboot-envtools/files/oxnas @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (C) 2013 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/oxnas.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(oxnas_board_name) + +case "$board" in +stg212 | \ +kd20) + ubootenv_add_uci_config "/dev/ubi0_0" "0x0" "0x4000" "0x1F000" "1" + ubootenv_add_uci_config "/dev/ubi0_1" "0x0" "0x4000" "0x1F000" "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..4640f43 --- /dev/null +++ b/package/boot/uboot-envtools/files/ramips @@ -0,0 +1,33 @@ +#!/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" + ;; +linkits7688 | \ +wsr-600 | \ +wsr-1166 | \ +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 <>/etc/fw_env.config +} + diff --git a/package/boot/uboot-envtools/patches/001-compile.patch b/package/boot/uboot-envtools/patches/001-compile.patch new file mode 100644 index 0000000..1705979 --- /dev/null +++ b/package/boot/uboot-envtools/patches/001-compile.patch @@ -0,0 +1,13 @@ +--- a/tools/env/Makefile ++++ b/tools/env/Makefile +@@ -10,6 +10,10 @@ + # with "CC" here for the maximum code reuse of scripts/Makefile.host. + HOSTCC = $(CC) + ++ifneq ($(TARGET_CFLAGS),) ++HOSTCFLAGS = $(TARGET_CFLAGS) ++endif ++ + # Compile for a hosted environment on the target + HOST_EXTRACFLAGS = $(patsubst -I%,-idirafter%, $(filter -I%, $(UBOOTINCLUDE))) \ + -idirafter $(srctree)/tools/env \ diff --git a/package/boot/uboot-envtools/patches/200-fw_env_no_aes.patch b/package/boot/uboot-envtools/patches/200-fw_env_no_aes.patch new file mode 100644 index 0000000..9c8681f --- /dev/null +++ b/package/boot/uboot-envtools/patches/200-fw_env_no_aes.patch @@ -0,0 +1,38 @@ +--- a/tools/env/fw_env.c ++++ b/tools/env/fw_env.c +@@ -246,7 +246,7 @@ int fw_printenv (int argc, char *argv[]) + int i, n_flag; + int rc = 0; + +- if (argc >= 2 && strcmp(argv[1], "-a") == 0) { ++ if (0 && argc >= 2 && strcmp(argv[1], "-a") == 0) { + if (argc < 3) { + fprintf(stderr, + "## Error: '-a' option requires AES key\n"); +@@ -325,7 +325,7 @@ int fw_printenv (int argc, char *argv[]) + int fw_env_close(void) + { + int ret; +- if (aes_flag) { ++ if (0 && aes_flag) { + ret = env_aes_cbc_crypt(environment.data, 1); + if (ret) { + fprintf(stderr, +@@ -1223,7 +1223,7 @@ int fw_env_open(void) + + crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE); + +- if (aes_flag) { ++ if (0 && aes_flag) { + ret = env_aes_cbc_crypt(environment.data, 0); + if (ret) + return ret; +@@ -1280,7 +1280,7 @@ int fw_env_open(void) + + crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE); + +- if (aes_flag) { ++ if (0 && aes_flag) { + ret = env_aes_cbc_crypt(redundant->data, 0); + if (ret) + return ret; diff --git a/package/boot/uboot-envtools/patches/300-support-env-in-ubivol-chardev.patch b/package/boot/uboot-envtools/patches/300-support-env-in-ubivol-chardev.patch new file mode 100644 index 0000000..75d3804 --- /dev/null +++ b/package/boot/uboot-envtools/patches/300-support-env-in-ubivol-chardev.patch @@ -0,0 +1,163 @@ +From 6e2630a0fc872d0db34157972f6dc3941f6d66dd Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 19 May 2014 21:38:01 +0200 +Subject: [PATCH] tools/env: add support for env in ubi volume chardev + +Signed-off-by: Daniel Golle +--- + tools/env/Makefile | 5 ++++ + tools/env/fw_env.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++------- + 2 files changed, 71 insertions(+), 10 deletions(-) + +--- a/tools/env/Makefile ++++ b/tools/env/Makefile +@@ -24,6 +24,13 @@ ifeq ($(MTD_VERSION),old) + HOST_EXTRACFLAGS += -DMTD_OLD + endif + ++ifeq ($(UBI),y) ++HOST_EXTRACFLAGS += -DUBI ++HOST_LOADLIBES = "-Wl,--gc-sections,-lubi-utils" ++else ++HOST_LOADLIBES = "-Wl,--gc-sections" ++endif ++ + always := fw_printenv + hostprogs-y := fw_printenv + +--- a/tools/env/fw_env.c ++++ b/tools/env/fw_env.c +@@ -31,6 +31,9 @@ + # include + #endif + ++#ifdef UBI ++# include ++#endif + #include "fw_env.h" + + #include +@@ -811,6 +814,11 @@ static int flash_write_buf (int dev, int + off_t top_of_range; /* end of the last block we may use */ + loff_t blockstart; /* running start of the current block - + MEMGETBADBLOCK needs 64 bits */ ++#ifdef UBI ++ libubi_t *libubi = NULL;/* pointer to libubi struct */ ++#else ++ void *libubi = NULL; ++#endif + int rc; + + /* +@@ -916,7 +924,30 @@ static int flash_write_buf (int dev, int + continue; + } + +- if (mtd_type != MTD_ABSENT) { ++#ifdef UBI ++ if (mtd_type == MTD_UBIVOLUME) { ++ struct ubi_vol_info volinfo; ++ libubi = libubi_open(); ++ if (libubi) ++ rc = ubi_get_vol_info(libubi, ++ DEVNAME(dev_current), &volinfo); ++ if (libubi && !rc) { ++ erasesize = volinfo.leb_size; ++ int leb = blockstart / erasesize; ++ if (volinfo.type != UBI_STATIC_VOLUME) ++ rc = ubi_leb_change_start(libubi, fd, ++ leb, erasesize); ++ else ++ rc = ubi_update_start(libubi, fd, ++ erasesize); ++ } ++ if (libubi && rc) { ++ libubi_close(libubi); ++ libubi = NULL; ++ } ++ } ++#endif ++ if (!libubi && mtd_type != MTD_ABSENT) { + erase.start = blockstart; + ioctl(fd, MEMUNLOCK, &erase); + /* These do not need an explicit erase cycle */ +@@ -933,7 +964,8 @@ static int flash_write_buf (int dev, int + fprintf (stderr, + "Seek error on %s: %s\n", + DEVNAME (dev), strerror (errno)); +- return -1; ++ processed = -1; ++ goto out; + } + + #ifdef DEBUG +@@ -943,10 +975,11 @@ static int flash_write_buf (int dev, int + if (write (fd, data + processed, erasesize) != erasesize) { + fprintf (stderr, "Write error on %s: %s\n", + DEVNAME (dev), strerror (errno)); +- return -1; ++ processed = -1; ++ goto out; + } + +- if (mtd_type != MTD_ABSENT) ++ if (!libubi && mtd_type != MTD_ABSENT) + ioctl(fd, MEMLOCK, &erase); + + processed += erasesize; +@@ -957,6 +990,11 @@ static int flash_write_buf (int dev, int + if (write_total > count) + free (data); + ++out: ++#ifdef UBI ++ if (libubi) ++ libubi_close(libubi); ++#endif + return processed; + } + +@@ -1068,12 +1106,8 @@ static int flash_read (int fd) + + if (S_ISCHR(st.st_mode)) { + rc = ioctl(fd, MEMGETINFO, &mtdinfo); +- if (rc < 0) { +- fprintf(stderr, "Cannot get MTD information for %s\n", +- DEVNAME(dev_current)); +- return -1; +- } +- if (mtdinfo.type != MTD_NORFLASH && ++ if (!rc && ++ mtdinfo.type != MTD_NORFLASH && + mtdinfo.type != MTD_NANDFLASH && + mtdinfo.type != MTD_DATAFLASH && + mtdinfo.type != MTD_UBIVOLUME) { +@@ -1081,6 +1115,28 @@ static int flash_read (int fd) + mtdinfo.type, DEVNAME(dev_current)); + return -1; + } ++#ifdef UBI ++ if (rc) { ++ libubi_t *libubi; ++ struct ubi_vol_info volinfo; ++ libubi = libubi_open(); ++ if (!libubi) ++ return -ENOMEM; ++ ++ rc = ubi_get_vol_info(libubi, DEVNAME(dev_current), ++ &volinfo); ++ if (rc) { ++ libubi_close(libubi); ++ return -ENODEV; ++ } ++ memset(&mtdinfo, 0, sizeof(mtdinfo)); ++ mtdinfo.type = MTD_UBIVOLUME; ++ mtdinfo.size = volinfo.data_bytes; ++ mtdinfo.erasesize = volinfo.leb_size; ++ mtdinfo.writesize = volinfo.leb_size; ++ libubi_close(libubi); ++ } ++#endif + } else { + memset(&mtdinfo, 0, sizeof(mtdinfo)); + mtdinfo.type = MTD_ABSENT; diff --git a/package/boot/uboot-imx6/Makefile b/package/boot/uboot-imx6/Makefile new file mode 100644 index 0000000..7074da9 --- /dev/null +++ b/package/boot/uboot-imx6/Makefile @@ -0,0 +1,132 @@ +# +# Copyright (C) 2013-2014 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:=2014.04 +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:= \ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=6d2116d1385a66e9a59742caa9d62a54 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/nitrogen6dl + TITLE:=U-Boot for Nitrogen6x i.MX6Dual-Lite 1GB board +endef + +define uboot/nitrogen6dl2g + TITLE:=U-Boot for Nitrogen6x i.MX6Dual-Lite 2GB board +endef + +define uboot/nitrogen6q + TITLE:=U-Boot for Nitrogen6x/SABRE Lite (MX6Q/1GB) +endef + +define uboot/nitrogen6q2g + TITLE:=U-Boot for Nitrogen6x i.MX6Quad 2GB board +endef + +define uboot/nitrogen6s + TITLE:=U-Boot for Nitrogen6x i.MX6Solo 512MB board +endef + +define uboot/nitrogen6s1g + TITLE:=U-Boot for Nitrogen6x i.MX6Solo 1GB board +endef + +define uboot/wandboard_dl + TITLE:=U-Boot for the Wandboard Dual Lite +endef + +define uboot/wandboard_quad + TITLE:=U-Boot for the Wandboard Quad +endef + +define uboot/wandboard_solo + TITLE:=U-Boot for the Wandboard Solo +endef + +UBOOTS := \ + nitrogen6dl \ + nitrogen6dl2g \ + nitrogen6q \ + nitrogen6q2g \ + nitrogen6s \ + nitrogen6s1g \ + wandboard_dl \ + wandboard_quad \ + wandboard_solo + +define Package/uboot/template +define Package/uboot-imx6-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_imx6 + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Luka Perkov +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) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/default + $(INSTALL_DIR) $(BIN_DIR)/uboot-$(BOARD)-$(1) + $(CP) \ + $(PKG_BUILD_DIR)/u-boot.imx \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.imx +endef + +define Package/uboot/install/template +define Package/uboot-imx6-$(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-imx6-$(u))) \ +) diff --git a/package/boot/uboot-imx6/patches/100-wandboard-enable-fit.patch b/package/boot/uboot-imx6/patches/100-wandboard-enable-fit.patch new file mode 100644 index 0000000..894ccf0 --- /dev/null +++ b/package/boot/uboot-imx6/patches/100-wandboard-enable-fit.patch @@ -0,0 +1,10 @@ +--- a/include/configs/wandboard.h ++++ b/include/configs/wandboard.h +@@ -238,4 +238,7 @@ + #define CONFIG_CMD_CACHE + #endif + ++#define CONFIG_FIT ++#define CONFIG_FIT_VERBOSE ++ + #endif /* __CONFIG_H * */ diff --git a/package/boot/uboot-imx6/patches/110-wandboard-owrt-env.patch b/package/boot/uboot-imx6/patches/110-wandboard-owrt-env.patch new file mode 100644 index 0000000..7bef453 --- /dev/null +++ b/package/boot/uboot-imx6/patches/110-wandboard-owrt-env.patch @@ -0,0 +1,89 @@ +--- a/include/configs/wandboard.h ++++ b/include/configs/wandboard.h +@@ -49,7 +49,7 @@ + #define CONFIG_CMD_BMODE + #define CONFIG_CMD_SETEXPR + +-#define CONFIG_BOOTDELAY 5 ++#define CONFIG_BOOTDELAY 3 + + #define CONFIG_SYS_MEMTEST_START 0x10000000 + #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 500 * SZ_1M) +@@ -102,13 +102,15 @@ + + #if defined(CONFIG_MX6DL) || defined(CONFIG_MX6S) + #define CONFIG_DEFAULT_FDT_FILE "imx6dl-wandboard.dtb" ++#define CONFIG_OWRT_NAME "openwrt-imx6-imx6dl-wandboard-fit-uImage.itb" + #elif defined(CONFIG_MX6Q) + #define CONFIG_DEFAULT_FDT_FILE "imx6q-wandboard.dtb" ++#define CONFIG_OWRT_NAME "openwrt-imx6-imx6q-wandboard-fit-uImage.itb" + #endif + + #define CONFIG_EXTRA_ENV_SETTINGS \ + "script=boot.scr\0" \ +- "image=zImage\0" \ ++ "image=" CONFIG_OWRT_NAME "\0" \ + "console=ttymxc0\0" \ + "splashpos=m,m\0" \ + "fdt_high=0xffffffff\0" \ +@@ -137,11 +139,11 @@ + "mmcargs=setenv bootargs console=${console},${baudrate} " \ + "root=${mmcroot}\0" \ + "loadbootscript=" \ +- "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \ ++ "ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \ + "bootscript=echo Running bootscript from mmc ...; " \ + "source\0" \ +- "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ +- "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \ ++ "loaduimage=ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \ ++ "loadfdt=ext2load mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \ + "mmcboot=echo Booting from mmc ...; " \ + "run mmcargs; " \ + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ +@@ -155,31 +157,7 @@ + "fi; " \ + "fi; " \ + "else " \ +- "bootz; " \ +- "fi;\0" \ +- "netargs=setenv bootargs console=${console},${baudrate} " \ +- "root=/dev/nfs " \ +- "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ +- "netboot=echo Booting from net ...; " \ +- "run netargs; " \ +- "if test ${ip_dyn} = yes; then " \ +- "setenv get_cmd dhcp; " \ +- "else " \ +- "setenv get_cmd tftp; " \ +- "fi; " \ +- "${get_cmd} ${image}; " \ +- "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ +- "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ +- "bootz ${loadaddr} - ${fdt_addr}; " \ +- "else " \ +- "if test ${boot_fdt} = try; then " \ +- "bootz; " \ +- "else " \ +- "echo WARN: Cannot load the DT; " \ +- "fi; " \ +- "fi; " \ +- "else " \ +- "bootz; " \ ++ "bootm; " \ + "fi;\0" + + #define CONFIG_BOOTCOMMAND \ +@@ -189,10 +167,10 @@ + "else " \ + "if run loadimage; then " \ + "run mmcboot; " \ +- "else run netboot; " \ ++ "else echo WARN: Can not boot the image; " \ + "fi; " \ + "fi; " \ +- "else run netboot; fi" ++ "fi" + + /* Miscellaneous configurable options */ + #define CONFIG_SYS_LONGHELP diff --git a/package/boot/uboot-kirkwood/Makefile b/package/boot/uboot-kirkwood/Makefile new file mode 100644 index 0000000..89caaf1 --- /dev/null +++ b/package/boot/uboot-kirkwood/Makefile @@ -0,0 +1,145 @@ +# +# Copyright (C) 2010-2014 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:=2014.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:=\ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=3ddcaee2f05b7c464778112ec83664b5 +PKG_TARGETS:=bin + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= +endef + +define uboot/dockstar + TITLE:=U-Boot for Seagate DockStar +endef + +define uboot/dockstar_second_stage + TITLE:=second stage U-Boot for Seagate DockStar +endef + +define uboot/goflexhome + TITLE:=U-Boot for the Seagate GoFlexHome/GoFlexNet +endef + +define uboot/ib62x0 + TITLE:=U-Boot for RaidSonic ICY BOX NAS6210 and NAS6220 +endef + +define uboot/ib62x0_second_stage + TITLE:=second stage U-Boot for RaidSonic ICY BOX NAS6210 and NAS6220 +endef + +define uboot/iconnect + TITLE:=U-Boot for Iomega iConnect Wireless +endef + +define uboot/iconnect_second_stage + TITLE:=second stage U-Boot for Iomega iConnect Wireless +endef + +define uboot/pogo_e02 + TITLE:=U-Boot for Cloud Engines Pogoplug E02 +endef + +define uboot/pogo_e02_second_stage + TITLE:=second stage U-Boot for Cloud Engines Pogoplug E02 +endef + +define uboot/sheevaplug + TITLE:=U-Boot for SheevaPlug +endef + +UBOOTS:= \ + dockstar dockstar_second_stage \ + goflexhome \ + ib62x0 ib62x0_second_stage \ + iconnect iconnect_second_stage \ + pogo_e02 pogo_e02_second_stage \ + sheevaplug + +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 + +define Build/Configure + $(if $(findstring _second_stage,$(BUILD_VARIANT)), + $(CP) \ + $(PKG_BUILD_DIR)/configs/$(subst _second_stage,,$(BUILD_VARIANT))_defconfig \ + $(PKG_BUILD_DIR)/configs/$(BUILD_VARIANT)_defconfig + echo CONFIG_SECOND_STAGE=y >> $(PKG_BUILD_DIR)/configs/$(BUILD_VARIANT)_defconfig + ) + +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ + $(BUILD_VARIANT)_config V=1 +endef + +define Build/Compile + +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ + u-boot.kwb \ + CROSS_COMPILE=$(TARGET_CROSS) + mkimage -A $(ARCH) -O linux -T kernel -C none \ + -a 0x600000 -e 0x600000 \ + -n 'OpenWrt Das U-Boot uImage' \ + -d $(PKG_BUILD_DIR)/u-boot.bin $(PKG_BUILD_DIR)/u-boot.img +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 + $(CP) $(PKG_BUILD_DIR)/u-boot.img \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.img + $(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/patches/0001-cosmetic-kirkwood-style-fixes-in-kwbimage.cfg-files.patch b/package/boot/uboot-kirkwood/patches/0001-cosmetic-kirkwood-style-fixes-in-kwbimage.cfg-files.patch new file mode 100644 index 0000000..5abdad9 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/0001-cosmetic-kirkwood-style-fixes-in-kwbimage.cfg-files.patch @@ -0,0 +1,96 @@ +From 76a9fed9e5580945827a82963ac7315186fd0ebe Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Mon, 11 Nov 2013 06:45:44 +0100 +Subject: [PATCH 1/9] cosmetic: kirkwood: style fixes in kwbimage.cfg files + +When diffing through the changes only the relevant changes +should be displayed. + +Signed-off-by: Luka Perkov +--- + board/iomega/iconnect/kwbimage.cfg | 4 ++-- + board/raidsonic/ib62x0/kwbimage.cfg | 22 +++++++++++----------- + 2 files changed, 13 insertions(+), 13 deletions(-) + +--- a/board/iomega/iconnect/kwbimage.cfg ++++ b/board/iomega/iconnect/kwbimage.cfg +@@ -20,7 +20,7 @@ NAND_PAGE_SIZE 0x0800 + # Configure RGMII-0 interface pad voltage to 1.8V + DATA 0xffd100e0 0x1b1b1b9b + +-#Dram initalization for SINGLE x16 CL=5 @ 400MHz ++# Dram initalization for SINGLE x16 CL=5 @ 400MHz + DATA 0xffd01400 0x43000c30 # DDR Configuration register + # bit13-0: 0xc30, (3120 DDR2 clks refresh rate) + # bit23-14: 0x0, +@@ -87,7 +87,7 @@ DATA 0xffd0141c 0x00000c52 # DDR Mode + # bit6-4: 0x4, CL=5 + # bit7: 0x0, TestMode=0 normal + # bit8: 0x0, DLL reset=0 normal +-# bit11-9: 0x6, auto-precharge write recovery ???????????? ++# bit11-9: 0x6, auto-precharge write recovery + # bit12: 0x0, PD must be zero + # bit31-13: 0x0, required + +--- a/board/raidsonic/ib62x0/kwbimage.cfg ++++ b/board/raidsonic/ib62x0/kwbimage.cfg +@@ -11,7 +11,7 @@ + # + + # Boot Media configurations +-BOOT_FROM nand # change from nand to uart if building UART image ++BOOT_FROM nand + NAND_ECC_MODE default + NAND_PAGE_SIZE 0x0800 + +@@ -21,12 +21,12 @@ NAND_PAGE_SIZE 0x0800 + # Configure RGMII-0 interface pad voltage to 1.8V + DATA 0xffd100e0 0x1b1b1b9b + +-#Dram initalization for SINGLE x16 CL=5 @ 400MHz ++# Dram initalization for SINGLE x16 CL=5 @ 400MHz + DATA 0xffd01400 0x43000c30 # DDR Configuration register + # bit13-0: 0xc30, (3120 DDR2 clks refresh rate) + # bit23-14: 0x0, +-# bit24: 0x1, enable exit self refresh mode on DDR access +-# bit25: 0x1, required ++# bit24: 0x1, enable exit self refresh mode on DDR access ++# bit25: 0x1, required + # bit29-26: 0x0, + # bit31-30: 0x1, + +@@ -64,10 +64,10 @@ DATA 0xffd01410 0x0000000c # DDR Address + # bit3-2: 11, Cs0size (1Gb) + # bit5-4: 00, Cs1width (x8) + # bit7-6: 11, Cs1size (1Gb) +-# bit9-8: 00, Cs2width (nonexistent +-# bit11-10: 00, Cs2size (nonexistent +-# bit13-12: 00, Cs3width (nonexistent +-# bit15-14: 00, Cs3size (nonexistent ++# bit9-8: 00, Cs2width (nonexistent) ++# bit11-10: 00, Cs2size (nonexistent) ++# bit13-12: 00, Cs3width (nonexistent) ++# bit15-14: 00, Cs3size (nonexistent) + # bit16: 0, Cs0AddrSel + # bit17: 0, Cs1AddrSel + # bit18: 0, Cs2AddrSel +@@ -88,7 +88,7 @@ DATA 0xffd0141c 0x00000c52 # DDR Mode + # bit6-4: 0x4, CL=5 + # bit7: 0x0, TestMode=0 normal + # bit8: 0x0, DLL reset=0 normal +-# bit11-9: 0x6, auto-precharge write recovery ???????????? ++# bit11-9: 0x6, auto-precharge write recovery + # bit12: 0x0, PD must be zero + # bit31-13: 0x0, required + +@@ -148,8 +148,8 @@ DATA 0xffd0149c 0x0000e803 # CPU ODT Con + DATA 0xffd01480 0x00000001 # DDR Initialization Control + # bit0: 0x1, enable DDR init upon this register write + +-DATA 0xFFD20134 0x66666666 # L2 RAM Timing 0 Register +-DATA 0xFFD20138 0x66666666 # L2 RAM Timing 1 Register ++DATA 0xffd20134 0x66666666 # L2 RAM Timing 0 Register ++DATA 0xffd20138 0x66666666 # L2 RAM Timing 1 Register + + # End of Header extension + DATA 0x0 0x0 diff --git a/package/boot/uboot-kirkwood/patches/0002-kirkwood-define-empty-CONFIG_MVGBE_PORTS-by-default.patch b/package/boot/uboot-kirkwood/patches/0002-kirkwood-define-empty-CONFIG_MVGBE_PORTS-by-default.patch new file mode 100644 index 0000000..5b3c328 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/0002-kirkwood-define-empty-CONFIG_MVGBE_PORTS-by-default.patch @@ -0,0 +1,32 @@ +From 292d4cf9257921912e8ea352687c977208e7553d Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Mon, 11 Nov 2013 07:27:53 +0100 +Subject: [PATCH 2/9] kirkwood: define empty CONFIG_MVGBE_PORTS by default + +Each board with defines it's own set of values. If we do not define +CONFIG_MVGBE_PORTS we will hit following error: + +mvgbe.c: In function 'mvgbe_initialize': +mvgbe.c:700:34: error: 'CONFIG_MVGBE_PORTS' undeclared (first use in this function) + u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS; + +This patch fixes above described problem. + +Signed-off-by: Luka Perkov +--- + drivers/net/mvgbe.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/mvgbe.c ++++ b/drivers/net/mvgbe.c +@@ -35,6 +35,10 @@ + + DECLARE_GLOBAL_DATA_PTR; + ++#ifndef CONFIG_MVGBE_PORTS ++# define CONFIG_MVGBE_PORTS {0, 0} ++#endif ++ + #define MV_PHY_ADR_REQUEST 0xee + #define MVGBE_SMI_REG (((struct mvgbe_registers *)MVGBE0_BASE)->smi) + diff --git a/package/boot/uboot-kirkwood/patches/0003-ARM-kirkwood-fix-cpu-info-for-6282-device-id.patch b/package/boot/uboot-kirkwood/patches/0003-ARM-kirkwood-fix-cpu-info-for-6282-device-id.patch new file mode 100644 index 0000000..f92e520 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/0003-ARM-kirkwood-fix-cpu-info-for-6282-device-id.patch @@ -0,0 +1,45 @@ +From fa0ece2cc571ba1ccb9d1e0a8d337417c032576e Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Mon, 23 Dec 2013 01:23:07 +0100 +Subject: [PATCH 3/9] ARM: kirkwood: fix cpu info for 6282 device id + +Signed-off-by: Luka Perkov +CC: Prafulla Wadaskar +--- + arch/arm/cpu/arm926ejs/kirkwood/cpu.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c ++++ b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c +@@ -253,7 +253,7 @@ static void kw_sysrst_check(void) + #if defined(CONFIG_DISPLAY_CPUINFO) + int print_cpuinfo(void) + { +- char *rev; ++ char *rev = "??"; + u16 devid = (readl(KW_REG_PCIE_DEVID) >> 16) & 0xffff; + u8 revid = readl(KW_REG_PCIE_REVID) & 0xff; + +@@ -264,7 +264,13 @@ int print_cpuinfo(void) + + switch (revid) { + case 0: +- rev = "Z0"; ++ if (devid == 0x6281) ++ rev = "Z0"; ++ else if (devid == 0x6282) ++ rev = "A0"; ++ break; ++ case 1: ++ rev = "A1"; + break; + case 2: + rev = "A0"; +@@ -273,7 +279,6 @@ int print_cpuinfo(void) + rev = "A1"; + break; + default: +- rev = "??"; + break; + } + diff --git a/package/boot/uboot-kirkwood/patches/0004-kirkwood-ib62x0-add-CONFIG_SYS_GENERIC_BOARD-define.patch b/package/boot/uboot-kirkwood/patches/0004-kirkwood-ib62x0-add-CONFIG_SYS_GENERIC_BOARD-define.patch new file mode 100644 index 0000000..65ae63f --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/0004-kirkwood-ib62x0-add-CONFIG_SYS_GENERIC_BOARD-define.patch @@ -0,0 +1,27 @@ +From 280b03ba28b4287de677d4c4b097918364395b5e Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Wed, 2 Jul 2014 01:47:23 +0200 +Subject: [PATCH 4/9] kirkwood: ib62x0: add CONFIG_SYS_GENERIC_BOARD define + +Signed-off-by: Luka Perkov +CC: Prafulla Wadaskar +CC: Stefan Roese +--- +This is patch was sent already in July: + +http://lists.denx.de/pipermail/u-boot/2014-July/182900.html +--- + include/configs/ib62x0.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/configs/ib62x0.h ++++ b/include/configs/ib62x0.h +@@ -9,6 +9,8 @@ + #ifndef _CONFIG_IB62x0_H + #define _CONFIG_IB62x0_H + ++#define CONFIG_SYS_GENERIC_BOARD ++ + /* + * Version number information + */ diff --git a/package/boot/uboot-kirkwood/patches/0005-kirkwood-dockstar-add-CONFIG_SYS_GENERIC_BOARD-defin.patch b/package/boot/uboot-kirkwood/patches/0005-kirkwood-dockstar-add-CONFIG_SYS_GENERIC_BOARD-defin.patch new file mode 100644 index 0000000..6ec6052 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/0005-kirkwood-dockstar-add-CONFIG_SYS_GENERIC_BOARD-defin.patch @@ -0,0 +1,23 @@ +From 5f9e6f640098e6963ff9b470cd5d2ab9f6a3579e Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sun, 30 Nov 2014 02:40:37 +0100 +Subject: [PATCH 5/9] kirkwood: dockstar: add CONFIG_SYS_GENERIC_BOARD define + +Signed-off-by: Luka Perkov +CC: Prafulla Wadaskar +CC: Stefan Roese +--- + include/configs/dockstar.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/configs/dockstar.h ++++ b/include/configs/dockstar.h +@@ -12,6 +12,8 @@ + #ifndef _CONFIG_DOCKSTAR_H + #define _CONFIG_DOCKSTAR_H + ++#define CONFIG_SYS_GENERIC_BOARD ++ + /* + * Version number information + */ diff --git a/package/boot/uboot-kirkwood/patches/0006-kirkwood-goflexhome-add-CONFIG_SYS_GENERIC_BOARD-def.patch b/package/boot/uboot-kirkwood/patches/0006-kirkwood-goflexhome-add-CONFIG_SYS_GENERIC_BOARD-def.patch new file mode 100644 index 0000000..ac0bc0d --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/0006-kirkwood-goflexhome-add-CONFIG_SYS_GENERIC_BOARD-def.patch @@ -0,0 +1,23 @@ +From 0d0a6606396f0cc1a4f2966d167ef9e85d533650 Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sun, 30 Nov 2014 02:40:51 +0100 +Subject: [PATCH 6/9] kirkwood: goflexhome: add CONFIG_SYS_GENERIC_BOARD define + +Signed-off-by: Luka Perkov +CC: Prafulla Wadaskar +CC: Stefan Roese +--- + include/configs/goflexhome.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/configs/goflexhome.h ++++ b/include/configs/goflexhome.h +@@ -15,6 +15,8 @@ + #ifndef _CONFIG_GOFLEXHOME_H + #define _CONFIG_GOFLEXHOME_H + ++#define CONFIG_SYS_GENERIC_BOARD ++ + /* + * Version number information + */ diff --git a/package/boot/uboot-kirkwood/patches/0007-kirkwood-iconnect-add-CONFIG_SYS_GENERIC_BOARD-defin.patch b/package/boot/uboot-kirkwood/patches/0007-kirkwood-iconnect-add-CONFIG_SYS_GENERIC_BOARD-defin.patch new file mode 100644 index 0000000..ab23481 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/0007-kirkwood-iconnect-add-CONFIG_SYS_GENERIC_BOARD-defin.patch @@ -0,0 +1,23 @@ +From 45ba20427135e526cfa528773de0cfe215f4dc40 Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sun, 30 Nov 2014 02:41:04 +0100 +Subject: [PATCH 7/9] kirkwood: iconnect: add CONFIG_SYS_GENERIC_BOARD define + +Signed-off-by: Luka Perkov +CC: Prafulla Wadaskar +CC: Stefan Roese +--- + include/configs/iconnect.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/configs/iconnect.h ++++ b/include/configs/iconnect.h +@@ -9,6 +9,8 @@ + #ifndef _CONFIG_ICONNECT_H + #define _CONFIG_ICONNECT_H + ++#define CONFIG_SYS_GENERIC_BOARD ++ + /* + * Version number information + */ diff --git a/package/boot/uboot-kirkwood/patches/0008-kirkwood-pogo_e02-add-CONFIG_SYS_GENERIC_BOARD-defin.patch b/package/boot/uboot-kirkwood/patches/0008-kirkwood-pogo_e02-add-CONFIG_SYS_GENERIC_BOARD-defin.patch new file mode 100644 index 0000000..40918d4 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/0008-kirkwood-pogo_e02-add-CONFIG_SYS_GENERIC_BOARD-defin.patch @@ -0,0 +1,23 @@ +From bd862f4e7a559e38763a5280e35bf7ff14b535f1 Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sun, 30 Nov 2014 02:41:19 +0100 +Subject: [PATCH 8/9] kirkwood: pogo_e02: add CONFIG_SYS_GENERIC_BOARD define + +Signed-off-by: Luka Perkov +CC: Prafulla Wadaskar +CC: Stefan Roese +--- + include/configs/pogo_e02.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/configs/pogo_e02.h ++++ b/include/configs/pogo_e02.h +@@ -13,6 +13,8 @@ + #ifndef _CONFIG_POGO_E02_H + #define _CONFIG_POGO_E02_H + ++#define CONFIG_SYS_GENERIC_BOARD ++ + /* + * Machine type definition and ID + */ diff --git a/package/boot/uboot-kirkwood/patches/0009-kirkwood-sheevaplug-add-CONFIG_SYS_GENERIC_BOARD-def.patch b/package/boot/uboot-kirkwood/patches/0009-kirkwood-sheevaplug-add-CONFIG_SYS_GENERIC_BOARD-def.patch new file mode 100644 index 0000000..d976bbc --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/0009-kirkwood-sheevaplug-add-CONFIG_SYS_GENERIC_BOARD-def.patch @@ -0,0 +1,23 @@ +From 787e23179708ddad7ecd9dcd6c841546689864b0 Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sun, 30 Nov 2014 02:41:49 +0100 +Subject: [PATCH 9/9] kirkwood: sheevaplug: add CONFIG_SYS_GENERIC_BOARD define + +Signed-off-by: Luka Perkov +CC: Prafulla Wadaskar +CC: Stefan Roese +--- + include/configs/sheevaplug.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/configs/sheevaplug.h ++++ b/include/configs/sheevaplug.h +@@ -10,6 +10,8 @@ + #ifndef _CONFIG_SHEEVAPLUG_H + #define _CONFIG_SHEEVAPLUG_H + ++#define CONFIG_SYS_GENERIC_BOARD ++ + /* + * Version number information + */ 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..4c9ccdf --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/110-dockstar.patch @@ -0,0 +1,129 @@ +--- a/include/configs/dockstar.h ++++ b/include/configs/dockstar.h +@@ -17,20 +17,25 @@ + /* + * Version number information + */ +-#define CONFIG_IDENT_STRING "\nSeagate FreeAgent DockStar" ++#define CONFIG_IDENT_STRING "Seagate FreeAgent DockStar" + + /* +- * High Level Configuration Options (easy to change) ++ * High Level Configuration Options + */ +-#define CONFIG_FEROCEON_88FR131 1 /* CPU Core subversion */ +-#define CONFIG_KW88F6281 1 /* SOC Name */ +-#define CONFIG_MACH_DOCKSTAR /* Machine type */ ++#define CONFIG_FEROCEON_88FR131 /* CPU Core subversion */ ++#define CONFIG_KW88F6281 /* SOC Name */ + #define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ + + /* ++ * Machine type ++ */ ++#define CONFIG_MACH_DOCKSTAR ++ ++/* + * Commands configuration + */ +-#define CONFIG_SYS_NO_FLASH /* Declare no flash (NOR/SPI) */ ++#define CONFIG_SYS_NO_FLASH /* declare no flash (NOR/SPI) */ ++#define CONFIG_SYS_MVFS + #include + #define CONFIG_CMD_DHCP + #define CONFIG_CMD_ENV +@@ -38,55 +43,58 @@ + #define CONFIG_CMD_NAND + #define CONFIG_CMD_PING + #define CONFIG_CMD_USB ++ + /* + * mv-common.h should be defined after CMD configs since it used them + * to enable certain macros + */ + #include "mv-common.h" + +-#undef CONFIG_SYS_PROMPT /* previously defined in mv-common.h */ +-#define CONFIG_SYS_PROMPT "DockStar> " /* Command Prompt */ ++#undef CONFIG_SYS_PROMPT ++#define CONFIG_SYS_PROMPT "dockstar => " + + /* +- * Environment variables configurations ++ * Environment variables configuration + */ + #ifdef CONFIG_CMD_NAND +-#define CONFIG_ENV_IS_IN_NAND 1 +-#define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K */ ++#define CONFIG_ENV_IS_IN_NAND ++#define CONFIG_ENV_SECT_SIZE 0x20000 + #else +-#define CONFIG_ENV_IS_NOWHERE 1 /* if env in SDRAM */ ++#define CONFIG_ENV_IS_NOWHERE + #endif +-/* +- * max 4k env size is enough, but in case of nand +- * it has to be rounded to sector size +- */ +-#define CONFIG_ENV_SIZE 0x20000 /* 128k */ +-#define CONFIG_ENV_ADDR 0x60000 +-#define CONFIG_ENV_OFFSET 0x60000 /* env starts here */ ++#define CONFIG_ENV_SIZE 0x20000 ++#define CONFIG_ENV_OFFSET 0xe0000 + + /* + * Default environment variables + */ + #define CONFIG_BOOTCOMMAND \ + "setenv bootargs ${console} ${mtdparts} ${bootargs_root}; " \ +- "ubi part root; " \ +- "ubifsmount ubi:root; " \ +- "ubifsload 0x800000 ${kernel}; " \ +- "ubifsload 0x1100000 ${initrd}; " \ +- "bootm 0x800000 0x1100000" +- +-#define CONFIG_MTDPARTS "mtdparts=orion_nand:1m(uboot),-(root)\0" ++ "ubi part root; " \ ++ "ubifsmount ubi:rootfs; " \ ++ "ubifsload 0x800000 ${kernel}; " \ ++ "ubifsload 0x700000 ${fdt}; " \ ++ "ubifsumount; " \ ++ "fdt addr 0x700000; fdt resize; fdt chosen; " \ ++ "bootz 0x800000 - 0x700000" ++ ++#define CONFIG_MTDPARTS \ ++ "mtdparts=orion_nand:" \ ++ "0xe0000@0x0(uboot)," \ ++ "0x20000@0xe0000(uboot_env)," \ ++ "0x100000@0x100000(second_stage_uboot)," \ ++ "-@0x200000(root)\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" ++ "console=console=ttyS0,115200\0" \ ++ "mtdids=nand0=orion_nand\0" \ ++ "mtdparts="CONFIG_MTDPARTS \ ++ "kernel=/boot/zImage\0" \ ++ "fdt=/boot/dockstar.dtb\0" \ ++ "bootargs_root=ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs rw\0" + + /* +- * Ethernet Driver configuration ++ * Ethernet driver configuration + */ + #ifdef CONFIG_CMD_NET + #define CONFIG_MVGBE_PORTS {1, 0} /* enable port 0 only */ +@@ -102,7 +110,7 @@ + #define CONFIG_CMD_UBI + #define CONFIG_CMD_UBIFS + #define CONFIG_RBTREE +-#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ ++#define CONFIG_MTD_DEVICE + #define CONFIG_MTD_PARTITIONS + #define CONFIG_CMD_MTDPARTS + #define CONFIG_LZO diff --git a/package/boot/uboot-kirkwood/patches/120-iconnect.patch b/package/boot/uboot-kirkwood/patches/120-iconnect.patch new file mode 100644 index 0000000..e525ca0 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/120-iconnect.patch @@ -0,0 +1,47 @@ +--- a/include/configs/iconnect.h ++++ b/include/configs/iconnect.h +@@ -66,30 +66,35 @@ + #define CONFIG_ENV_IS_NOWHERE + #endif + #define CONFIG_ENV_SIZE 0x20000 +-#define CONFIG_ENV_OFFSET 0x80000 ++#define CONFIG_ENV_OFFSET 0xe0000 + + /* + * Default environment variables + */ + #define CONFIG_BOOTCOMMAND \ + "setenv bootargs ${console} ${mtdparts} ${bootargs_root}; " \ +- "ubi part rootfs; " \ ++ "ubi part root; " \ + "ubifsmount ubi:rootfs; " \ + "ubifsload 0x800000 ${kernel}; " \ +- "bootm 0x800000" ++ "ubifsload 0x700000 ${fdt}; " \ ++ "ubifsumount; " \ ++ "fdt addr 0x700000; fdt resize; fdt chosen; " \ ++ "bootz 0x800000 - 0x700000" + + #define CONFIG_MTDPARTS \ +- "mtdparts=orion_nand:" \ +- "0x80000@0x0(uboot)," \ +- "0x20000@0x80000(uboot_env)," \ +- "-@0xa0000(rootfs)\0" ++ "mtdparts=orion_nand:" \ ++ "0xe0000@0x0(uboot)," \ ++ "0x20000@0xe0000(uboot_env)," \ ++ "0x100000@0x100000(second_stage_uboot)," \ ++ "-@0x200000(root)\0" + + #define CONFIG_EXTRA_ENV_SETTINGS \ + "console=console=ttyS0,115200\0" \ + "mtdids=nand0=orion_nand\0" \ + "mtdparts="CONFIG_MTDPARTS \ +- "kernel=/boot/uImage\0" \ +- "bootargs_root=noinitrd ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs\0" ++ "kernel=/boot/zImage\0" \ ++ "fdt=/boot/iconnect.dtb\0" \ ++ "bootargs_root=ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs rw\0" + + /* + * Ethernet driver configuration diff --git a/package/boot/uboot-kirkwood/patches/130-ib62x0.patch b/package/boot/uboot-kirkwood/patches/130-ib62x0.patch new file mode 100644 index 0000000..f46970c --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/130-ib62x0.patch @@ -0,0 +1,21 @@ +--- a/include/configs/ib62x0.h ++++ b/include/configs/ib62x0.h +@@ -92,7 +92,8 @@ + "mtdparts=orion_nand:" \ + "0xe0000@0x0(uboot)," \ + "0x20000@0xe0000(uboot_env)," \ +- "-@0x100000(root)\0" ++ "0x100000@0x100000(second_stage_uboot)," \ ++ "-@0x200000(root)\0" + + #define CONFIG_EXTRA_ENV_SETTINGS \ + "console=console=ttyS0,115200\0" \ +@@ -100,7 +101,7 @@ + "mtdparts="CONFIG_MTDPARTS \ + "kernel=/boot/zImage\0" \ + "fdt=/boot/ib62x0.dtb\0" \ +- "bootargs_root=ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs rw\0" ++ "bootargs_root=ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs rw\0" + + /* + * Ethernet driver configuration diff --git a/package/boot/uboot-kirkwood/patches/140-pogoplug_e02.patch b/package/boot/uboot-kirkwood/patches/140-pogoplug_e02.patch new file mode 100644 index 0000000..40e659f --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/140-pogoplug_e02.patch @@ -0,0 +1,48 @@ +--- a/include/configs/pogo_e02.h ++++ b/include/configs/pogo_e02.h +@@ -63,23 +63,35 @@ + #endif + + #define CONFIG_ENV_SIZE 0x20000 /* 128k */ +-#define CONFIG_ENV_OFFSET 0x60000 /* env starts here */ ++#define CONFIG_ENV_OFFSET 0xe0000 /* env starts here */ + + /* + * Default environment variables + */ + #define CONFIG_BOOTCOMMAND \ +- "setenv bootargs $(bootargs_console); " \ +- "run bootcmd_usb; " \ +- "bootm 0x00800000 0x01100000" ++ "setenv bootargs ${console} ${mtdparts} ${bootargs_root}; " \ ++ "ubi part root; " \ ++ "ubifsmount ubi:rootfs; " \ ++ "ubifsload 0x800000 ${kernel}; " \ ++ "ubifsload 0x700000 ${fdt}; " \ ++ "ubifsumount; " \ ++ "fdt addr 0x700000; fdt resize; fdt chosen; " \ ++ "bootz 0x800000 - 0x700000" ++ ++#define CONFIG_MTDPARTS \ ++ "mtdparts=orion_nand:" \ ++ "0xe0000@0x0(uboot)," \ ++ "0x20000@0xe0000(uboot_env)," \ ++ "0x100000@0x100000(second_stage_uboot)," \ ++ "-@0x200000(root)\0" + + #define CONFIG_EXTRA_ENV_SETTINGS \ +- "mtdparts=mtdparts=orion_nand:1M(u-boot),4M(uImage)," \ +- "32M(rootfs),-(data)\0"\ +- "mtdids=nand0=orion_nand\0"\ +- "bootargs_console=console=ttyS0,115200\0" \ +- "bootcmd_usb=usb start; ext2load usb 0:1 0x00800000 /uImage; " \ +- "ext2load usb 0:1 0x01100000 /uInitrd\0" ++ "console=console=ttyS0,115200\0" \ ++ "mtdids=nand0=orion_nand\0" \ ++ "mtdparts="CONFIG_MTDPARTS \ ++ "kernel=/boot/zImage\0" \ ++ "fdt=/boot/pogo_e02.dtb\0" \ ++ "bootargs_root=ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs rw\0" + + /* + * Ethernet Driver configuration diff --git a/package/boot/uboot-kirkwood/patches/200-openwrt-config.patch b/package/boot/uboot-kirkwood/patches/200-openwrt-config.patch new file mode 100644 index 0000000..0e0dd02 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/200-openwrt-config.patch @@ -0,0 +1,110 @@ +--- a/arch/arm/cpu/arm926ejs/kirkwood/Kconfig ++++ b/arch/arm/cpu/arm926ejs/kirkwood/Kconfig +@@ -84,4 +84,7 @@ + source "board/Seagate/dockstar/Kconfig" + source "board/Seagate/goflexhome/Kconfig" + ++config SECOND_STAGE ++ bool "OpenWrt second stage hack" ++ + endif +--- a/include/configs/dockstar.h ++++ b/include/configs/dockstar.h +@@ -115,4 +115,6 @@ + #define CONFIG_CMD_MTDPARTS + #define CONFIG_LZO + ++#include "openwrt-kirkwood-common.h" ++ + #endif /* _CONFIG_DOCKSTAR_H */ +--- a/include/configs/ib62x0.h ++++ b/include/configs/ib62x0.h +@@ -145,4 +145,6 @@ + #define CONFIG_MTD_PARTITIONS + #define CONFIG_CMD_MTDPARTS + ++#include "openwrt-kirkwood-common.h" ++ + #endif /* _CONFIG_IB62x0_H */ +--- a/include/configs/iconnect.h ++++ b/include/configs/iconnect.h +@@ -118,4 +118,6 @@ + #define CONFIG_MTD_PARTITIONS + #define CONFIG_CMD_MTDPARTS + ++#include "openwrt-kirkwood-common.h" ++ + #endif /* _CONFIG_ICONNECT_H */ +--- /dev/null ++++ b/include/configs/openwrt-kirkwood-common.h +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __OPENWRT_KIRKWOOD_COMMON_H ++#define __OPENWRT_KIRKWOOD_COMMON_H ++ ++/* Commands */ ++#define CONFIG_CMD_BOOTZ ++ ++#if defined(CONFIG_CMD_NET) ++#define CONFIG_CMD_DHCP ++#define CONFIG_CMD_PING ++#endif ++ ++/* Auto boot */ ++#undef CONFIG_BOOTDELAY ++#define CONFIG_BOOTDELAY 3 ++ ++/* Ethernet */ ++#if defined(CONFIG_CMD_NET) ++#define CONFIG_SERVERIP 192.168.1.2 ++#define CONFIG_IPADDR 192.168.1.1 ++#endif ++ ++/* second stage loader */ ++#if defined(CONFIG_SECOND_STAGE) ++#undef CONFIG_ENV_IS_IN_NAND ++#undef CONFIG_ENV_SECT_SIZE ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++/* Flattened Device Tree */ ++#define CONFIG_OF_LIBFDT ++ ++/* Flattened uImage Tree */ ++#define CONFIG_FIT ++#define CONFIG_FIT_VERBOSE ++ ++/* Various */ ++#define CONFIG_BZIP2 ++#define CONFIG_LZMA ++#define CONFIG_LZO ++ ++/* Unnecessary */ ++#undef CONFIG_BOOTM_NETBSD ++#undef CONFIG_BOOTM_PLAN9 ++#undef CONFIG_BOOTM_RTEMS ++ ++#endif /* __OPENWRT_KIRKWOOD_COMMON_H */ +--- a/include/configs/pogo_e02.h ++++ b/include/configs/pogo_e02.h +@@ -115,4 +115,6 @@ + #define CONFIG_CMD_MTDPARTS + #define CONFIG_LZO + ++#include "openwrt-kirkwood-common.h" ++ + #endif /* _CONFIG_POGO_E02_H */ +--- a/include/configs/sheevaplug.h ++++ b/include/configs/sheevaplug.h +@@ -143,4 +143,6 @@ + #define CONFIG_CMD_MTDPARTS + #define CONFIG_LZO + ++#include "openwrt-kirkwood-common.h" ++ + #endif /* _CONFIG_SHEEVAPLUG_H */ diff --git a/package/boot/uboot-lantiq/Makefile b/package/boot/uboot-lantiq/Makefile new file mode 100644 index 0000000..99b101f --- /dev/null +++ b/package/boot/uboot-lantiq/Makefile @@ -0,0 +1,383 @@ +# +# 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.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:= \ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=a076a044b64371edc52f7e562b13f6b2 +PKG_TARGETS:=bin + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +PKG_BUILD_PARALLEL:=1 + +FIRMWARE_LANTIQ_SOURCE:=$(TOPDIR)/target/linux/lantiq/files/firmware/lantiq + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + SOC:= + DDR_SETTINGS:= + IMAGE:= + DEPS:= +endef + +define uboot/arv4519pw_ram + TITLE:=U-Boot for Arcadyan arv4519pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv4519pw/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV4519PW +endef + +define uboot/arv4519pw_nor + TITLE:=U-Boot for Arcadyan arv4519pw (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV4519PW +endef + +define uboot/arv4519pw_brn + TITLE:=U-Boot for Arcadyan arv4519pw (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV4519PW +endef + +define uboot/arv7510pw_ram + TITLE:=U-Boot for Arcadyan arv7510pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv7510pw/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV4510PW +endef + +define uboot/arv7510pw_nor + TITLE:=U-Boot for Arcadyan arv7510pw (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV4510PW +endef + +define uboot/arv7510pw_brn + TITLE:=U-Boot for Arcadyan arv7510pw (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV4510PW +endef + +define uboot/arv7510pw22_ram + TITLE:=U-Boot for Arcadyan arv7510pw22 (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv7510pw22/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV7510PW22 +endef + +define uboot/arv7510pw22_nor + TITLE:=U-Boot for Arcadyan arv7510pw22 (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV7510PW22 +endef + +define uboot/arv7510pw22_brn + TITLE:=U-Boot for Arcadyan arv7510pw22 (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV7510PW22 +endef + +define uboot/arv7518pw_ram + TITLE:=U-Boot for Arcadyan arv7518pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv7518pw/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV7518PW +endef + +define uboot/arv7518pw_nor + TITLE:=U-Boot for Arcadyan arv7518pw (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV7518PW +endef + +define uboot/arv7518pw_brn + TITLE:=U-Boot for Arcadyan arv7518pw (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV7518PW +endef + +define uboot/arv752dpw_ram + TITLE:=U-Boot for Arcadyan arv752dpw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv752dpw/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV752DPW +endef + +define uboot/arv752dpw_nor + TITLE:=U-Boot for Arcadyan arv752dpw (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV752DPW +endef + +define uboot/arv752dpw_brn + TITLE:=U-Boot for Arcadyan arv752dpw (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV752DPW +endef + +define uboot/arv752dpw22_ram + TITLE:=U-Boot for Arcadyan arv752dpw22 (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv752dpw22/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV752DPW22 +endef + +define uboot/arv752dpw22_nor + TITLE:=U-Boot for Arcadyan arv752dpw22 (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV752DPW22 +endef + +define uboot/arv752dpw22_brn + TITLE:=U-Boot for Arcadyan arv752dpw22 (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV752DPW22 +endef + +define uboot/arv8539pw22_ram + TITLE:=U-Boot for Speedport W 504V Typ A (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv8539pw22/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV8539PW22 +endef + +define uboot/arv8539pw22_nor + TITLE:=U-Boot for Speedport W 504V Typ A (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV8539PW22 +endef + +define uboot/arv8539pw22_brn + TITLE:=U-Boot for Speedport W 504V Typ A (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV8539PW22 +endef + +define uboot/gigasx76x_ram + TITLE:=U-Boot for Siemens Gigaset sx76x (RAM) + SOC:=danube + DDR_SETTINGS:=board/gigaset/sx76x/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_GIGASX76X +endef + +define uboot/gigasx76x_nor + TITLE:=U-Boot for Siemens Gigaset sx76x (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_GIGASX76X +endef + +define uboot/acmp252_ram + TITLE:=U-Boot for AudioCodes MP-252 (RAM) + SOC:=danube + DDR_SETTINGS:=board/audiocodes/acmp252/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ACMP252 +endef + +define uboot/acmp252_nor + TITLE:=U-Boot for AudioCodes MP-252 (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ACMP252 +endef + +define uboot/easy50712_ram + TITLE:=U-Boot for Lantiq EASY50712 (RAM) + SOC:=danube + DDR_SETTINGS:=board/lantiq/easy50712/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_EASY50712 +endef + +define uboot/easy50712_nor + TITLE:=U-Boot for Lantiq EASY50712 (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_EASY50712 +endef + +define uboot/easy50712_norspl + TITLE:=U-Boot for Lantiq EASY50712 (NOR SPL) + SOC:=danube + IMAGE:=u-boot.ltq.lzo.norspl + DEPS:=@TARGET_lantiq_xway_EASY50712 +endef + +define uboot/easy80920_ram + TITLE:=U-Boot for Lantiq EASY80920 (RAM) + SOC:=vr9 + DDR_SETTINGS:=board/lantiq/easy80920/ddr_settings.h + DEPS:=@(TARGET_lantiq_xrx200_EASY80920NOR||TARGET_lantiq_xrx200_EASY80920NAND) +endef + +define uboot/easy80920_nor + TITLE:=U-Boot for Lantiq EASY80920 (NOR) + SOC:=vr9 + DEPS:=@(TARGET_lantiq_xrx200_EASY80920NOR||TARGET_lantiq_xrx200_EASY80920NAND) +endef + +define uboot/easy80920_norspl + TITLE:=U-Boot for Lantiq EASY80920 (NOR SPL) + SOC:=vr9 + IMAGE:=u-boot.ltq.lzo.norspl + DEPS:=@(TARGET_lantiq_xrx200_EASY80920NOR||TARGET_lantiq_xrx200_EASY80920NAND) +endef + +define uboot/easy80920_sfspl + TITLE:=U-Boot for Lantiq EASY80920 (SPI SPL) + SOC:=vr9 + IMAGE:=u-boot.ltq.lzo.sfspl + DEPS:=@(TARGET_lantiq_xrx200_EASY80920NOR||TARGET_lantiq_xrx200_EASY80920NAND) +endef + +define uboot/fb3370_eva + TITLE:=U-Boot for AVM FRITZ3370 (EVA) + SOC:=vr9 + DEPS:=@TARGET_lantiq_xrx200_FRITZ3370 +endef + +define uboot/fb3370_ram + TITLE:=U-Boot for AVM FRITZ3370 (RAM) + SOC:=vr9 + DDR_SETTINGS:=board/avm/fb3370/ddr_settings.h + DEPS:=@TARGET_lantiq_xrx200_FRITZ3370 +endef + +define uboot/fb3370_sfspl + TITLE:=U-Boot for AVM FRITZ3370 (SPI SPL) + SOC:=vr9 + IMAGE:=u-boot.ltq.lzo.sfspl + DEPS:=@TARGET_lantiq_xrx200_FRITZ3370 +endef + +define uboot/p2812hnufx_ram + TITLE:=U-Boot for ZyXEL P-2812HNU-Fx (RAM) + SOC:=vr9 + DDR_SETTINGS:=board/zyxel/p2812hnufx/ddr_settings.h + DEPS:=@TARGET_lantiq_xrx200_P2812HNUF1||@TARGET_lantiq_xrx200_P2812HNUF3 +endef + +define uboot/p2812hnufx_nandspl + TITLE:=U-Boot for ZyXEL P-2812HNU-Fx (NAND SPL) + SOC:=vr9 + IMAGE:=u-boot.ltq.lzo.nandspl + DEPS:=@TARGET_lantiq_xrx200_P2812HNUF1||@TARGET_lantiq_xrx200_P2812HNUF3 +endef + +define uboot/vgv7510kw22_brn + TITLE:=U-Boot for Arcadyan VGV7510KW22 (BRN) + SOC:=vr9 + DEPS:=@TARGET_lantiq_xrx200_VGV7510KW22NOR||@TARGET_lantiq_xrx200_VGV7510KW22BRN +endef + +define uboot/vgv7510kw22_nor + TITLE:=U-Boot for Arcadyan VGV7510KW22 (NOR) + SOC:=vr9 + DEPS:=@TARGET_lantiq_xrx200_VGV7510KW22NOR||@TARGET_lantiq_xrx200_VGV7510KW22BRN +endef + +define uboot/vgv7510kw22_ram + TITLE:=U-Boot for Arcadyan VGV7510KW22 (RAM) + SOC:=vr9 + DDR_SETTINGS:=board/arcadyan/vgv7510kw22/ddr_settings.h + DEPS:=@TARGET_lantiq_xrx200_VGV7510KW22NOR||@TARGET_lantiq_xrx200_VGV7510KW22BRN +endef + +UBOOTS:= \ + arv4519pw_ram arv4519pw_nor arv4519pw_brn \ + arv7510pw_ram arv7510pw_nor arv7510pw_brn \ + arv7510pw22_ram arv7510pw22_nor arv7510pw22_brn \ + arv7518pw_ram arv7518pw_nor arv7518pw_brn \ + arv752dpw_ram arv752dpw_nor arv752dpw_brn \ + arv752dpw22_ram arv752dpw22_nor arv752dpw22_brn \ + arv8539pw22_brn arv8539pw22_nor arv8539pw22_ram \ + gigasx76x_ram gigasx76x_nor \ + acmp252_ram acmp252_nor \ + easy50712_ram easy50712_nor easy50712_norspl \ + easy80920_ram easy80920_nor easy80920_norspl easy80920_sfspl \ + fb3370_eva fb3370_ram fb3370_sfspl \ + p2812hnufx_ram p2812hnufx_nandspl \ + vgv7510kw22_brn vgv7510kw22_nor vgv7510kw22_ram + +define Package/uboot/template +define Package/uboot-lantiq-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=$(3) + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Luka Perkov +endef +endef + +define BuildUBootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + DEPS:=$(uboot/$(1)/DEPS) + $(call Package/uboot/template,$(1),$(TITLE),$(DEPS)) +endef + +define CopyVR9Firmware + $(CP) $(FIRMWARE_LANTIQ_SOURCE)/vr9_phy$(1)_a$(2)x.bin \ + $(PKG_BUILD_DIR)/arch/mips/cpu/mips32/vrx200/fw_phy$(1)_a$(2)x.blob +endef + +define Build/Prepare + $(call Build/Prepare/Default) + mkdir -p $(PKG_BUILD_DIR)/arch/mips/cpu/mips32/vrx200/ + $(call CopyVR9Firmware,11g,1) + $(call CopyVR9Firmware,11g,2) + $(call CopyVR9Firmware,22f,1) + $(call CopyVR9Firmware,22f,2) +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/README b/package/boot/uboot-lantiq/README new file mode 100644 index 0000000..44ed2bb --- /dev/null +++ b/package/boot/uboot-lantiq/README @@ -0,0 +1,6 @@ +# How to refresh patches + +$ git clone git@github.com:danielschwierzeck/u-boot-lantiq.git +$ mkdir -p $OPENWRT_ROOT/packages/boot/uboot-lantiq/patches +$ cd u-boot-lantiq.git +$ git format-patch -p -k --no-renames --no-binary -o $OPENWRT_ROOT/package/boot/uboot-lantiq/patches v2013.10..u-boot-lantiq-v2013.10-openwrtN diff --git a/package/boot/uboot-lantiq/patches/0001-sf-fix-out-of-order-calls-for-spi_claim_bus-and-spi_.patch b/package/boot/uboot-lantiq/patches/0001-sf-fix-out-of-order-calls-for-spi_claim_bus-and-spi_.patch new file mode 100644 index 0000000..7ecf544 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0001-sf-fix-out-of-order-calls-for-spi_claim_bus-and-spi_.patch @@ -0,0 +1,170 @@ +From 909840ef844013379e5ec399c1e76c65d1a6eb1d Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sat, 12 Oct 2013 21:09:47 +0200 +Subject: sf: fix out-of-order calls for spi_claim_bus and spi_release_bus + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/mtd/spi/sf_ops.c ++++ b/drivers/mtd/spi/sf_ops.c +@@ -132,12 +132,6 @@ int spi_flash_write_common(struct spi_fl + if (buf == NULL) + timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT; + +- ret = spi_claim_bus(flash->spi); +- if (ret) { +- debug("SF: unable to claim SPI bus\n"); +- return ret; +- } +- + ret = spi_flash_cmd_write_enable(flash); + if (ret < 0) { + debug("SF: enabling write failed\n"); +@@ -158,8 +152,6 @@ int spi_flash_write_common(struct spi_fl + return ret; + } + +- spi_release_bus(spi); +- + return ret; + } + +@@ -175,12 +167,18 @@ int spi_flash_cmd_erase_ops(struct spi_f + return -1; + } + ++ ret = spi_claim_bus(flash->spi); ++ if (ret) { ++ debug("SF: unable to claim SPI bus\n"); ++ return ret; ++ } ++ + cmd[0] = flash->erase_cmd; + while (len) { + #ifdef CONFIG_SPI_FLASH_BAR + ret = spi_flash_bank(flash, offset); + if (ret < 0) +- return ret; ++ goto done; + #endif + spi_flash_addr(offset, cmd); + +@@ -190,13 +188,16 @@ int spi_flash_cmd_erase_ops(struct spi_f + ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); + if (ret < 0) { + debug("SF: erase failed\n"); +- break; ++ goto done; + } + + offset += erase_size; + len -= erase_size; + } + ++done: ++ spi_release_bus(flash->spi); ++ + return ret; + } + +@@ -208,6 +209,12 @@ int spi_flash_cmd_write_ops(struct spi_f + u8 cmd[4]; + int ret = -1; + ++ ret = spi_claim_bus(flash->spi); ++ if (ret) { ++ debug("SF: unable to claim SPI bus\n"); ++ return ret; ++ } ++ + page_size = flash->page_size; + + cmd[0] = CMD_PAGE_PROGRAM; +@@ -215,7 +222,7 @@ int spi_flash_cmd_write_ops(struct spi_f + #ifdef CONFIG_SPI_FLASH_BAR + ret = spi_flash_bank(flash, offset); + if (ret < 0) +- return ret; ++ goto done; + #endif + byte_addr = offset % page_size; + chunk_len = min(len - actual, page_size - byte_addr); +@@ -232,12 +239,15 @@ int spi_flash_cmd_write_ops(struct spi_f + buf + actual, chunk_len); + if (ret < 0) { + debug("SF: write failed\n"); +- break; ++ goto done; + } + + offset += chunk_len; + } + ++done: ++ spi_release_bus(flash->spi); ++ + return ret; + } + +@@ -247,20 +257,12 @@ int spi_flash_read_common(struct spi_fla + struct spi_slave *spi = flash->spi; + int ret; + +- ret = spi_claim_bus(flash->spi); +- if (ret) { +- debug("SF: unable to claim SPI bus\n"); +- return ret; +- } +- + ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len); + if (ret < 0) { + debug("SF: read cmd failed\n"); + return ret; + } + +- spi_release_bus(spi); +- + return ret; + } + +@@ -271,6 +273,12 @@ int spi_flash_cmd_read_ops(struct spi_fl + u32 remain_len, read_len; + int ret = -1; + ++ ret = spi_claim_bus(flash->spi); ++ if (ret) { ++ debug("SF: unable to claim SPI bus\n"); ++ return ret; ++ } ++ + /* Handle memory-mapped SPI */ + if (flash->memory_map) { + spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP); +@@ -289,7 +297,7 @@ int spi_flash_cmd_read_ops(struct spi_fl + ret = spi_flash_cmd_bankaddr_write(flash, bank_sel); + if (ret) { + debug("SF: fail to set bank%d\n", bank_sel); +- return ret; ++ goto done; + } + #endif + remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1)) - offset; +@@ -304,7 +312,7 @@ int spi_flash_cmd_read_ops(struct spi_fl + data, read_len); + if (ret < 0) { + debug("SF: read failed\n"); +- break; ++ goto done; + } + + offset += read_len; +@@ -312,6 +320,9 @@ int spi_flash_cmd_read_ops(struct spi_fl + data += read_len; + } + ++done: ++ spi_release_bus(flash->spi); ++ + return ret; + } + diff --git a/package/boot/uboot-lantiq/patches/0002-sf-consistently-use-debug-for-warning-error-messages.patch b/package/boot/uboot-lantiq/patches/0002-sf-consistently-use-debug-for-warning-error-messages.patch new file mode 100644 index 0000000..af2612f --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0002-sf-consistently-use-debug-for-warning-error-messages.patch @@ -0,0 +1,49 @@ +From bb7df8c6ff30be3786483767d3afb0e77a69a640 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sat, 12 Oct 2013 21:21:18 +0200 +Subject: sf: consistently use debug() for warning/error messages + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/mtd/spi/sf_probe.c ++++ b/drivers/mtd/spi/sf_probe.c +@@ -176,8 +176,8 @@ static struct spi_flash *spi_flash_valid + } + + if (i == ARRAY_SIZE(spi_flash_params_table)) { +- printf("SF: Unsupported flash IDs: "); +- printf("manuf %02x, jedec %04x, ext_jedec %04x\n", ++ debug("SF: Unsupported flash IDs: "); ++ debug("manuf %02x, jedec %04x, ext_jedec %04x\n", + idcode[0], jedec, ext_jedec); + return NULL; + } +@@ -296,7 +296,7 @@ struct spi_flash *spi_flash_probe(unsign + /* Setup spi_slave */ + spi = spi_setup_slave(bus, cs, max_hz, spi_mode); + if (!spi) { +- printf("SF: Failed to set up slave\n"); ++ debug("SF: Failed to set up slave\n"); + return NULL; + } + +@@ -310,7 +310,7 @@ struct spi_flash *spi_flash_probe(unsign + /* Read the ID codes */ + ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); + if (ret) { +- printf("SF: Failed to get idcodes\n"); ++ debug("SF: Failed to get idcodes\n"); + goto err_read_id; + } + +@@ -341,8 +341,8 @@ struct spi_flash *spi_flash_probe(unsign + #endif + #ifndef CONFIG_SPI_FLASH_BAR + if (flash->size > SPI_FLASH_16MB_BOUN) { +- puts("SF: Warning - Only lower 16MiB accessible,"); +- puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); ++ debug("SF: Warning - Only lower 16MiB accessible,"); ++ debug(" Full access #define CONFIG_SPI_FLASH_BAR\n"); + } + #endif + diff --git a/package/boot/uboot-lantiq/patches/0003-sf-move-malloc-of-spi_flash-to-spi_flash_probe.patch b/package/boot/uboot-lantiq/patches/0003-sf-move-malloc-of-spi_flash-to-spi_flash_probe.patch new file mode 100644 index 0000000..d47d3df --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0003-sf-move-malloc-of-spi_flash-to-spi_flash_probe.patch @@ -0,0 +1,110 @@ +From 36b7400465fe2339f1c78274b3fd258ade3a4c00 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sat, 12 Oct 2013 21:30:07 +0200 +Subject: sf: move malloc of spi_flash to spi_flash_probe() + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/mtd/spi/sf_probe.c ++++ b/drivers/mtd/spi/sf_probe.c +@@ -153,11 +153,10 @@ static const struct spi_flash_params spi + */ + }; + +-static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi, ++static int spi_flash_validate_params(struct spi_flash *flash, + u8 *idcode) + { + const struct spi_flash_params *params; +- struct spi_flash *flash; + int i; + u16 jedec = idcode[1] << 8 | idcode[2]; + u16 ext_jedec = idcode[3] << 8 | idcode[4]; +@@ -179,20 +178,12 @@ static struct spi_flash *spi_flash_valid + debug("SF: Unsupported flash IDs: "); + debug("manuf %02x, jedec %04x, ext_jedec %04x\n", + idcode[0], jedec, ext_jedec); +- return NULL; +- } +- +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate spi_flash\n"); +- return NULL; ++ return -1; + } +- memset(flash, '\0', sizeof(*flash)); + + /* Assign spi data */ +- flash->spi = spi; + flash->name = params->name; +- flash->memory_map = spi->memory_map; ++ flash->memory_map = flash->spi->memory_map; + + /* Assign spi_flash ops */ + flash->write = spi_flash_cmd_write_ops; +@@ -239,7 +230,7 @@ static struct spi_flash *spi_flash_valid + if (spi_flash_read_common(flash, &flash->bank_read_cmd, 1, + &curr_bank, 1)) { + debug("SF: fail to read bank addr register\n"); +- return NULL; ++ return -1; + } + flash->bank_curr = curr_bank; + } else { +@@ -254,7 +245,7 @@ static struct spi_flash *spi_flash_valid + spi_flash_cmd_write_status(flash, 0); + #endif + +- return flash; ++ return 0; + } + + #ifdef CONFIG_OF_CONTROL +@@ -289,15 +280,22 @@ 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; + u8 idcode[5]; + int ret; + ++ flash = malloc(sizeof(*flash)); ++ if (!flash) { ++ debug("SF: Failed to allocate spi_flash\n"); ++ return NULL; ++ } ++ memset(flash, 0, sizeof(*flash)); ++ + /* Setup spi_slave */ + spi = spi_setup_slave(bus, cs, max_hz, spi_mode); + if (!spi) { + debug("SF: Failed to set up slave\n"); +- return NULL; ++ goto err_setup; + } + + /* Claim spi bus */ +@@ -320,8 +318,9 @@ struct spi_flash *spi_flash_probe(unsign + #endif + + /* Validate params from spi_flash_params table */ +- flash = spi_flash_validate_params(spi, idcode); +- if (!flash) ++ flash->spi = spi; ++ ret = spi_flash_validate_params(flash, idcode); ++ if (ret) + goto err_read_id; + + #ifdef CONFIG_OF_CONTROL +@@ -355,6 +354,9 @@ err_read_id: + spi_release_bus(spi); + err_claim_bus: + spi_free_slave(spi); ++err_setup: ++ free(flash); ++ + return NULL; + } + diff --git a/package/boot/uboot-lantiq/patches/0004-sf-add-slim-probe-funtions-for-SPL.patch b/package/boot/uboot-lantiq/patches/0004-sf-add-slim-probe-funtions-for-SPL.patch new file mode 100644 index 0000000..960085c --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0004-sf-add-slim-probe-funtions-for-SPL.patch @@ -0,0 +1,80 @@ +From da11da943487e2f724f25d409bcaa1f099637c0b Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sun, 13 Oct 2013 14:56:45 +0200 +Subject: sf: add slim probe funtions for SPL + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/mtd/spi/sf_probe.c ++++ b/drivers/mtd/spi/sf_probe.c +@@ -365,3 +365,58 @@ void spi_flash_free(struct spi_flash *fl + spi_free_slave(flash->spi); + free(flash); + } ++ ++#ifdef CONFIG_SPI_SPL_SIMPLE ++int spl_spi_flash_probe(struct spi_flash *flash) ++{ ++ struct spi_slave *spi; ++ u8 idcode[5]; ++ int ret; ++ ++ /* Setup spi_slave */ ++ spi = spi_setup_slave(CONFIG_SPL_SPI_BUS, CONFIG_SPL_SPI_CS, ++ CONFIG_SPL_SPI_MAX_HZ, CONFIG_SPL_SPI_MODE); ++ if (!spi) { ++ debug("SF: Failed to set up slave\n"); ++ return -1; ++ } ++ ++ /* Claim spi bus */ ++ ret = spi_claim_bus(spi); ++ if (ret) { ++ debug("SF: Failed to claim SPI bus: %d\n", ret); ++ goto err_claim_bus; ++ } ++ ++ /* Read the ID codes */ ++ ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); ++ if (ret) { ++ debug("SF: Failed to get idcodes\n"); ++ goto err_read_id; ++ } ++ ++ /* Validate params from spi_flash_params table */ ++ flash->spi = spi; ++ ret = spi_flash_validate_params(flash, idcode); ++ if (ret) ++ goto err_read_id; ++ ++ /* Release spi bus */ ++ spi_release_bus(spi); ++ ++ return 0; ++ ++err_read_id: ++ spi_release_bus(spi); ++err_claim_bus: ++ spi_free_slave(spi); ++ flash->spi = NULL; ++ ++ return ret; ++} ++ ++void spl_spi_flash_free(struct spi_flash *flash) ++{ ++ spi_free_slave(flash->spi); ++} ++#endif +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -69,6 +69,9 @@ struct spi_flash *spi_flash_probe(unsign + unsigned int max_hz, unsigned int spi_mode); + void spi_flash_free(struct spi_flash *flash); + ++int spl_spi_flash_probe(struct spi_flash *flash); ++void spl_spi_flash_free(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-make-calculatiom-of-address-bytes-completely-conf.patch b/package/boot/uboot-lantiq/patches/0005-sf-make-calculatiom-of-address-bytes-completely-conf.patch new file mode 100644 index 0000000..8000ff0 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0005-sf-make-calculatiom-of-address-bytes-completely-conf.patch @@ -0,0 +1,134 @@ +From 6fb5f86b094756d94de8abe7425e3d290ff22dd2 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sun, 13 Oct 2013 15:09:28 +0200 +Subject: sf: make calculatiom of address bytes completely configurable + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/mtd/spi/sf_ops.c ++++ b/drivers/mtd/spi/sf_ops.c +@@ -15,12 +15,17 @@ + + #include "sf_internal.h" + +-static void spi_flash_addr(u32 addr, u8 *cmd) ++static void spi_flash_addr(const struct spi_flash *flash, u32 addr, u8 *cmd) + { + /* cmd[0] is actual command */ +- cmd[1] = addr >> 16; +- cmd[2] = addr >> 8; +- cmd[3] = addr >> 0; ++ cmd[1] = addr >> (flash->addr_width * 8 - 8); ++ cmd[2] = addr >> (flash->addr_width * 8 - 16); ++ cmd[3] = addr >> (flash->addr_width * 8 - 24); ++} ++ ++static int spi_flash_cmdsz(const struct spi_flash *flash) ++{ ++ return 1 + flash->addr_width; + } + + int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr) +@@ -158,7 +163,7 @@ int spi_flash_write_common(struct spi_fl + int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) + { + u32 erase_size; +- u8 cmd[4]; ++ u8 cmd[4], cmd_len; + int ret = -1; + + erase_size = flash->erase_size; +@@ -180,12 +185,13 @@ int spi_flash_cmd_erase_ops(struct spi_f + if (ret < 0) + goto done; + #endif +- spi_flash_addr(offset, cmd); ++ spi_flash_addr(flash, offset, cmd); ++ cmd_len = spi_flash_cmdsz(flash); + + debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], + cmd[2], cmd[3], offset); + +- ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); ++ ret = spi_flash_write_common(flash, cmd, cmd_len, NULL, 0); + if (ret < 0) { + debug("SF: erase failed\n"); + goto done; +@@ -206,7 +212,7 @@ int spi_flash_cmd_write_ops(struct spi_f + { + unsigned long byte_addr, page_size; + size_t chunk_len, actual; +- u8 cmd[4]; ++ u8 cmd[4], cmd_len; + int ret = -1; + + ret = spi_claim_bus(flash->spi); +@@ -230,12 +236,13 @@ int spi_flash_cmd_write_ops(struct spi_f + if (flash->spi->max_write_size) + chunk_len = min(chunk_len, flash->spi->max_write_size); + +- spi_flash_addr(offset, cmd); ++ spi_flash_addr(flash, offset, cmd); ++ cmd_len = spi_flash_cmdsz(flash); + + 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); + +- ret = spi_flash_write_common(flash, cmd, sizeof(cmd), ++ ret = spi_flash_write_common(flash, cmd, cmd_len, + buf + actual, chunk_len); + if (ret < 0) { + debug("SF: write failed\n"); +@@ -269,7 +276,7 @@ int spi_flash_read_common(struct spi_fla + int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, + size_t len, void *data) + { +- u8 cmd[5], bank_sel = 0; ++ u8 cmd[5], cmd_len, bank_sel = 0; + u32 remain_len, read_len; + int ret = -1; + +@@ -288,7 +295,6 @@ int spi_flash_cmd_read_ops(struct spi_fl + } + + cmd[0] = CMD_READ_ARRAY_FAST; +- cmd[4] = 0x00; + + while (len) { + #ifdef CONFIG_SPI_FLASH_BAR +@@ -306,9 +312,11 @@ int spi_flash_cmd_read_ops(struct spi_fl + else + read_len = remain_len; + +- spi_flash_addr(offset, cmd); ++ spi_flash_addr(flash, offset, cmd); ++ cmd_len = spi_flash_cmdsz(flash); ++ cmd[cmd_len] = 0x00; + +- ret = spi_flash_read_common(flash, cmd, sizeof(cmd), ++ ret = spi_flash_read_common(flash, cmd, cmd_len + 1, + data, read_len); + if (ret < 0) { + debug("SF: read failed\n"); +--- a/drivers/mtd/spi/sf_probe.c ++++ b/drivers/mtd/spi/sf_probe.c +@@ -218,6 +218,9 @@ static int spi_flash_validate_params(str + flash->poll_cmd = CMD_FLAG_STATUS; + #endif + ++ /* Configure default 3-byte addressing */ ++ flash->addr_width = 3; ++ + /* Configure the BAR - discover bank cmds and read current bank */ + #ifdef CONFIG_SPI_FLASH_BAR + u8 curr_bank = 0; +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -57,6 +57,7 @@ struct spi_flash { + #endif + u8 poll_cmd; + u8 erase_cmd; ++ u8 addr_width; + + void *memory_map; + int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf); diff --git a/package/boot/uboot-lantiq/patches/0006-sf-add-support-for-4-byte-addressing.patch b/package/boot/uboot-lantiq/patches/0006-sf-add-support-for-4-byte-addressing.patch new file mode 100644 index 0000000..b903114 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0006-sf-add-support-for-4-byte-addressing.patch @@ -0,0 +1,160 @@ +From 3af3addee645bd81537be1ddee49969f8dfc64ee Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sun, 13 Oct 2013 15:24:56 +0200 +Subject: sf: add support for 4-byte addressing + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/mtd/spi/sf_internal.h ++++ b/drivers/mtd/spi/sf_internal.h +@@ -38,12 +38,14 @@ + #define CMD_READ_ID 0x9f + + /* Bank addr access commands */ +-#ifdef CONFIG_SPI_FLASH_BAR +-# define CMD_BANKADDR_BRWR 0x17 +-# define CMD_BANKADDR_BRRD 0x16 +-# define CMD_EXTNADDR_WREAR 0xC5 +-# define CMD_EXTNADDR_RDEAR 0xC8 +-#endif ++#define CMD_BANKADDR_BRWR 0x17 ++#define CMD_BANKADDR_BRRD 0x16 ++#define CMD_EXTNADDR_WREAR 0xC5 ++#define CMD_EXTNADDR_RDEAR 0xC8 ++ ++/* Macronix style 4-byte addressing */ ++#define CMD_EN4B 0xb7 ++#define CMD_EX4B 0xe9 + + /* Common status */ + #define STATUS_WIP 0x01 +--- a/drivers/mtd/spi/sf_ops.c ++++ b/drivers/mtd/spi/sf_ops.c +@@ -21,6 +21,7 @@ static void spi_flash_addr(const struct + cmd[1] = addr >> (flash->addr_width * 8 - 8); + cmd[2] = addr >> (flash->addr_width * 8 - 16); + cmd[3] = addr >> (flash->addr_width * 8 - 24); ++ cmd[4] = addr >> (flash->addr_width * 8 - 32); + } + + static int spi_flash_cmdsz(const struct spi_flash *flash) +@@ -163,7 +164,7 @@ int spi_flash_write_common(struct spi_fl + int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) + { + u32 erase_size; +- u8 cmd[4], cmd_len; ++ u8 cmd[5], cmd_len; + int ret = -1; + + erase_size = flash->erase_size; +@@ -188,8 +189,8 @@ int spi_flash_cmd_erase_ops(struct spi_f + spi_flash_addr(flash, offset, cmd); + cmd_len = spi_flash_cmdsz(flash); + +- 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_write_common(flash, cmd, cmd_len, NULL, 0); + if (ret < 0) { +@@ -212,7 +213,7 @@ int spi_flash_cmd_write_ops(struct spi_f + { + unsigned long byte_addr, page_size; + size_t chunk_len, actual; +- u8 cmd[4], cmd_len; ++ u8 cmd[5], cmd_len; + int ret = -1; + + ret = spi_claim_bus(flash->spi); +@@ -239,8 +240,8 @@ int spi_flash_cmd_write_ops(struct spi_f + spi_flash_addr(flash, offset, cmd); + cmd_len = spi_flash_cmdsz(flash); + +- 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_write_common(flash, cmd, cmd_len, + buf + actual, chunk_len); +@@ -276,9 +277,13 @@ int spi_flash_read_common(struct spi_fla + int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, + size_t len, void *data) + { +- u8 cmd[5], cmd_len, bank_sel = 0; +- u32 remain_len, read_len; ++ u8 cmd[6], cmd_len; ++ u32 read_len; + int ret = -1; ++#ifdef CONFIG_SPI_FLASH_BAR ++ u8 bank_sel = 0; ++ u32 remain_len; ++#endif + + ret = spi_claim_bus(flash->spi); + if (ret) { +@@ -305,12 +310,15 @@ int spi_flash_cmd_read_ops(struct spi_fl + debug("SF: fail to set bank%d\n", bank_sel); + goto done; + } +-#endif ++ + remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1)) - offset; + if (len < remain_len) + read_len = len; + else + read_len = remain_len; ++#else ++ read_len = len; ++#endif + + spi_flash_addr(flash, offset, cmd); + cmd_len = spi_flash_cmdsz(flash); +--- a/drivers/mtd/spi/sf_probe.c ++++ b/drivers/mtd/spi/sf_probe.c +@@ -153,6 +153,25 @@ static const struct spi_flash_params spi + */ + }; + ++int spi_flash_4byte_set(struct spi_flash *flash, u8 idcode0, int enable) ++{ ++ u8 cmd, bankaddr; ++ ++ switch (idcode0) { ++ case 0xc2: ++ case 0xef: ++ case 0x1c: ++ /* Macronix style */ ++ cmd = enable ? CMD_EN4B : CMD_EX4B; ++ return spi_flash_cmd(flash->spi, cmd, NULL, 0); ++ default: ++ /* Spansion style */ ++ cmd = CMD_BANKADDR_BRWR; ++ bankaddr = enable << 7; ++ return spi_flash_cmd_write(flash->spi, &cmd, 1, &bankaddr, 1); ++ } ++} ++ + static int spi_flash_validate_params(struct spi_flash *flash, + u8 *idcode) + { +@@ -218,8 +237,18 @@ static int spi_flash_validate_params(str + flash->poll_cmd = CMD_FLAG_STATUS; + #endif + ++#ifndef CONFIG_SPI_FLASH_BAR ++ /* enable 4-byte addressing if the device exceeds 16MiB */ ++ if (flash->size > SPI_FLASH_16MB_BOUN) { ++ flash->addr_width = 4; ++ spi_flash_4byte_set(flash, idcode[0], 1); ++ } else { ++ flash->addr_width = 3; ++ } ++#else + /* Configure default 3-byte addressing */ + flash->addr_width = 3; ++#endif + + /* Configure the BAR - discover bank cmds and read current bank */ + #ifdef CONFIG_SPI_FLASH_BAR diff --git a/package/boot/uboot-lantiq/patches/0007-sf-add-support-for-EN25QH256.patch b/package/boot/uboot-lantiq/patches/0007-sf-add-support-for-EN25QH256.patch new file mode 100644 index 0000000..04d008f --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0007-sf-add-support-for-EN25QH256.patch @@ -0,0 +1,17 @@ +From d5aa0d4117a439803a3d074d2745372036d2a1eb Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sun, 13 Oct 2013 15:35:34 +0200 +Subject: sf: add support for EN25QH256 + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/mtd/spi/sf_probe.c ++++ b/drivers/mtd/spi/sf_probe.c +@@ -53,6 +53,7 @@ static const struct spi_flash_params spi + {"EN25Q64", 0x1c3017, 0x0, 64 * 1024, 128, SECT_4K}, + {"EN25Q128B", 0x1c3018, 0x0, 64 * 1024, 256, 0}, + {"EN25S64", 0x1c3817, 0x0, 64 * 1024, 128, 0}, ++ {"EN25QH256", 0x1c7019, 0x0, 64 * 1024, 512, 0}, + #endif + #ifdef CONFIG_SPI_FLASH_GIGADEVICE /* GIGADEVICE */ + {"GD25Q64B", 0xc84017, 0x0, 64 * 1024, 128, SECT_4K}, diff --git a/package/boot/uboot-lantiq/patches/0008-sf-fix-sector-layout-of-S25FL256S_256K-and-S25FL512S.patch b/package/boot/uboot-lantiq/patches/0008-sf-fix-sector-layout-of-S25FL256S_256K-and-S25FL512S.patch new file mode 100644 index 0000000..64f80bf --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0008-sf-fix-sector-layout-of-S25FL256S_256K-and-S25FL512S.patch @@ -0,0 +1,21 @@ +From 5a6d8045190c887c7f65e65fb1bfc8854774c458 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sun, 13 Oct 2013 15:40:07 +0200 +Subject: sf: fix sector layout of S25FL256S_256K and S25FL512S_256K + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/mtd/spi/sf_probe.c ++++ b/drivers/mtd/spi/sf_probe.c +@@ -80,9 +80,9 @@ static const struct spi_flash_params spi + {"S25FL032P", 0x010215, 0x4d00, 64 * 1024, 64, 0}, + {"S25FL064P", 0x010216, 0x4d00, 64 * 1024, 128, 0}, + {"S25FL128S_64K", 0x012018, 0x4d01, 64 * 1024, 256, 0}, +- {"S25FL256S_256K", 0x010219, 0x4d00, 64 * 1024, 512, 0}, ++ {"S25FL256S_256K", 0x010219, 0x4d00, 256 * 1024, 128, 0}, + {"S25FL256S_64K", 0x010219, 0x4d01, 64 * 1024, 512, 0}, +- {"S25FL512S_256K", 0x010220, 0x4d00, 64 * 1024, 1024, 0}, ++ {"S25FL512S_256K", 0x010220, 0x4d00, 256 * 1024, 256, 0}, + {"S25FL512S_64K", 0x010220, 0x4d01, 64 * 1024, 1024, 0}, + #endif + #ifdef CONFIG_SPI_FLASH_STMICRO /* STMICRO */ diff --git a/package/boot/uboot-lantiq/patches/0009-net-switchlib-add-framework-for-ethernet-switch-driv.patch b/package/boot/uboot-lantiq/patches/0009-net-switchlib-add-framework-for-ethernet-switch-driv.patch new file mode 100644 index 0000000..de6f51b --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0009-net-switchlib-add-framework-for-ethernet-switch-driv.patch @@ -0,0 +1,244 @@ +From 0dff8c753c8929a478357abb38db0d1c1a60ec94 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +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 +Cc: Joe Hershberger + +--- a/Makefile ++++ b/Makefile +@@ -280,6 +280,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,30 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,62 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++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,102 @@ ++/* ++ * 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-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#ifndef __SWITCH_H ++#define __SWITCH_H ++ ++#include ++ ++#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 ++ */ ++#ifdef CONFIG_SWITCH_MULTI ++extern struct switch_device *switch_connect(struct mii_dev *bus); ++#else ++static inline struct switch_device *switch_connect(struct mii_dev *bus) ++{ ++ return NULL; ++} ++#endif ++ ++/* ++ * 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 +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + void eth_parse_enetaddr(const char *addr, uchar *enetaddr) + { +@@ -287,6 +288,8 @@ int eth_initialize(bd_t *bis) + phy_init(); + #endif + ++ switch_init(); ++ + eth_env_init(bis); + + /* diff --git a/package/boot/uboot-lantiq/patches/0010-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch b/package/boot/uboot-lantiq/patches/0010-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch new file mode 100644 index 0000000..8f486e8 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0010-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch @@ -0,0 +1,161 @@ +From e2c59cedebf72e4a002134a2932f722b508a5448 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Wed, 29 Aug 2012 22:08:15 +0200 +Subject: net: switchlib: add driver for Lantiq PSB697X switch family + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/net/switch/Makefile ++++ b/drivers/net/switch/Makefile +@@ -10,6 +10,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,118 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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 +@@ -17,6 +17,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 +@@ -97,6 +97,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/0011-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch b/package/boot/uboot-lantiq/patches/0011-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch new file mode 100644 index 0000000..a8b142e --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0011-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch @@ -0,0 +1,157 @@ +From c291443dc97dadcf0c6afd04688a7d9f79a221b5 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Wed, 29 Aug 2012 22:08:16 +0200 +Subject: net: switchlib: add driver for Lantiq ADM6996I switch family + +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/net/switch/Makefile ++++ b/drivers/net/switch/Makefile +@@ -11,6 +11,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,115 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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 +@@ -20,6 +20,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 +@@ -98,6 +98,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/0012-net-switchlib-add-driver-for-Atheros-AR8216.patch b/package/boot/uboot-lantiq/patches/0012-net-switchlib-add-driver-for-Atheros-AR8216.patch new file mode 100644 index 0000000..568f9ad --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0012-net-switchlib-add-driver-for-Atheros-AR8216.patch @@ -0,0 +1,157 @@ +From 1a1d61a2faf0390033a3766559ce0e758e15894e Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Wed, 29 Aug 2012 22:08:16 +0200 +Subject: net: switchlib: add driver for Atheros AR8216 + +Signed-off-by: Luka Perkov +Signed-off-by: Daniel Schwierzeck + +--- 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-$(CONFIG_SWITCH_AR8216) += ar8216.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +--- /dev/null ++++ b/drivers/net/switch/ar8216.c +@@ -0,0 +1,114 @@ ++/* ++ * Copyright (C) 2012 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 +@@ -23,6 +23,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 +@@ -99,6 +99,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/0013-net-switchlib-add-driver-for-REALTEK-RTL8306.patch b/package/boot/uboot-lantiq/patches/0013-net-switchlib-add-driver-for-REALTEK-RTL8306.patch new file mode 100644 index 0000000..4c01ad0 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0013-net-switchlib-add-driver-for-REALTEK-RTL8306.patch @@ -0,0 +1,375 @@ +From 42cb399df978a33539b95d668b3f973d927cb902 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Mon, 17 Dec 2012 23:37:57 +0100 +Subject: net: switchlib: add driver for REALTEK RTL8306 + +Signed-off-by: Oliver Muth +Signed-off-by: Daniel Schwierzeck + +--- a/drivers/net/switch/Makefile ++++ b/drivers/net/switch/Makefile +@@ -13,6 +13,7 @@ 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-$(CONFIG_SWITCH_RTL8306) += rtl8306.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +--- /dev/null ++++ b/drivers/net/switch/rtl8306.c +@@ -0,0 +1,332 @@ ++/* ++ * Based on OpenWrt linux driver ++ * ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * Copyright (C) 2009 Felix Fietkau ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#define DEBUG ++#include ++#include ++#include ++#include ++ ++#define RTL8306_REG_PAGE 16 ++#define RTL8306_REG_PAGE_LO (1 << 15) ++#define RTL8306_REG_PAGE_HI (1 << 1) /* inverted */ ++#define RTL8306_CHIPID 0x5988 ++ ++#define RTL8306_NUM_VLANS 16 ++#define RTL8306_NUM_PORTS 6 ++#define RTL8306_PORT_CPU 5 ++#define RTL8306_NUM_PAGES 4 ++#define RTL8306_NUM_REGS 32 ++ ++enum { ++ RTL_TYPE_S, ++ RTL_TYPE_SD, ++ RTL_TYPE_SDM, ++}; ++ ++struct rtl_reg { ++ int page; ++ int phy; ++ int reg; ++ int bits; ++ int shift; ++ int inverted; ++}; ++ ++enum rtl_regidx { ++ RTL_REG_CHIPID, ++ RTL_REG_CHIPVER, ++ RTL_REG_CHIPTYPE, ++ RTL_REG_CPUPORT, ++ ++ RTL_REG_EN_CPUPORT, ++ RTL_REG_EN_TAG_OUT, ++ RTL_REG_EN_TAG_CLR, ++ RTL_REG_EN_TAG_IN, ++ RTL_REG_TRAP_CPU, ++ RTL_REG_TRUNK_PORTSEL, ++ RTL_REG_EN_TRUNK, ++ RTL_REG_RESET, ++ RTL_REG_PHY_RESET, ++ RTL_REG_CPU_LINKUP, ++ ++ RTL_REG_VLAN_ENABLE, ++ RTL_REG_VLAN_FILTER, ++ RTL_REG_VLAN_TAG_ONLY, ++ RTL_REG_VLAN_TAG_AWARE, ++#define RTL_VLAN_ENUM(id) \ ++ RTL_REG_VLAN##id##_VID, \ ++ RTL_REG_VLAN##id##_PORTMASK ++ RTL_VLAN_ENUM(0), ++ RTL_VLAN_ENUM(1), ++ RTL_VLAN_ENUM(2), ++ RTL_VLAN_ENUM(3), ++ RTL_VLAN_ENUM(4), ++ RTL_VLAN_ENUM(5), ++ RTL_VLAN_ENUM(6), ++ RTL_VLAN_ENUM(7), ++ RTL_VLAN_ENUM(8), ++ RTL_VLAN_ENUM(9), ++ RTL_VLAN_ENUM(10), ++ RTL_VLAN_ENUM(11), ++ RTL_VLAN_ENUM(12), ++ RTL_VLAN_ENUM(13), ++ RTL_VLAN_ENUM(14), ++ RTL_VLAN_ENUM(15), ++#define RTL_PORT_ENUM(id) \ ++ RTL_REG_PORT##id##_PVID, \ ++ RTL_REG_PORT##id##_NULL_VID_REPLACE, \ ++ RTL_REG_PORT##id##_NON_PVID_DISCARD, \ ++ RTL_REG_PORT##id##_VID_INSERT, \ ++ RTL_REG_PORT##id##_TAG_INSERT, \ ++ RTL_REG_PORT##id##_LINK, \ ++ RTL_REG_PORT##id##_SPEED, \ ++ RTL_REG_PORT##id##_NWAY, \ ++ RTL_REG_PORT##id##_NRESTART, \ ++ RTL_REG_PORT##id##_DUPLEX, \ ++ RTL_REG_PORT##id##_RXEN, \ ++ RTL_REG_PORT##id##_TXEN, \ ++ RTL_REG_PORT##id##_LRNEN ++ RTL_PORT_ENUM(0), ++ RTL_PORT_ENUM(1), ++ RTL_PORT_ENUM(2), ++ RTL_PORT_ENUM(3), ++ RTL_PORT_ENUM(4), ++ RTL_PORT_ENUM(5), ++}; ++ ++static const struct rtl_reg rtl_regs[] = { ++ [RTL_REG_CHIPID] = { 0, 4, 30, 16, 0, 0 }, ++ [RTL_REG_CHIPVER] = { 0, 4, 31, 8, 0, 0 }, ++ [RTL_REG_CHIPTYPE] = { 0, 4, 31, 2, 8, 0 }, ++ ++ /* CPU port number */ ++ [RTL_REG_CPUPORT] = { 2, 4, 21, 3, 0, 0 }, ++ /* Enable CPU port function */ ++ [RTL_REG_EN_CPUPORT] = { 3, 2, 21, 1, 15, 1 }, ++ /* Enable CPU port tag insertion */ ++ [RTL_REG_EN_TAG_OUT] = { 3, 2, 21, 1, 12, 0 }, ++ /* Enable CPU port tag removal */ ++ [RTL_REG_EN_TAG_CLR] = { 3, 2, 21, 1, 11, 0 }, ++ /* Enable CPU port tag checking */ ++ [RTL_REG_EN_TAG_IN] = { 0, 4, 21, 1, 7, 0 }, ++ [RTL_REG_EN_TRUNK] = { 0, 0, 19, 1, 11, 1 }, ++ [RTL_REG_TRUNK_PORTSEL] = { 0, 0, 16, 1, 6, 1 }, ++ [RTL_REG_RESET] = { 0, 0, 16, 1, 12, 0 }, ++ [RTL_REG_PHY_RESET] = { 0, 0, 0, 1, 15, 0 }, ++ [RTL_REG_CPU_LINKUP] = { 0, 6, 22, 1, 15, 0 }, ++ [RTL_REG_TRAP_CPU] = { 3, 2, 22, 1, 6, 0 }, ++ ++ [RTL_REG_VLAN_TAG_ONLY] = { 0, 0, 16, 1, 8, 1 }, ++ [RTL_REG_VLAN_FILTER] = { 0, 0, 16, 1, 9, 1 }, ++ [RTL_REG_VLAN_TAG_AWARE] = { 0, 0, 16, 1, 10, 1 }, ++ [RTL_REG_VLAN_ENABLE] = { 0, 0, 18, 1, 8, 1 }, ++ ++#define RTL_VLAN_REGS(id, phy, page, regofs) \ ++ [RTL_REG_VLAN##id##_VID] = { page, phy, 25 + regofs, 12, 0, 0 }, \ ++ [RTL_REG_VLAN##id##_PORTMASK] = { page, phy, 24 + regofs, 6, 0, 0 } ++ RTL_VLAN_REGS( 0, 0, 0, 0), ++ RTL_VLAN_REGS( 1, 1, 0, 0), ++ RTL_VLAN_REGS( 2, 2, 0, 0), ++ RTL_VLAN_REGS( 3, 3, 0, 0), ++ RTL_VLAN_REGS( 4, 4, 0, 0), ++ RTL_VLAN_REGS( 5, 0, 1, 2), ++ RTL_VLAN_REGS( 6, 1, 1, 2), ++ RTL_VLAN_REGS( 7, 2, 1, 2), ++ RTL_VLAN_REGS( 8, 3, 1, 2), ++ RTL_VLAN_REGS( 9, 4, 1, 2), ++ RTL_VLAN_REGS(10, 0, 1, 4), ++ RTL_VLAN_REGS(11, 1, 1, 4), ++ RTL_VLAN_REGS(12, 2, 1, 4), ++ RTL_VLAN_REGS(13, 3, 1, 4), ++ RTL_VLAN_REGS(14, 4, 1, 4), ++ RTL_VLAN_REGS(15, 0, 1, 6), ++ ++#define REG_PORT_SETTING(port, phy) \ ++ [RTL_REG_PORT##port##_SPEED] = { 0, phy, 0, 1, 13, 0 }, \ ++ [RTL_REG_PORT##port##_NWAY] = { 0, phy, 0, 1, 12, 0 }, \ ++ [RTL_REG_PORT##port##_NRESTART] = { 0, phy, 0, 1, 9, 0 }, \ ++ [RTL_REG_PORT##port##_DUPLEX] = { 0, phy, 0, 1, 8, 0 }, \ ++ [RTL_REG_PORT##port##_TXEN] = { 0, phy, 24, 1, 11, 0 }, \ ++ [RTL_REG_PORT##port##_RXEN] = { 0, phy, 24, 1, 10, 0 }, \ ++ [RTL_REG_PORT##port##_LRNEN] = { 0, phy, 24, 1, 9, 0 }, \ ++ [RTL_REG_PORT##port##_LINK] = { 0, phy, 1, 1, 2, 0 }, \ ++ [RTL_REG_PORT##port##_NULL_VID_REPLACE] = { 0, phy, 22, 1, 12, 0 }, \ ++ [RTL_REG_PORT##port##_NON_PVID_DISCARD] = { 0, phy, 22, 1, 11, 0 }, \ ++ [RTL_REG_PORT##port##_VID_INSERT] = { 0, phy, 22, 2, 9, 0 }, \ ++ [RTL_REG_PORT##port##_TAG_INSERT] = { 0, phy, 22, 2, 0, 0 } ++ ++ REG_PORT_SETTING(0, 0), ++ REG_PORT_SETTING(1, 1), ++ REG_PORT_SETTING(2, 2), ++ REG_PORT_SETTING(3, 3), ++ REG_PORT_SETTING(4, 4), ++ REG_PORT_SETTING(5, 6), ++ ++#define REG_PORT_PVID(phy, page, regofs) \ ++ { page, phy, 24 + regofs, 4, 12, 0 } ++ [RTL_REG_PORT0_PVID] = REG_PORT_PVID(0, 0, 0), ++ [RTL_REG_PORT1_PVID] = REG_PORT_PVID(1, 0, 0), ++ [RTL_REG_PORT2_PVID] = REG_PORT_PVID(2, 0, 0), ++ [RTL_REG_PORT3_PVID] = REG_PORT_PVID(3, 0, 0), ++ [RTL_REG_PORT4_PVID] = REG_PORT_PVID(4, 0, 0), ++ [RTL_REG_PORT5_PVID] = REG_PORT_PVID(0, 1, 2), ++}; ++ ++static void rtl_set_page(struct mii_dev *bus, unsigned int page) ++{ ++ u16 pgsel; ++ ++ BUG_ON(page > RTL8306_NUM_PAGES); ++ ++ pgsel = bus->read(bus, 0, MDIO_DEVAD_NONE, RTL8306_REG_PAGE); ++ pgsel &= ~(RTL8306_REG_PAGE_LO | RTL8306_REG_PAGE_HI); ++ ++ if (page & (1 << 0)) ++ pgsel |= RTL8306_REG_PAGE_LO; ++ ++ if (!(page & (1 << 1))) /* bit is inverted */ ++ pgsel |= RTL8306_REG_PAGE_HI; ++ ++ bus->write(bus, 0, MDIO_DEVAD_NONE, RTL8306_REG_PAGE, pgsel); ++ ++} ++ ++static __maybe_unused int rtl_w16(struct mii_dev *bus, unsigned int page, unsigned int phy, ++ unsigned int reg, u16 val) ++{ ++ rtl_set_page(bus, page); ++ ++ bus->write(bus, phy, MDIO_DEVAD_NONE, reg, val); ++ bus->read(bus, phy, MDIO_DEVAD_NONE, reg); /* flush */ ++ ++ return 0; ++} ++ ++static int rtl_r16(struct mii_dev *bus, unsigned int page, unsigned int phy, ++ unsigned int reg) ++{ ++ rtl_set_page(bus, page); ++ ++ return bus->read(bus, phy, MDIO_DEVAD_NONE, reg); ++} ++ ++static u16 rtl_rmw(struct mii_dev *bus, unsigned int page, unsigned int phy, ++ unsigned int reg, u16 mask, u16 val) ++{ ++ u16 r; ++ ++ rtl_set_page(bus, page); ++ ++ r = bus->read(bus, phy, MDIO_DEVAD_NONE, reg); ++ r &= ~mask; ++ r |= val; ++ bus->write(bus, phy, MDIO_DEVAD_NONE, reg, r); ++ ++ return bus->read(bus, phy, MDIO_DEVAD_NONE, reg); /* flush */ ++} ++ ++static int rtl_get(struct mii_dev *bus, enum rtl_regidx s) ++{ ++ const struct rtl_reg *r = &rtl_regs[s]; ++ u16 val; ++ ++ BUG_ON(s >= ARRAY_SIZE(rtl_regs)); ++ ++ if (r->bits == 0) /* unimplemented */ ++ return 0; ++ ++ val = rtl_r16(bus, r->page, r->phy, r->reg); ++ ++ if (r->shift > 0) ++ val >>= r->shift; ++ ++ if (r->inverted) ++ val = ~val; ++ ++ val &= (1 << r->bits) - 1; ++ ++ return val; ++} ++ ++static __maybe_unused int rtl_set(struct mii_dev *bus, enum rtl_regidx s, unsigned int val) ++{ ++ const struct rtl_reg *r = &rtl_regs[s]; ++ u16 mask = 0xffff; ++ ++ BUG_ON(s >= ARRAY_SIZE(rtl_regs)); ++ ++ if (r->bits == 0) /* unimplemented */ ++ return 0; ++ ++ if (r->shift > 0) ++ val <<= r->shift; ++ ++ if (r->inverted) ++ val = ~val; ++ ++ if (r->bits != 16) { ++ mask = (1 << r->bits) - 1; ++ mask <<= r->shift; ++ } ++ ++ val &= mask; ++ ++ return rtl_rmw(bus, r->page, r->phy, r->reg, mask, val); ++} ++ ++static int rtl8306_probe(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ unsigned int chipid, chipver, chiptype; ++ ++ chipid = rtl_get(bus, RTL_REG_CHIPID); ++ chipver = rtl_get(bus, RTL_REG_CHIPVER); ++ chiptype = rtl_get(bus, RTL_REG_CHIPTYPE); ++ ++ debug("%s: chipid %x, chipver %x, chiptype %x\n", ++ __func__, chipid, chipver, chiptype); ++ ++ if (chipid == RTL8306_CHIPID) ++ return 0; ++ ++ return 1; ++} ++ ++static void rtl8306_setup(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ ++ /* initialize cpu port settings */ ++ rtl_set(bus, RTL_REG_CPUPORT, dev->cpu_port); ++ rtl_set(bus, RTL_REG_EN_CPUPORT, 1); ++ ++ /* enable phy 5 link status */ ++ rtl_set(bus, RTL_REG_CPU_LINKUP, 1); ++// rtl_set(bus, RTL_REG_PORT5_TXEN, 1); ++// rtl_set(bus, RTL_REG_PORT5_RXEN, 1); ++// rtl_set(bus, RTL_REG_PORT5_LRNEN, 1); ++#ifdef DEBUG ++ debug("%s: CPU link up: %i\n", ++ __func__, rtl_get(bus, RTL_REG_PORT5_LINK)); ++#endif ++ ++} ++ ++static struct switch_driver rtl8306_drv = { ++ .name = "rtl8306", ++}; ++ ++void switch_rtl8306_init(void) ++{ ++ /* For archs with manual relocation */ ++ rtl8306_drv.probe = rtl8306_probe; ++ rtl8306_drv.setup = rtl8306_setup; ++ ++ switch_driver_register(&rtl8306_drv); ++} +--- a/drivers/net/switch/switch.c ++++ b/drivers/net/switch/switch.c +@@ -26,6 +26,9 @@ void switch_init(void) + #if defined(CONFIG_SWITCH_AR8216) + switch_ar8216_init(); + #endif ++#if defined(CONFIG_SWITCH_RTL8306) ++ switch_rtl8306_init(); ++#endif + + board_switch_init(); + } +--- a/include/switch.h ++++ b/include/switch.h +@@ -100,6 +100,7 @@ static inline void switch_setup(struct s + extern void switch_psb697x_init(void); + extern void switch_adm6996i_init(void); + extern void switch_ar8216_init(void); ++extern void switch_rtl8306_init(void); + + #endif /* __SWITCH_H */ + diff --git a/package/boot/uboot-lantiq/patches/0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch b/package/boot/uboot-lantiq/patches/0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch new file mode 100644 index 0000000..ef6eb1a --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch @@ -0,0 +1,9339 @@ +From 11553b0de8992ded6240d034bd49f561d17bea53 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Thu, 13 Jun 2013 01:18:02 +0200 +Subject: MIPS: add support for Lantiq XWAY SoCs + +Signed-off-by: Luka Perkov +Signed-off-by: Daniel Schwierzeck + +--- a/.gitignore ++++ b/.gitignore +@@ -49,6 +49,13 @@ + /u-boot.sb + /u-boot.bd + /u-boot.geany ++/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 +@@ -435,6 +435,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) +@@ -454,13 +460,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 depend + $(MAKE) -C $(SRCTREE)/arch/arm/imx-common $(OBJTREE)/u-boot.imx +@@ -571,6 +587,27 @@ $(obj)u-boot-img-spl-at-end.bin: $(obj)s + conv=notrunc 2>/dev/null + cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@ + ++$(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 +@@ -468,6 +468,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 +@@ -45,9 +45,13 @@ 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 ++PF_PIE ?= -pie ++ ++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 +-LDFLAGS_FINAL += --gc-sections -pie ++LDFLAGS_FINAL += --gc-sections $(PF_PIE) + OBJCFLAGS += --remove-section=.dynsym +--- a/arch/mips/cpu/mips32/cache.S ++++ b/arch/mips/cpu/mips32/cache.S +@@ -29,7 +29,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 +@@ -65,7 +69,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 +@@ -90,7 +98,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,31 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,117 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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(<q_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,142 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* 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,59 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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(<q_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(<q_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,25 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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 ++PF_PIE := ++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 +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/ebu.c +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++ ++#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[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) ++{ ++ 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(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE | ++ EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE | ++ EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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/danube/mem.c +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++ ++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,114 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Must be configured in BOARDDIR */ ++#include ++ ++#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,117 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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(<q_pmu_regs->pwdcr, val); ++ ++ timebase = get_timer(0); ++ ++ do { ++ sr = ltq_readl(<q_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(<q_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(<q_pmu_regs->pwdcr, clr, set); ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/rcu.c +@@ -0,0 +1,125 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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(<q_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(<q_rcu_regs->req, val); ++ ++ return 0; ++} ++ ++enum ltq_boot_select ltq_boot_select(void) ++{ ++ u32 stat; ++ unsigned int bootstrap; ++ ++ stat = ltq_readl(<q_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/lantiq-common/Makefile +@@ -0,0 +1,34 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,59 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++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,20 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++ ++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,9 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++ +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/spl.c +@@ -0,0 +1,403 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#define spl_has_debug 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; ++ ulong data_size; ++ ulong entry_size; ++ ulong data_crc; ++ u8 comp; ++}; ++ ++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) ++{ ++ spl_puts("SPL: checking U-Boot image\n"); ++ ++ if (!image_check_magic(hdr)) { ++ spl_puts("SPL: invalid magic\n"); ++ return -1; ++ } ++ ++ if (!image_check_hcrc(hdr)) { ++ spl_puts("SPL: invalid header CRC\n"); ++ 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->data_crc = image_get_dcrc(hdr); ++ spl->comp = image_get_comp(hdr); ++ ++ spl_debug("SPL: data %08lx, size %lu, entry %08lx, comp %u\n", ++ spl->data_addr, spl->data_size, spl->entry_addr, spl->comp); ++ ++ return 0; ++} ++ ++static int spl_check_data(const struct spl_image *spl, ulong loadaddr) ++{ ++ ulong dcrc = crc32(0, (unsigned char *)loadaddr, spl->data_size); ++ ++ if (dcrc != spl->data_crc) { ++ spl_puts("SPL: invalid data CRC\n"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++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 = { 0 }; ++ 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 = image_copy_end() - CONFIG_SPL_TEXT_BASE + 24; ++ ++ spl_puts("SPL: probing SPI flash\n"); ++ ++ spi_init(); ++ ret = spl_spi_flash_probe(&sf); ++ 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_check_data(spl, loadaddr)) ++ return -1; ++ ++ 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 = 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,143 @@ ++/* ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++ ++#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,48 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++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 +@@ -105,7 +105,7 @@ reset: + 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 +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/Makefile +@@ -0,0 +1,32 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,208 @@ ++/* ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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(<q_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(<q_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK); ++ ltq_setbits(<q_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT); ++} ++ ++static inline int ltq_cgu_pll1_locked(void) ++{ ++ u32 pll1_cfg = ltq_readl(<q_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(<q_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN); ++ ltq_setbits(<q_cgu_regs->update, LTQ_CGU_UPDATE); ++ ++ pll1_cfg = ltq_readl(<q_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(<q_cgu_regs->pll1_cfg, pll1_cfg); ++ ltq_setbits(<q_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,119 @@ ++/* ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* 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,62 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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(<q_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(<q_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,30 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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 ++PF_PIE := ++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 +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/dcdc.c +@@ -0,0 +1,106 @@ ++/* ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++ ++#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(<q_dcdc_regs->duty_cycle_max_sat, 0x5A); ++ ltq_writeb(<q_dcdc_regs->duty_cycle_min_sat, 0x46); ++ val = ltq_readb(<q_dcdc_regs->conf_test_dig); ++ val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE; ++ ltq_writeb(<q_dcdc_regs->conf_test_dig, val); ++ ++ /* Program new coefficients */ ++ ltq_writeb(<q_dcdc_regs->b0_coeh, 0x00); ++ ltq_writeb(<q_dcdc_regs->b0_coel, 0x00); ++ ltq_writeb(<q_dcdc_regs->b1_coeh, 0xFF); ++ ltq_writeb(<q_dcdc_regs->b1_coel, 0xE6); ++ ltq_writeb(<q_dcdc_regs->b2_coeh, 0x00); ++ ltq_writeb(<q_dcdc_regs->b2_coel, 0x1B); ++ ltq_writeb(<q_dcdc_regs->non_ov_delay, 0x8B); ++ ++ /* Set duty cycle max sat. to 60/108, disable PID freeze */ ++ ltq_writeb(<q_dcdc_regs->duty_cycle_max_sat, 0x6C); ++ ltq_writeb(<q_dcdc_regs->duty_cycle_min_sat, 0x3C); ++ val = ltq_readb(<q_dcdc_regs->conf_test_dig); ++ val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE; ++ ltq_writeb(<q_dcdc_regs->conf_test_dig, val); ++ ++ /* Init clock and DLL settings */ ++ val = ltq_readb(<q_dcdc_regs->clk_set0); ++ val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P; ++ ltq_writeb(<q_dcdc_regs->clk_set0, val); ++ val = ltq_readb(<q_dcdc_regs->clk_set1); ++ val |= LTQ_DCDC_CLK_SET1_SEL_DIV25; ++ ltq_writeb(<q_dcdc_regs->clk_set1, val); ++ ltq_writeb(<q_dcdc_regs->pwm_confh, 0xF9); ++ ++ wmb(); ++ ++ /* Adapt value of digital reference of DCDC converter */ ++ dig_ref_cur = ltq_readb(<q_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(<q_dcdc_regs->bias_vreg1, dig_ref_cur); ++ __udelay(1000); ++ } ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/ebu.c +@@ -0,0 +1,111 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++ ++#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(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE | ++ EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE | ++ EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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,58 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++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,27 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++ ++ .section .rodata.__ltq_fw_phy11g_a1x ++EXPORT(__ltq_fw_phy11g_a1x_start) ++ .incbin "fw_phy11g_a1x.blob" ++EXPORT(__ltq_fw_phy11g_a1x_end) ++ ++ .section .rodata.__ltq_fw_phy11g_a2x ++EXPORT(__ltq_fw_phy11g_a2x_start) ++ .incbin "fw_phy11g_a2x.blob" ++EXPORT(__ltq_fw_phy11g_a2x_end) ++ ++ .section .rodata.__ltq_fw_phy22f_a1x ++EXPORT(__ltq_fw_phy22f_a1x_start) ++ .incbin "fw_phy22f_a1x.blob" ++EXPORT(__ltq_fw_phy22f_a1x_end) ++ ++ .section .rodata.__ltq_fw_phy22f_a2x ++EXPORT(__ltq_fw_phy22f_a2x_start) ++ .incbin "fw_phy22f_a2x.blob" ++EXPORT(__ltq_fw_phy22f_a2x_end) +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/mem.c +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++ ++#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,233 @@ ++/* ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Must be configured in BOARDDIR */ ++#include ++ ++#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,130 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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(<q_pmu_regs->pwdcr, val); ++ ++ timebase = get_timer(0); ++ ++ do { ++ sr = ltq_readl(<q_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(<q_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(<q_pmu_regs->pwdcr, clr, set); ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/rcu.c +@@ -0,0 +1,194 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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(<q_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(<q_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(<q_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 = <q_rcu_regs->gfs_add0; ++ break; ++ case 1: ++ module = LTQ_RCU_RD_GPHY1; ++ gfs_add = <q_rcu_regs->gfs_add1; ++ break; ++ default: ++ BUG(); ++ } ++ ++ /* Stop and reset GPHY */ ++ ltq_setbits(<q_rcu_regs->req, module); ++ ++ /* Configure firmware and boot address */ ++ ltq_writel(gfs_add, CPHYSADDR(addr & 0xFFFFC000)); ++ ++ /* Start GPHY by releasing reset */ ++ ltq_clrbits(<q_rcu_regs->req, module); ++} +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/config.h +@@ -0,0 +1,163 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * ++ * 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 0xBE1A0000 ++#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_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_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,12 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __DANUBE_GPIO_H__ ++#define __DANUBE_GPIO_H__ ++ ++#include ++ ++#endif /* __DANUBE_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/nand.h +@@ -0,0 +1,13 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __DANUBE_NAND_H__ ++#define __DANUBE_NAND_H__ ++ ++struct nand_chip; ++int ltq_nand_init(struct nand_chip *nand); ++ ++#endif /* __DANUBE_NAND_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/soc.h +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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_REGION1_BASE 0x14000000 ++#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0) ++ ++#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,184 @@ ++/* ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * ++ * 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_ETHERNET ++ * - support the VRX200 internal switch ++ * ++ * 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_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,65 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,12 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __VRX200_GPIO_H__ ++#define __VRX200_GPIO_H__ ++ ++#include ++ ++#endif /* __VRX200_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/nand.h +@@ -0,0 +1,13 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,45 @@ ++/* ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,502 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __VRX200_SWITCH_H__ ++#define __VRX200_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 ®s->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 ®s->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 = ®s->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 ®s->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 ®s->mii.mii_cfg0; ++ case 1: ++ return ®s->mii.mii_cfg1; ++ case 5: ++ return ®s->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 ®s->mii.pcdu0; ++ case 1: ++ return ®s->mii.pcdu1; ++ case 5: ++ return ®s->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 /* __VRX200_SWITCH_H__ */ +--- 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,6 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/chipid.h +@@ -0,0 +1,73 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,30 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,164 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 ++#define CONFIG_SPI_SPL_SIMPLE ++#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_LOADB ++ ++/* Other U-Boot settings */ ++#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,34 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,94 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,35 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __LANTIQ_ETH_H__ ++#define __LANTIQ_ETH_H__ ++ ++#include ++ ++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,50 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 ++ ++#endif /* __LANTIQ_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/io.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (C) 2010 John Crispin ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __LANTIQ_IO_H__ ++#define __LANTIQ_IO_H__ ++ ++#include ++ ++#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,21 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,37 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 +@@ -23,3 +23,4 @@ static inline unsigned long image_copy_e + } + + extern int incaip_set_cpuclk(void); ++extern int arch_cpu_init(void); +--- a/arch/mips/lib/board.c ++++ b/arch/mips/lib/board.c +@@ -33,6 +33,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) + { + /* +@@ -106,6 +116,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,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/lantiq/easy50712/ddr_settings.h +@@ -0,0 +1,54 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,112 @@ ++/* ++ * Copyright (C) 2010 Thomas Langer ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void gpio_init(void) ++{ ++ /* SPI/CS output (low-active) for serial flash */ ++ gpio_direction_output(22, 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); ++ ++ /* 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(ð_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,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/lantiq/easy80920/ddr_settings.h +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,138 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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(ð_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 +@@ -502,10 +502,17 @@ Active mips mips32 au1x0 + Active mips mips32 au1x00 - dbau1x00 dbau1550 dbau1x00:DBAU1550 Thomas Lange + Active mips mips32 au1x00 - dbau1x00 dbau1550_el dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN Thomas Lange + Active mips mips32 au1x00 - pb1x00 pb1000 pb1x00:PB1000 - ++Active mips mips32 danube lantiq easy50712 easy50712_nor easy50712:SYS_BOOT_NOR Daniel Schwierzeck ++Active mips mips32 danube lantiq easy50712 easy50712_norspl easy50712:SYS_BOOT_NORSPL Daniel Schwierzeck ++Active mips mips32 danube lantiq easy50712 easy50712_ram easy50712:SYS_BOOT_RAM Daniel Schwierzeck + Active mips mips32 incaip - incaip incaip - Wolfgang Denk + Active mips mips32 incaip - incaip incaip_100MHz incaip:CPU_CLOCK_RATE=100000000 Wolfgang Denk + Active mips mips32 incaip - incaip incaip_133MHz incaip:CPU_CLOCK_RATE=133000000 Wolfgang Denk + Active mips mips32 incaip - incaip incaip_150MHz incaip:CPU_CLOCK_RATE=150000000 Wolfgang Denk ++Active mips mips32 vrx200 lantiq easy80920 easy80920_nor easy80920:SYS_BOOT_NOR Daniel Schwierzeck ++Active mips mips32 vrx200 lantiq easy80920 easy80920_norspl easy80920:SYS_BOOT_NORSPL Daniel Schwierzeck ++Active mips mips32 vrx200 lantiq easy80920 easy80920_ram easy80920:SYS_BOOT_RAM Daniel Schwierzeck ++Active mips mips32 vrx200 lantiq easy80920 easy80920_sfspl easy80920:SYS_BOOT_SFSPL Daniel Schwierzeck + Active mips mips64 - - qemu-mips qemu_mips64 qemu-mips64:SYS_BIG_ENDIAN - + Active mips mips64 - - qemu-mips qemu_mips64el qemu-mips64:SYS_LITTLE_ENDIAN - + Active nds32 n1213 ag101 AndesTech adp-ag101 adp-ag101 - Andes +--- a/drivers/dma/Makefile ++++ b/drivers/dma/Makefile +@@ -12,6 +12,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,387 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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(<q_dma_regs->ctrl, DMA_CTRL_RESET); ++ ++ /* Disable and clear all interrupts */ ++ ltq_writel(<q_dma_regs->irnen, 0); ++ ltq_writel(<q_dma_regs->irncr, 0xFFFFF); ++ ++#if 0 ++ /* Enable packet arbitration */ ++ ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_PKTARB); ++#endif ++ ++#if 0 ++ /* Enable descriptor read back */ ++ ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_DRB); ++#endif ++ ++ /* Enable polling for descriptor fetching for all channels */ ++ ltq_writel(<q_dma_regs->cpoll, DMA_CPOLL_EN | ++ (4 << DMA_CPOLL_CNT_SHIFT)); ++} ++ ++static void ltq_dma_channel_reset(struct ltq_dma_channel *chan) ++{ ++ ltq_writel(<q_dma_regs->cs, chan->chan_no); ++ ltq_setbits(<q_dma_regs->cctrl, DMA_CCTRL_RST); ++} ++ ++static void ltq_dma_channel_enable(struct ltq_dma_channel *chan) ++{ ++ ltq_writel(<q_dma_regs->cs, chan->chan_no); ++ ltq_setbits(<q_dma_regs->cctrl, DMA_CCTRL_ONOFF); ++} ++ ++static void ltq_dma_channel_disable(struct ltq_dma_channel *chan) ++{ ++ ltq_writel(<q_dma_regs->cs, chan->chan_no); ++ ltq_clrbits(<q_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(<q_dma_regs->ps, dev->port); ++ ltq_writel(<q_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(<q_dma_regs->cs, chan->chan_no); ++ ltq_writel(<q_dma_regs->cdba, chan->dma_addr); ++ ltq_writel(<q_dma_regs->cdlen, chan->num_desc); ++ ltq_writel(<q_dma_regs->cctrl, (3 << DMA_CCTRL_TXWGT_SHIFT) | ++ (chan->class << DMA_CCTRL_CLASS_SHIFT)); ++ ltq_writel(<q_dma_regs->cctrl, DMA_CCTRL_RST); ++ ++ return 0; ++} ++ ++static void ltq_dma_free_descriptors(struct ltq_dma_channel *chan) ++{ ++ ltq_writel(<q_dma_regs->cs, chan->chan_no); ++ ltq_writel(<q_dma_regs->cdba, 0); ++ ltq_writel(<q_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 +@@ -12,6 +12,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,329 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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(<q_ssio_regs->ar, 0); ++ ltq_writel(<q_ssio_regs->cpu0, CONFIG_LTQ_SSIO_INIT_VALUE); ++ ltq_writel(<q_ssio_regs->cpu1, 0); ++ ltq_writel(<q_ssio_regs->con0, SSIO_CON0_SWU); ++ ++ if (enable_ssio) { ++ ltq_writel(<q_ssio_regs->con0, SSIO_CON0_GPHY1_CONFIG | ++ SSIO_RZFL_CONFIG); ++ ltq_writel(<q_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 = <q_gpio_regs->ports[port].od; ++ const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0; ++ const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1; ++ const void *gpio_dir = <q_gpio_regs->ports[port].dir; ++ ++ if (is_gpio_ssio(gpio)) ++ return 0; ++ ++ if (is_gpio_bank3(port)) { ++ gpio_od = <q_gpio3_regs->od; ++ gpio_altsel0 = <q_gpio3_regs->altsel0; ++ gpio_altsel1 = <q_gpio3_regs->altsel1; ++ gpio_dir = <q_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 = <q_gpio_regs->ports[port].od; ++ const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0; ++ const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1; ++ const void *gpio_dir = <q_gpio_regs->ports[port].dir; ++ const void *gpio_out = <q_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(<q_ssio_regs->cpu0, data); ++ else ++ ltq_clrbits(<q_ssio_regs->cpu0, data); ++ ++ return 0; ++ } ++ ++ if (is_gpio_bank3(port)) { ++ gpio_od = <q_gpio3_regs->od; ++ gpio_altsel0 = <q_gpio3_regs->altsel0; ++ gpio_altsel1 = <q_gpio3_regs->altsel1; ++ gpio_dir = <q_gpio3_regs->dir; ++ gpio_out = <q_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 = <q_gpio_regs->ports[port].in; ++ u32 data = gpio_to_bit(gpio); ++ u32 val; ++ ++ if (is_gpio_ssio(gpio)) { ++ gpio_in = <q_ssio_regs->cpu0; ++ data = ssio_gpio_to_bit(gpio); ++ } ++ ++ if (is_gpio_bank3(port)) ++ gpio_in = <q_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 = <q_gpio_regs->ports[port].out; ++ u32 data = gpio_to_bit(gpio); ++ ++ if (is_gpio_ssio(gpio)) { ++ gpio_out = <q_ssio_regs->cpu0; ++ data = ssio_gpio_to_bit(gpio); ++ } ++ ++ if (is_gpio_bank3(port)) ++ gpio_out = <q_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 = <q_gpio_regs->ports[port].od; ++ const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0; ++ const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1; ++ const void *gpio_dir = <q_gpio_regs->ports[port].dir; ++ ++ if (is_gpio_ssio(gpio)) ++ return 0; ++ ++ if (is_gpio_bank3(port)) { ++ gpio_od = <q_gpio3_regs->od; ++ gpio_altsel0 = <q_gpio3_regs->altsel0; ++ gpio_altsel1 = <q_gpio3_regs->altsel1; ++ gpio_dir = <q_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 = <q_gpio_regs->ports[port].od; ++ ++ if (is_gpio_ssio(gpio)) ++ return 0; ++ ++ if (is_gpio_bank3(port)) ++ gpio_od = <q_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 +@@ -161,6 +161,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) +@@ -196,7 +208,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 +@@ -53,6 +53,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,126 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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(<q_nand_regs->wait) & NAND_WAIT_WR_C) == 0) ++ ; ++} ++ ++static int ltq_nand_dev_ready(struct mtd_info *mtd) ++{ ++ u32 data = ltq_readl(<q_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(<q_nand_regs->con, NAND_CON_NANDM); ++ ltq_setbits(<q_nand_regs->con, NAND_CON_LATCH_CS); ++ } else { ++ ltq_clrbits(<q_nand_regs->con, NAND_CON_LATCH_CS); ++ ltq_clrbits(<q_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(<q_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 +@@ -37,6 +37,8 @@ COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-i + COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o + COBJS-$(CONFIG_KS8851_MLL) += ks8851_mll.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,410 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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(<q_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(<q_ppe_etop_regs->mdio_acc, acc.val); ++ ++ ret = ltq_mdio_poll(); ++ if (ret) ++ return ret; ++ ++ acc.val = ltq_readl(<q_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(<q_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(<q_ppe_enet0_regs->mac_da0, da0); ++ ltq_writel(<q_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(<q_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(<q_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(<q_ppe_etop_regs->cfg, data); ++ ++ /* Set allowed packet length from 64 bytes to 1518 bytes */ ++ ltq_writel(<q_ppe_etop_regs->ig_plen_ctrl, (64 << 16) | 1518); ++ ++ /* Enable filter for unicast packets */ ++ ltq_setbits(<q_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,675 @@ ++/* ++ * Copyright (C) 2010-2011 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#define DEBUG ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 +@@ -20,6 +20,7 @@ COBJS-$(CONFIG_PHY_BROADCOM) += broadcom + COBJS-$(CONFIG_PHY_DAVICOM) += davicom.o + COBJS-$(CONFIG_PHY_ET1011C) += et1011c.o + COBJS-$(CONFIG_PHY_ICPLUS) += icplus.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,238 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#define DEBUG ++ ++#include ++#include ++ ++#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 +@@ -16,9 +16,10 @@ + #include + #include + #include +-#include + #include + ++DECLARE_GLOBAL_DATA_PTR; ++ + /* Generic PHY support and helper functions */ + + /** +@@ -440,6 +441,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 +@@ -455,6 +466,9 @@ int phy_init(void) + #ifdef CONFIG_PHY_ICPLUS + phy_icplus_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 +@@ -24,6 +24,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 +--- a/drivers/serial/serial.c ++++ b/drivers/serial/serial.c +@@ -160,6 +160,7 @@ serial_initfunc(sa1100_serial_initialize + serial_initfunc(sh_serial_initialize); + serial_initfunc(arm_dcc_initialize); + serial_initfunc(mxs_auart_initialize); ++serial_initfunc(ltq_serial_initialize); + + /** + * serial_register() - Register serial driver with serial driver core +@@ -253,6 +254,7 @@ void serial_initialize(void) + sh_serial_initialize(); + arm_dcc_initialize(); + mxs_auart_initialize(); ++ ltq_serial_initialize(); + + serial_assign(default_serial_console()->name); + } +--- /dev/null ++++ b/drivers/serial/serial_lantiq.c +@@ -0,0 +1,263 @@ ++/* ++ * Copyright (C) 2010 Thomas Langer ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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(<q_asc_regs->clc, 0x100); ++ ++ /* Reset MCON register */ ++ ltq_writel(<q_asc_regs->mcon, 0); ++ ++ /* Use Port A as receiver input */ ++ ltq_writel(<q_asc_regs->pisel, 0); ++ ++ /* Enable and flush RX/TX FIFOs */ ++ ltq_setbits(<q_asc_regs->rxfcon, ++ LTQ_ASC_RXFCON_RXFITL_RXFFLU | LTQ_ASC_RXFCON_RXFITL_RXFEN); ++ ltq_setbits(<q_asc_regs->txfcon, ++ LTQ_ASC_TXFCON_TXFITL_TXFFLU | LTQ_ASC_TXFCON_TXFITL_TXFEN); ++ ++ serial_setbrg(); ++ ++ /* Disable error flags, enable receiver */ ++ ltq_writel(<q_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(<q_asc_regs->mcon, LTQ_ASC_MCON_R); ++ ++ /* Enable fractional divider */ ++ ltq_setbits(<q_asc_regs->mcon, LTQ_ASC_MCON_FDE); ++ ++ /* Set fdv and bg values */ ++ ltq_writel(<q_asc_regs->fdv, fdv); ++ ltq_writel(<q_asc_regs->bg, bg); ++ ++ /* Enable baudrate generator */ ++ ltq_setbits(<q_asc_regs->mcon, LTQ_ASC_MCON_R); ++} ++ ++static unsigned int ltq_serial_tx_free(void) ++{ ++ unsigned int txfree; ++ ++ txfree = (ltq_readl(<q_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(<q_asc_regs->fstat) & LTQ_ASC_FSTAT_RXFFL_MASK; ++ ++ return rxffl; ++} ++ ++static void ltq_serial_tx(const char c) ++{ ++ ltq_writeb(<q_asc_regs->tbuf[LTQ_ASC_TBUF_OFFSET], c); ++} ++ ++static u8 ltq_serial_rx(void) ++{ ++ return ltq_readb(<q_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 = "ltq_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 ltq_serial_initialize(void) ++{ ++ serial_register(<q_serial_drv); ++} ++ ++__weak struct serial_device *default_serial_console(void) ++{ ++ return <q_serial_drv; ++} +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -25,6 +25,7 @@ COBJS-$(CONFIG_DAVINCI_SPI) += davinci_s + COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o + COBJS-$(CONFIG_ICH_SPI) += ich.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,666 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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_IDLE (1 << 23) ++#define LTQ_SPI_CON_RUEN (1 << 12) ++#define LTQ_SPI_CON_AEN (1 << 10) ++#define LTQ_SPI_CON_REN (1 << 9) ++#define LTQ_SPI_CON_TEN (1 << 8) ++#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_WHBSTATE_CLR_ERRORS 0x0F50 ++ ++#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 { ++ __be32 clc; /* Clock control */ ++ __be32 pisel; /* Port input select */ ++ __be32 id; /* Identification */ ++ __be32 rsvd0; ++ __be32 con; /* Control */ ++ __be32 stat; /* Status */ ++ __be32 whbstate; /* Write HW modified state */ ++ __be32 rsvd1; ++ __be32 tb; /* Transmit buffer */ ++ __be32 rb; /* Receive buffer */ ++ __be32 rsvd2[2]; ++ __be32 rxfcon; /* Recevie FIFO control */ ++ __be32 txfcon; /* Transmit FIFO control */ ++ __be32 fstat; /* FIFO status */ ++ __be32 rsvd3; ++ __be32 brt; /* Baudrate timer */ ++ __be32 brstat; /* Baudrate timer status */ ++ __be32 rsvd4[6]; ++ __be32 sfcon; /* Serial frame control */ ++ __be32 sfstat; /* Serial frame status */ ++ __be32 rsvd5[2]; ++ __be32 gpocon; /* General purpose output control */ ++ __be32 gpostat; /* General purpose output status */ ++ __be32 fgpo; /* Force general purpose output */ ++ __be32 rsvd6; ++ __be32 rxreq; /* Receive request */ ++ __be32 rxcnt; /* Receive count */ ++ __be32 rsvd7[25]; ++ __be32 dmacon; /* DMA control */ ++ __be32 rsvd8; ++ __be32 irnen; /* Interrupt node enable */ ++ __be32 irnicr; /* Interrupt node interrupt capture */ ++ __be32 irncr; /* Interrupt node control */ ++}; ++ ++struct ltq_spi_drv_data { ++ struct ltq_spi_regs __iomem *regs; ++ ++ struct spi_slave slave; ++ unsigned int max_hz; ++ unsigned int mode; ++ unsigned int tx_todo; ++ unsigned int rx_todo; ++ unsigned int rx_req; ++ unsigned int bits_per_word; ++ unsigned int speed_hz; ++ const u8 *tx; ++ u8 *rx; ++ int status; ++}; ++ ++static struct ltq_spi_drv_data *to_ltq_spi_slave(struct spi_slave *slave) ++{ ++ return container_of(slave, struct ltq_spi_drv_data, 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_drv_data ltq_spi_slave; ++ ++static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus, ++ unsigned int cs) ++{ ++ ltq_spi_slave.slave.bus = bus; ++ ltq_spi_slave.slave.cs = cs; ++ ++ return <q_spi_slave; ++} ++ ++static void ltq_spi_slave_free(struct spi_slave *slave) ++{ ++} ++#else ++static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus, ++ unsigned int cs) ++{ ++ return spi_alloc_slave(struct ltq_spi_drv_data, bus, cs); ++} ++ ++static void ltq_spi_slave_free(struct spi_slave *slave) ++{ ++ struct ltq_spi_drv_data *drv; ++ ++ if (slave) { ++ drv = to_ltq_spi_slave(slave); ++ free(drv); ++ } ++} ++#endif ++ ++static unsigned int tx_fifo_size(struct ltq_spi_drv_data *drv) ++{ ++ u32 id = ltq_readl(&drv->regs->id); ++ ++ return (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT; ++} ++ ++static unsigned int rx_fifo_size(struct ltq_spi_drv_data *drv) ++{ ++ u32 id = ltq_readl(&drv->regs->id); ++ ++ return (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT; ++} ++ ++static unsigned int tx_fifo_level(struct ltq_spi_drv_data *drv) ++{ ++ u32 fstat = ltq_readl(&drv->regs->fstat); ++ ++ return (fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >> LTQ_SPI_FSTAT_TXFFL_SHIFT; ++} ++ ++static unsigned int rx_fifo_level(struct ltq_spi_drv_data *drv) ++{ ++ u32 fstat = ltq_readl(&drv->regs->fstat); ++ ++ return fstat & LTQ_SPI_FSTAT_RXFFL_MASK; ++} ++ ++static unsigned int tx_fifo_free(struct ltq_spi_drv_data *drv) ++{ ++ return tx_fifo_size(drv) - tx_fifo_level(drv); ++} ++ ++static void hw_power_on(struct ltq_spi_drv_data *drv) ++{ ++ u32 clc; ++ ++ /* Power-up mdule */ ++ ltq_pm_enable(LTQ_PM_SPI); ++ ++ /* ++ * Set clock divider for run mode to 1 to ++ * run at same frequency as FPI bus ++ */ ++ clc = (1 << LTQ_SPI_CLC_RMC_SHIFT); ++ ltq_writel(&drv->regs->clc, clc); ++} ++ ++static void hw_reset_fifos(struct ltq_spi_drv_data *drv) ++{ ++ u32 val; ++ ++ val = LTQ_SPI_TXFCON_TXFEN | LTQ_SPI_TXFCON_TXFLU; ++ ltq_writel(&drv->regs->txfcon, val); ++ ++ val = LTQ_SPI_RXFCON_RXFEN | LTQ_SPI_RXFCON_RXFLU; ++ ltq_writel(&drv->regs->rxfcon, val); ++} ++ ++static int hw_is_busy(struct ltq_spi_drv_data *drv) ++{ ++ u32 stat = ltq_readl(&drv->regs->stat); ++ ++ return stat & LTQ_SPI_STAT_BSY; ++} ++ ++static void hw_enter_config_mode(struct ltq_spi_drv_data *drv) ++{ ++ ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_CLREN); ++} ++ ++static void hw_enter_active_mode(struct ltq_spi_drv_data *drv) ++{ ++ ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETEN); ++} ++ ++static void hw_setup_speed_hz(struct ltq_spi_drv_data *drv, ++ unsigned int max_speed_hz) ++{ ++ unsigned int spi_hz, speed_hz, brt; ++ ++ /* ++ * SPI module clock is derived from FPI bus clock dependent on ++ * divider value in CLC.RMS which is always set to 1. ++ * ++ * f_SPI ++ * baudrate = -------------- ++ * 2 * (BR + 1) ++ */ ++ spi_hz = ltq_get_bus_clock() / 2; ++ ++ /* TODO: optimize baudrate calculation */ ++ for (brt = 0; brt < 0xFFFF; brt++) { ++ speed_hz = spi_hz / (brt + 1); ++ if (speed_hz <= max_speed_hz) ++ break; ++ } ++ ++ ltq_writel(&drv->regs->brt, brt); ++} ++ ++static void hw_setup_bits_per_word(struct ltq_spi_drv_data *drv, ++ unsigned int bits_per_word) ++{ ++ u32 bm; ++ ++ /* CON.BM value = bits_per_word - 1 */ ++ bm = (bits_per_word - 1) << LTQ_SPI_CON_BM_SHIFT; ++ ++ ltq_clrsetbits(&drv->regs->con, LTQ_SPI_CON_BM_MASK, bm); ++} ++ ++static void hw_setup_clock_mode(struct ltq_spi_drv_data *drv, unsigned int mode) ++{ ++ u32 con_set = 0, con_clr = 0; ++ ++ /* ++ * SPI mode mapping in CON register: ++ * 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 (mode & SPI_CPHA) ++ con_clr |= LTQ_SPI_CON_PH; ++ else ++ con_set |= LTQ_SPI_CON_PH; ++ ++ if (mode & SPI_CPOL) ++ con_set |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE; ++ else ++ con_clr |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE; ++ ++ /* Set heading control */ ++ if (mode & SPI_LSB_FIRST) ++ con_clr |= LTQ_SPI_CON_HB; ++ else ++ con_set |= LTQ_SPI_CON_HB; ++ ++ /* Set loopback mode */ ++ if (mode & SPI_LOOP) ++ con_set |= LTQ_SPI_CON_LB; ++ else ++ con_clr |= LTQ_SPI_CON_LB; ++ ++ ltq_clrsetbits(&drv->regs->con, con_clr, con_set); ++} ++ ++static void hw_set_rxtx(struct ltq_spi_drv_data *drv) ++{ ++ u32 con; ++ ++ /* Configure transmitter and receiver */ ++ con = ltq_readl(&drv->regs->con); ++ if (drv->tx) ++ con &= ~LTQ_SPI_CON_TXOFF; ++ else ++ con |= LTQ_SPI_CON_TXOFF; ++ ++ if (drv->rx) ++ con &= ~LTQ_SPI_CON_RXOFF; ++ else ++ con |= LTQ_SPI_CON_RXOFF; ++ ++ ltq_writel(&drv->regs->con, con); ++} ++ ++static void hw_init(struct ltq_spi_drv_data *drv) ++{ ++ hw_power_on(drv); ++ ++ /* Put controller into config mode */ ++ hw_enter_config_mode(drv); ++ ++ /* Disable all interrupts */ ++ ltq_writel(&drv->regs->irnen, 0); ++ ++ /* Clear error flags */ ++ ltq_clrsetbits(&drv->regs->whbstate, 0, LTQ_SPI_WHBSTATE_CLR_ERRORS); ++ ++ /* Enable error checking, disable TX/RX */ ++ ltq_writel(&drv->regs->con, LTQ_SPI_CON_RUEN | LTQ_SPI_CON_AEN | ++ LTQ_SPI_CON_TEN | LTQ_SPI_CON_REN | LTQ_SPI_CON_TXOFF | ++ LTQ_SPI_CON_RXOFF); ++ ++ /* Setup default SPI mode */ ++ drv->bits_per_word = 8; ++ drv->speed_hz = 0; ++ hw_setup_bits_per_word(drv, drv->bits_per_word); ++ hw_setup_clock_mode(drv, SPI_MODE_0); ++ ++ /* Enable master mode and clear error flags */ ++ ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETMS | ++ LTQ_SPI_WHBSTATE_CLR_ERRORS); ++ ++ /* Reset GPIO/CS registers */ ++ ltq_writel(&drv->regs->gpocon, 0); ++ ltq_writel(&drv->regs->fgpo, 0xFF00); ++ ++ /* Enable and flush FIFOs */ ++ hw_reset_fifos(drv); ++ ++ /* 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 void tx_fifo_write(struct ltq_spi_drv_data *drv) ++{ ++ const u8 *tx8; ++ const u16 *tx16; ++ const u32 *tx32; ++ u32 data; ++ unsigned int tx_free = tx_fifo_free(drv); ++ ++ while (drv->tx_todo && tx_free) { ++ switch (drv->bits_per_word) { ++ case 8: ++ tx8 = drv->tx; ++ data = *tx8; ++ drv->tx_todo--; ++ drv->tx++; ++ break; ++ case 16: ++ tx16 = (u16 *) drv->tx; ++ data = *tx16; ++ drv->tx_todo -= 2; ++ drv->tx += 2; ++ break; ++ case 32: ++ tx32 = (u32 *) drv->tx; ++ data = *tx32; ++ drv->tx_todo -= 4; ++ drv->tx += 4; ++ break; ++ default: ++ return; ++ } ++ ++ ltq_writel(&drv->regs->tb, data); ++ tx_free--; ++ } ++} ++ ++static void rx_fifo_read_full_duplex(struct ltq_spi_drv_data *drv) ++{ ++ u8 *rx8; ++ u16 *rx16; ++ u32 *rx32; ++ u32 data; ++ unsigned int rx_fill = rx_fifo_level(drv); ++ ++ while (rx_fill) { ++ data = ltq_readl(&drv->regs->rb); ++ ++ switch (drv->bits_per_word) { ++ case 8: ++ rx8 = drv->rx; ++ *rx8 = data; ++ drv->rx_todo--; ++ drv->rx++; ++ break; ++ case 16: ++ rx16 = (u16 *) drv->rx; ++ *rx16 = data; ++ drv->rx_todo -= 2; ++ drv->rx += 2; ++ break; ++ case 32: ++ rx32 = (u32 *) drv->rx; ++ *rx32 = data; ++ drv->rx_todo -= 4; ++ drv->rx += 4; ++ break; ++ default: ++ return; ++ } ++ ++ rx_fill--; ++ } ++} ++ ++static void rx_fifo_read_half_duplex(struct ltq_spi_drv_data *drv) ++{ ++ u32 data, *rx32; ++ u8 *rx8; ++ unsigned int rxbv, shift; ++ unsigned int rx_fill = rx_fifo_level(drv); ++ ++ /* ++ * In RX-only mode the bits per word value is ignored by HW. A value ++ * of 32 is used instead. Thus all 4 bytes per FIFO must be read. ++ * If remaining RX bytes are less than 4, the FIFO must be read ++ * differently. The amount of received and valid bytes is indicated ++ * by STAT.RXBV register value. ++ */ ++ while (rx_fill) { ++ if (drv->rx_todo < 4) { ++ rxbv = (ltq_readl(&drv->regs->stat) & ++ LTQ_SPI_STAT_RXBV_MASK) >> ++ LTQ_SPI_STAT_RXBV_SHIFT; ++ data = ltq_readl(&drv->regs->rb); ++ ++ shift = (rxbv - 1) * 8; ++ rx8 = drv->rx; ++ ++ while (rxbv) { ++ *rx8++ = (data >> shift) & 0xFF; ++ rxbv--; ++ shift -= 8; ++ drv->rx_todo--; ++ drv->rx++; ++ ++ if (drv->rx_req) ++ drv->rx_req --; ++ } ++ } else { ++ data = ltq_readl(&drv->regs->rb); ++ rx32 = (u32 *) drv->rx; ++ ++ *rx32++ = data; ++ drv->rx_todo -= 4; ++ drv->rx += 4; ++ ++ if (drv->rx_req >= 4) ++ drv->rx_req -= 4; ++ } ++ rx_fill--; ++ } ++} ++ ++static void rx_request(struct ltq_spi_drv_data *drv) ++{ ++ unsigned int rxreq, rxreq_max; ++ ++ if (drv->rx_req) ++ return; ++ ++ /* ++ * 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 = drv->rx_todo; ++ rxreq_max = rx_fifo_size(drv) * 4; ++ if (rxreq > rxreq_max) ++ rxreq = rxreq_max; ++ ++ drv->rx_req = rxreq; ++ ltq_writel(&drv->regs->rxreq, rxreq); ++} ++ ++void spi_init(void) ++{ ++} ++ ++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, ++ unsigned int max_hz, unsigned int mode) ++{ ++ struct ltq_spi_drv_data *drv; ++ ++ if (!spi_cs_is_valid(bus, cs)) ++ return NULL; ++ ++ drv = ltq_spi_slave_alloc(bus, cs); ++ if (!drv) ++ return NULL; ++ ++ drv->regs = (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE); ++ ++ hw_init(drv); ++ ++ drv->max_hz = max_hz; ++ drv->mode = mode; ++ ++ return &drv->slave; ++} ++ ++void spi_free_slave(struct spi_slave *slave) ++{ ++ ltq_spi_slave_free(slave); ++} ++ ++static int ltq_spi_wait_ready(struct ltq_spi_drv_data *drv) ++{ ++ const unsigned long timeout = 20000; ++ unsigned long timebase; ++ ++ timebase = get_timer(0); ++ ++ do { ++ WATCHDOG_RESET(); ++ ++ if (!hw_is_busy(drv)) ++ return 0; ++ } while (get_timer(timebase) < timeout); ++ ++ return 1; ++} ++ ++int spi_claim_bus(struct spi_slave *slave) ++{ ++ struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave); ++ int ret; ++ ++ ret = ltq_spi_wait_ready(drv); ++ if (ret) { ++ debug("cannot claim bus\n"); ++ return ret; ++ } ++ ++ hw_enter_config_mode(drv); ++ hw_setup_clock_mode(drv, drv->mode); ++ hw_setup_speed_hz(drv, drv->max_hz); ++ hw_setup_bits_per_word(drv, drv->bits_per_word); ++ hw_enter_active_mode(drv); ++ ++ return 0; ++} ++ ++void spi_release_bus(struct spi_slave *slave) ++{ ++ struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave); ++ ++ hw_enter_config_mode(drv); ++} ++ ++int spi_xfer(struct spi_slave *slave, unsigned int bitlen, ++ const void *dout, void *din, unsigned long flags) ++{ ++ ++ struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave); ++ int ret = 0; ++ ++ if (bitlen % 8) ++ return 1; ++ ++ if (!bitlen) { ++ ret = 0; ++ goto done; ++ } ++ ++ if (flags & SPI_XFER_BEGIN) ++ spi_cs_activate(slave); ++ ++ drv->tx = dout; ++ drv->tx_todo = 0; ++ drv->rx = din; ++ drv->rx_todo = 0; ++ hw_set_rxtx(drv); ++ ++ if (drv->tx) { ++ drv->tx_todo = bitlen / 8; ++ ++ tx_fifo_write(drv); ++ } ++ ++ if (drv->rx) { ++ drv->rx_todo = bitlen / 8; ++ ++ if (!drv->tx) ++ rx_request(drv); ++ } ++ ++ for (;;) { ++ if (drv->tx) { ++ if (drv->rx && drv->rx_todo) ++ rx_fifo_read_full_duplex(drv); ++ ++ if (drv->tx_todo) ++ tx_fifo_write(drv); ++ else ++ goto done; ++ } else if (drv->rx) { ++ if (drv->rx_todo) { ++ rx_fifo_read_half_duplex(drv); ++ ++ if (drv->rx_todo) ++ rx_request(drv); ++ else ++ goto done; ++ } else { ++ goto done; ++ } ++ } ++ } ++ ++done: ++ ret = ltq_spi_wait_ready(drv); ++ ++ drv->rx = NULL; ++ drv->tx = NULL; ++ hw_set_rxtx(drv); ++ ++ if (flags & SPI_XFER_END) ++ spi_cs_deactivate(slave); ++ ++ return ret; ++} +--- /dev/null ++++ b/include/configs/easy50712.h +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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_NAND_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 ++#include ++ ++#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,92 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 ++#include ++ ++#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 +@@ -214,6 +214,7 @@ int phy_atheros_init(void); + int phy_broadcom_init(void); + int phy_davicom_init(void); + int phy_et1011c_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 +@@ -100,6 +100,8 @@ LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += dri + LIBS-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/libusb_musb-new.o + LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/libusb_gadget.o + LIBS-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/libwatchdog.o ++LIBS-$(CONFIG_SPL_LZMA_SUPPORT) += lib/lzma/liblzma.o ++LIBS-$(CONFIG_SPL_LZO_SUPPORT) += lib/lzo/liblzo.o + + ifneq ($(CONFIG_OMAP_COMMON),) + 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 +@@ -49,6 +49,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) +@@ -95,6 +96,7 @@ OBJ_FILES-$(CONFIG_MX28) += mxsboot.o + OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o + OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o + OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o ++OBJ_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image.o + OBJ_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo.o + OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o + +@@ -195,6 +197,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,315 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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_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/0015-MIPS-lantiq-add-support-for-Lantiq-XWAY-ARX100-SoC-f.patch b/package/boot/uboot-lantiq/patches/0015-MIPS-lantiq-add-support-for-Lantiq-XWAY-ARX100-SoC-f.patch new file mode 100644 index 0000000..acda83c --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0015-MIPS-lantiq-add-support-for-Lantiq-XWAY-ARX100-SoC-f.patch @@ -0,0 +1,1228 @@ +From 4953294aa8f8b9023e6b5f7f39059706c72d916c Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sun, 9 Dec 2012 17:54:56 +0100 +Subject: MIPS: lantiq: add support for Lantiq XWAY ARX100 SoC family + +Signed-off-by: Luka Perkov +Signed-off-by: John Crispin +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/arch/mips/cpu/mips32/arx100/Makefile +@@ -0,0 +1,31 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/arx100/cgu.c +@@ -0,0 +1,109 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#define CGU_SYS_DDR_SEL (1 << 0) ++#define CGU_SYS_CPU_SEL (1 << 2) ++#define CGU_SYS_SYS_SHIFT 3 ++#define CGU_SYS_SYS_MASK (0x3 << CGU_SYS_SYS_SHIFT) ++#define CGU_SYS_FPI_SEL (1 << 6) ++#define CGU_SYS_PPE_SEL (1 << 7) ++ ++struct ltq_cgu_regs { ++ u32 rsvd0; ++ __be32 pll0_cfg; /* PLL0 config */ ++ __be32 pll1_cfg; /* PLL1 config */ ++ u32 rsvd2; ++ __be32 sys; /* System clock */ ++ __be32 update; /* CGU update control */ ++ __be32 if_clk; /* Interface clock */ ++ u32 rsvd3; ++ __be32 smd; /* SDRAM Memory Control */ ++ u32 rsvd4; ++ __be32 ct1_sr; /* CT status 1 */ ++ __be32 ct_kval; /* CT K value */ ++ __be32 pcm_cr; /* PCM 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(<q_cgu_regs->sys) & mask) >> shift; ++} ++ ++static unsigned long ltq_get_system_clock(void) ++{ ++ u32 sys_sel; ++ unsigned long clk; ++ ++ sys_sel = ltq_cgu_sys_readl(CGU_SYS_SYS_MASK, CGU_SYS_SYS_SHIFT); ++ ++ switch (sys_sel) { ++ case 0: ++ clk = CLOCK_333_MHZ; ++ break; ++ case 2: ++ clk = CLOCK_393_MHZ; ++ break; ++ default: ++ clk = 0; ++ break; ++ } ++ ++ return clk; ++} ++ ++unsigned long ltq_get_io_region_clock(void) ++{ ++ u32 ddr_sel; ++ unsigned long clk; ++ ++ ddr_sel = ltq_cgu_sys_readl(1, CGU_SYS_DDR_SEL); ++ ++ if (ddr_sel) ++ clk = ltq_get_system_clock() / 3; ++ else ++ clk = ltq_get_system_clock() / 2; ++ ++ return clk; ++} ++ ++unsigned long ltq_get_cpu_clock(void) ++{ ++ u32 cpu_sel; ++ unsigned long clk; ++ ++ cpu_sel = ltq_cgu_sys_readl(1, CGU_SYS_CPU_SEL); ++ ++ if (cpu_sel) ++ clk = ltq_get_io_region_clock(); ++ else ++ clk = ltq_get_system_clock(); ++ ++ return clk; ++} ++ ++unsigned long ltq_get_bus_clock(void) ++{ ++ u32 fpi_sel; ++ unsigned long clk; ++ ++ fpi_sel = ltq_cgu_sys_readl(1, CGU_SYS_FPI_SEL); ++ ++ if (fpi_sel) ++ clk = ltq_get_io_region_clock() / 2; ++ else ++ clk = ltq_get_io_region_clock(); ++ ++ return clk; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/arx100/cgu_init.S +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* CGU module register */ ++#define CGU_PLL0_CFG 0x0004 /* PLL0 config */ ++#define CGU_PLL1_CFG 0x0008 /* PLL1 config */ ++#define CGU_SYS 0x0010 /* System clock */ ++#define CGU_UPDATE 0x0014 /* Clock update control */ ++ ++/* Valid SYS.PPE_SEL values */ ++#define CGU_SYS_PPESEL_SHIFT 7 ++#define CGU_SYS_PPESEL_250_MHZ (0x1 << CGU_SYS_PPESEL_SHIFT) ++ ++/* Valid SYS.SYS_SEL values */ ++#define CGU_SYS_SYSSEL_SHIFT 3 ++#define CGU_SYS_SYSSEL_PLL0_333_MHZ (0x0 << CGU_SYS_SYSSEL_SHIFT) ++#define CGU_SYS_SYSSEL_PLL1_393_MHZ (0x2 << CGU_SYS_SYSSEL_SHIFT) ++ ++/* Valid SYS.CPU_SEL values */ ++#define CGU_SYS_CPUSEL_SHIFT 2 ++#define CGU_SYS_CPUSEL_EQUAL_SYSCLK (0x0 << CGU_SYS_CPUSEL_SHIFT) ++#define CGU_SYS_CPUSEL_EQUAL_DDRCLK (0x1 << CGU_SYS_CPUSEL_SHIFT) ++ ++/* Valid SYS.DDR_SEL values */ ++#define CGU_SYS_DDRSEL_HALF_SYSCLK 0x0 ++#define CGU_SYS_DDRSEL_THIRD_SYSCLK 0x1 ++ ++#define CGU_UPDATE_UPD 0x1 ++ ++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_393_DDR_197) ++#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ ++#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL1_393_MHZ ++#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_SYSCLK ++#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_HALF_SYSCLK ++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_197_DDR_197) ++#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ ++#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL1_393_MHZ ++#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_DDRCLK ++#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_HALF_SYSCLK ++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167) ++#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ ++#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL0_333_MHZ ++#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_SYSCLK ++#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_HALF_SYSCLK ++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_167_DDR_167) ++#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ ++#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL0_333_MHZ ++#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_DDRCLK ++#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_HALF_SYSCLK ++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_131_DDR_131) ++#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ ++#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL1_393_MHZ ++#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_DDRCLK ++#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_THIRD_SYSCLK ++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111) ++#define CGU_SYS_PPESEL_CONFIG CGU_SYS_PPESEL_250_MHZ ++#define CGU_SYS_SYSSEL_CONFIG CGU_SYS_SYSSEL_PLL0_333_MHZ ++#define CGU_SYS_CPUSEL_CONFIG CGU_SYS_CPUSEL_EQUAL_DDRCLK ++#define CGU_SYS_DDRSEL_CONFIG CGU_SYS_DDRSEL_THIRD_SYSCLK ++#else ++#error "Invalid system clock configuration!" ++#endif ++ ++/* Build register values */ ++#define CGU_SYS_VALUE (CGU_SYS_PPESEL_CONFIG | \ ++ CGU_SYS_SYSSEL_CONFIG | \ ++ CGU_SYS_CPUSEL_CONFIG | \ ++ CGU_SYS_DDRSEL_CONFIG) ++ ++ .set noreorder ++ ++LEAF(ltq_cgu_init) ++ /* Load current CGU register value */ ++ li t0, (LTQ_CGU_BASE | KSEG1) ++ lw t1, CGU_SYS(t0) ++ ++ /* Load target CGU register values */ ++ li t2, CGU_SYS_VALUE ++ ++ /* Only update registers if values differ */ ++ beq t1, t2, finished ++ nop ++ ++ /* Store target register values */ ++ sw t2, CGU_SYS(t0) ++ ++ /* Trigger CGU update */ ++ li t1, CGU_UPDATE_UPD ++ sw t1, CGU_UPDATE(t0) ++ ++finished: ++ jr ra ++ nop ++ ++ END(ltq_cgu_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/arx100/chipid.c +@@ -0,0 +1,60 @@ ++/* ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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(<q_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(<q_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_ARX188: ++ return "ARX188"; ++ case LTQ_SOC_ARX186: ++ case LTQ_SOC_ARX186_2: ++ return "ARX186"; ++ case LTQ_SOC_ARX182: ++ return "ARX182"; ++ default: ++ printf("Unknown partnum: %x\n", partnum); ++ } ++ ++ return ""; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/arx100/config.mk +@@ -0,0 +1,30 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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 ++PF_PIE := ++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 +--- /dev/null ++++ b/arch/mips/cpu/mips32/arx100/ebu.c +@@ -0,0 +1,111 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++ ++#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(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE | ++ EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE | ++ EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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/arx100/mem.c +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++ ++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/arx100/mem_init.S +@@ -0,0 +1,114 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Must be configured in BOARDDIR */ ++#include ++ ++#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 0xD ++#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/arx100/pmu.c +@@ -0,0 +1,120 @@ ++/* ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#define LTQ_PMU_PWDCR_RESERVED 0xE00C200C ++ ++#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_DDR_MEM (1 << 24) ++#define LTQ_PMU_PWDCR_PPE_DP (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_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_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_PCI (1 << 4) ++#define LTQ_PMU_PWDCR_FPI1 (1 << 1) ++#define LTQ_PMU_PWDCR_USB0_PHY (1 << 0) ++ ++struct ltq_pmu_regs { ++ u32 rsvd0[7]; ++ __be32 pwdcr; ++ __be32 sr; ++}; ++ ++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_DDR_MEM | 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_SWITCH | LTQ_PMU_PWDCR_PPE_DP | ++ LTQ_PMU_PWDCR_PPE_EMA | LTQ_PMU_PWDCR_PPE_TC; ++ 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(<q_pmu_regs->pwdcr, val); ++ ++ timebase = get_timer(0); ++ ++ do { ++ sr = ltq_readl(<q_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(<q_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(<q_pmu_regs->pwdcr, clr, set); ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/arx100/rcu.c +@@ -0,0 +1,130 @@ ++/* ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */ ++#define LTQ_RCU_RD_USB1 (1 << 28) /* USB1 MAC and PHY */ ++#define LTQ_RCU_RD_REG25_PD (1 << 26) /* Power down 2.5V regulator */ ++#define LTQ_RCU_RD_PPE_ATM_TC (1 << 22) /* PPE ATM TC */ ++#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_MC (1 << 14) /* Memory Controller */ ++#define LTQ_RCU_RD_PCI (1 << 13) /* PCI 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_ARC_DFE (1 << 7) /* ARC/DFE core */ ++#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */ ++#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */ ++#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 17 ++#define LTQ_RCU_STAT_BOOT_MASK (0xf << LTQ_RCU_STAT_BOOT_SHIFT) ++ ++struct ltq_rcu_regs { ++ u32 rsvd0[4]; ++ __be32 req; /* Reset request */ ++ __be32 stat; /* Reset status */ ++ __be32 usb0_cfg; /* USB0 config */ ++ u32 rsvd1[2]; ++ __be32 pci_rdy; /* PCI boot ready */ ++ __be32 ppe_conf; /* PPE config */ ++ u32 rsvd2; ++ __be32 usb1_cfg; /* USB1 config */ ++}; ++ ++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_CPU0; ++ 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_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(<q_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(<q_rcu_regs->req, val); ++ ++ return 0; ++} ++ ++enum ltq_boot_select ltq_boot_select(void) ++{ ++ u32 stat; ++ unsigned int bootstrap; ++ ++ stat = ltq_readl(<q_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_RGMII0; ++ case 2: ++ return BOOT_NOR; ++ case 3: ++ return BOOT_MII0; ++ case 5: ++ return BOOT_RMII0; ++ case 6: ++ return BOOT_PCI; ++ case 8: ++ return BOOT_UART; ++ case 10: ++ return BOOT_SPI; ++ default: ++ return BOOT_UNKNOWN; ++ } ++} +--- a/arch/mips/cpu/mips32/lantiq-common/cpu.c ++++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c +@@ -20,6 +20,7 @@ static const char ltq_bootsel_strings[][ + "PCI", + "MII0", + "RMII0", ++ "RGMII0", + "RGMII1", + "unknown", + }; +--- a/arch/mips/cpu/mips32/lantiq-common/start.S ++++ b/arch/mips/cpu/mips32/lantiq-common/start.S +@@ -64,6 +64,11 @@ + #define STATUS_LANTIQ (STATUS_MIPS24K | STATUS_MIPS32_64) + #endif + ++#ifdef CONFIG_SOC_XWAY_ARX100 ++#define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64) ++#define STATUS_LANTIQ (STATUS_MIPS34K | 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) +--- /dev/null ++++ b/arch/mips/include/asm/arch-arx100/config.h +@@ -0,0 +1,175 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * ++ * Common board configuration for Lantiq XWAY ARX100 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 __ARX100_CONFIG_H__ ++#define __ARX100_CONFIG_H__ ++ ++/* CPU and SoC type */ ++#define CONFIG_SOC_LANTIQ ++#define CONFIG_SOC_XWAY_ARX100 ++ ++/* Cache configuration */ ++#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT ++#define CONFIG_SYS_DCACHE_SIZE (16 * 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: rational PLL running at 500 MHz ++ * PLL1: fractional PLL running at 393.219 MHz ++ */ ++#define LTQ_CLK_CPU_393_DDR_197 0 ++#define LTQ_CLK_CPU_197_DDR_197 1 ++#define LTQ_CLK_CPU_333_DDR_167 2 ++#define LTQ_CLK_CPU_167_DDR_167 3 ++#define LTQ_CLK_CPU_131_DDR_131 4 ++#define LTQ_CLK_CPU_111_DDR_111 5 ++ ++/* 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_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 0xBE1A0000 ++#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_ARX100_SWITCH ++ ++#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) || defined(CONFIG_SYS_BOOT_NANDSPL) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SPL_TEXT_BASE 0xBE1A0000 ++#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 /* __ARX100_CONFIG_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-arx100/gpio.h +@@ -0,0 +1,12 @@ ++/* ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __ARX100_GPIO_H__ ++#define __ARX100_GPIO_H__ ++ ++#include ++ ++#endif /* __ARX100_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-arx100/nand.h +@@ -0,0 +1,13 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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-arx100/soc.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __ARX100_SOC_H__ ++#define __ARX100_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_PPE_BASE 0x1E180000 ++#define LTQ_SWITCH_BASE 0x1E108000 ++ ++#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 /* __ARX100_SOC_H__ */ +--- a/arch/mips/include/asm/lantiq/chipid.h ++++ b/arch/mips/include/asm/lantiq/chipid.h +@@ -15,6 +15,10 @@ enum ltq_chip_partnum { + LTQ_SOC_DANUBE = 0x0129, + LTQ_SOC_DANUBE_S = 0x012B, + LTQ_SOC_TWINPASS = 0x012D, ++ LTQ_SOC_ARX188 = 0x016C, /* ARX188 */ ++ LTQ_SOC_ARX186 = 0x016D, /* ARX186 v1.1 */ ++ LTQ_SOC_ARX186_2 = 0x016E, /* ARX186 v1.2 */ ++ LTQ_SOC_ARX182 = 0x016F, /* ARX182 */ + LTQ_SOC_VRX288 = 0x01C0, /* VRX288 v1.1 */ + LTQ_SOC_VRX268 = 0x01C2, /* VRX268 v1.1 */ + LTQ_SOC_GRX288 = 0x01C9, /* GRX288 v1.1 */ +@@ -36,6 +40,38 @@ static inline int ltq_soc_is_danube(void + { + return 0; + } ++#endif ++ ++#ifdef CONFIG_SOC_XWAY_ARX100 ++static inline int ltq_soc_is_arx100(void) ++{ ++ return 1; ++} ++ ++static inline int ltq_soc_is_arx100_v1(void) ++{ ++ return ltq_chip_version_get() == 1; ++} ++ ++static inline int ltq_soc_is_arx100_v2(void) ++{ ++ return ltq_chip_version_get() == 2; ++} ++#else ++static inline int ltq_soc_is_arx100(void) ++{ ++ return 0; ++} ++ ++static inline int ltq_soc_is_arx100_v1(void) ++{ ++ return 0; ++} ++ ++static inline int ltq_soc_is_arx100_v2(void) ++{ ++ return 0; ++} + #endif + + #ifdef CONFIG_SOC_XWAY_VRX200 +--- a/arch/mips/include/asm/lantiq/clk.h ++++ b/arch/mips/include/asm/lantiq/clk.h +@@ -13,9 +13,10 @@ enum ltq_clk { + CLOCK_83_MHZ = 83333333, + CLOCK_111_MHZ = 111111111, + CLOCK_125_MHZ = 125000000, ++ CLOCK_131_MHZ = 131073000, + CLOCK_133_MHZ = 133333333, + CLOCK_166_MHZ = 166666667, +- CLOCK_197_MHZ = 197000000, ++ CLOCK_197_MHZ = 196609500, + CLOCK_333_MHZ = 333333333, + CLOCK_393_MHZ = 393219000, + CLOCK_500_MHZ = 500000000, +--- a/arch/mips/include/asm/lantiq/cpu.h ++++ b/arch/mips/include/asm/lantiq/cpu.h +@@ -17,6 +17,7 @@ enum ltq_boot_select { + BOOT_PCI, + BOOT_MII0, + BOOT_RMII0, ++ BOOT_RGMII0, + BOOT_RGMII1, + BOOT_UNKNOWN, + }; diff --git a/package/boot/uboot-lantiq/patches/0016-net-add-driver-for-Lantiq-XWAY-ARX100-switch.patch b/package/boot/uboot-lantiq/patches/0016-net-add-driver-for-Lantiq-XWAY-ARX100-switch.patch new file mode 100644 index 0000000..16e16d0 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0016-net-add-driver-for-Lantiq-XWAY-ARX100-switch.patch @@ -0,0 +1,546 @@ +From 7288414298b34dcda1216fee1fe38d05ea0027a2 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Mon, 17 Dec 2012 23:32:39 +0100 +Subject: net: add driver for Lantiq XWAY ARX100 switch + +Signed-off-by: Daniel Schwierzeck + +--- a/arch/mips/include/asm/arch-arx100/config.h ++++ b/arch/mips/include/asm/arch-arx100/config.h +@@ -10,17 +10,21 @@ + * and drivers for this SoC: + * + * CONFIG_LTQ_SUPPORT_UART +- * - support the Danube ASC/UART interface and console ++ * - support the ARX100 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 ++ * - support the ARX100 ETOP and MAC interface + * + * CONFIG_LTQ_SUPPORT_SPI_FLASH +- * - support the Danube SPI interface and serial flash drivers ++ * - support the ARX100 SPI interface and serial flash drivers + * - specific SPI flash drivers must be configured separately ++ * ++ * 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 __ARX100_CONFIG_H__ +--- /dev/null ++++ b/arch/mips/include/asm/arch-arx100/switch.h +@@ -0,0 +1,86 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __ARX100_SWITCH_H__ ++#define __ARX100_SWITCH_H__ ++ ++struct ar9_switch_regs { ++ __be32 ps; /* Port status*/ ++ __be32 p0_ctl; /* Port 0 control */ ++ __be32 p1_ctl; /* Port 1 control */ ++ __be32 p2_ctl; /* Port 2 control */ ++ __be32 p0_vlan; /* Port 0 VLAN control */ ++ __be32 p1_vlan; /* Port 1 VLAN control */ ++ __be32 p2_vlan; /* Port 2 VLAN control */ ++ __be32 p0_inctl; /* Port 0 ingress control */ ++ __be32 p1_inctl; /* Port 1 ingress control */ ++ __be32 p2_inctl; /* Port 2 ingress control */ ++ u32 rsvd0[16]; ++ __be32 sw_gctl0; /* Switch global control 0 */ ++ __be32 sw_gctl1; /* Switch global control 1 */ ++ __be32 arp; /* ARP/RARP */ ++ __be32 strm_ctl; /* Storm control */ ++ __be32 rgmii_ctl; /* RGMII/GMII port control */ ++ u32 rsvd1[4]; ++ __be32 pmac_hd_ctl; /* PMAC header control */ ++ u32 rsvd2[15]; ++ __be32 mdio_ctrl; /* MDIO indirect access control */ ++ __be32 mdio_data; /* MDIO indirect read data */ ++}; ++ ++#define BUILD_CHECK_AR9_REG(name, offset) \ ++ BUILD_BUG_ON(offsetof(struct ar9_switch_regs, name) != (offset)) ++ ++static inline void build_check_ar9_registers(void) ++{ ++ BUILD_CHECK_AR9_REG(sw_gctl0, 0x68); ++ BUILD_CHECK_AR9_REG(rgmii_ctl, 0x78); ++ BUILD_CHECK_AR9_REG(pmac_hd_ctl, 0x8c); ++ BUILD_CHECK_AR9_REG(mdio_ctrl, 0xcc); ++ BUILD_CHECK_AR9_REG(mdio_data, 0xd0); ++} ++ ++#define P0_CTL_FLP (1 << 18) ++#define P0_CTL_FLD (1 << 17) ++ ++#define SW_GCTL0_SE (1 << 31) ++ ++#define RGMII_CTL_P1_SHIFT 10 ++#define RGMII_CTL_P1_MASK (0x3FF << RGMII_CTL_P1_SHIFT) ++#define RGMII_CTL_P0_MASK 0x3FF ++#define RGMII_CTL_P0IS_SHIFT 8 ++#define RGMII_CTL_P0IS_RGMII (0x0 << RGMII_CTL_P0IS_SHIFT) ++#define RGMII_CTL_P0IS_MII (0x1 << RGMII_CTL_P0IS_SHIFT) ++#define RGMII_CTL_P0IS_REVMII (0x2 << RGMII_CTL_P0IS_SHIFT) ++#define RGMII_CTL_P0IS_RMII (0x3 << RGMII_CTL_P0IS_SHIFT) ++#define RGMII_CTL_P0RDLY_SHIFT 6 ++#define RGMII_CTL_P0RDLY_0_0 (0x0 << RGMII_CTL_P0RDLY_SHIFT) ++#define RGMII_CTL_P0RDLY_1_5 (0x1 << RGMII_CTL_P0RDLY_SHIFT) ++#define RGMII_CTL_P0RDLY_1_75 (0x2 << RGMII_CTL_P0RDLY_SHIFT) ++#define RGMII_CTL_P0RDLY_2_0 (0x3 << RGMII_CTL_P0RDLY_SHIFT) ++#define RGMII_CTL_P0TDLY_SHIFT 4 ++#define RGMII_CTL_P0TDLY_0_0 (0x0 << RGMII_CTL_P0TDLY_SHIFT) ++#define RGMII_CTL_P0TDLY_1_5 (0x1 << RGMII_CTL_P0TDLY_SHIFT) ++#define RGMII_CTL_P0TDLY_1_75 (0x2 << RGMII_CTL_P0TDLY_SHIFT) ++#define RGMII_CTL_P0TDLY_2_0 (0x3 << RGMII_CTL_P0TDLY_SHIFT) ++#define RGMII_CTL_P0SPD_SHIFT 2 ++#define RGMII_CTL_P0SPD_10 (0x0 << RGMII_CTL_P0SPD_SHIFT) ++#define RGMII_CTL_P0SPD_100 (0x1 << RGMII_CTL_P0SPD_SHIFT) ++#define RGMII_CTL_P0SPD_1000 (0x2 << RGMII_CTL_P0SPD_SHIFT) ++#define RGMII_CTL_P0DUP_FULL (1 << 1) ++#define RGMII_CTL_P0FCE_EN (1 << 0) ++ ++#define PMAC_HD_CTL_AC (1 << 18) ++ ++#define MDIO_CTRL_WD_SHIFT 16 ++#define MDIO_CTRL_MBUSY (1 << 15) ++#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 /* __ARX100_SWITCH_H__ */ +--- a/drivers/net/Makefile ++++ b/drivers/net/Makefile +@@ -38,6 +38,7 @@ COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks86 + COBJS-$(CONFIG_KS8851_MLL) += ks8851_mll.o + COBJS-$(CONFIG_LAN91C96) += lan91c96.o + COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o ++COBJS-$(CONFIG_LANTIQ_ARX100_SWITCH) += lantiq_arx100_switch.o + COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o + COBJS-$(CONFIG_MACB) += macb.o + COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o +--- /dev/null ++++ b/drivers/net/lantiq_arx100_switch.c +@@ -0,0 +1,410 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#define DEBUG ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 2 ++#define LTQ_ETHSW_PMAC 2 ++ ++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 ar9_switch_regs *switch_regs = ++ (struct ar9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE); ++ ++static int ltq_mdio_is_busy(void) ++{ ++ u32 mdio_ctrl = ltq_readl(&switch_regs->mdio_ctrl); ++ ++ return mdio_ctrl & MDIO_CTRL_MBUSY; ++} ++ ++static void ltq_mdio_poll(void) ++{ ++ while (ltq_mdio_is_busy()) ++ cpu_relax(); ++ ++ __udelay(1000); ++} ++ ++static int ltq_mdio_read(struct mii_dev *bus, int phyad, int devad, ++ int regad) ++{ ++ u32 mdio_ctrl; ++ int retval; ++ ++ mdio_ctrl = MDIO_CTRL_MBUSY | MDIO_CTRL_OP_READ | ++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) | ++ (regad & MDIO_CTRL_REGAD_MASK); ++ ++ ltq_mdio_poll(); ++ ltq_writel(&switch_regs->mdio_ctrl, mdio_ctrl); ++ ltq_mdio_poll(); ++ retval = ltq_readl(&switch_regs->mdio_data); ++ ltq_writel(&switch_regs->mdio_data, 0xFFFF); ++ ++ debug("%s: phyad %02x, regad %02x, val %02x\n", __func__, phyad, regad, retval); ++ ++ return retval; ++} ++ ++static int ltq_mdio_write(struct mii_dev *bus, int phyad, int devad, ++ int regad, u16 val) ++{ ++ u32 mdio_ctrl; ++ ++ debug("%s: phyad %02x, regad %02x, val %02x\n", __func__, phyad, regad, val); ++ ++ mdio_ctrl = (val << MDIO_CTRL_WD_SHIFT) | MDIO_CTRL_MBUSY | ++ MDIO_CTRL_OP_WRITE | ++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) | ++ (regad & MDIO_CTRL_REGAD_MASK); ++ ++ ltq_mdio_poll(); ++ ltq_writel(&switch_regs->mdio_ctrl, mdio_ctrl); ++ ++ return 0; ++} ++ ++static void ltq_eth_gmac_update(struct phy_device *phydev, int num) ++{ ++} ++ ++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; ++ int err; ++ ++ 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_pmac_init(void) ++{ ++ /* Add CRC to packets from DMA to PMAC */ ++ ltq_setbits(&switch_regs->pmac_hd_ctl, PMAC_HD_CTL_AC); ++ ++ /* Force link up */ ++ ltq_setbits(&switch_regs->p2_ctl, P0_CTL_FLP); ++} ++ ++static void ltq_eth_hw_init(const struct ltq_eth_port_config *port) ++{ ++ /* Power up ethernet subsystems */ ++ ltq_pm_enable(LTQ_PM_ETH); ++ ++ /* Enable switch core */ ++ ltq_setbits(&switch_regs->sw_gctl0, SW_GCTL0_SE); ++ ++ /* 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); ++ ++ ltq_eth_pmac_init(); ++} ++ ++static void ltq_eth_port_config(struct ltq_eth_priv *priv, ++ const struct ltq_eth_port_config *port) ++{ ++ struct phy_device *phydev; ++ struct switch_device *sw; ++ u32 rgmii_ctl; ++ unsigned int port_ctl, port_xmii = 0; ++ ++ if (port->num > 1) ++ return; ++ ++ rgmii_ctl = ltq_readl(&switch_regs->rgmii_ctl); ++ ++ if (port->num == 1) ++ port_ctl = ltq_readl(&switch_regs->p1_ctl); ++ else ++ port_ctl = ltq_readl(&switch_regs->p0_ctl); ++ ++ switch (port->phy_if) { ++ case PHY_INTERFACE_MODE_RGMII: ++ port_xmii = RGMII_CTL_P0IS_RGMII; ++ ++ switch (port->rgmii_tx_delay) { ++ case 1: ++ port_xmii |= RGMII_CTL_P0TDLY_1_5; ++ break; ++ case 2: ++ port_xmii |= RGMII_CTL_P0TDLY_1_75; ++ break; ++ case 3: ++ port_xmii |= RGMII_CTL_P0TDLY_2_0; ++ break; ++ default: ++ break; ++ } ++ ++ switch (port->rgmii_rx_delay) { ++ case 1: ++ port_xmii |= RGMII_CTL_P0RDLY_1_5; ++ break; ++ case 2: ++ port_xmii |= RGMII_CTL_P0RDLY_1_75; ++ break; ++ case 3: ++ port_xmii |= RGMII_CTL_P0RDLY_2_0; ++ break; ++ default: ++ break; ++ } ++ ++ if (!(port->flags & LTQ_ETH_PORT_PHY)) { ++ port_xmii |= (RGMII_CTL_P0SPD_1000 | ++ RGMII_CTL_P0DUP_FULL); ++ port_ctl |= P0_CTL_FLP; ++ } ++ ++ break; ++ case PHY_INTERFACE_MODE_MII: ++ port_xmii = RGMII_CTL_P0IS_MII; ++ ++ if (!(port->flags & LTQ_ETH_PORT_PHY)) { ++ port_xmii |= (RGMII_CTL_P0SPD_100 | ++ RGMII_CTL_P0DUP_FULL); ++ port_ctl |= P0_CTL_FLP; ++ } ++ ++ break; ++ default: ++ break; ++ } ++ ++ if (port->num == 1) { ++ ltq_writel(&switch_regs->p1_ctl, port_ctl); ++ ++ rgmii_ctl &= ~RGMII_CTL_P1_MASK; ++ rgmii_ctl |= (port_xmii << RGMII_CTL_P1_SHIFT); ++ } else { ++ ltq_writel(&switch_regs->p0_ctl, port_ctl); ++ ++ rgmii_ctl &= ~RGMII_CTL_P0_MASK; ++ rgmii_ctl |= port_xmii; ++ } ++ ++ ltq_writel(&switch_regs->rgmii_ctl, rgmii_ctl); ++ ++ /* Connect to external switch */ ++ if (port->flags & LTQ_ETH_PORT_SWITCH) { ++ sw = switch_connect(priv->bus); ++ if (sw) ++ switch_setup(sw); ++ } ++ ++ /* 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; ++ const struct ltq_eth_port_config *port = &board_config->ports[0]; ++ int i, ret; ++ ++ build_check_ar9_registers(); ++ ++ 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 = 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 ret; ++ ++ ret = mdio_register(bus); ++ if (ret) ++ return ret; ++ ++ ret = eth_register(dev); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < board_config->num_ports; i++) ++ ltq_eth_port_config(priv, &board_config->ports[i]); ++ ++ return 0; ++} diff --git a/package/boot/uboot-lantiq/patches/0017-tools-add-some-helper-tools-for-Lantiq-SoCs.patch b/package/boot/uboot-lantiq/patches/0017-tools-add-some-helper-tools-for-Lantiq-SoCs.patch new file mode 100644 index 0000000..ef6666a --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0017-tools-add-some-helper-tools-for-Lantiq-SoCs.patch @@ -0,0 +1,477 @@ +From 1da5479d59b39d7931a2b0efabdfa314f6788b6d Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sat, 2 Mar 2013 23:34:00 +0100 +Subject: tools: add some helper tools for Lantiq SoCs + +Signed-off-by: Luka Perkov Luka Perkov +Signed-off-by: Daniel Schwierzeck + +--- /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 = ){ ++ 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=){ ++ $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_bdi_conf.awk +@@ -0,0 +1,116 @@ ++#!/usr/bin/awk -f ++# ++# Copyright (C) 2013 Luka Perkov ++# Copyright (C) 2013 Daniel Schwierzeck ++# ++# Usage: ++# awk -f lantiq_bdi_conf.awk -v soc=ar9 board= PATH_TO_BOARD/ddr_settings.h ++# ++# Additional information: ++# http://www.abatron.ch/fileadmin/user_upload/products/pdf/ManGDBR4K-3000.pdf ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++function print_header() ++{ ++ print "; " ++ print "; Copyright (C) 2013 Luka Perkov " ++ print "; Copyright (C) 2013 Daniel Schwierzeck " ++ print "; " ++ print "; This file has been generated with lantiq_bdi_conf.awk script. " ++ print "; " ++ print "; SPDX-License-Identifier: GPL-2.0+ " ++ print "; " ++ print "" ++} ++ ++function init_ar9_prologue() ++{ ++ print "WM32 0xBF103010 0x80 ; CGU for CPU 333Mhz, DDR 167Mhz" ++ print "WM32 0xBF103014 0x01 ; CGU update" ++ print "WM32 0xBF800010 0x0 ; Clear error access log register" ++ print "WM32 0xBF800020 0x0 ; Clear error access log register" ++ print "WM32 0xBF800060 0xD ; Enable FPI, DDR and SRAM module in memory controller" ++ print "WM32 0xBF801030 0x0 ; Clear start bit of DDR memory controller" ++} ++ ++function init_ar9_epilogue() ++{ ++ print "WM32 0xBE105360 0x4001D7FF ; EBU setup" ++} ++ ++function init_ddr1_epilogue() ++{ ++ print "WM32 0xBF801030 0x100 ; Set start bit of DDR memory controller" ++} ++ ++function ar9_target() ++{ ++ print "CPUTYPE M34K" ++ print "ENDIAN BIG" ++ print "JTAGCLOCK 1" ++ print "BDIMODE AGENT ; [ LOADONLY, AGENT ]" ++ print "RESET JTAG ; [ NONE, JTAG, HARD ]" ++ print "POWERUP 100" ++ print "WAKEUP 100" ++ print "BREAKMODE HARD ; [ SOFT, HARD ]" ++ print "STEPMODE SWBP ; [ JTAG, HWBP, SWBP ]" ++ print "VECTOR CATCH" ++ print "SCANSUCC 1 5" ++} ++ ++function flash_p2601hnfx() ++{ ++ print "CHIPTYPE MIRRORX16" ++ print "CHIPSIZE 0x1000000" ++ print "BUSWIDTH 16" ++} ++ ++BEGIN { ++ switch (soc) { ++ case "ar9": ++ reg_base = 0xbf801000 ++ print_header() ++ print "[INIT]" ++ init_ar9_prologue() ++ break ++ default: ++ print "Invalid or no value for SoC specified!" ++ exit 1 ++ } ++} ++ ++/^#define/ { ++ /* DC03 contains MC enable bit and must not be set here */ ++ if (tolower($2) != "mc_dc03_value") ++ printf("WM32 0x%x %s\n", reg_base, tolower($3)) ++ ++ reg_base += 0x10 ++} ++ ++END { ++ switch (soc) { ++ case "ar9": ++ init_ddr1_epilogue() ++ init_ar9_epilogue() ++ print "" ++ print "[TARGET]" ++ ar9_target() ++ print "" ++ print "[HOST]" ++ print "PROMPT \"ar9> \"" ++ print "" ++ break ++ default: ++ } ++ ++ switch (board) { ++ case "p2601hnfx": ++ print "[FLASH]" ++ flash_p2601hnfx() ++ print "" ++ break ++ default: ++ } ++} +--- /dev/null ++++ b/tools/lantiq_ram_extract_magic.awk +@@ -0,0 +1,69 @@ ++# ++# Copyright (C) 2011-2013 Luka Perkov ++# ++# Usage: ++# mips-openwrt-linux-objdump -EB -b binary -m mips:isa32r2 -D YOUR_IMAGE_DUMP | awk -f lantiq_ram_extract_magic.awk ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++BEGIN { ++ print "/* " ++ print " * Copyright (C) 2011-2013 Luka Perkov " ++ print " * " ++ print " * This file has been generated with lantiq_ram_extract_magic.awk script. " ++ print " * " ++ print " * SPDX-License-Identifier: GPL-2.0+ " ++ 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,117 @@ ++#!/usr/bin/awk -f ++# ++# Copyright (C) 2011-2012 Luka Perkov ++# Copyright (C) 2012 Daniel Schwierzeck ++# ++# Usage: ++# awk -f lantiq_ram_init_uart.awk -v soc= PATH_TO_BOARD/ddr_settings.h ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++function print_header() ++{ ++ print "; " ++ print "; Copyright (C) 2011-2013 Luka Perkov " ++ print "; Copyright (C) 2012-2013 Daniel Schwierzeck " ++ print "; " ++ print "; This file has been generated with lantiq_ram_init_uart.awk script. " ++ print "; " ++ print "; SPDX-License-Identifier: GPL-2.0+ " ++ print "" ++} ++ ++function mc_danube_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_ar9_prologue() ++{ ++ /* Clear access error log registers */ ++ print "0xbf800010", "0x0" ++ print "0xbf800020", "0x0" ++ ++ /* Enable FPI, DDR and SRAM module in memory controller */ ++ print "0xbf800060", "0xD" ++ ++ /* 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": ++ reg_base = 0xbf801000 ++ print_header() ++ mc_danube_prologue() ++ break ++ case "ar9": ++ reg_base = 0xbf801000 ++ print_header() ++ mc_ar9_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/ { ++ /* CCR07 contains MC enable bit and must not be set here */ ++ if (tolower($2) == "mc_ccr07_value") ++ mc_ccr07_value = strtonum($3) ++ if (tolower($2) == "mc_dc03_value") ++ /* CCR07 contains MC enable bit and must not be set here */ ++ else ++ printf("0x%x %s\n", reg_base, tolower($3)) ++ ++ reg_base += 0x10 ++} ++ ++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/0018-tools-lantiq-add-NAND-SPL-support.patch b/package/boot/uboot-lantiq/patches/0018-tools-lantiq-add-NAND-SPL-support.patch new file mode 100644 index 0000000..471c902 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0018-tools-lantiq-add-NAND-SPL-support.patch @@ -0,0 +1,223 @@ +From 43b9a7c9b903302c56d0a1d292a146dbf4de8e49 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Mon, 12 Aug 2013 01:17:08 +0200 +Subject: tools: lantiq: add NAND SPL support + +Signed-off-by: Daniel Schwierzeck + +--- a/tools/ltq-boot-image.c ++++ b/tools/ltq-boot-image.c +@@ -14,7 +14,8 @@ + + enum image_types { + IMAGE_NONE, +- IMAGE_SFSPL ++ IMAGE_SFSPL, ++ IMAGE_NANDSPL + }; + + /* Lantiq non-volatile bootstrap command IDs */ +@@ -43,6 +44,8 @@ enum nvb_cmd_flags { + struct args { + enum image_types type; + __u32 entry_addr; ++ loff_t uboot_offset; ++ unsigned int page_size; + const char *uboot_bin; + const char *spl_bin; + const char *out_bin; +@@ -50,10 +53,11 @@ struct args { + + 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", ++ fprintf(stderr, "%s: [-h] -t type -e entry-addr [-x uboot-offset] [-p page-size] -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"); ++ " sfspl - SPL + [compressed] U-Boot for SPI flash\n" ++ " nandspl - SPL + [compressed] U-Boot for NAND flash\n"); + } + + static enum image_types parse_image_type(const char *type) +@@ -64,6 +68,9 @@ static enum image_types parse_image_type + if (!strncmp(type, "sfspl", 6)) + return IMAGE_SFSPL; + ++ if (!strncmp(type, "nandspl", 6)) ++ return IMAGE_NANDSPL; ++ + return IMAGE_NONE; + } + +@@ -73,7 +80,7 @@ static int parse_args(int argc, char *ar + + memset(arg, 0, sizeof(*arg)); + +- while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) { ++ while ((opt = getopt(argc, argv, "ht:e:x:p:u:s:o:")) != -1) { + switch (opt) { + case 'h': + usage_msg(argv[0]); +@@ -84,6 +91,12 @@ static int parse_args(int argc, char *ar + case 'e': + arg->entry_addr = strtoul(optarg, NULL, 16); + break; ++ case 'x': ++ arg->uboot_offset = strtoul(optarg, NULL, 16); ++ break; ++ case 'p': ++ arg->page_size = strtoul(optarg, NULL, 10); ++ break; + case 'u': + arg->uboot_bin = optarg; + break; +@@ -114,11 +127,22 @@ static int parse_args(int argc, char *ar + goto parse_error; + } + +- if (arg->type == IMAGE_SFSPL && !arg->spl_bin) { ++ if ((arg->type == IMAGE_SFSPL || arg->type == IMAGE_NANDSPL) && ++ !arg->spl_bin) { + fprintf(stderr, "Missing SPL binary\n"); + goto parse_error; + } + ++ if (arg->type == IMAGE_NANDSPL && !arg->uboot_offset) { ++ fprintf(stderr, "Missing U-Boot offset\n"); ++ goto parse_error; ++ } ++ ++ if (arg->type == IMAGE_NANDSPL && !arg->page_size) { ++ fprintf(stderr, "Missing NAND page size\n"); ++ goto parse_error; ++ } ++ + return 0; + + parse_error: +@@ -174,6 +198,19 @@ static int write_nvb_start_header(int fd + return write_header(fd, hdr, sizeof(hdr)); + } + ++#if 0 ++static int write_nvb_regcfg_header(int fd, __u32 addr) ++{ ++ __u32 hdr[2]; ++ ++ hdr[0] = build_nvb_command(NVB_CMD_REGCFG, NVB_FLAG_SDBG | ++ NVB_FLAG_DBG); ++ hdr[1] = cpu_to_be32(addr); ++ ++ return write_header(fd, hdr, sizeof(hdr)); ++} ++#endif ++ + static int open_input_bin(const char *name, void **ptr, size_t *size) + { + struct stat sbuf; +@@ -238,9 +275,37 @@ static int open_output_bin(const char *n + return fd; + } + +-static int create_sfspl(const struct args *arg) ++static int pad_to_offset(int fd, loff_t offset) + { +- int out_fd, uboot_fd, spl_fd, ret; ++ loff_t pos; ++ size_t size; ++ ssize_t n; ++ __u8 *buf; ++ ++ pos = lseek(fd, 0, SEEK_CUR); ++ size = offset - pos; ++ ++ buf = malloc(size); ++ if (!buf) { ++ fprintf(stderr, "Failed to malloc buffer\n"); ++ return -1; ++ } ++ ++ memset(buf, 0xff, size); ++ n = write(fd, buf, size); ++ free(buf); ++ ++ if (n != size) { ++ fprintf(stderr, "Failed to write pad bytes\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int create_spl_image(const struct args *arg) ++{ ++ int out_fd, uboot_fd, spl_fd, ret = 0; + void *uboot_ptr, *spl_ptr; + size_t uboot_size, spl_size; + +@@ -256,9 +321,22 @@ static int create_sfspl(const struct arg + if (0 > uboot_fd) + goto err_uboot; + ++#if 0 ++ ret = write_nvb_regcfg_header(out_fd, 0); ++ if (ret) ++ goto err_write; ++#endif ++ + ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr); + if (ret) + goto err_write; ++#if 0 ++ if (arg->page_size) { ++ ret = pad_to_offset(out_fd, arg->page_size); ++ if (ret) ++ goto err_write; ++ } ++#endif + + ret = copy_bin(out_fd, spl_ptr, spl_size); + if (ret) +@@ -268,16 +346,16 @@ static int create_sfspl(const struct arg + if (ret) + goto err_write; + ++ if (arg->uboot_offset) { ++ ret = pad_to_offset(out_fd, arg->uboot_offset); ++ 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: +@@ -285,7 +363,7 @@ err_uboot: + err_spl: + close(out_fd); + err: +- return -1; ++ return ret; + } + + int main(int argc, char *argv[]) +@@ -299,7 +377,8 @@ int main(int argc, char *argv[]) + + switch (arg.type) { + case IMAGE_SFSPL: +- ret = create_sfspl(&arg); ++ case IMAGE_NANDSPL: ++ ret = create_spl_image(&arg); + break; + default: + fprintf(stderr, "Image type not implemented\n"); diff --git a/package/boot/uboot-lantiq/patches/0019-Makefile-add-Lantiq-NAND-SPL-images.patch b/package/boot/uboot-lantiq/patches/0019-Makefile-add-Lantiq-NAND-SPL-images.patch new file mode 100644 index 0000000..53df7ac --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0019-Makefile-add-Lantiq-NAND-SPL-images.patch @@ -0,0 +1,46 @@ +From 2e01dc015bc8bb9ca45f369025c342ede990863e Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Mon, 12 Aug 2013 01:16:09 +0200 +Subject: Makefile: add Lantiq NAND SPL images + +Signed-off-by: Daniel Schwierzeck + +--- a/.gitignore ++++ b/.gitignore +@@ -54,6 +54,9 @@ + /u-boot.ltq.lzma.norspl + /u-boot.ltq.lzo.norspl + /u-boot.ltq.norspl ++/u-boot.ltq.lzma.nandspl ++/u-boot.ltq.lzo.nandspl ++/u-boot.ltq.nandspl + /u-boot.lzma.img + /u-boot.lzo.img + +--- a/Makefile ++++ b/Makefile +@@ -599,6 +599,24 @@ $(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boo + $(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.nandspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin ++ $(obj)tools/ltq-boot-image -t nandspl -e $(CONFIG_SPL_TEXT_BASE) \ ++ -x $(CONFIG_SYS_NAND_U_BOOT_OFFS) \ ++ -p $(CONFIG_SYS_NAND_PAGE_SIZE) \ ++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@ ++ ++$(obj)u-boot.ltq.lzo.nandspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin ++ $(obj)tools/ltq-boot-image -t nandspl -e $(CONFIG_SPL_TEXT_BASE) \ ++ -x $(CONFIG_SYS_NAND_U_BOOT_OFFS) \ ++ -p $(CONFIG_SYS_NAND_PAGE_SIZE) \ ++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@ ++ ++$(obj)u-boot.ltq.lzma.nandspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin ++ $(obj)tools/ltq-boot-image -t nandspl -e $(CONFIG_SPL_TEXT_BASE) \ ++ -x $(CONFIG_SYS_NAND_U_BOOT_OFFS) \ ++ -p $(CONFIG_SYS_NAND_PAGE_SIZE) \ ++ -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 $< > $@ + diff --git a/package/boot/uboot-lantiq/patches/0020-MIPS-lantiq-add-NAND-SPL-support.patch b/package/boot/uboot-lantiq/patches/0020-MIPS-lantiq-add-NAND-SPL-support.patch new file mode 100644 index 0000000..8d9eca7 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0020-MIPS-lantiq-add-NAND-SPL-support.patch @@ -0,0 +1,165 @@ +From e17398316e82d8b28217232b4fd6030c65138e74 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Mon, 12 Aug 2013 01:18:00 +0200 +Subject: MIPS: lantiq: add NAND SPL support + +Signed-off-by: Daniel Schwierzeck + +--- a/arch/mips/cpu/mips32/lantiq-common/spl.c ++++ b/arch/mips/cpu/mips32/lantiq-common/spl.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -63,6 +64,18 @@ + #define spl_boot_nor_flash 0 + #endif + ++#if defined(CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH) && defined(CONFIG_SYS_BOOT_NANDSPL) ++#define spl_boot_nand_flash 1 ++#else ++#define spl_boot_nand_flash 0 ++#ifndef CONFIG_SYS_NAND_U_BOOT_OFFS ++#define CONFIG_SYS_NAND_U_BOOT_OFFS 0 ++#endif ++#ifndef CONFIG_SYS_NAND_PAGE_SIZE ++#define CONFIG_SYS_NAND_PAGE_SIZE 0 ++#endif ++#endif ++ + #define spl_sync() __asm__ __volatile__("sync"); + + struct spl_image { +@@ -337,6 +350,58 @@ static int spl_load_nor_flash(struct spl + return ret; + } + ++static int spl_load_nand_flash(struct spl_image *spl) ++{ ++ 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 ++ * - padding bytes up to CONFIG_SYS_NAND_U_BOOT_OFFS ++ * - 64 byte U-Boot mkimage header ++ * - U-Boot binary ++ */ ++ spl->data_addr = CONFIG_SYS_NAND_U_BOOT_OFFS; ++ ++ spl_puts("SPL: initializing NAND flash\n"); ++ nand_init(); ++ ++ spl_debug("SPL: reading image header at page offset %lx\n", ++ spl->data_addr); ++ ++ hdr = (image_header_t *) CONFIG_LOADADDR; ++ ret = nand_spl_load_image(spl->data_addr, ++ CONFIG_SYS_NAND_PAGE_SIZE, hdr); ++ if (ret) ++ return ret; ++ ++ 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)) ++ loadaddr = CONFIG_LOADADDR; ++ else ++ loadaddr = spl->entry_addr; ++ ++ spl_puts("SPL: loading U-Boot to RAM\n"); ++ ++ ret = nand_spl_load_image(spl->data_addr, spl->data_size, ++ (void *) loadaddr); ++ ++ if (spl_is_compressed(spl)) ++ ret = spl_uncompress(spl, loadaddr); ++ ++ return ret; ++} ++ + static int spl_load(struct spl_image *spl) + { + int ret; +@@ -345,6 +410,8 @@ static int spl_load(struct spl_image *sp + ret = spl_load_spi_flash(spl); + else if (spl_boot_nor_flash) + ret = spl_load_nor_flash(spl); ++ else if (spl_boot_nand_flash) ++ ret = spl_load_nand_flash(spl); + else + ret = 1; + +--- a/arch/mips/include/asm/lantiq/config.h ++++ b/arch/mips/include/asm/lantiq/config.h +@@ -40,6 +40,26 @@ + #define CONFIG_SPI_SPL_SIMPLE + #endif + ++/* ++ * NAND flash SPL ++ * BOOT CFG 06 only (address cycle based probing, 2KB or 512B page size) ++ */ ++#if defined(CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH) && defined(CONFIG_SYS_BOOT_NANDSPL) ++#define CONFIG_SPL ++#define CONFIG_SPL_NAND_SUPPORT ++#define CONFIG_SPL_NAND_DRIVERS ++#define CONFIG_SPL_NAND_SIMPLE ++#define CONFIG_SPL_NAND_ECC ++ ++/* use software ECC until driver supports HW ECC */ ++#define CONFIG_SPL_NAND_SOFTECC ++#define CONFIG_SYS_NAND_ECCSIZE 256 ++#define CONFIG_SYS_NAND_ECCBYTES 3 ++#define CONFIG_SYS_NAND_ECCPOS {40, 41, 42, 43, 44, 45, 46, 47, \ ++ 48, 49, 50, 51, 52, 53, 54, 55, \ ++ 56, 57, 58, 59, 60, 61, 62, 63} ++#endif ++ + #if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL) + #define CONFIG_SPL + #endif +@@ -148,6 +168,21 @@ + #define CONFIG_ENV_LOAD_UBOOT_SF + #endif + ++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH) ++#define CONFIG_ENV_WRITE_UBOOT_NAND \ ++ "write-uboot-nand=" \ ++ "nand erase 0 $filesize && " \ ++ "nand write $fileaddr 0 $filesize\0" ++ ++#define CONFIG_ENV_LOAD_UBOOT_NAND \ ++ "load-uboot-nandspl=tftpboot u-boot.ltq.nandspl\0" \ ++ "load-uboot-nandspl-lzo=tftpboot u-boot.ltq.lzo.nandspl\0" \ ++ "load-uboot-nandspl-lzma=tftpboot u-boot.ltq.lzma.nandspl\0" ++#else ++#define CONFIG_ENV_WRITE_UBOOT_NAND ++#define CONFIG_ENV_LOAD_UBOOT_NAND ++#endif ++ + #define CONFIG_ENV_LANTIQ_DEFAULTS \ + CONFIG_ENV_CONSOLEDEV \ + CONFIG_ENV_ADDCONSOLE \ +@@ -159,6 +194,8 @@ + CONFIG_ENV_LOAD_UBOOT_NOR \ + CONFIG_ENV_SF_PROBE \ + CONFIG_ENV_WRITE_UBOOT_SF \ +- CONFIG_ENV_LOAD_UBOOT_SF ++ CONFIG_ENV_LOAD_UBOOT_SF \ ++ CONFIG_ENV_WRITE_UBOOT_NAND \ ++ CONFIG_ENV_LOAD_UBOOT_NAND + + #endif /* __LANTIQ_CONFIG_H__ */ diff --git a/package/boot/uboot-lantiq/patches/0021-MIPS-vrx200-add-NAND-SPL-support.patch b/package/boot/uboot-lantiq/patches/0021-MIPS-vrx200-add-NAND-SPL-support.patch new file mode 100644 index 0000000..6c9f14b --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0021-MIPS-vrx200-add-NAND-SPL-support.patch @@ -0,0 +1,30 @@ +From 7361581a1baaec43058f5b9350c32c7ac4e58064 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Mon, 12 Aug 2013 00:11:16 +0200 +Subject: MIPS: vrx200: add NAND SPL support + +Signed-off-by: Daniel Schwierzeck + +--- a/arch/mips/cpu/mips32/vrx200/config.mk ++++ b/arch/mips/cpu/mips32/vrx200/config.mk +@@ -27,4 +27,9 @@ 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 ++ifdef CONFIG_SYS_BOOT_NANDSPL ++ALL-y += $(obj)u-boot.ltq.nandspl ++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.nandspl ++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.nandspl ++endif + endif +--- a/arch/mips/include/asm/arch-vrx200/config.h ++++ b/arch/mips/include/asm/arch-vrx200/config.h +@@ -164,7 +164,7 @@ + #define CONFIG_SYS_TEXT_BASE 0xB0000000 + #endif + +-#if defined(CONFIG_SYS_BOOT_SFSPL) ++#if defined(CONFIG_SYS_BOOT_SFSPL) || defined(CONFIG_SYS_BOOT_NANDSPL) + #define CONFIG_SYS_TEXT_BASE 0x80100000 + #define CONFIG_SPL_TEXT_BASE 0xBE220000 + #endif diff --git a/package/boot/uboot-lantiq/patches/0022-MIPS-lantiq-easy80920-add-support-for-NAND-SPL.patch b/package/boot/uboot-lantiq/patches/0022-MIPS-lantiq-easy80920-add-support-for-NAND-SPL.patch new file mode 100644 index 0000000..8e1d5bd --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0022-MIPS-lantiq-easy80920-add-support-for-NAND-SPL.patch @@ -0,0 +1,61 @@ +From 6fa1c350fa19a054371eccef84e4885cfdd6a2d7 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Mon, 19 Aug 2013 18:11:31 +0200 +Subject: MIPS: lantiq: easy80920: add support for NAND SPL + +Signed-off-by: Daniel Schwierzeck + +--- a/boards.cfg ++++ b/boards.cfg +@@ -509,6 +509,7 @@ Active mips mips32 incai + Active mips mips32 incaip - incaip incaip_100MHz incaip:CPU_CLOCK_RATE=100000000 Wolfgang Denk + Active mips mips32 incaip - incaip incaip_133MHz incaip:CPU_CLOCK_RATE=133000000 Wolfgang Denk + Active mips mips32 incaip - incaip incaip_150MHz incaip:CPU_CLOCK_RATE=150000000 Wolfgang Denk ++Active mips mips32 vrx200 lantiq easy80920 easy80920_nandspl easy80920:SYS_BOOT_NANDSPL Daniel Schwierzeck + Active mips mips32 vrx200 lantiq easy80920 easy80920_nor easy80920:SYS_BOOT_NOR Daniel Schwierzeck + Active mips mips32 vrx200 lantiq easy80920 easy80920_norspl easy80920:SYS_BOOT_NORSPL Daniel Schwierzeck + Active mips mips32 vrx200 lantiq easy80920 easy80920_ram easy80920:SYS_BOOT_RAM Daniel Schwierzeck +--- a/include/configs/easy80920.h ++++ b/include/configs/easy80920.h +@@ -31,6 +31,14 @@ + + #define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */ + ++#define CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH /* Build NAND flash SPL */ ++#define CONFIG_SYS_NAND_PAGE_COUNT 128 ++#define CONFIG_SYS_NAND_PAGE_SIZE 2048 ++#define CONFIG_SYS_NAND_OOBSIZE 64 ++#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * 1024) ++#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS ++#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x4000 ++ + #define CONFIG_LTQ_SPL_COMP_LZO + #define CONFIG_LTQ_SPL_CONSOLE + +@@ -57,6 +65,11 @@ + #define CONFIG_ENV_OVERWRITE + #define CONFIG_ENV_OFFSET (192 * 1024) + #define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#elif defined(CONFIG_SYS_BOOT_NANDSPL) ++#define CONFIG_ENV_IS_IN_NAND ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (256 * 1024) ++#define CONFIG_ENV_SECT_SIZE (256 * 1024) + #else + #define CONFIG_ENV_IS_NOWHERE + #endif +@@ -84,9 +97,13 @@ + #define CONFIG_ENV_UPDATE_UBOOT_SF \ + "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0" + ++#define CONFIG_ENV_UPDATE_UBOOT_NAND \ ++ "update-uboot-nand=run load-uboot-nandspl-lzo write-uboot-nand\0" ++ + #define CONFIG_EXTRA_ENV_SETTINGS \ + CONFIG_ENV_LANTIQ_DEFAULTS \ + CONFIG_ENV_UPDATE_UBOOT_NOR \ +- CONFIG_ENV_UPDATE_UBOOT_SF ++ CONFIG_ENV_UPDATE_UBOOT_SF \ ++ CONFIG_ENV_UPDATE_UBOOT_NAND + + #endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0023-MIPS-lantiq-add-default-openwrt-config.patch b/package/boot/uboot-lantiq/patches/0023-MIPS-lantiq-add-default-openwrt-config.patch new file mode 100644 index 0000000..3b50c98 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0023-MIPS-lantiq-add-default-openwrt-config.patch @@ -0,0 +1,50 @@ +From 8f584936adad0fca8beece5f55eadcdcd02fad0a Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sat, 17 Aug 2013 03:44:46 +0200 +Subject: MIPS: lantiq: add default openwrt config + +Signed-off-by: Luka Perkov +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/include/configs/openwrt-lantiq-common.h +@@ -0,0 +1,39 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __OPENWRT_LANTIQ_COMMON_H ++#define __OPENWRT_LANTIQ_COMMON_H ++ ++/* Commands */ ++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET) ++#define CONFIG_CMD_PING ++#endif ++ ++/* Compression */ ++#define CONFIG_LZMA ++ ++/* Auto boot */ ++#define CONFIG_BOOTDELAY 2 ++ ++/* Environment */ ++#if !defined(CONFIG_SYS_BOOT_RAM) ++#define CONFIG_BOOTCOMMAND \ ++ "bootm ${kernel_addr}" ++#endif ++ ++/* Ethernet */ ++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET) ++#define CONFIG_ETHADDR 00:01:02:03:04:05 ++#define CONFIG_SERVERIP 192.168.1.2 ++#define CONFIG_IPADDR 192.168.1.1 ++#endif ++ ++/* Unnecessary */ ++#undef CONFIG_BOOTM_NETBSD ++#undef CONFIG_BOOTM_PLAN9 ++#undef CONFIG_BOOTM_RTEMS ++ ++#endif /* __OPENWRT_LANTIQ_COMMON_H */ diff --git a/package/boot/uboot-lantiq/patches/0024-MIPS-lantiq-easy50712-add-openwrt-lantiq-common.h.patch b/package/boot/uboot-lantiq/patches/0024-MIPS-lantiq-easy50712-add-openwrt-lantiq-common.h.patch new file mode 100644 index 0000000..5afe427 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0024-MIPS-lantiq-easy50712-add-openwrt-lantiq-common.h.patch @@ -0,0 +1,26 @@ +From ac6896098d9dd62a248340e6a090574399e1fd87 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Mon, 19 Aug 2013 18:46:47 +0200 +Subject: MIPS: lantiq: easy50712: add openwrt-lantiq-common.h + +Signed-off-by: Daniel Schwierzeck + +--- a/include/configs/easy50712.h ++++ b/include/configs/easy50712.h +@@ -62,13 +62,13 @@ + #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 + #include + ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ + #define CONFIG_ENV_UPDATE_UBOOT_NOR \ + "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0" + diff --git a/package/boot/uboot-lantiq/patches/0025-MIPS-lantiq-easy80920-add-openwrt-lantiq-common.h.patch b/package/boot/uboot-lantiq/patches/0025-MIPS-lantiq-easy80920-add-openwrt-lantiq-common.h.patch new file mode 100644 index 0000000..2f9fd59 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0025-MIPS-lantiq-easy80920-add-openwrt-lantiq-common.h.patch @@ -0,0 +1,26 @@ +From 7afbe4633773905ef94a8404510fb5a459926000 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Mon, 19 Aug 2013 18:11:57 +0200 +Subject: MIPS: lantiq: easy80920: add openwrt-lantiq-common.h + +Signed-off-by: Daniel Schwierzeck + +--- a/include/configs/easy80920.h ++++ b/include/configs/easy80920.h +@@ -84,13 +84,13 @@ + #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 + #include + ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ + #define CONFIG_ENV_UPDATE_UBOOT_NOR \ + "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0" + diff --git a/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Arcadyan-ARV4519.patch b/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Arcadyan-ARV4519.patch new file mode 100644 index 0000000..51738e4 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Arcadyan-ARV4519.patch @@ -0,0 +1,242 @@ +From 9f915cf9550a6234adecaf3031c2b279835e14af Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sat, 2 Mar 2013 23:34:00 +0100 +Subject: MIPS: add board support for Arcadyan ARV4519 + +Signed-off-by: Luka Perkov +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/arcadyan/arv4519pw/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,51 @@ ++/* ++ * Copyright (C) 2012 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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(ð_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,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv4519pw/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2012-2013 Luka Perkov ++ * ++ * This file has been generated with lantiq_ram_extract_magic.awk script. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 +@@ -502,6 +502,9 @@ Active mips mips32 au1x0 + Active mips mips32 au1x00 - dbau1x00 dbau1550 dbau1x00:DBAU1550 Thomas Lange + Active mips mips32 au1x00 - dbau1x00 dbau1550_el dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN Thomas Lange + Active mips mips32 au1x00 - pb1x00 pb1000 pb1x00:PB1000 - ++Active mips mips32 danube arcadyan arv4519pw arv4519pw_brn arv4519pw:SYS_BOOT_BRN Luka Perkov ++Active mips mips32 danube arcadyan arv4519pw arv4519pw_nor arv4519pw:SYS_BOOT_NOR Luka Perkov ++Active mips mips32 danube arcadyan arv4519pw arv4519pw_ram arv4519pw:SYS_BOOT_RAM Luka Perkov + Active mips mips32 danube lantiq easy50712 easy50712_nor easy50712:SYS_BOOT_NOR Daniel Schwierzeck + Active mips mips32 danube lantiq easy50712 easy50712_norspl easy50712:SYS_BOOT_NORSPL Daniel Schwierzeck + Active mips mips32 danube lantiq easy50712 easy50712_ram easy50712:SYS_BOOT_RAM Daniel Schwierzeck +--- /dev/null ++++ b/include/configs/arv4519pw.h +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) 2012-2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Brnboot loadable image */ ++#if defined(CONFIG_SYS_BOOT_BRN) ++#define CONFIG_SYS_TEXT_BASE 0x80002000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#define CONFIG_ENV_OVERWRITE 1 ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#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..21e6a2c --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch @@ -0,0 +1,242 @@ +From 54a31b334162e8dc2ea891057ddeab42978db8b3 Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sat, 2 Mar 2013 23:34:00 +0100 +Subject: MIPS: add board support for Arcadyan ARV7518 + +Signed-off-by: Luka Perkov +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/arcadyan/arv7518pw/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,51 @@ ++/* ++ * Copyright (C) 2012 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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(ð_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,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv7518pw/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2012-2013 Luka Perkov ++ * ++ * This file has been generated with lantiq_ram_extract_magic.awk script. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 +@@ -505,6 +505,9 @@ Active mips mips32 au1x0 + Active mips mips32 danube arcadyan arv4519pw arv4519pw_brn arv4519pw:SYS_BOOT_BRN Luka Perkov + Active mips mips32 danube arcadyan arv4519pw arv4519pw_nor arv4519pw:SYS_BOOT_NOR Luka Perkov + Active mips mips32 danube arcadyan arv4519pw arv4519pw_ram arv4519pw:SYS_BOOT_RAM Luka Perkov ++Active mips mips32 danube arcadyan arv7518pw arv7518pw_brn arv7518pw:SYS_BOOT_BRN Luka Perkov ++Active mips mips32 danube arcadyan arv7518pw arv7518pw_nor arv7518pw:SYS_BOOT_NOR Luka Perkov ++Active mips mips32 danube arcadyan arv7518pw arv7518pw_ram arv7518pw:SYS_BOOT_RAM Luka Perkov + Active mips mips32 danube lantiq easy50712 easy50712_nor easy50712:SYS_BOOT_NOR Daniel Schwierzeck + Active mips mips32 danube lantiq easy50712 easy50712_norspl easy50712:SYS_BOOT_NORSPL Daniel Schwierzeck + Active mips mips32 danube lantiq easy50712 easy50712_ram easy50712:SYS_BOOT_RAM Daniel Schwierzeck +--- /dev/null ++++ b/include/configs/arv7518pw.h +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) 2012-2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Brnboot loadable image */ ++#if defined(CONFIG_SYS_BOOT_BRN) ++#define CONFIG_SYS_TEXT_BASE 0x80002000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#define CONFIG_ENV_OVERWRITE 1 ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#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-AudioCodes-MP-252.patch b/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-AudioCodes-MP-252.patch new file mode 100644 index 0000000..00820f8 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-AudioCodes-MP-252.patch @@ -0,0 +1,248 @@ +From 4bacfc80eae768be45f9ddf7588ec55281354648 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Fri, 8 Mar 2013 13:29:04 +0200 +Subject: MIPS: add board support for AudioCodes MP-252 + +Signed-off-by: Daniel Golle + +--- /dev/null ++++ b/board/audiocodes/acmp252/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/audiocodes/acmp252/acmp252.c +@@ -0,0 +1,66 @@ ++/* ++ * Copyright (C) 2013 Daniel Golle ++ * Copyright (C) 2011 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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(ð_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); ++} +--- /dev/null ++++ b/board/audiocodes/acmp252/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/audiocodes/acmp252/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2011-2013 Luka Perkov ++ * ++ * This file has been generated with lantiq_ram_extract_magic.awk script. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 0x403 ++#define MC_DC08_VALUE 0x103 ++#define MC_DC09_VALUE 0x80B ++#define MC_DC10_VALUE 0x304 ++#define MC_DC11_VALUE 0xD03 ++#define MC_DC12_VALUE 0x2C8 ++#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 0x402 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA03 ++#define MC_DC21_VALUE 0x1700 ++#define MC_DC22_VALUE 0x1717 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x5C ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x510 ++#define MC_DC29_VALUE 0x2D93 ++#define MC_DC30_VALUE 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 +--- a/boards.cfg ++++ b/boards.cfg +@@ -508,6 +508,8 @@ Active mips mips32 danub + Active mips mips32 danube arcadyan arv7518pw arv7518pw_brn arv7518pw:SYS_BOOT_BRN Luka Perkov + Active mips mips32 danube arcadyan arv7518pw arv7518pw_nor arv7518pw:SYS_BOOT_NOR Luka Perkov + Active mips mips32 danube arcadyan arv7518pw arv7518pw_ram arv7518pw:SYS_BOOT_RAM Luka Perkov ++Active mips mips32 danube audiocodes acmp252 acmp252_nor acmp252:SYS_BOOT_NOR Daniel Golle ++Active mips mips32 danube audiocodes acmp252 acmp252_ram acmp252:SYS_BOOT_RAM Daniel Golle + Active mips mips32 danube lantiq easy50712 easy50712_nor easy50712:SYS_BOOT_NOR Daniel Schwierzeck + Active mips mips32 danube lantiq easy50712 easy50712_norspl easy50712:SYS_BOOT_NORSPL Daniel Schwierzeck + Active mips mips32 danube lantiq easy50712 easy50712_ram easy50712:SYS_BOOT_RAM Daniel Schwierzeck +--- /dev/null ++++ b/include/configs/acmp252.h +@@ -0,0 +1,60 @@ ++/* ++ * Copyright (C) 2013 Daniel Golle ++ * Copyright (C) 2011 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ACMP252" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "AudioCodes MP-252" ++ ++/* 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_SECT_SIZE (128 * 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" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#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-MIPS-add-board-support-for-AVM-FritzBox-3370.patch b/package/boot/uboot-lantiq/patches/0029-MIPS-add-board-support-for-AVM-FritzBox-3370.patch new file mode 100644 index 0000000..77014e4 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0029-MIPS-add-board-support-for-AVM-FritzBox-3370.patch @@ -0,0 +1,354 @@ +From 37a95ae4ba75407a26862ece6f48fa68aa6c5c78 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sat, 2 Mar 2013 23:34:00 +0100 +Subject: MIPS: add board support for AVM FritzBox 3370 + +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/avm/fb3370/Makefile +@@ -0,0 +1,28 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,7 @@ ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/avm/fb3370/ddr_settings.h +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,138 @@ ++/* ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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(ð_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 +@@ -517,6 +517,9 @@ Active mips mips32 incai + Active mips mips32 incaip - incaip incaip_100MHz incaip:CPU_CLOCK_RATE=100000000 Wolfgang Denk + Active mips mips32 incaip - incaip incaip_133MHz incaip:CPU_CLOCK_RATE=133000000 Wolfgang Denk + Active mips mips32 incaip - incaip incaip_150MHz incaip:CPU_CLOCK_RATE=150000000 Wolfgang Denk ++Active mips mips32 vrx200 avm fb3370 fb3370_eva fb3370:SYS_BOOT_EVA Daniel Schwierzeck ++Active mips mips32 vrx200 avm fb3370 fb3370_ram fb3370:SYS_BOOT_RAM Daniel Schwierzeck ++Active mips mips32 vrx200 avm fb3370 fb3370_sfspl fb3370:SYS_BOOT_SFSPL Daniel Schwierzeck + Active mips mips32 vrx200 lantiq easy80920 easy80920_nandspl easy80920:SYS_BOOT_NANDSPL Daniel Schwierzeck + Active mips mips32 vrx200 lantiq easy80920 easy80920_nor easy80920:SYS_BOOT_NOR Daniel Schwierzeck + Active mips mips32 vrx200 lantiq easy80920 easy80920_norspl easy80920:SYS_BOOT_NORSPL Daniel Schwierzeck +--- /dev/null ++++ b/include/configs/fb3370.h +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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_LTQ_SPL_COMP_LZO /* Compress SPL with LZO */ ++#define CONFIG_LTQ_SPL_CONSOLE /* Enable SPL console */ ++ ++#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_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 ++ ++#if defined(CONFIG_SYS_BOOT_EVA) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.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/0030-MIPS-add-board-support-for-Gigaset-SX76X.patch b/package/boot/uboot-lantiq/patches/0030-MIPS-add-board-support-for-Gigaset-SX76X.patch new file mode 100644 index 0000000..96737fa --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0030-MIPS-add-board-support-for-Gigaset-SX76X.patch @@ -0,0 +1,247 @@ +From 9e9dec563e4d061e7b34d2d59a89eb05c60f43a7 Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sat, 2 Mar 2013 23:34:00 +0100 +Subject: MIPS: add board support for Gigaset SX76X + +Signed-off-by: Luka Perkov +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/gigaset/sx76x/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/gigaset/sx76x/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2011-2013 Luka Perkov ++ * ++ * This file has been generated with lantiq_ram_extract_magic.awk script. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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,65 @@ ++/* ++ * Copyright (C) 2011 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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(ð_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 +@@ -510,6 +510,8 @@ Active mips mips32 danub + Active mips mips32 danube arcadyan arv7518pw arv7518pw_ram arv7518pw:SYS_BOOT_RAM Luka Perkov + Active mips mips32 danube audiocodes acmp252 acmp252_nor acmp252:SYS_BOOT_NOR Daniel Golle + Active mips mips32 danube audiocodes acmp252 acmp252_ram acmp252:SYS_BOOT_RAM Daniel Golle ++Active mips mips32 danube gigaset sx76x gigasx76x_nor sx76x:SYS_BOOT_NOR Luka Perkov ++Active mips mips32 danube gigaset sx76x gigasx76x_ram sx76x:SYS_BOOT_RAM Luka Perkov + Active mips mips32 danube lantiq easy50712 easy50712_nor easy50712:SYS_BOOT_NOR Daniel Schwierzeck + Active mips mips32 danube lantiq easy50712 easy50712_norspl easy50712:SYS_BOOT_NORSPL Daniel Schwierzeck + Active mips mips32 danube lantiq easy50712 easy50712_ram easy50712:SYS_BOOT_RAM Daniel Schwierzeck +--- /dev/null ++++ b/include/configs/sx76x.h +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (C) 2011-2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "GIGASX76X" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#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_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" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#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/0031-MIPS-add-board-support-for-ZTE-ZXHN-H367N.patch b/package/boot/uboot-lantiq/patches/0031-MIPS-add-board-support-for-ZTE-ZXHN-H367N.patch new file mode 100644 index 0000000..ba63b2c --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0031-MIPS-add-board-support-for-ZTE-ZXHN-H367N.patch @@ -0,0 +1,307 @@ +From 0597056e2ba19ea783ef5c3d14c75c4722740e48 Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Sun, 10 Mar 2013 17:59:56 +0100 +Subject: MIPS: add board support for ZTE ZXHN H367N + +Signed-off-by: Luka Perkov + +--- /dev/null ++++ b/board/zte/zxhnh367n/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/zte/zxhnh367n/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/zte/zxhnh367n/ddr_settings.h +@@ -0,0 +1,70 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * The values have been extracted from original ZTE U-Boot. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#define MC_CCR00_VALUE 0x101 ++#define MC_CCR01_VALUE 0x1000101 ++#define MC_CCR02_VALUE 0x1010000 ++#define MC_CCR03_VALUE 0x100 ++#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 0x2000401 ++#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/zte/zxhnh367n/zxhnh367n.c +@@ -0,0 +1,97 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#else ++#define do_gpio_init 0 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#endif ++ ++static void gpio_init(void) ++{ ++ /* 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 WANoE port */ ++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC1: unused */ ++ { 1, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE }, ++ /* GMAC2: internal GPHY0 with 10/100 firmware for LAN port 1 */ ++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++ /* GMAC3: internal GPHY0 with 10/100 firmware for LAN port 2 */ ++ { 3, 0x12, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++ /* GMAC4: internal GPHY1 with 10/100 firmware for LAN port 3 */ ++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++ /* GMAC5: internal GPHY1 with 10/100 firmware for LAN port 4 */ ++ { 5, 0x14, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++}; ++ ++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_phy22f_a2x_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(ð_board_config); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -527,6 +527,9 @@ Active mips mips32 vrx20 + Active mips mips32 vrx200 lantiq easy80920 easy80920_norspl easy80920:SYS_BOOT_NORSPL Daniel Schwierzeck + Active mips mips32 vrx200 lantiq easy80920 easy80920_ram easy80920:SYS_BOOT_RAM Daniel Schwierzeck + Active mips mips32 vrx200 lantiq easy80920 easy80920_sfspl easy80920:SYS_BOOT_SFSPL Daniel Schwierzeck ++Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_nandspl zxhnh367n:SYS_BOOT_NANDSPL Luka Perkov ++Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_ram zxhnh367n:SYS_BOOT_RAM Luka Perkov ++Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_zte zxhnh367n:SYS_BOOT_ZTE Luka Perkov + Active mips mips64 - - qemu-mips qemu_mips64 qemu-mips64:SYS_BIG_ENDIAN - + Active mips mips64 - - qemu-mips qemu_mips64el qemu-mips64:SYS_LITTLE_ENDIAN - + Active nds32 n1213 ag101 AndesTech adp-ag101 adp-ag101 - Andes +--- /dev/null ++++ b/include/configs/zxhnh367n.h +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ZXHN H367N" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "ZTE ZXHN H367N" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NAND_FLASH /* Have a NAND flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH /* Build NAND flash SPL */ ++#define CONFIG_LTQ_SPL_COMP_LZO /* Compress SPL with LZO */ ++#define CONFIG_LTQ_SPL_CONSOLE /* Enable SPL console */ ++ ++#define CONFIG_SYS_NAND_PAGE_COUNT 128 ++#define CONFIG_SYS_NAND_PAGE_SIZE 2048 ++#define CONFIG_SYS_NAND_OOBSIZE 64 ++#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * 1024) ++#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS ++#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x4000 ++ ++#define CONFIG_SYS_DRAM_PROBE ++ ++/* Environment */ ++#if defined(CONFIG_SYS_BOOT_NANDSPL) ++#define CONFIG_ENV_IS_IN_NAND ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (256 * 1024) ++#define CONFIG_ENV_SECT_SIZE (256 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++#if defined(CONFIG_SYS_BOOT_ZTE) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NAND \ ++ "update-uboot-nand=run load-uboot-nandspl-lzo write-uboot-nand\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NAND ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0032-MIPS-add-board-support-for-ZTE-ZXV10-H201L.patch b/package/boot/uboot-lantiq/patches/0032-MIPS-add-board-support-for-ZTE-ZXV10-H201L.patch new file mode 100644 index 0000000..eb77f96 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0032-MIPS-add-board-support-for-ZTE-ZXV10-H201L.patch @@ -0,0 +1,251 @@ +From 2473526cf879ead429c6aa1fb7fb77ed3407baaa Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sun, 9 Dec 2012 17:35:09 +0100 +Subject: MIPS: add board support for ZTE ZXV10 H201L + +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/zte/zxv10h201l/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/zte/zxv10h201l/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/zte/zxv10h201l/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * The values have been extracted from original ZTE U-Boot. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 0x307 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x103 ++#define MC_DC09_VALUE 0x80B ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xE02 ++#define MC_DC12_VALUE 0x2C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x100 ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xF ++#define MC_DC18_VALUE 0x301 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0x1600 ++#define MC_DC22_VALUE 0x1616 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x5D ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x5FB ++#define MC_DC29_VALUE 0x35DF ++#define MC_DC30_VALUE 0x99E9 ++#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 0x600 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/zte/zxv10h201l/zxv10h201l.c +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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: REALTEK RTL8306 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(ð_board_config); ++} ++ ++static struct switch_device rtl8306_dev = { ++ .name = "rtl8306", ++ .cpu_port = 5, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ return switch_device_register(&rtl8306_dev); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -496,6 +496,9 @@ Active mips mips32 - + Active mips mips32 - micronas vct vct_premium_onenand vct:VCT_PREMIUM,VCT_ONENAND - + Active mips mips32 - micronas vct vct_premium_onenand_small vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE - + Active mips mips32 - micronas vct vct_premium_small vct:VCT_PREMIUM,VCT_SMALL_IMAGE - ++Active mips mips32 arx100 zte zxv10h201l zxv10h201l_nor zxv10h201l:SYS_BOOT_NOR Luka Perkov ++Active mips mips32 arx100 zte zxv10h201l zxv10h201l_ram zxv10h201l:SYS_BOOT_RAM Luka Perkov ++Active mips mips32 arx100 zte zxv10h201l zxv10h201l_zte zxv10h201l:SYS_BOOT_ZTE Luka Perkov + Active mips mips32 au1x00 - dbau1x00 dbau1000 dbau1x00:DBAU1000 Thomas Lange + Active mips mips32 au1x00 - dbau1x00 dbau1100 dbau1x00:DBAU1100 Thomas Lange + Active mips mips32 au1x00 - dbau1x00 dbau1500 dbau1x00:DBAU1500 Thomas Lange +--- /dev/null ++++ b/include/configs/zxv10h201l.h +@@ -0,0 +1,77 @@ ++/* ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ZXV10 H201L" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "ZTE ZXV10 H201L" ++ ++/* 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_SPL_NOR_FLASH /* Build NOR flash SPL */ ++#define CONFIG_LTQ_SPL_COMP_LZO /* Compress SPL with LZO */ ++#define CONFIG_LTQ_SPL_CONSOLE /* Enable SPL console */ ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_RTL8306 ++ ++/* 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_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 ++ ++#if defined(CONFIG_SYS_BOOT_ZTE) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++#if defined(CONFIG_SYS_BOOT_ZTE) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#endif ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.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 */ diff --git a/package/boot/uboot-lantiq/patches/0033-MIPS-add-board-support-for-ZyXEL-P-661HNU-Fx.patch b/package/boot/uboot-lantiq/patches/0033-MIPS-add-board-support-for-ZyXEL-P-661HNU-Fx.patch new file mode 100644 index 0000000..38d7856 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0033-MIPS-add-board-support-for-ZyXEL-P-661HNU-Fx.patch @@ -0,0 +1,304 @@ +From a18f994f373db4467a4680f83ead997c8122908e Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Wed, 22 May 2013 17:48:08 +0200 +Subject: MIPS: add board support for ZyXEL P-661HNU-Fx + +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/zyxel/p661hnufx/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/zyxel/p661hnufx/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/zyxel/p661hnufx/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * The values have been extracted from original ZyXEL U-Boot. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 0x307 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x103 ++#define MC_DC09_VALUE 0x80B ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xE02 ++#define MC_DC12_VALUE 0x2C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x100 ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xF ++#define MC_DC18_VALUE 0x301 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0x1600 ++#define MC_DC22_VALUE 0x1616 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x5D ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x5FB ++#define MC_DC29_VALUE 0x35DF ++#define MC_DC30_VALUE 0x99E9 ++#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 0x600 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/zyxel/p661hnufx/p661hnufx.c +@@ -0,0 +1,102 @@ ++/* ++ * Copyright (C) 2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void gpio_init(void) ++{ ++ /* SPI CS 0.4 to serial flash */ ++ gpio_direction_output(10, 1); ++} ++ ++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 Tantos switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII }, ++ /* MAC1: unused */ ++ { 1, 0x0, LTQ_ETH_PORT_NONE, 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(ð_board_config); ++} ++ ++static struct switch_device psb697x_dev = { ++ .name = "psb697x", ++ .cpu_port = 5, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ printf("%s\n", __func__); ++ ++#if 0 ++ ltq_reset_once(LTQ_RESET_HARD, 200000); ++ __udelay(50000); ++#endif ++ ++ return switch_device_register(&psb697x_dev); ++} ++ ++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 +@@ -499,6 +499,9 @@ Active mips mips32 - + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_nor zxv10h201l:SYS_BOOT_NOR Luka Perkov + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_ram zxv10h201l:SYS_BOOT_RAM Luka Perkov + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_zte zxv10h201l:SYS_BOOT_ZTE Luka Perkov ++Active mips mips32 arx100 zyxel p661hnufx p661hnufx_ram p661hnufx:SYS_BOOT_RAM Luka Perkov ++Active mips mips32 arx100 zyxel p661hnufx p661hnufx_sfspl p661hnufx:SYS_BOOT_SFSPL Luka Perkov ++Active mips mips32 arx100 zyxel p661hnufx p661hnufx_zyxel p661hnufx:SYS_BOOT_ZYXEL Luka Perkov + Active mips mips32 au1x00 - dbau1x00 dbau1000 dbau1x00:DBAU1000 Thomas Lange + Active mips mips32 au1x00 - dbau1x00 dbau1100 dbau1x00:DBAU1100 Thomas Lange + Active mips mips32 au1x00 - dbau1x00 dbau1500 dbau1x00:DBAU1500 Thomas Lange +--- /dev/null ++++ b/include/configs/p661hnufx.h +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (C) 2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "P-661HNU-Fx" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "ZyXEL P-661HNU-Fx" ++ ++/* 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 /* Supports Macronix serial flash */ ++#define CONFIG_SPI_FLASH_4BYTE_MODE ++ ++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */ ++#define CONFIG_LTQ_SPL_COMP_LZO /* Compress SPL with LZO */ ++#define CONFIG_LTQ_SPL_CONSOLE /* Enable SPL console */ ++ ++#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 ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_PSB697X ++ ++/* 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 (512 * 1024) ++#define CONFIG_ENV_SECT_SIZE (256 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++#if defined(CONFIG_SYS_BOOT_ZYXEL) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.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/0034-MIPS-add-board-support-for-ZyXEL-P-2601HN-Fx.patch b/package/boot/uboot-lantiq/patches/0034-MIPS-add-board-support-for-ZyXEL-P-2601HN-Fx.patch new file mode 100644 index 0000000..2cf66e4 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0034-MIPS-add-board-support-for-ZyXEL-P-2601HN-Fx.patch @@ -0,0 +1,242 @@ +From 4bfa74583bc938d2da41f255f22baa1845332893 Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Tue, 12 Mar 2013 01:42:46 +0100 +Subject: MIPS: add board support for ZyXEL P-2601HN-Fx + +Signed-off-by: Luka Perkov + +--- /dev/null ++++ b/board/zyxel/p2601hnfx/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/zyxel/p2601hnfx/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/zyxel/p2601hnfx/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * The values have been extracted from original ZyXEL U-Boot. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 0x306 ++#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 0x144 ++#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 0x1900 ++#define MC_DC22_VALUE 0x1919 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x66 ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x50A ++#define MC_DC29_VALUE 0x2D65 ++#define MC_DC30_VALUE 0x81B1 ++#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 0x600 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/zyxel/p2601hnfx/p2601hnfx.c +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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: REALTEK RTL8306 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(ð_board_config); ++} ++ ++static struct switch_device rtl8306_dev = { ++ .name = "rtl8306", ++ .cpu_port = 5, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ return switch_device_register(&rtl8306_dev); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -499,6 +499,10 @@ Active mips mips32 - + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_nor zxv10h201l:SYS_BOOT_NOR Luka Perkov + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_ram zxv10h201l:SYS_BOOT_RAM Luka Perkov + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_zte zxv10h201l:SYS_BOOT_ZTE Luka Perkov ++Active mips mips32 arx100 zyxel p2601hnfx p2601hnfx_nor p2601hnfx:SYS_BOOT_NOR Luka Perkov ++Active mips mips32 arx100 zyxel p2601hnfx p2601hnfx_norspl p2601hnfx:SYS_BOOT_NORSPL Luka Perkov ++Active mips mips32 arx100 zyxel p2601hnfx p2601hnfx_ram p2601hnfx:SYS_BOOT_RAM Luka Perkov ++Active mips mips32 arx100 zyxel p2601hnfx p2601hnfx_zyxel p2601hnfx:SYS_BOOT_ZYXEL Luka Perkov + Active mips mips32 arx100 zyxel p661hnufx p661hnufx_ram p661hnufx:SYS_BOOT_RAM Luka Perkov + Active mips mips32 arx100 zyxel p661hnufx p661hnufx_sfspl p661hnufx:SYS_BOOT_SFSPL Luka Perkov + Active mips mips32 arx100 zyxel p661hnufx p661hnufx_zyxel p661hnufx:SYS_BOOT_ZYXEL Luka Perkov +--- /dev/null ++++ b/include/configs/p2601hnfx.h +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "P-2601HN-Fx" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "ZyXEL P-2601HN-Fx" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */ ++#define CONFIG_LTQ_SPL_COMP_LZO /* Compress SPL with LZO */ ++#define CONFIG_LTQ_SPL_CONSOLE /* Enable SPL console */ ++ ++/* 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_SECT_SIZE (128 * 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 (128 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++#if defined(CONFIG_SYS_BOOT_ZYXEL) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.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 \ ++ "kernel_addr=0xB0040000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0035-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch b/package/boot/uboot-lantiq/patches/0035-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch new file mode 100644 index 0000000..3a0d8a6 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0035-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch @@ -0,0 +1,301 @@ +From 3f7be04a148d23cdb5fd320e0e2923983f8bd1f4 Mon Sep 17 00:00:00 2001 +From: Luka Perkov +Date: Tue, 6 Aug 2013 22:51:00 +0200 +Subject: MIPS: add board support for ZyXEL P-2812HNU-Fx + +Signed-off-by: Luka Perkov + +--- /dev/null ++++ b/board/zyxel/p2812hnufx/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/zyxel/p2812hnufx/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/zyxel/p2812hnufx/ddr_settings.h +@@ -0,0 +1,70 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * The values have been extracted from original ZyXEL U-Boot. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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/zyxel/p2812hnufx/p2812hnufx.c +@@ -0,0 +1,97 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#else ++#define do_gpio_init 0 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#endif ++ ++static void gpio_init(void) ++{ ++ /* 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(ð_board_config); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -540,6 +540,8 @@ Active mips mips32 vrx20 + Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_nandspl zxhnh367n:SYS_BOOT_NANDSPL Luka Perkov + Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_ram zxhnh367n:SYS_BOOT_RAM Luka Perkov + Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_zte zxhnh367n:SYS_BOOT_ZTE Luka Perkov ++Active mips mips32 vrx200 zyxel p2812hnufx p2812hnufx_nandspl p2812hnufx:SYS_BOOT_NANDSPL Luka Perkov ++Active mips mips32 vrx200 zyxel p2812hnufx p2812hnufx_ram p2812hnufx:SYS_BOOT_RAM Luka Perkov + Active mips mips64 - - qemu-mips qemu_mips64 qemu-mips64:SYS_BIG_ENDIAN - + Active mips mips64 - - qemu-mips qemu_mips64el qemu-mips64:SYS_LITTLE_ENDIAN - + Active nds32 n1213 ag101 AndesTech adp-ag101 adp-ag101 - Andes +--- /dev/null ++++ b/include/configs/p2812hnufx.h +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "P-2812HNU-Fx" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "ZyXEL P-2812HNU-Fx" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NAND_FLASH /* Have a K9F1G08U0D NAND flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH /* Build NAND flash SPL */ ++#define CONFIG_LTQ_SPL_COMP_LZO /* Compress SPL with LZO */ ++#define CONFIG_LTQ_SPL_CONSOLE /* Enable SPL console */ ++ ++#define CONFIG_SYS_NAND_PAGE_COUNT 64 ++#define CONFIG_SYS_NAND_PAGE_SIZE 2048 ++#define CONFIG_SYS_NAND_OOBSIZE 64 ++#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024) ++#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS ++#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x4000 ++ ++#define CONFIG_SYS_DRAM_PROBE ++ ++/* Environment */ ++#if defined(CONFIG_SYS_BOOT_NANDSPL) ++#define CONFIG_ENV_IS_IN_NAND ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (256 * 1024) ++#define CONFIG_ENV_SECT_SIZE (128 * 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" ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NAND \ ++ "update-uboot-nand=run load-uboot-nandspl-lzo write-uboot-nand\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NAND ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0036-MIPS-add-board-support-for-Arcadyan-Easybox-904.patch b/package/boot/uboot-lantiq/patches/0036-MIPS-add-board-support-for-Arcadyan-Easybox-904.patch new file mode 100644 index 0000000..a9cc6d9 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0036-MIPS-add-board-support-for-Arcadyan-Easybox-904.patch @@ -0,0 +1,277 @@ +From 60856fa8f9866f292df740ea98752a70738eb59a Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Fri, 9 Aug 2013 18:11:07 +0200 +Subject: MIPS: add board support for Arcadyan Easybox 904 + +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/arcadyan/easybox904/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/easybox904/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/easybox904/ddr_settings.h +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 0x1000000 ++#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 0x4401503 ++#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 0x1536B0 ++#define MC_CCR36_VALUE 0xC8 ++#define MC_CCR37_VALUE 0xC351 ++#define MC_CCR38_VALUE 0x0 ++#define MC_CCR39_VALUE 0x142404 ++#define MC_CCR40_VALUE 0x142604 ++#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 0x7C00301 ++#define MC_CCR58_VALUE 0x7C00301 ++#define MC_CCR59_VALUE 0x7C00301 ++#define MC_CCR60_VALUE 0x7C00301 ++#define MC_CCR61_VALUE 0x4 +--- /dev/null ++++ b/board/arcadyan/easybox904/easybox904.c +@@ -0,0 +1,98 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#else ++#define do_gpio_init 0 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#endif ++ ++static inline void gpio_init(void) ++{ ++ /* 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: ??? */ ++ { 0, 0x0, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_NONE }, ++ /* GMAC1: ??? */ ++ { 1, 0x1, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_NONE }, ++ /* GMAC2: ??? */ ++ { 2, 0x11, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_NONE }, ++ /* GMAC3: unused */ ++ { 3, 0x0, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_NONE }, ++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for WANoE port */ ++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC5: ??? */ ++ { 5, 0x5, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_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) ++{ ++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0; ++ const ulong fw_ge_addr = 0x80FE0000; ++ ++ ltq_gphy_phy11g_a2x_load(fw_ge_addr); ++ ++ ltq_cgu_gphy_clk_src(clk); ++ ++ ltq_rcu_gphy_boot(0, fw_ge_addr); ++ ltq_rcu_gphy_boot(1, fw_ge_addr); ++ ++ return ltq_eth_initialize(ð_board_config); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -529,6 +529,7 @@ Active mips mips32 incai + Active mips mips32 incaip - incaip incaip_100MHz incaip:CPU_CLOCK_RATE=100000000 Wolfgang Denk + Active mips mips32 incaip - incaip incaip_133MHz incaip:CPU_CLOCK_RATE=133000000 Wolfgang Denk + Active mips mips32 incaip - incaip incaip_150MHz incaip:CPU_CLOCK_RATE=150000000 Wolfgang Denk ++Active mips mips32 vrx200 arcadyan easybox904 easybox904_ram easybox904:SYS_BOOT_RAM Daniel Schwierzeck + Active mips mips32 vrx200 avm fb3370 fb3370_eva fb3370:SYS_BOOT_EVA Daniel Schwierzeck + Active mips mips32 vrx200 avm fb3370 fb3370_ram fb3370:SYS_BOOT_RAM Daniel Schwierzeck + Active mips mips32 vrx200 avm fb3370 fb3370_sfspl fb3370:SYS_BOOT_SFSPL Daniel Schwierzeck +--- /dev/null ++++ b/include/configs/easybox904.h +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "EASYBOX904" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan EasyBox 904" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NAND_FLASH ++ ++#define CONFIG_SYS_DRAM_PROBE ++ ++/* Environment */ ++#define CONFIG_ENV_IS_NOWHERE ++ ++#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" ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0037-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch b/package/boot/uboot-lantiq/patches/0037-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch new file mode 100644 index 0000000..676ef12 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0037-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch @@ -0,0 +1,242 @@ +From fbdbf2ddf2b34d675d53de679c179788b0604c1a Mon Sep 17 00:00:00 2001 +From: Oliver Muth +Date: Sat, 12 Oct 2013 16:49:53 +0200 +Subject: MIPS: add board support for Arcadyan ARV752DPW + +Signed-off-by: Oliver Muth +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/arcadyan/arv752dpw/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/arv752dpw/arv752dpw.c +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2012 Luka Perkov ++ * Copyright (C) 2013 Oliver Muth ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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: Realtek rtl8306 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(ð_board_config); ++} ++static struct switch_device rtl8306_dev = { ++ .name = "rtl8306", ++ .cpu_port = 5, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ return switch_device_register(&rtl8306_dev); ++} +--- /dev/null ++++ b/board/arcadyan/arv752dpw/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv752dpw/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2011-2013 Luka Perkov ++ * ++ * This file has been generated with lantiq_ram_extract_magic.awk script. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 +@@ -518,6 +518,9 @@ Active mips mips32 danub + Active mips mips32 danube arcadyan arv7518pw arv7518pw_brn arv7518pw:SYS_BOOT_BRN Luka Perkov + Active mips mips32 danube arcadyan arv7518pw arv7518pw_nor arv7518pw:SYS_BOOT_NOR Luka Perkov + Active mips mips32 danube arcadyan arv7518pw arv7518pw_ram arv7518pw:SYS_BOOT_RAM Luka Perkov ++Active mips mips32 danube arcadyan arv752dpw arv752dpw_brn arv752dpw:SYS_BOOT_BRN - ++Active mips mips32 danube arcadyan arv752dpw arv752dpw_nor arv752dpw:SYS_BOOT_NOR - ++Active mips mips32 danube arcadyan arv752dpw arv752dpw_ram arv752dpw:SYS_BOOT_RAM - + Active mips mips32 danube audiocodes acmp252 acmp252_nor acmp252:SYS_BOOT_NOR Daniel Golle + Active mips mips32 danube audiocodes acmp252 acmp252_ram acmp252:SYS_BOOT_RAM Daniel Golle + Active mips mips32 danube gigaset sx76x gigasx76x_nor sx76x:SYS_BOOT_NOR Luka Perkov +--- /dev/null ++++ b/include/configs/arv752dpw.h +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) 2012-2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ARV752DPW" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan ARV752DPW" ++ ++/* 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_RTL8206 ++ ++/* 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_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Brnboot loadable image */ ++#if defined(CONFIG_SYS_BOOT_BRN) ++#define CONFIG_SYS_TEXT_BASE 0x80002000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#define CONFIG_ENV_OVERWRITE 1 ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#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/0038-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch b/package/boot/uboot-lantiq/patches/0038-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch new file mode 100644 index 0000000..2cf0e95 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0038-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch @@ -0,0 +1,244 @@ +From 09f411b4d10f10a62f147264121bb853b4649c3e Mon Sep 17 00:00:00 2001 +From: Oliver Muth +Date: Sat, 12 Oct 2013 16:49:53 +0200 +Subject: MIPS: add board support for Arcadyan ARV752DPW22 + +Signed-off-by: Oliver Muth +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/arcadyan/arv752dpw22/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/arv752dpw22/arv752dpw22.c +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (C) 2012 Luka Perkov ++ * Copyright (C) 2013 Oliver Muth ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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_MII }, ++}; ++ ++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(ð_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/arv752dpw22/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv752dpw22/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2011-2013 Luka Perkov ++ * ++ * This file has been generated with lantiq_ram_extract_magic.awk script. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 +@@ -521,6 +521,9 @@ Active mips mips32 danub + Active mips mips32 danube arcadyan arv752dpw arv752dpw_brn arv752dpw:SYS_BOOT_BRN - + Active mips mips32 danube arcadyan arv752dpw arv752dpw_nor arv752dpw:SYS_BOOT_NOR - + Active mips mips32 danube arcadyan arv752dpw arv752dpw_ram arv752dpw:SYS_BOOT_RAM - ++Active mips mips32 danube arcadyan arv752dpw22 arv752dpw22_brn arv752dpw22:SYS_BOOT_BRN - ++Active mips mips32 danube arcadyan arv752dpw22 arv752dpw22_nor arv752dpw22:SYS_BOOT_NOR - ++Active mips mips32 danube arcadyan arv752dpw22 arv752dpw22_ram arv752dpw22:SYS_BOOT_RAM - + Active mips mips32 danube audiocodes acmp252 acmp252_nor acmp252:SYS_BOOT_NOR Daniel Golle + Active mips mips32 danube audiocodes acmp252 acmp252_ram acmp252:SYS_BOOT_RAM Daniel Golle + Active mips mips32 danube gigaset sx76x gigasx76x_nor sx76x:SYS_BOOT_NOR Luka Perkov +--- /dev/null ++++ b/include/configs/arv752dpw22.h +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (C) 2012-2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ARV752DPW22" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan ARV752DPW22" ++ ++/* 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_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Burnboot loadable image */ ++#if defined(CONFIG_SYS_BOOT_BRN) ++#define CONFIG_SYS_TEXT_BASE 0x80002000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#define CONFIG_ENV_OVERWRITE 1 ++#endif ++ ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#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/0039-MIPS-add-board-support-for-Arcadyan-ARV7510.patch b/package/boot/uboot-lantiq/patches/0039-MIPS-add-board-support-for-Arcadyan-ARV7510.patch new file mode 100644 index 0000000..76f8955 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0039-MIPS-add-board-support-for-Arcadyan-ARV7510.patch @@ -0,0 +1,269 @@ +From ba27086a5174130d138d645c2f4a49b08c3f2386 Mon Sep 17 00:00:00 2001 +From: Matti Laakso +Date: Sat, 2 Mar 2013 23:34:00 +0100 +Subject: MIPS: add board support for Arcadyan ARV7510 + +Signed-off-by: Matti Laakso +Signed-off-by: Daniel Schwierzeck + +--- /dev/null ++++ b/board/arcadyan/arv7510pw/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/arv7510pw/arv7510pw.c +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (C) 2013 Matti Laakso ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void gpio_init(void) ++{ ++ /* Initialize SSIO GPIOs */ ++ gpio_set_altfunc(4, 1, 0, 1); ++ gpio_set_altfunc(5, 1, 0, 1); ++ gpio_set_altfunc(6, 1, 0, 1); ++ ltq_gpio_init(); ++ ++ /* Power led on */ ++ gpio_direction_output(76, 1); ++} ++ ++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: ADM6996I */ ++ { 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(ð_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); ++} +--- /dev/null ++++ b/board/arcadyan/arv7510pw/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv7510pw/ddr_settings.h +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (C) 2013 Matti Laakso ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 0x120 ++#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 0x52 ++#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 +@@ -515,6 +515,9 @@ Active mips mips32 au1x0 + Active mips mips32 danube arcadyan arv4519pw arv4519pw_brn arv4519pw:SYS_BOOT_BRN Luka Perkov + Active mips mips32 danube arcadyan arv4519pw arv4519pw_nor arv4519pw:SYS_BOOT_NOR Luka Perkov + Active mips mips32 danube arcadyan arv4519pw arv4519pw_ram arv4519pw:SYS_BOOT_RAM Luka Perkov ++Active mips mips32 danube arcadyan arv7510pw arv7510pw_brn arv7510pw:SYS_BOOT_BRN Luka Perkov ++Active mips mips32 danube arcadyan arv7510pw arv7510pw_nor arv7510pw:SYS_BOOT_NOR Luka Perkov ++Active mips mips32 danube arcadyan arv7510pw arv7510pw_ram arv7510pw:SYS_BOOT_RAM Luka Perkov + Active mips mips32 danube arcadyan arv7518pw arv7518pw_brn arv7518pw:SYS_BOOT_BRN Luka Perkov + Active mips mips32 danube arcadyan arv7518pw arv7518pw_nor arv7518pw:SYS_BOOT_NOR Luka Perkov + Active mips mips32 danube arcadyan arv7518pw arv7518pw_ram arv7518pw:SYS_BOOT_RAM Luka Perkov +--- /dev/null ++++ b/include/configs/arv7510pw.h +@@ -0,0 +1,75 @@ ++/* ++ * Copyright (C) 2013 Matti Laakso ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ARV7510PW" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan ARV7510PW" ++ ++/* 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 ++ ++/* SSIO */ ++#define CONFIG_LTQ_SSIO_SHIFT_REGS ++#define CONFIG_LTQ_SSIO_EDGE_FALLING ++#define CONFIG_LTQ_SSIO_GPHY1_MODE 0 ++#define CONFIG_LTQ_SSIO_GPHY2_MODE 0 ++#define CONFIG_LTQ_SSIO_INIT_VALUE 0 ++ ++/* 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_SECT_SIZE (128 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Brnboot loadable image */ ++#if defined(CONFIG_SYS_BOOT_BRN) ++#define CONFIG_SYS_TEXT_BASE 0x80002000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#define CONFIG_ENV_OVERWRITE 1 ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Buffered write broken in ARV7510PW */ ++#undef CONFIG_SYS_FLASH_USE_BUFFER_WRITE ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#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=0xB0060000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0041-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch b/package/boot/uboot-lantiq/patches/0041-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch new file mode 100644 index 0000000..f866921 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0041-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch @@ -0,0 +1,238 @@ +--- /dev/null ++++ b/board/arcadyan/arv7510pw22/arv7510pw22.c +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2014 Álvaro Fernández Rojas ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int board_early_init_f(void) ++{ ++ /* Switch on Power LED */ ++ gpio_direction_output(2, 0); ++ gpio_set_value(2, 0); ++ ++ 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(ð_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/arv7510pw22/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv7510pw22/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2014 Álvaro Fernández Rojas ++ * ++ * This file has been generated with lantiq_ram_extract_magic.awk script. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 +--- /dev/null ++++ b/board/arcadyan/arv7510pw22/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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 ++ ++######################################################################### +--- a/boards.cfg ++++ b/boards.cfg +@@ -518,6 +518,9 @@ Active mips mips32 danub + Active mips mips32 danube arcadyan arv7510pw arv7510pw_brn arv7510pw:SYS_BOOT_BRN Luka Perkov + Active mips mips32 danube arcadyan arv7510pw arv7510pw_nor arv7510pw:SYS_BOOT_NOR Luka Perkov + Active mips mips32 danube arcadyan arv7510pw arv7510pw_ram arv7510pw:SYS_BOOT_RAM Luka Perkov ++Active mips mips32 danube arcadyan arv7510pw22 arv7510pw22_brn arv7510pw22:SYS_BOOT_BRN Álvaro Fernández Rojas ++Active mips mips32 danube arcadyan arv7510pw22 arv7510pw22_nor arv7510pw22:SYS_BOOT_NOR Álvaro Fernández Rojas ++Active mips mips32 danube arcadyan arv7510pw22 arv7510pw22_ram arv7510pw22:SYS_BOOT_RAM Álvaro Fernández Rojas + Active mips mips32 danube arcadyan arv7518pw arv7518pw_brn arv7518pw:SYS_BOOT_BRN Luka Perkov + Active mips mips32 danube arcadyan arv7518pw arv7518pw_nor arv7518pw:SYS_BOOT_NOR Luka Perkov + Active mips mips32 danube arcadyan arv7518pw arv7518pw_ram arv7518pw:SYS_BOOT_RAM Luka Perkov +--- /dev/null ++++ b/include/configs/arv7510pw22.h +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) 2014 Álvaro Fernández Rojas ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ARV7510PW22" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan ARV7510PW22" ++ ++/* 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 (256 * 1024) ++#define CONFIG_ENV_SECT_SIZE (128 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Burnboot loadable image */ ++#if defined(CONFIG_SYS_BOOT_BRN) ++#define CONFIG_SYS_TEXT_BASE 0x80002000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#define CONFIG_ENV_OVERWRITE 1 ++#endif ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#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=0xB0060000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0041-Makefile-prepare-u-boot-lantiq-v2013.10-openwrt4.patch b/package/boot/uboot-lantiq/patches/0041-Makefile-prepare-u-boot-lantiq-v2013.10-openwrt4.patch new file mode 100644 index 0000000..1f89e54 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0041-Makefile-prepare-u-boot-lantiq-v2013.10-openwrt4.patch @@ -0,0 +1,18 @@ +From 7e2f79bc40b572763a4a1ed69f63aa2eaa6df254 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck +Date: Sun, 20 Oct 2013 19:39:17 +0200 +Subject: Makefile: prepare u-boot-lantiq-v2013.10-openwrt4 + +Signed-off-by: Daniel Schwierzeck + +--- a/Makefile ++++ b/Makefile +@@ -8,7 +8,7 @@ + VERSION = 2013 + PATCHLEVEL = 10 + SUBLEVEL = +-EXTRAVERSION = ++EXTRAVERSION = -openwrt4 + ifneq "$(SUBLEVEL)" "" + U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) + else diff --git a/package/boot/uboot-lantiq/patches/0041-lzma-fixup.patch b/package/boot/uboot-lantiq/patches/0041-lzma-fixup.patch new file mode 100644 index 0000000..5b16758 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0041-lzma-fixup.patch @@ -0,0 +1,44 @@ +From: Antonios Vamporakis +Date: Tue, 31 Dec 2013 01:05:42 +0100 +Subject: [PATCH] lzma: fix buffer bound check error + +Variable uncompressedSize references the space available, while outSizeFull is +the actual expected uncompressed size. Using the wrong value causes LzmaDecode +to return SZ_ERROR_INPUT_EOF. Problem was introduced in commit afca294. While +at it add additional debug message. + +Signed-off-by: Antonios Vamporakis +CC: Kees Cook +CC: Simon Glass +CC: Daniel Schwierzeck +CC: Luka Perkov +--- + lib/lzma/LzmaTools.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/lib/lzma/LzmaTools.c b/lib/lzma/LzmaTools.c +index 0aec2f9..90d31cd 100644 +--- a/lib/lzma/LzmaTools.c ++++ b/lib/lzma/LzmaTools.c +@@ -102,7 +102,7 @@ int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize, + return SZ_ERROR_OUTPUT_EOF; + + /* Decompress */ +- outProcessed = *uncompressedSize; ++ outProcessed = outSizeFull; + + WATCHDOG_RESET(); + +@@ -111,6 +111,9 @@ int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize, + inStream + LZMA_DATA_OFFSET, &compressedSize, + inStream, LZMA_PROPS_SIZE, LZMA_FINISH_END, &state, &g_Alloc); + *uncompressedSize = outProcessed; ++ ++ debug("LZMA: Uncompresed ................ 0x%zx\n", outProcessed); ++ + if (res != SZ_OK) { + return res; + } +-- +1.8.3.2 + diff --git a/package/boot/uboot-lantiq/patches/0042-arx100-cgu-fixes.patch b/package/boot/uboot-lantiq/patches/0042-arx100-cgu-fixes.patch new file mode 100644 index 0000000..8ca6a1e --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0042-arx100-cgu-fixes.patch @@ -0,0 +1,148 @@ +From patchwork Tue Jan 20 11:28:45 2015 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [OpenWrt-Devel] uboot-lantiq cgu settings for ramboot image +From: Ben Mulvihill +X-Patchwork-Id: 431024 +Message-Id: <1421753325.25187.58.camel@merveille.lan> +To: Daniel Schwierzeck +Cc: OpenWrt Development List +Date: Tue, 20 Jan 2015 12:28:45 +0100 + +On Tue, 2015-01-20 at 00:39 +0100, Ben Mulvihill wrote: +> On Mon, 2015-01-19 at 19:21 +0100, Ben Mulvihill wrote: +> > On Mon, 2015-01-19 at 16:47 +0100, Daniel Schwierzeck wrote: +> > > 2015-01-19 15:44 GMT+01:00 Ben Mulvihill : +> > > > On Mon, 2015-01-19 at 11:51 +0000, Conor O'Gorman wrote: +> > > >> On 19/01/15 10:46, Ben Mulvihill wrote: +> > > >> > Hello, +> > > >> > +> > > >> > I am trying to build uboot-lantiq for the BT Home Hub 3A (lantiq +> > > >> > ar9), and am wondering where to initialise the cgu, in the case +> > > >> > of a ramboot image for uart booting. Normally the cgu is initialised +> > > >> > in lowlevel_init, but that code is bypassed in ramboot images. The +> > > >> > result is that the board boots with the wrong cgu settings, which +> > > >> > sends the console haywire. So far I have tried two solutions: +> > > >> +> > > >> Another option is to try and not change anything. The console is already +> > > >> configured and running. The ram does need config. +> > > >> +> > > >> I was used to seeing the ramboot version running at half clock speed, at +> > > >> least on danube, previous to ar9. +> > > >> +> > > >> Conor +> > > > +> > > > Hi Conor, +> > > > +> > > > Thanks for the reply. But with the latest uboot-lantiq, not changing +> > > > anything means that I don't get a usable console. With an older +> > > > version I do at least get a uboot console, but no linux console when +> > > > I boot openwrt. Correcting the cgu settings solves both problems. +> > > > +> > > +> > > could you try this? +> > > +> > > diff --git a/arch/mips/cpu/mips32/arx100/cgu.c +> > > b/arch/mips/cpu/mips32/arx100/cgu.c +> > > index 6e71ee7..e0afbda 100644 +> > > --- a/arch/mips/cpu/mips32/arx100/cgu.c +> > > +++ b/arch/mips/cpu/mips32/arx100/cgu.c +> > > @@ -95,15 +95,5 @@ unsigned long ltq_get_cpu_clock(void) +> > > +> > > unsigned long ltq_get_bus_clock(void) +> > > { +> > > - u32 fpi_sel; +> > > - unsigned long clk; +> > > - +> > > - fpi_sel = ltq_cgu_sys_readl(1, CGU_SYS_FPI_SEL); +> > > - +> > > - if (fpi_sel) +> > > - clk = ltq_get_io_region_clock() / 2; +> > > - else +> > > - clk = ltq_get_io_region_clock(); +> > > - +> > > - return clk; +> > > + return ltq_get_io_region_clock(); +> > > } +> > > +> > > the UART driver calculates the baudrate from the FPI bus clock, but +> > > FPI_SEL is not available on AR9. FPI bus clock is always the same as +> > > DDR clock, Obviously a copy&paste error from VR9 code ;) +> > > +> > +> > No, even with this patch, I still don't get a working console I'm +> > afraid. If I don't set anything explicitly, the board comes up with +> > CGU_SYS set to 0x05, ie CGU_SYS_SYSSEL_PLL0_333_MHZ | +> > CGU_SYS_CPUSEL_EQUAL_DDRCLK | CGU_SYS_DDRSEL_THIRD_SYSCLK. +> > Is this a valid combination without CGU_SYS_PPESEL_250_MHZ ? +> > I don't understand what CGU_SYS_PPESEL_250_MHZ does? +> > The "right setting", as set by the stock uboot, is 0x80. +> +> P.S. There also seems to be a discrepancy between the uboot and +> linux code. I take it from what you say above that fpi clock, ddr +> clock and io region clock are all the same. Now if the least +> significant bit of CGU_SYS is set, then according to the uboot +> code - function ltq_get_bus_clock() - their value is one +> third of the system clock. But according to the linux code +> - function ltq_ar9_fpi_hz() in arch/mips/lantiq/xway/clk.c - +> their value in this case is equal to the system clock. +> +> Or am I getting muddled? It's past my bedtime! +> +> + +Some of the bitshifting in arch/mips/cpu/mips32/arx100/cgu.c is 1 +out. A patch along these lines should fix it: + +--- a/arch/mips/cpu/mips32/arx100/cgu.c 2015-01-20 11:57:22.000000000 +0100 ++++ b/arch/mips/cpu/mips32/arx100/cgu.c 2015-01-20 12:00:15.000000000 +0100 +@@ -10,12 +10,17 @@ + #include + #include + +-#define CGU_SYS_DDR_SEL (1 << 0) +-#define CGU_SYS_CPU_SEL (1 << 2) ++#define CGU_SYS_DDR_SHIFT 0 ++#define CGU_SYS_CPU_SHIFT 2 + #define CGU_SYS_SYS_SHIFT 3 ++#define CGU_SYS_FPI_SHIFT 6 ++#define CGU_SYS_PPE_SHIFT 7 ++ ++#define CGU_SYS_DDR_MASK (1 << CGU_SYS_DDR_SHIFT) ++#define CGU_SYS_CPU_MASK (1 << CGU_SYS_CPU_SHIFT) + #define CGU_SYS_SYS_MASK (0x3 << CGU_SYS_SYS_SHIFT) +-#define CGU_SYS_FPI_SEL (1 << 6) +-#define CGU_SYS_PPE_SEL (1 << 7) ++#define CGU_SYS_FPI_MASK (1 << CGU_SYS_FPI_SHIFT) ++#define CGU_SYS_PPE_MASK (1 << CGU_SYS_PPE_SHIFT) + + struct ltq_cgu_regs { + u32 rsvd0; +@@ -68,7 +73,7 @@ unsigned long ltq_get_io_region_clock(vo + u32 ddr_sel; + unsigned long clk; + +- ddr_sel = ltq_cgu_sys_readl(1, CGU_SYS_DDR_SEL); ++ ddr_sel = ltq_cgu_sys_readl(CGU_SYS_DDR_MASK, CGU_SYS_DDR_SHIFT); + + if (ddr_sel) + clk = ltq_get_system_clock() / 3; +@@ -83,7 +88,7 @@ unsigned long ltq_get_cpu_clock(void) + u32 cpu_sel; + unsigned long clk; + +- cpu_sel = ltq_cgu_sys_readl(1, CGU_SYS_CPU_SEL); ++ cpu_sel = ltq_cgu_sys_readl(CGU_SYS_CPU_MASK, CGU_SYS_CPU_SHIFT); + + if (cpu_sel) + clk = ltq_get_io_region_clock(); +@@ -98,7 +103,7 @@ unsigned long ltq_get_bus_clock(void) + u32 fpi_sel; + unsigned long clk; + +- fpi_sel = ltq_cgu_sys_readl(1, CGU_SYS_FPI_SEL); ++ fpi_sel = ltq_cgu_sys_readl(CGU_SYS_FPI_MASK, CGU_SYS_FPI_SHIFT); + + if (fpi_sel) + clk = ltq_get_io_region_clock() / 2; diff --git a/package/boot/uboot-lantiq/patches/0043-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch b/package/boot/uboot-lantiq/patches/0043-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch new file mode 100644 index 0000000..adb894f --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0043-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch @@ -0,0 +1,346 @@ +--- /dev/null ++++ b/board/arcadyan/vgv7510kw22/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/vgv7510kw22/vgv7510kw22.c +@@ -0,0 +1,136 @@ ++/* ++ * Copyright (C) 2015 Martin Blumenstingl ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ ++#define GPIO_POWER_GREEN 14 ++ ++static void gpio_init(void) ++{ ++ /* SPI CS 0.4 to serial flash */ ++ gpio_direction_output(10, 1); ++ ++ /* Turn on the green power LED */ ++ gpio_direction_output(GPIO_POWER_GREEN, 0); ++ gpio_set_value(GPIO_POWER_GREEN, 0); ++} ++ ++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[] = { ++ /* unused */ ++ { 0, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE }, ++ /* unused */ ++ { 1, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE }, ++ /* Internal GPHY0 with 10/100 firmware for LAN port 2 */ ++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++ /* Internal GPHY0 with 10/100 firmware for LAN port 1 */ ++ { 3, 0x12, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++ /* Internal GPHY1 with 10/100 firmware for LAN port 4 */ ++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++ /* Internal GPHY1 with 10/100 firmware for LAN port 3 */ ++ { 5, 0x14, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++}; ++ ++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; ++ ++ if (ltq_chip_version_get() == 1) ++ ltq_gphy_phy22f_a1x_load(fw_addr); ++ else ++ ltq_gphy_phy22f_a2x_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(ð_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; ++ } ++} +--- /dev/null ++++ b/board/arcadyan/vgv7510kw22/config.mk +@@ -0,0 +1,7 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/vgv7510kw22/ddr_settings.h +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (C) 2015 Martin Blumenstingl ++ * Based on code by: ++ * Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * and Lantiq Deutschland GmbH ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#define MC_CCR00_VALUE 0x101 ++#define MC_CCR01_VALUE 0x1000100 ++#define MC_CCR02_VALUE 0x1010000 ++#define MC_CCR03_VALUE 0x100 ++#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 0x2000401 ++#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 +--- a/boards.cfg ++++ b/boards.cfg +@@ -542,6 +542,9 @@ + Active mips mips32 incaip - incaip incaip_133MHz incaip:CPU_CLOCK_RATE=133000000 Wolfgang Denk + Active mips mips32 incaip - incaip incaip_150MHz incaip:CPU_CLOCK_RATE=150000000 Wolfgang Denk + Active mips mips32 vrx200 arcadyan easybox904 easybox904_ram easybox904:SYS_BOOT_RAM Daniel Schwierzeck ++Active mips mips32 vrx200 arcadyan vgv7510kw22 vgv7510kw22_brn vgv7510kw22:SYS_BOOT_BRN Martin Blumenstingl ++Active mips mips32 vrx200 arcadyan vgv7510kw22 vgv7510kw22_nor vgv7510kw22:SYS_BOOT_NOR Martin Blumenstingl ++Active mips mips32 vrx200 arcadyan vgv7510kw22 vgv7510kw22_ram vgv7510kw22:SYS_BOOT_RAM Martin Blumenstingl + Active mips mips32 vrx200 avm fb3370 fb3370_eva fb3370:SYS_BOOT_EVA Daniel Schwierzeck + Active mips mips32 vrx200 avm fb3370 fb3370_ram fb3370:SYS_BOOT_RAM Daniel Schwierzeck + Active mips mips32 vrx200 avm fb3370 fb3370_sfspl fb3370:SYS_BOOT_SFSPL Daniel Schwierzeck +--- /dev/null ++++ b/include/configs/vgv7510kw22.h +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (C) 2015 Martin Blumenstingl ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "VGV7510KW22" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan VGV7510KW22" ++ ++/* 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 MX29GL128EL parallel flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */ ++#define CONFIG_LTQ_SPL_COMP_LZO /* Compress SPL with LZO */ ++#define CONFIG_LTQ_SPL_CONSOLE /* Enable SPL console */ ++ ++#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_SYS_BOOTM_LEN 0x1000000 /* 16 MB */ ++ ++/* 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_BRN) ++#define CONFIG_SYS_TEXT_BASE 0x80002000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#define CONFIG_ENV_IS_NOWHERE ++#elif 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 (128 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (128 * 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" ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ "kernel_addr=0xB0080000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0044-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch b/package/boot/uboot-lantiq/patches/0044-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch new file mode 100644 index 0000000..5cc71b6 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0044-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch @@ -0,0 +1,240 @@ +--- /dev/null ++++ b/board/arcadyan/arv8539pw22/Makefile +@@ -0,0 +1,28 @@ ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++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/arv8539pw22/arv8539pw22.c +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (C) 2012 Luka Perkov ++ * Copyright (C) 2013 Oliver Muth ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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_MII }, ++}; ++ ++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(ð_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/arv8539pw22/config.mk +@@ -0,0 +1,8 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) ++ +--- /dev/null ++++ b/board/arcadyan/arv8539pw22/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2011-2013 Luka Perkov ++ * ++ * This file has been generated with lantiq_ram_extract_magic.awk script. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#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 +@@ -553,6 +553,9 @@ Active mips mips32 danube arcadyan arv752dpw + Active mips mips32 danube arcadyan arv752dpw22 arv752dpw22_brn arv752dpw22:SYS_BOOT_BRN - + Active mips mips32 danube arcadyan arv752dpw22 arv752dpw22_nor arv752dpw22:SYS_BOOT_NOR - + Active mips mips32 danube arcadyan arv752dpw22 arv752dpw22_ram arv752dpw22:SYS_BOOT_RAM - ++Active mips mips32 danube arcadyan arv8539pw22 arv8539pw22_brn arv8539pw22:SYS_BOOT_BRN - ++Active mips mips32 danube arcadyan arv8539pw22 arv8539pw22_nor arv8539pw22:SYS_BOOT_NOR - ++Active mips mips32 danube arcadyan arv8539pw22 arv8539pw22_ram arv8539pw22:SYS_BOOT_RAM - + Active mips mips32 danube audiocodes acmp252 acmp252_nor acmp252:SYS_BOOT_NOR Daniel Golle + Active mips mips32 danube audiocodes acmp252 acmp252_ram acmp252:SYS_BOOT_RAM Daniel Golle + Active mips mips32 danube gigaset sx76x gigasx76x_nor sx76x:SYS_BOOT_NOR Luka Perkov +--- /dev/null ++++ b/include/configs/arv8539pw22.h +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (C) 2012-2013 Luka Perkov ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ARV8539PW22" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Speedport W 504V Typ A" ++ ++/* 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_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Burnboot loadable image */ ++#if defined(CONFIG_SYS_BOOT_BRN) ++#define CONFIG_SYS_TEXT_BASE 0x80002000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#define CONFIG_ENV_OVERWRITE 1 ++#endif ++ ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyS1" ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include ++#include ++ ++/* Pull in default OpenWrt configs for Lantiq SoC */ ++#include "openwrt-lantiq-common.h" ++ ++#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-mxs/Makefile b/package/boot/uboot-mxs/Makefile new file mode 100644 index 0000000..373b8d8 --- /dev/null +++ b/package/boot/uboot-mxs/Makefile @@ -0,0 +1,96 @@ +# +# Copyright (C) 2013-2015 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:=2015.07 +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:= \ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=3dac9a0b46fed77fc768ad3bd2d68c05 + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/mx23_olinuxino + TITLE:=U-Boot 2015.07 for the Olinuxino i.MX233 +endef + +define uboot/duckbill + TITLE:=U-Boot 2015.07 for the I2SE Duckbill +endef + +UBOOTS := \ + mx23_olinuxino \ + duckbill + +define Package/uboot/template +define Package/uboot-mxs-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_mxs + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Zoltan HERPAI +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),u-boot.sb) +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) $(UBOOT_IMAGE) +endef + +define Package/uboot/install/default + $(INSTALL_DIR) $(BIN_DIR)/uboot-$(BOARD)-$(1) + $(CP) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(BIN_DIR)/uboot-$(BOARD)-$(1)/uboot-$(BOARD)-$(1).sb +endef + +define Package/uboot/install/template +define Package/uboot-mxs-$(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-mxs-$(u))) \ +) diff --git a/package/boot/uboot-mxs/patches/001-add-i2se-duckbill.patch b/package/boot/uboot-mxs/patches/001-add-i2se-duckbill.patch new file mode 100644 index 0000000..f410b19 --- /dev/null +++ b/package/boot/uboot-mxs/patches/001-add-i2se-duckbill.patch @@ -0,0 +1,581 @@ +From 4d9a32780ec795b9edc83c7b3a1e947cec49a5a4 Mon Sep 17 00:00:00 2001 +From: Michael Heimpold +Date: Sat, 15 Aug 2015 20:26:18 +0200 +Subject: [PATCH] Add support for I2SE Duckbill boards + +Signed-off-by: Michael Heimpold +--- + arch/arm/Kconfig | 6 ++ + arch/arm/include/asm/mach-types.h | 13 +++ + board/i2se/duckbill/Kconfig | 15 ++++ + board/i2se/duckbill/MAINTAINERS | 6 ++ + board/i2se/duckbill/Makefile | 12 +++ + board/i2se/duckbill/duckbill.c | 112 +++++++++++++++++++++++ + board/i2se/duckbill/iomux.c | 125 ++++++++++++++++++++++++++ + configs/duckbill_defconfig | 9 ++ + include/configs/duckbill.h | 177 +++++++++++++++++++++++++++++++++++++ + 9 files changed, 475 insertions(+) + create mode 100644 board/i2se/duckbill/Kconfig + create mode 100644 board/i2se/duckbill/MAINTAINERS + create mode 100644 board/i2se/duckbill/Makefile + create mode 100644 board/i2se/duckbill/duckbill.c + create mode 100644 board/i2se/duckbill/iomux.c + create mode 100644 configs/duckbill_defconfig + create mode 100644 include/configs/duckbill.h + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 9908b43..7c795ac 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -178,6 +178,11 @@ config TARGET_MX28EVK + select CPU_ARM926EJS + select SUPPORT_SPL + ++config TARGET_DUCKBILL ++ bool "Support I2SE Duckbill" ++ select CPU_ARM926EJS ++ select SUPPORT_SPL ++ + config TARGET_MX23_OLINUXINO + bool "Support mx23_olinuxino" + select CPU_ARM926EJS +@@ -926,6 +931,7 @@ source "board/genesi/mx51_efikamx/Kconfig" + source "board/gumstix/pepper/Kconfig" + source "board/h2200/Kconfig" + source "board/hale/tt01/Kconfig" ++source "board/i2se/duckbill/Kconfig" + source "board/icpdas/lp8x4x/Kconfig" + source "board/imx31_phycore/Kconfig" + source "board/isee/igep0033/Kconfig" +diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h +index 5afe791..330a88d 100644 +--- a/arch/arm/include/asm/mach-types.h ++++ b/arch/arm/include/asm/mach-types.h +@@ -1109,6 +1109,7 @@ extern unsigned int __machine_arch_type; + #define MACH_TYPE_COLIBRI_T30 4493 + #define MACH_TYPE_APALIS_T30 4513 + #define MACH_TYPE_OMAPL138_LCDK 2495 ++#define MACH_TYPE_DUCKBILL 4754 + + #ifdef CONFIG_ARCH_EBSA110 + # ifdef machine_arch_type +@@ -14262,6 +14263,18 @@ extern unsigned int __machine_arch_type; + # define machine_is_apalis_t30() (0) + #endif + ++#ifdef CONFIG_MACH_DUCKBILL ++# ifdef machine_arch_type ++# undef machine_arch_type ++# define machine_arch_type __machine_arch_type ++# else ++# define machine_arch_type MACH_TYPE_DUCKBILL ++# endif ++# define machine_is_duckbill() (machine_arch_type == MACH_TYPE_DUCKBILL) ++#else ++# define machine_is_duckbill() (0) ++#endif ++ + /* + * These have not yet been registered + */ +diff --git a/board/i2se/duckbill/Kconfig b/board/i2se/duckbill/Kconfig +new file mode 100644 +index 0000000..98c1e46 +--- /dev/null ++++ b/board/i2se/duckbill/Kconfig +@@ -0,0 +1,15 @@ ++if TARGET_DUCKBILL ++ ++config SYS_BOARD ++ default "duckbill" ++ ++config SYS_VENDOR ++ default "i2se" ++ ++config SYS_SOC ++ default "mxs" ++ ++config SYS_CONFIG_NAME ++ default "duckbill" ++ ++endif +diff --git a/board/i2se/duckbill/MAINTAINERS b/board/i2se/duckbill/MAINTAINERS +new file mode 100644 +index 0000000..5496baa +--- /dev/null ++++ b/board/i2se/duckbill/MAINTAINERS +@@ -0,0 +1,6 @@ ++I2SE DUCKBILL BOARD ++M: Michael Heimpold ++S: Maintained ++F: board/i2se/duckbill/ ++F: include/configs/duckbill.h ++F: configs/duckbill_defconfig +diff --git a/board/i2se/duckbill/Makefile b/board/i2se/duckbill/Makefile +new file mode 100644 +index 0000000..b5577e3 +--- /dev/null ++++ b/board/i2se/duckbill/Makefile +@@ -0,0 +1,12 @@ ++# ++# (C) Copyright 2014-2015 ++# Michael Heimpold, mhei@heimpold.de. ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++ifndef CONFIG_SPL_BUILD ++obj-y := duckbill.o ++else ++obj-y := iomux.o ++endif +diff --git a/board/i2se/duckbill/duckbill.c b/board/i2se/duckbill/duckbill.c +new file mode 100644 +index 0000000..7794f65 +--- /dev/null ++++ b/board/i2se/duckbill/duckbill.c +@@ -0,0 +1,112 @@ ++/* ++ * I2SE Duckbill board ++ * ++ * (C) Copyright 2014-2015 Michael Heimpold ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define GPIO_PHY_RESET MX28_PAD_SSP0_DATA7__GPIO_2_7 ++#define GPIO_LED_GREEN MX28_PAD_AUART1_TX__GPIO_3_5 ++#define GPIO_LED_RED MX28_PAD_AUART1_RX__GPIO_3_4 ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* ++ * Functions ++ */ ++int board_early_init_f(void) ++{ ++ /* IO0 clock at 480MHz */ ++ mxs_set_ioclk(MXC_IOCLK0, 480000); ++ /* IO1 clock at 480MHz */ ++ mxs_set_ioclk(MXC_IOCLK1, 480000); ++ ++ /* SSP0 clock at 96MHz */ ++ mxs_set_sspclk(MXC_SSPCLK0, 96000, 0); ++ ++ return 0; ++} ++ ++int dram_init(void) ++{ ++ return mxs_dram_init(); ++} ++ ++int board_init(void) ++{ ++ /* Adress of boot parameters */ ++ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; ++ ++ return 0; ++} ++ ++#ifdef CONFIG_CMD_MMC ++int board_mmc_init(bd_t *bis) ++{ ++ return mxsmmc_initialize(bis, 0, NULL, NULL); ++} ++#endif ++ ++#ifdef CONFIG_CMD_NET ++int board_eth_init(bd_t *bis) ++{ ++ int ret; ++ ++ ret = cpu_eth_init(bis); ++ ++ /* Reset PHY */ ++ gpio_direction_output(GPIO_PHY_RESET, 0); ++ udelay(200); ++ gpio_set_value(GPIO_PHY_RESET, 1); ++ ++ /* give PHY some time to get out of the reset */ ++ udelay(10000); ++ ++ ret = fecmxc_initialize(bis); ++ if (ret) { ++ puts("FEC MXS: Unable to init FEC\n"); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++void mx28_adjust_mac(int dev_id, unsigned char *mac) ++{ ++ mac[0] = 0x00; ++ mac[1] = 0x01; ++ ++ if (dev_id == 1) /* Let MAC1 be MAC0 + 1 by default */ ++ mac[5] += 1; ++} ++#endif ++ ++int misc_init_r(void) ++{ ++ char *s = getenv("serial#"); ++ ++ /* enable red LED to indicate a running bootloader */ ++ gpio_direction_output(GPIO_LED_RED, 1); ++ ++ puts("Board: I2SE Duckbill\n"); ++ if (s && s[0]) { ++ puts("Serial: "); ++ puts(s); ++ putc('\n'); ++ } ++ ++ return 0; ++} +diff --git a/board/i2se/duckbill/iomux.c b/board/i2se/duckbill/iomux.c +new file mode 100644 +index 0000000..538e138 +--- /dev/null ++++ b/board/i2se/duckbill/iomux.c +@@ -0,0 +1,125 @@ ++/* ++ * I2SE Duckbill IOMUX setup ++ * ++ * Copyright (C) 2013-2015 Michael Heimpold ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MUX_CONFIG_SSP0 (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP) ++#define MUX_CONFIG_ENET (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP) ++#define MUX_CONFIG_EMI (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_NOPULL) ++ ++const iomux_cfg_t iomux_setup[] = { ++ /* DUART */ ++ MX28_PAD_PWM0__DUART_RX, ++ MX28_PAD_PWM1__DUART_TX, ++ ++ /* SD card */ ++ MX28_PAD_SSP0_DATA0__SSP0_D0 | MUX_CONFIG_SSP0, ++ MX28_PAD_SSP0_DATA1__SSP0_D1 | MUX_CONFIG_SSP0, ++ MX28_PAD_SSP0_DATA2__SSP0_D2 | MUX_CONFIG_SSP0, ++ MX28_PAD_SSP0_DATA3__SSP0_D3 | MUX_CONFIG_SSP0, ++ MX28_PAD_SSP0_CMD__SSP0_CMD | MUX_CONFIG_SSP0, ++ MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT | ++ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), ++ MX28_PAD_SSP0_SCK__SSP0_SCK | ++ (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), ++ ++ /* Ethernet */ ++ MX28_PAD_ENET0_MDC__ENET0_MDC | MUX_CONFIG_ENET, ++ MX28_PAD_ENET0_MDIO__ENET0_MDIO | MUX_CONFIG_ENET, ++ MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | MUX_CONFIG_ENET, ++ MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MUX_CONFIG_ENET, ++ MX28_PAD_ENET0_RXD0__ENET0_RXD0 | MUX_CONFIG_ENET, ++ MX28_PAD_ENET0_RXD1__ENET0_RXD1 | MUX_CONFIG_ENET, ++ MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MUX_CONFIG_ENET, ++ MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MUX_CONFIG_ENET, ++ MX28_PAD_ENET_CLK__CLKCTRL_ENET | MUX_CONFIG_ENET, ++ ++ /* PHY reset */ ++ MX28_PAD_SSP0_DATA7__GPIO_2_7 | ++ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), ++ ++ /* EMI */ ++ MX28_PAD_EMI_D00__EMI_DATA0 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D01__EMI_DATA1 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D02__EMI_DATA2 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D03__EMI_DATA3 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D04__EMI_DATA4 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D05__EMI_DATA5 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D06__EMI_DATA6 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D07__EMI_DATA7 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D08__EMI_DATA8 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D09__EMI_DATA9 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D10__EMI_DATA10 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D11__EMI_DATA11 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D12__EMI_DATA12 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D13__EMI_DATA13 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D14__EMI_DATA14 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_D15__EMI_DATA15 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_ODT0__EMI_ODT0 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_DQM0__EMI_DQM0 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_ODT1__EMI_ODT1 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_DQM1__EMI_DQM1 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_CLK__EMI_CLK | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_DQS0__EMI_DQS0 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_DQS1__EMI_DQS1 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN | MUX_CONFIG_EMI, ++ ++ MX28_PAD_EMI_A00__EMI_ADDR0 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A01__EMI_ADDR1 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A02__EMI_ADDR2 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A03__EMI_ADDR3 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A04__EMI_ADDR4 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A05__EMI_ADDR5 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A06__EMI_ADDR6 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A07__EMI_ADDR7 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A08__EMI_ADDR8 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A09__EMI_ADDR9 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A10__EMI_ADDR10 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A11__EMI_ADDR11 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A12__EMI_ADDR12 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A13__EMI_ADDR13 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_A14__EMI_ADDR14 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_BA0__EMI_BA0 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_BA1__EMI_BA1 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_BA2__EMI_BA2 | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_CASN__EMI_CASN | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_RASN__EMI_RASN | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_WEN__EMI_WEN | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_CE0N__EMI_CE0N | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_CE1N__EMI_CE1N | MUX_CONFIG_EMI, ++ MX28_PAD_EMI_CKE__EMI_CKE | MUX_CONFIG_EMI, ++ ++ /* LEDs */ ++ MX28_PAD_AUART1_RX__GPIO_3_4, ++ MX28_PAD_AUART1_TX__GPIO_3_5, ++}; ++ ++#define HW_DRAM_CTL29 (0x74 >> 2) ++#define CS_MAP 0xf ++#define COLUMN_SIZE 0x2 ++#define ADDR_PINS 0x1 ++#define APREBIT 0xa ++ ++#define HW_DRAM_CTL29_CONFIG (CS_MAP << 24 | COLUMN_SIZE << 16 | \ ++ ADDR_PINS << 8 | APREBIT) ++ ++void mxs_adjust_memory_params(uint32_t *dram_vals) ++{ ++ dram_vals[HW_DRAM_CTL29] = HW_DRAM_CTL29_CONFIG; ++} ++ ++void board_init_ll(const uint32_t arg, const uint32_t *resptr) ++{ ++ mxs_common_spl_init(arg, resptr, iomux_setup, ARRAY_SIZE(iomux_setup)); ++} +diff --git a/configs/duckbill_defconfig b/configs/duckbill_defconfig +new file mode 100644 +index 0000000..2edf895 +--- /dev/null ++++ b/configs/duckbill_defconfig +@@ -0,0 +1,9 @@ ++CONFIG_ARM=y ++CONFIG_TARGET_DUCKBILL=y ++CONFIG_SPL=y ++CONFIG_SYS_EXTRA_OPTIONS="ENV_IS_IN_MMC" ++# CONFIG_CMD_IMLS is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_SPI_FLASH is not set ++# CONFIG_CMD_FPGA is not set ++CONFIG_CMD_PING=y +diff --git a/include/configs/duckbill.h b/include/configs/duckbill.h +new file mode 100644 +index 0000000..46e403b +--- /dev/null ++++ b/include/configs/duckbill.h +@@ -0,0 +1,177 @@ ++/* ++ * Copyright (C) 2014-2015 Michael Heimpold ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef __CONFIGS_DUCKBILL_H__ ++#define __CONFIGS_DUCKBILL_H__ ++ ++/* System configurations */ ++#define CONFIG_MX28 /* i.MX28 SoC */ ++#define CONFIG_MACH_TYPE MACH_TYPE_DUCKBILL ++ ++#define CONFIG_MISC_INIT_R ++ ++#define CONFIG_SYS_MXS_VDD5V_ONLY ++ ++/* U-Boot Commands */ ++#define CONFIG_SYS_NO_FLASH ++#define CONFIG_DISPLAY_CPUINFO ++#define CONFIG_DOS_PARTITION ++ ++#define CONFIG_CMD_BOOTZ ++#define CONFIG_CMD_CACHE ++#define CONFIG_CMD_DHCP ++#define CONFIG_CMD_EXT4 ++#define CONFIG_CMD_EXT4_WRITE ++#define CONFIG_CMD_FAT ++#define CONFIG_CMD_FUSE ++#define CONFIG_CMD_GPIO ++#define CONFIG_CMD_I2C ++#define CONFIG_CMD_MII ++#define CONFIG_CMD_MMC ++#define CONFIG_CMD_SPI ++#define CONFIG_CMD_UNZIP ++ ++/* Memory configuration */ ++#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */ ++#define PHYS_SDRAM_1 0x40000000 /* Base address */ ++#define PHYS_SDRAM_1_SIZE 0x40000000 /* Max 1 GB RAM */ ++#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 ++ ++/* Environment is in MMC */ ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_IS_IN_MMC 1 ++#define CONFIG_ENV_SIZE (128 * 1024) ++#define CONFIG_ENV_OFFSET (128 * 1024) ++#define CONFIG_ENV_OFFSET_REDUND (256 * 1024) ++#define CONFIG_SYS_MMC_ENV_DEV 0 ++#define CONFIG_SYS_REDUNDAND_ENVIRONMENT ++ ++/* FEC Ethernet on SoC */ ++#ifdef CONFIG_CMD_NET ++#define CONFIG_FEC_MXC ++#define CONFIG_NET_MULTI ++#define CONFIG_MX28_FEC_MAC_IN_OCOTP ++#define CONFIG_FEC_MXC_PHYADDR 1 ++#define IMX_FEC_BASE MXS_ENET0_BASE ++#endif ++ ++#define CONFIG_IPADDR 192.168.1.10 ++#define CONFIG_SERVERIP 192.168.1.1 ++#define CONFIG_NETMASK 255.255.255.0 ++#define CONFIG_GATEWAYIP 192.168.1.254 ++ ++/* BOOTP options */ ++#define CONFIG_BOOTP_SUBNETMASK ++#define CONFIG_BOOTP_GATEWAY ++#define CONFIG_BOOTP_HOSTNAME ++ ++/* SPI */ ++#ifdef CONFIG_CMD_SPI ++#define CONFIG_DEFAULT_SPI_BUS 2 ++#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0 ++#endif ++ ++/* Boot Linux */ ++#define CONFIG_BOOTDELAY 1 ++#define CONFIG_BOOTFILE "zImage" ++#define CONFIG_LOADADDR 0x42000000 ++#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR ++ ++/* Extra Environment */ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ "update_sd_firmware_filename=openwrt-mxs-root.ext4\0" \ ++ "update_sd_firmware=" \ ++ "if mmc rescan; then " \ ++ "if tftp ${update_sd_firmware_filename}; then " \ ++ "setexpr fw_sz ${filesize} / 200; " \ ++ "setexpr fw_sz ${fw_sz} + 1; " \ ++ "mmc dev ${mmcdev} 3; " \ ++ "mmc write ${loadaddr} 0 ${fw_sz}; " \ ++ "mmc dev ${mmcdev} 2; " \ ++ "mmc write ${loadaddr} 0 ${fw_sz}; " \ ++ "mmc dev ${mmcdev}; " \ ++ "fi; " \ ++ "fi\0" \ ++ "erase_mmc=mmc erase 0 2\0" \ ++ "erase_env1=mmc erase 100 100\0" \ ++ "erase_env2=mmc erase 200 100\0" \ ++ "script=boot.scr\0" \ ++ "image=zImage\0" \ ++ "console=ttyAMA0\0" \ ++ "fdt_file=imx28-duckbill.dtb\0" \ ++ "fdt_addr=0x41000000\0" \ ++ "boot_fdt=try\0" \ ++ "ip_dyn=yes\0" \ ++ "bootsys=1\0" \ ++ "mmcdev=0\0" \ ++ "mmcpart=2\0" \ ++ "mmcroot=/dev/mmcblk0p2\0" \ ++ "mmcargs=setenv bootargs console=${console},${baudrate} " \ ++ "root=${mmcroot} " \ ++ "rootwait bootsys=${bootsys} panic=1\0" \ ++ "loadbootscript=" \ ++ "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \ ++ "bootscript=echo Running bootscript from mmc ...; " \ ++ "source\0" \ ++ "loadimage=ext4load mmc ${mmcdev}:${mmcpart} ${loadaddr} /boot/${image}\0" \ ++ "loadfdt=ext4load mmc ${mmcdev}:${mmcpart} ${fdt_addr} /boot/${fdt_file}\0" \ ++ "mmcboot=echo Booting from mmc ...; " \ ++ "setexpr mmcpart 1 + ${bootsys}; " \ ++ "setenv mmcroot /dev/mmcblk0p${mmcpart}; " \ ++ "run mmcargs; " \ ++ "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ ++ "if run loadfdt; then " \ ++ "bootz ${loadaddr} - ${fdt_addr}; " \ ++ "else " \ ++ "if test ${boot_fdt} = try; then " \ ++ "bootz; " \ ++ "else " \ ++ "echo WARN: Cannot load the DT; " \ ++ "fi; " \ ++ "fi; " \ ++ "else " \ ++ "bootz; " \ ++ "fi;\0" \ ++ "netargs=setenv bootargs console=${console},${baudrate} " \ ++ "root=/dev/nfs " \ ++ "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ ++ "netboot=echo Booting from net ...; " \ ++ "run netargs; " \ ++ "if test ${ip_dyn} = yes; then " \ ++ "setenv get_cmd dhcp; " \ ++ "else " \ ++ "setenv get_cmd tftp; " \ ++ "fi; " \ ++ "${get_cmd} ${image}; " \ ++ "if test ${boot_fdt} = yes; then " \ ++ "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ ++ "bootz ${loadaddr} - ${fdt_addr}; " \ ++ "else " \ ++ "if test ${boot_fdt} = try; then " \ ++ "bootz; " \ ++ "else " \ ++ "echo WARN: Cannot load the DT; " \ ++ "fi;" \ ++ "fi; " \ ++ "else " \ ++ "bootz; " \ ++ "fi;\0" ++ ++#define CONFIG_BOOTCOMMAND \ ++ "mmc dev ${mmcdev}; if mmc rescan; then " \ ++ "if run loadbootscript; then " \ ++ "run bootscript; " \ ++ "else " \ ++ "if run loadimage; then " \ ++ "run mmcboot; " \ ++ "else run netboot; " \ ++ "fi; " \ ++ "fi; " \ ++ "else run netboot; fi" ++ ++/* The rest of the configuration is shared */ ++#include ++ ++#endif /* __CONFIGS_DUCKBILL_H__ */ +-- +1.7.10.4 + diff --git a/package/boot/uboot-omap/Makefile b/package/boot/uboot-omap/Makefile new file mode 100644 index 0000000..e21e2e1 --- /dev/null +++ b/package/boot/uboot-omap/Makefile @@ -0,0 +1,103 @@ +# +# 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.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:= \ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=a076a044b64371edc52f7e562b13f6b2 + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/omap4_panda + TITLE:=U-Boot for the Pandaboard +endef + +define uboot/am335x_evm + TITLE:=U-Boot for the AM335x EVM +endef + +define uboot/omap3_overo + TITLE:=U-Boot for the Gumstix Overo +endef + +define uboot/omap3_beagle + TITLE:=U-Boot for the BeagleBoard +endef + +UBOOTS:=omap4_panda am335x_evm omap3_overo omap3_beagle + +define Package/uboot/template +define Package/uboot-omap-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_omap + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + HIDDEN:=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.img) +endif + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + USE_PRIVATE_LIBGCC=yes $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/default + $(INSTALL_DIR) $(BIN_DIR)/uboot-$(BOARD)-$(1) + $(CP) $(PKG_BUILD_DIR)/u-boot.img $(BIN_DIR)/uboot-$(BOARD)-$(1)/u-boot.img + $(CP) $(PKG_BUILD_DIR)/MLO $(BIN_DIR)/uboot-$(BOARD)-$(1)/MLO +endef + +define Package/uboot/install/template +define Package/uboot-omap-$(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-omap-$(u))) \ +) diff --git a/package/boot/uboot-omap/patches/001-switch_omap4_ext4.patch b/package/boot/uboot-omap/patches/001-switch_omap4_ext4.patch new file mode 100644 index 0000000..d741c08 --- /dev/null +++ b/package/boot/uboot-omap/patches/001-switch_omap4_ext4.patch @@ -0,0 +1,11 @@ +--- a/include/configs/omap4_common ++++ b/include/configs/omap4_common.h +@@ -143,7 +143,7 @@ + "vram=16M\0" \ + "mmcdev=0\0" \ + "mmcroot=/dev/mmcblk0p2 rw\0" \ +- "mmcrootfstype=ext3 rootwait\0" \ ++ "mmcrootfstype=ext4 rootwait\0" \ + "mmcargs=setenv bootargs console=${console} " \ + "vram=${vram} " \ + "root=${mmcroot} " \ diff --git a/package/boot/uboot-omap/patches/002-fix_jffs2.patch b/package/boot/uboot-omap/patches/002-fix_jffs2.patch new file mode 100644 index 0000000..cba0e25 --- /dev/null +++ b/package/boot/uboot-omap/patches/002-fix_jffs2.patch @@ -0,0 +1,34 @@ +Building boards that have JFFS2 support enabled will fail when using +U-Boot's builtin GCC library, for example like this: + +USE_PRIVATE_LIBGCC=yes ./MAKEALL omap3_evm +... +fs/jffs2/libjffs2.o: In function `jffs2_1pass_build_lists': +fs/jffs2/jffs2_1pass.c:1441: undefined reference to `__aeabi_uldivmod' + +This is caused by a u64 / u32 division in jffs2_1pass.c; the problem +can be avoided by using do_div() instead of plain division. + +Signed-off-by: Wolfgang Denk +Reported-by: Chris Ruehl +Cc: Chris Ruehl + +--- + fs/jffs2/jffs2_1pass.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c +index c856983..a7dbe79 100644 +--- a/fs/jffs2/jffs2_1pass.c ++++ b/fs/jffs2/jffs2_1pass.c +@@ -1438,7 +1438,7 @@ jffs2_1pass_build_lists(struct part_info * part) + { + struct b_lists *pL; + struct jffs2_unknown_node *node; +- u32 nr_sectors = part->size/part->sector_size; ++ u32 nr_sectors = do_div(part->size, part->sector_size); + u32 i; + u32 counter4 = 0; + u32 counterF = 0; +-- +1.8.3.1 diff --git a/package/boot/uboot-omap/patches/003-fix_findfdt_C4.patch b/package/boot/uboot-omap/patches/003-fix_findfdt_C4.patch new file mode 100644 index 0000000..b0b85e5 --- /dev/null +++ b/package/boot/uboot-omap/patches/003-fix_findfdt_C4.patch @@ -0,0 +1,11 @@ +--- a/include/configs/omap3_beagle.h ++++ b/include/configs/omap3_beagle.h +@@ -242,6 +242,8 @@ + "setenv fdtfile omap3-beagle.dtb; fi; " \ + "if test $beaglerev = Cx; then " \ + "setenv fdtfile omap3-beagle.dtb; fi; " \ ++ "if test $beaglerev = C4; then " \ ++ "setenv fdtfile omap3-beagle.dtb; fi; " \ + "if test $beaglerev = xMAB; then " \ + "setenv fdtfile omap3-beagle-xm.dtb; fi; " \ + "if test $beaglerev = xMC; then " \ diff --git a/package/boot/uboot-oxnas/Makefile b/package/boot/uboot-oxnas/Makefile new file mode 100644 index 0000000..825907b --- /dev/null +++ b/package/boot/uboot-oxnas/Makefile @@ -0,0 +1,102 @@ +# +# 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:=2014.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:= \ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot + +PKG_MD5SUM:=3ddcaee2f05b7c464778112ec83664b5 + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/ox820 + TITLE:=U-Boot for the Oxford/PLX NAS7820 +endef + +UBOOTS:=ox820 + +define Package/uboot/template +define Package/uboot-oxnas-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_oxnas + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Daniel Golle +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) \ + 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 + $(CP) $(PKG_BUILD_DIR)/u-boot.bin \ + $(KERNEL_BUILD_DIR)/u-boot.bin +endef + +define Package/uboot/install/template +define Package/uboot-oxnas-$(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-oxnas-$(u))) \ +) diff --git a/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/Makefile b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/Makefile new file mode 100644 index 0000000..4c32f5c --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008-2009 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += reset.o +obj-y += timer.o +obj-y += clock.o +obj-y += pinmux.o diff --git a/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/clock.c b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/clock.c new file mode 100644 index 0000000..8974ca0 --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/clock.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include + +typedef struct { + unsigned short mhz; + unsigned char refdiv; + unsigned char outdiv; + unsigned int fbdiv; + unsigned short bwadj; + unsigned short sfreq; + unsigned int sslope; +} PLL_CONFIG; + +const PLL_CONFIG C_PLL_CONFIG[] = { + { 500, 1, 2, 3932160, 119, 208, 189 }, // 500 MHz + { 525, 2, 1, 4128768, 125, 139, 297 }, // 525 MHz + { 550, 2, 1, 4325376, 131, 139, 311 }, // 550 MHz + { 575, 2, 1, 4521984, 137, 139, 326 }, // 575 MHz + { 600, 2, 1, 4718592, 143, 138, 339 }, // 600 MHz + { 625, 1, 1, 3276800, 99, 208, 157 }, // 625 MHz + { 650, 1, 1, 3407872, 103, 208, 164 }, // 650 MHz + { 675, 1, 1, 3538944, 107, 208, 170 }, // 675 MHz + { 700, 0, 0, 917504, 27, 416, 22 }, // 700 MHz + { 725, 1, 1, 3801088, 115, 208, 182 }, // 725 MHz + { 750, 0, 0, 983040, 29, 416, 23 }, // 750 MHz + { 775, 3, 0, 4063232, 123, 104, 390 }, // 775 MHz + { 800, 3, 0, 4194304, 127, 104, 403 }, // 800 MHz + { 825, 3, 0, 4325376, 131, 104, 415 }, // 825 MHz + { 850, 2, 0, 3342336, 101, 139, 241 }, // 850 MHz + { 875, 2, 0, 3440640, 104, 139, 248 }, // 875 MHz + { 900, 2, 0, 3538944, 107, 139, 255 }, // 900 MHz + { 925, 2, 0, 3637248, 110, 139, 262 }, // 925 MHz + { 950, 2, 0, 3735552, 113, 139, 269 }, // 950 MHz + { 975, 2, 0, 3833856, 116, 139, 276 }, // 975 MHz + { 1000, 2, 0, 3932160, 119, 139, 283 }, // 1000 MHz +}; + +#define PLL_BYPASS (1<<1) +#define SAT_ENABLE (1<<3) + +#define PLL_OUTDIV_SHIFT 4 +#define PLL_REFDIV_SHIFT 8 +#define PLL_BWADJ_SHIFT 16 + +#define PLL_LOW_FREQ 500 +#define PLL_FREQ_STEP 25 +static void plla_configure(int outdiv, int refdiv, int fbdiv, int bwadj, + int sfreq, int sslope) +{ + setbits_le32(SYS_CTRL_PLLA_CTRL0, PLL_BYPASS); + udelay(10); + reset_block(SYS_CTRL_RST_PLLA, 1); + udelay(10); + + writel((refdiv << PLL_REFDIV_SHIFT) | (outdiv << PLL_OUTDIV_SHIFT) | + SAT_ENABLE | PLL_BYPASS, + SYS_CTRL_PLLA_CTRL0); + + writel(fbdiv, SYS_CTRL_PLLA_CTRL1); + writel((bwadj << PLL_BWADJ_SHIFT) | sfreq, SYS_CTRL_PLLA_CTRL2); + writel(sslope, SYS_CTRL_PLLA_CTRL3); + + udelay(10); // 5us delay required (from TCI datasheet), use 10us + + reset_block(SYS_CTRL_RST_PLLA, 0); + + udelay(100); // Delay for PLL to lock + + printf(" plla_ctrl0 : %08x\n", readl(SYS_CTRL_PLLA_CTRL0)); + printf(" plla_ctrl1 : %08x\n", readl(SYS_CTRL_PLLA_CTRL1)); + printf(" plla_ctrl2 : %08x\n", readl(SYS_CTRL_PLLA_CTRL2)); + printf(" plla_ctrl3 : %08x\n", readl(SYS_CTRL_PLLA_CTRL3)); + + clrbits_le32(SYS_CTRL_PLLA_CTRL0, PLL_BYPASS); // Take PLL out of bypass + puts("\nPLLA Set\n"); +} + +int plla_set_config(int mhz) +{ + int index = (mhz - PLL_LOW_FREQ) / PLL_FREQ_STEP; + const PLL_CONFIG *cfg; + + if (index < 0 || index > ARRAY_SIZE(C_PLL_CONFIG)) { + debug("Freq %d MHz out of range, default to lowest\n", mhz); + index = 0; + } + cfg = &C_PLL_CONFIG[index]; + + printf("Attempting to set PLLA to %d MHz ...\n", (unsigned) cfg->mhz); + plla_configure(cfg->outdiv, cfg->refdiv, cfg->fbdiv, cfg->bwadj, + cfg->sfreq, cfg->sslope); + + return cfg->mhz; +} + diff --git a/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/pinmux.c b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/pinmux.c new file mode 100644 index 0000000..a6f5e9a --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/pinmux.c @@ -0,0 +1,43 @@ +#include +#include + +void pinmux_set(int bank, int pin, int func) +{ + u32 reg; + u32 base; + /* TODO: check parameters */ + + if (bank == PINMUX_BANK_MFA) + base = SYS_CONTROL_BASE; + else + base = SEC_CONTROL_BASE; + + clrbits_le32(base + PINMUX_SECONDARY_SEL, BIT(pin)); + clrbits_le32(base + PINMUX_TERTIARY_SEL, BIT(pin)); + clrbits_le32(base + PINMUX_QUATERNARY_SEL, BIT(pin)); + clrbits_le32(base + PINMUX_DEBUG_SEL, BIT(pin)); + clrbits_le32(base + PINMUX_ALTERNATIVE_SEL, BIT(pin)); + + switch (func) { + case PINMUX_GPIO: + default: + return; + break; + case PINMUX_2: + reg = base + PINMUX_SECONDARY_SEL; + break; + case PINMUX_3: + reg = base + PINMUX_TERTIARY_SEL; + break; + case PINMUX_4: + reg = base + PINMUX_QUATERNARY_SEL; + break; + case PINMUX_DEBUG: + reg = base + PINMUX_DEBUG_SEL; + break; + case PINMUX_ALT: + reg = base + PINMUX_ALTERNATIVE_SEL; + break; + } + setbits_le32(reg, BIT(pin)); +} diff --git a/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/reset.c b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/reset.c new file mode 100644 index 0000000..276c912 --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/reset.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +void reset_cpu(ulong addr) +{ + u32 value; + + // Assert reset to cores as per power on defaults + // Don't touch the DDR interface as things will come to an impromptu stop + // NB Possibly should be asserting reset for PLLB, but there are timing + // concerns here according to the docs + + value = + BIT(SYS_CTRL_RST_COPRO ) | + BIT(SYS_CTRL_RST_USBHS ) | + BIT(SYS_CTRL_RST_USBHSPHYA ) | + BIT(SYS_CTRL_RST_MACA ) | + BIT(SYS_CTRL_RST_PCIEA ) | + BIT(SYS_CTRL_RST_SGDMA ) | + BIT(SYS_CTRL_RST_CIPHER ) | + BIT(SYS_CTRL_RST_SATA ) | + BIT(SYS_CTRL_RST_SATA_LINK ) | + BIT(SYS_CTRL_RST_SATA_PHY ) | + BIT(SYS_CTRL_RST_PCIEPHY ) | + BIT(SYS_CTRL_RST_STATIC ) | + BIT(SYS_CTRL_RST_UART1 ) | + BIT(SYS_CTRL_RST_UART2 ) | + BIT(SYS_CTRL_RST_MISC ) | + BIT(SYS_CTRL_RST_I2S ) | + BIT(SYS_CTRL_RST_SD ) | + BIT(SYS_CTRL_RST_MACB ) | + BIT(SYS_CTRL_RST_PCIEB ) | + BIT(SYS_CTRL_RST_VIDEO ) | + BIT(SYS_CTRL_RST_USBHSPHYB ) | + BIT(SYS_CTRL_RST_USBDEV ); + + writel(value, SYS_CTRL_RST_SET_CTRL); + + // Release reset to cores as per power on defaults + writel(BIT(SYS_CTRL_RST_GPIO), SYS_CTRL_RST_CLR_CTRL); + + // Disable clocks to cores as per power-on defaults - must leave DDR + // related clocks enabled otherwise we'll stop rather abruptly. + value = + BIT(SYS_CTRL_CLK_COPRO) | + BIT(SYS_CTRL_CLK_DMA) | + BIT(SYS_CTRL_CLK_CIPHER) | + BIT(SYS_CTRL_CLK_SD) | + BIT(SYS_CTRL_CLK_SATA) | + BIT(SYS_CTRL_CLK_I2S) | + BIT(SYS_CTRL_CLK_USBHS) | + BIT(SYS_CTRL_CLK_MAC) | + BIT(SYS_CTRL_CLK_PCIEA) | + BIT(SYS_CTRL_CLK_STATIC) | + BIT(SYS_CTRL_CLK_MACB) | + BIT(SYS_CTRL_CLK_PCIEB) | + BIT(SYS_CTRL_CLK_REF600) | + BIT(SYS_CTRL_CLK_USBDEV); + + writel(value, SYS_CTRL_CLK_CLR_CTRL); + + // Enable clocks to cores as per power-on defaults + + // Set sys-control pin mux'ing as per power-on defaults + + writel(0, SYS_CONTROL_BASE + PINMUX_SECONDARY_SEL); + writel(0, SYS_CONTROL_BASE + PINMUX_TERTIARY_SEL); + writel(0, SYS_CONTROL_BASE + PINMUX_QUATERNARY_SEL); + writel(0, SYS_CONTROL_BASE + PINMUX_DEBUG_SEL); + writel(0, SYS_CONTROL_BASE + PINMUX_ALTERNATIVE_SEL); + writel(0, SYS_CONTROL_BASE + PINMUX_PULLUP_SEL); + + writel(0, SEC_CONTROL_BASE + PINMUX_SECONDARY_SEL); + writel(0, SEC_CONTROL_BASE + PINMUX_TERTIARY_SEL); + writel(0, SEC_CONTROL_BASE + PINMUX_QUATERNARY_SEL); + writel(0, SEC_CONTROL_BASE + PINMUX_DEBUG_SEL); + writel(0, SEC_CONTROL_BASE + PINMUX_ALTERNATIVE_SEL); + writel(0, SEC_CONTROL_BASE + PINMUX_PULLUP_SEL); + + // No need to save any state, as the ROM loader can determine whether reset + // is due to power cycling or programatic action, just hit the (self- + // clearing) CPU reset bit of the block reset register + value = + BIT(SYS_CTRL_RST_SCU) | + BIT(SYS_CTRL_RST_ARM0) | + BIT(SYS_CTRL_RST_ARM1); + + writel(value, SYS_CTRL_RST_SET_CTRL); +} diff --git a/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/timer.c b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/timer.c new file mode 100644 index 0000000..5e87608 --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/cpu/arm1136/nas782x/timer.c @@ -0,0 +1,129 @@ +/* + * (C) Copyright 2004 + * Texas Instruments + * Richard Woodruff + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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 +#include + +#define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (1 << (CONFIG_TIMER_PRESCALE * 4))) +#define TIMER_LOAD_VAL 0xFFFFFF + +/* macro to read the 32 bit timer */ +#define READ_TIMER (TIMER_LOAD_VAL - readl(CONFIG_SYS_TIMERBASE + TIMER_CURR)) \ + / (TIMER_CLOCK / CONFIG_SYS_HZ) + +#define READ_TIMER_HW (TIMER_LOAD_VAL - readl(CONFIG_SYS_TIMERBASE + TIMER_CURR)) + +DECLARE_GLOBAL_DATA_PTR; + +int timer_init (void) +{ + int32_t val; + + /* Start the counter ticking up */ + writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + TIMER_LOAD); /* reload value on overflow*/ + + val = (CONFIG_TIMER_PRESCALE << TIMER_PRESCALE_SHIFT) | + (TIMER_MODE_PERIODIC << TIMER_MODE_SHIFT) | + (TIMER_ENABLE << TIMER_ENABLE_SHIFT); /* mask to enable timer*/ + writel(val, CONFIG_SYS_TIMERBASE + TIMER_CTRL); /* start timer */ + + /* reset time */ + gd->arch.lastinc = READ_TIMER; /* capture current incrementer value */ + gd->arch.tbl = 0; /* start "advancing" time stamp */ + + return(0); +} +/* + * timer without interrupts + */ +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +/* delay x useconds AND preserve advance timestamp value */ +void __udelay (unsigned long usec) +{ + ulong tmo, tmp; + + if (usec > 100000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + + tmp = get_timer (0); /* get current timestamp */ + while (get_timer (tmp) < tmo)/* loop till event */ + /*NOP*/; + } else { /* else small number, convert to hw ticks */ + tmo = usec * (TIMER_CLOCK / 1000) / 1000; + /* timeout is no more than 0.1s, and the hw timer will roll over at most once */ + tmp = READ_TIMER_HW; + while (((READ_TIMER_HW -tmp) & TIMER_LOAD_VAL) < tmo)/* loop till event */ + /*NOP*/; + } +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; /* current tick value */ + + if (now >= gd->arch.lastinc) { /* normal mode (non roll) */ + /* move stamp fordward with absoulte diff ticks */ + gd->arch.tbl += (now - gd->arch.lastinc); + } else { + /* we have rollover of incrementer */ + gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ)) + - gd->arch.lastinc) + now; + } + gd->arch.lastinc = now; + return gd->arch.tbl; +} + + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/clock.h b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/clock.h new file mode 100644 index 0000000..da7dd1c --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/clock.h @@ -0,0 +1,84 @@ +#ifndef _NAS782X_CLOCK_H +#define _NAS782X_CLOCK_H + +#include +#include + +/* bit numbers of clock control register */ +#define SYS_CTRL_CLK_COPRO 0 +#define SYS_CTRL_CLK_DMA 1 +#define SYS_CTRL_CLK_CIPHER 2 +#define SYS_CTRL_CLK_SD 3 +#define SYS_CTRL_CLK_SATA 4 +#define SYS_CTRL_CLK_I2S 5 +#define SYS_CTRL_CLK_USBHS 6 +#define SYS_CTRL_CLK_MACA 7 +#define SYS_CTRL_CLK_MAC SYS_CTRL_CLK_MACA +#define SYS_CTRL_CLK_PCIEA 8 +#define SYS_CTRL_CLK_STATIC 9 +#define SYS_CTRL_CLK_MACB 10 +#define SYS_CTRL_CLK_PCIEB 11 +#define SYS_CTRL_CLK_REF600 12 +#define SYS_CTRL_CLK_USBDEV 13 +#define SYS_CTRL_CLK_DDR 14 +#define SYS_CTRL_CLK_DDRPHY 15 +#define SYS_CTRL_CLK_DDRCK 16 + +/* bit numbers of reset control register */ +#define SYS_CTRL_RST_SCU 0 +#define SYS_CTRL_RST_COPRO 1 +#define SYS_CTRL_RST_ARM0 2 +#define SYS_CTRL_RST_ARM1 3 +#define SYS_CTRL_RST_USBHS 4 +#define SYS_CTRL_RST_USBHSPHYA 5 +#define SYS_CTRL_RST_MACA 6 +#define SYS_CTRL_RST_MAC SYS_CTRL_RST_MACA +#define SYS_CTRL_RST_PCIEA 7 +#define SYS_CTRL_RST_SGDMA 8 +#define SYS_CTRL_RST_CIPHER 9 +#define SYS_CTRL_RST_DDR 10 +#define SYS_CTRL_RST_SATA 11 +#define SYS_CTRL_RST_SATA_LINK 12 +#define SYS_CTRL_RST_SATA_PHY 13 +#define SYS_CTRL_RST_PCIEPHY 14 +#define SYS_CTRL_RST_STATIC 15 +#define SYS_CTRL_RST_GPIO 16 +#define SYS_CTRL_RST_UART1 17 +#define SYS_CTRL_RST_UART2 18 +#define SYS_CTRL_RST_MISC 19 +#define SYS_CTRL_RST_I2S 20 +#define SYS_CTRL_RST_SD 21 +#define SYS_CTRL_RST_MACB 22 +#define SYS_CTRL_RST_PCIEB 23 +#define SYS_CTRL_RST_VIDEO 24 +#define SYS_CTRL_RST_DDR_PHY 25 +#define SYS_CTRL_RST_USBHSPHYB 26 +#define SYS_CTRL_RST_USBDEV 27 +#define SYS_CTRL_RST_ARMDBG 29 +#define SYS_CTRL_RST_PLLA 30 +#define SYS_CTRL_RST_PLLB 31 + +static inline void reset_block(int block, int reset) +{ + u32 reg; + if (reset) + reg = SYS_CTRL_RST_SET_CTRL; + else + reg = SYS_CTRL_RST_CLR_CTRL; + + writel(BIT(block), reg); +} + +static inline void enable_clock(int block) +{ + writel(BIT(block), SYS_CTRL_CLK_SET_CTRL); +} + +static inline void disable_clock(int block) +{ + writel(BIT(block), SYS_CTRL_CLK_CLR_CTRL); +} + +int plla_set_config(int idx); + +#endif /* _NAS782X_CLOCK_H */ diff --git a/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/cpu.h b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/cpu.h new file mode 100644 index 0000000..11e803c --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/cpu.h @@ -0,0 +1,26 @@ +#ifndef _NAS782X_CPU_H +#define _NAS782X_CPU_H + +#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__)) +#include +#include +#endif /* !(__KERNEL_STRICT_NAMES || __ASSEMBLY__) */ + +#include +#include + +#ifndef __KERNEL_STRICT_NAMES +#ifndef __ASSEMBLY__ + +#define BIT(x) (1 << (x)) + +/* fix "implicit declaration of function" warnning */ +void *memalign(size_t alignment, size_t bytes); +void free(void* mem); +void *malloc(size_t bytes); +void *calloc(size_t n, size_t elem_size); + +#endif /* __ASSEMBLY__ */ +#endif /* __KERNEL_STRICT_NAMES */ + +#endif /* _NAS782X_CPU_H */ diff --git a/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/hardware.h b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/hardware.h new file mode 100644 index 0000000..f26b17f --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/hardware.h @@ -0,0 +1,30 @@ +#ifndef _NAS782X_HARDWARE_H +#define _NAS782X_HARDWARE_H + +/* Core addresses */ +#define USB_HOST_BASE 0x40200000 +#define MACA_BASE 0x40400000 +#define MACB_BASE 0x40800000 +#define MAC_BASE MACA_BASE +#define STATIC_CS0_BASE 0x41000000 +#define STATIC_CS1_BASE 0x41400000 +#define STATIC_CONTROL_BASE 0x41C00000 +#define SATA_DATA_BASE 0x42000000 /* non-functional, DMA just needs an address */ +#define GPIO_1_BASE 0x44000000 +#define GPIO_2_BASE 0x44100000 +#define UART_1_BASE 0x44200000 +#define UART_2_BASE 0x44300000 +#define SYS_CONTROL_BASE 0x44e00000 +#define SEC_CONTROL_BASE 0x44f00000 +#define RPSA_BASE 0x44400000 +#define RPSC_BASE 0x44500000 +#define DDR_BASE 0x44700000 + +#define SATA_BASE 0x45900000 +#define SATA_0_REGS_BASE 0x45900000 +#define SATA_1_REGS_BASE 0x45910000 +#define SATA_DMA_REGS_BASE 0x459a0000 +#define SATA_SGDMA_REGS_BASE 0x459b0000 +#define SATA_HOST_REGS_BASE 0x459e0000 + +#endif /* _NAS782X_HARDWARE_H */ diff --git a/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/pinmux.h b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/pinmux.h new file mode 100644 index 0000000..810ba5c --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/pinmux.h @@ -0,0 +1,46 @@ +#ifndef _NAS782X_PINMUX_H +#define _NAS782X_PINMUX_H + +#include + +#define PINMUX_GPIO 0 +#define PINMUX_2 1 +#define PINMUX_3 2 +#define PINMUX_4 3 +#define PINMUX_DEBUG 4 +#define PINMUX_ALT 5 + +#define PINMUX_BANK_MFA 0 +#define PINMUX_BANK_MFB 1 + +/* System control multi-function pin function selection */ +#define PINMUX_SECONDARY_SEL 0x14 +#define PINMUX_TERTIARY_SEL 0x8c +#define PINMUX_QUATERNARY_SEL 0x94 +#define PINMUX_DEBUG_SEL 0x9c +#define PINMUX_ALTERNATIVE_SEL 0xa4 +#define PINMUX_PULLUP_SEL 0xac + +#define PINMUX_UARTA_SIN PINMUX_ALT +#define PINMUX_UARTA_SOUT PINMUX_ALT + +#define PINMUX_STATIC_DATA0 PINMUX_2 +#define PINMUX_STATIC_DATA1 PINMUX_2 +#define PINMUX_STATIC_DATA2 PINMUX_2 +#define PINMUX_STATIC_DATA3 PINMUX_2 +#define PINMUX_STATIC_DATA4 PINMUX_2 +#define PINMUX_STATIC_DATA5 PINMUX_2 +#define PINMUX_STATIC_DATA6 PINMUX_2 +#define PINMUX_STATIC_DATA7 PINMUX_2 +#define PINMUX_STATIC_NWE PINMUX_2 +#define PINMUX_STATIC_NOE PINMUX_2 +#define PINMUX_STATIC_NCS PINMUX_2 +#define PINMUX_STATIC_ADDR18 PINMUX_2 +#define PINMUX_STATIC_ADDR19 PINMUX_2 + +#define PINMUX_MACA_MDC PINMUX_2 +#define PINMUX_MACA_MDIO PINMUX_2 + +extern void pinmux_set(int bank, int pin, int func); + +#endif /* _NAS782X_PINMUX_H */ diff --git a/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/spl.h b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/spl.h new file mode 100644 index 0000000..f73afda --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/spl.h @@ -0,0 +1,6 @@ +#ifndef _NAS782X_SPL_H +#define _NAS782X_SPL_H + +#include + +#endif /* _NAS782X_SPL_H */ diff --git a/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/sysctl.h b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/sysctl.h new file mode 100644 index 0000000..3867e45 --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/sysctl.h @@ -0,0 +1,125 @@ +#ifndef _NAS782X_SYSCTL_H +#define _NAS782X_SYSCTL_H + +#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__)) +#include +#endif /* !(__KERNEL_STRICT_NAMES || __ASSEMBLY__) */ + +#include + +/** + * System block reset and clock control + */ +#define SYS_CTRL_PCI_STAT (SYS_CONTROL_BASE + 0x20) +#define SYS_CTRL_CLK_SET_CTRL (SYS_CONTROL_BASE + 0x2C) +#define SYS_CTRL_CLK_CLR_CTRL (SYS_CONTROL_BASE + 0x30) +#define SYS_CTRL_RST_SET_CTRL (SYS_CONTROL_BASE + 0x34) +#define SYS_CTRL_RST_CLR_CTRL (SYS_CONTROL_BASE + 0x38) +#define SYS_CTRL_PLLSYS_CTRL (SYS_CONTROL_BASE + 0x48) +#define SYS_CTRL_PLLSYS_KEY_CTRL (SYS_CONTROL_BASE + 0x6C) +#define SYS_CTRL_GMAC_CTRL (SYS_CONTROL_BASE + 0x78) + +/* Scratch registers */ +#define SYS_CTRL_SCRATCHWORD0 (SYS_CONTROL_BASE + 0xc4) +#define SYS_CTRL_SCRATCHWORD1 (SYS_CONTROL_BASE + 0xc8) +#define SYS_CTRL_SCRATCHWORD2 (SYS_CONTROL_BASE + 0xcc) +#define SYS_CTRL_SCRATCHWORD3 (SYS_CONTROL_BASE + 0xd0) + +#define SYS_CTRL_PLLA_CTRL0 (SYS_CONTROL_BASE + 0x1F0) +#define SYS_CTRL_PLLA_CTRL1 (SYS_CONTROL_BASE + 0x1F4) +#define SYS_CTRL_PLLA_CTRL2 (SYS_CONTROL_BASE + 0x1F8) +#define SYS_CTRL_PLLA_CTRL3 (SYS_CONTROL_BASE + 0x1FC) + +#define SYS_CTRL_GMAC_AUTOSPEED 3 +#define SYS_CTRL_GMAC_RGMII 2 +#define SYS_CTRL_GMAC_SIMPLE_MUX 1 +#define SYS_CTRL_GMAC_CKEN_GTX 0 + +#define SYS_CTRL_CKCTRL_CTRL_ADDR (SYS_CONTROL_BASE + 0x64) + +#define SYS_CTRL_CKCTRL_PCI_DIV_BIT 0 +#define SYS_CTRL_CKCTRL_SLOW_BIT 8 + + +#define SYS_CTRL_USBHSMPH_CTRL (SYS_CONTROL_BASE + 0x40) +#define SYS_CTRL_USBHSMPH_STAT (SYS_CONTROL_BASE + 0x44) +#define SYS_CTRL_REF300_DIV (SYS_CONTROL_BASE + 0xF8) +#define SYS_CTRL_USBHSPHY_CTRL (SYS_CONTROL_BASE + 0x84) +#define SYS_CTRL_USB_CTRL (SYS_CONTROL_BASE + 0x90) + +/* System control multi-function pin function selection */ +#define SYS_CTRL_SECONDARY_SEL (SYS_CONTROL_BASE + 0x14) +#define SYS_CTRL_TERTIARY_SEL (SYS_CONTROL_BASE + 0x8c) +#define SYS_CTRL_QUATERNARY_SEL (SYS_CONTROL_BASE + 0x94) +#define SYS_CTRL_DEBUG_SEL (SYS_CONTROL_BASE + 0x9c) +#define SYS_CTRL_ALTERNATIVE_SEL (SYS_CONTROL_BASE + 0xa4) +#define SYS_CTRL_PULLUP_SEL (SYS_CONTROL_BASE + 0xac) + +/* Secure control multi-function pin function selection */ +#define SEC_CTRL_SECONDARY_SEL (SEC_CONTROL_BASE + 0x14) +#define SEC_CTRL_TERTIARY_SEL (SEC_CONTROL_BASE + 0x8c) +#define SEC_CTRL_QUATERNARY_SEL (SEC_CONTROL_BASE + 0x94) +#define SEC_CTRL_DEBUG_SEL (SEC_CONTROL_BASE + 0x9c) +#define SEC_CTRL_ALTERNATIVE_SEL (SEC_CONTROL_BASE + 0xa4) +#define SEC_CTRL_PULLUP_SEL (SEC_CONTROL_BASE + 0xac) + +#define SEC_CTRL_COPRO_CTRL (SEC_CONTROL_BASE + 0x68) +#define SEC_CTRL_SECURE_CTRL (SEC_CONTROL_BASE + 0x98) +#define SEC_CTRL_LEON_DEBUG (SEC_CONTROL_BASE + 0xF0) +#define SEC_CTRL_PLLB_DIV_CTRL (SEC_CONTROL_BASE + 0xF8) +#define SEC_CTRL_PLLB_CTRL0 (SEC_CONTROL_BASE + 0x1F0) +#define SEC_CTRL_PLLB_CTRL1 (SEC_CONTROL_BASE + 0x1F4) +#define SEC_CTRL_PLLB_CTRL8 (SEC_CONTROL_BASE + 0x1F4) + +#define REF300_DIV_INT_SHIFT 8 +#define REF300_DIV_FRAC_SHIFT 0 +#define REF300_DIV_INT(val) ((val) << REF300_DIV_INT_SHIFT) +#define REF300_DIV_FRAC(val) ((val) << REF300_DIV_FRAC_SHIFT) + +#define USBHSPHY_SUSPENDM_MANUAL_ENABLE 16 +#define USBHSPHY_SUSPENDM_MANUAL_STATE 15 +#define USBHSPHY_ATE_ESET 14 +#define USBHSPHY_TEST_DIN 6 +#define USBHSPHY_TEST_ADD 2 +#define USBHSPHY_TEST_DOUT_SEL 1 +#define USBHSPHY_TEST_CLK 0 + +#define USB_CTRL_USBAPHY_CKSEL_SHIFT 5 +#define USB_CLK_XTAL0_XTAL1 (0 << USB_CTRL_USBAPHY_CKSEL_SHIFT) +#define USB_CLK_XTAL0 (1 << USB_CTRL_USBAPHY_CKSEL_SHIFT) +#define USB_CLK_INTERNAL (2 << USB_CTRL_USBAPHY_CKSEL_SHIFT) + +#define USBAMUX_DEVICE BIT(4) + +#define USBPHY_REFCLKDIV_SHIFT 2 +#define USB_PHY_REF_12MHZ (0 << USBPHY_REFCLKDIV_SHIFT) +#define USB_PHY_REF_24MHZ (1 << USBPHY_REFCLKDIV_SHIFT) +#define USB_PHY_REF_48MHZ (2 << USBPHY_REFCLKDIV_SHIFT) + +#define USB_CTRL_USB_CKO_SEL_BIT 0 + +#define USB_INT_CLK_XTAL 0 +#define USB_INT_CLK_REF300 2 +#define USB_INT_CLK_PLLB 3 + +#define SYS_CTRL_GMAC_AUTOSPEED 3 +#define SYS_CTRL_GMAC_RGMII 2 +#define SYS_CTRL_GMAC_SIMPLE_MUX 1 +#define SYS_CTRL_GMAC_CKEN_GTX 0 + + +#define PLLB_ENSAT 3 +#define PLLB_OUTDIV 4 +#define PLLB_REFDIV 8 +#define PLLB_DIV_INT_SHIFT 8 +#define PLLB_DIV_FRAC_SHIFT 0 +#define PLLB_DIV_INT(val) ((val) << PLLB_DIV_INT_SHIFT) +#define PLLB_DIV_FRAC(val) ((val) << PLLB_DIV_FRAC_SHIFT) + +#ifndef __KERNEL_STRICT_NAMES +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ +#endif /* __KERNEL_STRICT_NAMES */ + +#endif /* _NAS782X_SYSCTL_H */ diff --git a/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/timer.h b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/timer.h new file mode 100644 index 0000000..ea4d71e --- /dev/null +++ b/package/boot/uboot-oxnas/files/arch/arm/include/asm/arch-nas782x/timer.h @@ -0,0 +1,23 @@ +#ifndef _NAS782X_TIMER_H +#define _NAS782X_TIMER_H + +#define TIMER1_BASE (RPSA_BASE + 0x200) +#define TIMER2_BASE (RPSA_BASE + 0x220) + +#define TIMER_LOAD 0 +#define TIMER_CURR 4 +#define TIMER_CTRL 8 +#define TIMER_INTR 0x0C + +#define TIMER_PRESCALE_SHIFT 2 +#define TIMER_PRESCALE_1 0 +#define TIMER_PRESCALE_16 1 +#define TIMER_PRESCALE_256 2 +#define TIMER_MODE_SHIFT 6 +#define TIMER_MODE_FREE_RUNNING 0 +#define TIMER_MODE_PERIODIC 1 +#define TIMER_ENABLE_SHIFT 7 +#define TIMER_DISABLE 0 +#define TIMER_ENABLE 1 + +#endif /* _NAS782X_TIMER_H */ diff --git a/package/boot/uboot-oxnas/files/board/ox820/Kconfig b/package/boot/uboot-oxnas/files/board/ox820/Kconfig new file mode 100644 index 0000000..8f631aa --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/Kconfig @@ -0,0 +1,15 @@ +if TARGET_OX820 + +config SYS_CPU + default "arm1136" + +config SYS_SOC + default "nas782x" + +config SYS_BOARD + default "ox820" + +config SYS_CONFIG_NAME + default "ox820" + +endif diff --git a/package/boot/uboot-oxnas/files/board/ox820/MAINTAINERS b/package/boot/uboot-oxnas/files/board/ox820/MAINTAINERS new file mode 100644 index 0000000..a86ba26 --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/MAINTAINERS @@ -0,0 +1,6 @@ +SHEEVAPLUG BOARD +M: Daniel Golle +S: Maintained +F: board/ox820/ +F: include/configs/ox820.h +F: configs/ox820_defconfig diff --git a/package/boot/uboot-oxnas/files/board/ox820/Makefile b/package/boot/uboot-oxnas/files/board/ox820/Makefile new file mode 100644 index 0000000..445fc4c --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/Makefile @@ -0,0 +1,15 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008-2009 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ox820.o +obj-y += lowlevel_init.o + +obj-$(CONFIG_SPL_BUILD) += spl_start.o +obj-$(CONFIG_SPL_BUILD) += ddr.o + diff --git a/package/boot/uboot-oxnas/files/board/ox820/ddr.c b/package/boot/uboot-oxnas/files/board/ox820/ddr.c new file mode 100755 index 0000000..a665722 --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/ddr.c @@ -0,0 +1,477 @@ +/******************************************************************* + * + * File: ddr_oxsemi.c + * + * Description: Declarations for DDR routines and data objects + * + * Author: Julien Margetts + * + * Copyright: Oxford Semiconductor Ltd, 2009 + */ +#include +#include + +#include "ddr.h" + +typedef unsigned int UINT; + +// DDR TIMING PARAMETERS +typedef struct { + unsigned int holdoff_cmd_A; + unsigned int holdoff_cmd_ARW; + unsigned int holdoff_cmd_N; + unsigned int holdoff_cmd_LM; + unsigned int holdoff_cmd_R; + unsigned int holdoff_cmd_W; + unsigned int holdoff_cmd_PC; + unsigned int holdoff_cmd_RF; + unsigned int holdoff_bank_R; + unsigned int holdoff_bank_W; + unsigned int holdoff_dir_RW; + unsigned int holdoff_dir_WR; + unsigned int holdoff_FAW; + unsigned int latency_CAS; + unsigned int latency_WL; + unsigned int recovery_WR; + unsigned int width_update; + unsigned int odt_offset; + unsigned int odt_drive_all; + unsigned int use_fixed_re; + unsigned int delay_wr_to_re; + unsigned int wr_slave_ratio; + unsigned int rd_slave_ratio0; + unsigned int rd_slave_ratio1; +} T_DDR_TIMING_PARAMETERS; + +// DDR CONFIG PARAMETERS + +typedef struct { + unsigned int ddr_mode; + unsigned int width; + unsigned int blocs; + unsigned int banks8; + unsigned int rams; + unsigned int asize; + unsigned int speed; + unsigned int cmd_mode_wr_cl_bl; +} T_DDR_CONFIG_PARAMETERS; + +//cmd_mode_wr_cl_bl +//when SDR : cmd_mode_wr_cl_bl = 0x80200002 + (latency_CAS_RAM * 16) + (recovery_WR - 1) * 512; -- Sets write rec XX, CL=XX; BL=8 +//else cmd_mode_wr_cl_bl = 0x80200003 + (latency_CAS_RAM * 16) + (recovery_WR - 1) * 512; -- Sets write rec XX, CL=XX; BL=8 + +// cmd_ bank_ dir_ lat_ rec_ width_ odt_ odt_ fix delay ratio +// A F C update offset all re re_to_we w r0 r1 +// R L P R R W A A W W +//Timing Parameters A W N M R W C F R W W R W S L R +static const T_DDR_TIMING_PARAMETERS C_TP_DDR2_25E_CL5_1GB = { 4, 5, 0, 2, 4, 4, + 5, 51, 23, 24, 9, 11, 18, 5, 4, 6, 3, 2, 0, 1, 2, 75, 56, 56 }; //elida device. +static const T_DDR_TIMING_PARAMETERS C_TP_DDR2_25E_CL5_2GB = { 4, 5, 0, 2, 4, 4, + 5, 79, 22, 24, 9, 11, 20, 5, 4, 6, 3, 2, 0, 1, 2, 75, 56, 56 }; +static const T_DDR_TIMING_PARAMETERS C_TP_DDR2_25_CL6_1GB = { 4, 5, 0, 2, 4, 4, + 4, 51, 22, 26, 10, 12, 18, 6, 5, 6, 3, 2, 0, 1, 2, 75, 56, 56 }; // 400MHz, Speedgrade 25 timings (1Gb parts) + +// D B B R A S +// D W L K A S P +//Config Parameters R D C 8 M Z D CMD_MODE +//static const T_DDR_CONFIG_PARAMETERS C_CP_DDR2_25E_CL5 = { 2,16, 1, 0, 1, 32,25,0x80200A53}; // 64 MByte +static const T_DDR_CONFIG_PARAMETERS C_CP_DDR2_25E_CL5 = { 2, 16, 1, 1, 1, 64, + 25, 0x80200A53 }; // 128 MByte +static const T_DDR_CONFIG_PARAMETERS C_CP_DDR2_25_CL6 = { 2, 16, 1, 1, 1, 128, + 25, 0x80200A63 }; // 256 MByte + +static void ddr_phy_poll_until_locked(void) +{ + volatile UINT reg_tmp = 0; + volatile UINT locked = 0; + + //Extra read to put in delay before starting to poll... + reg_tmp = *(volatile UINT *) C_DDR_REG_PHY2; // read + + //POLL C_DDR_PHY2_REG register until clock and flock + //!!! Ideally have a timeout on this. + while (locked == 0) { + reg_tmp = *(volatile UINT *) C_DDR_REG_PHY2; // read + + //locked when bits 30 and 31 are set + if (reg_tmp & 0xC0000000) { + locked = 1; + } + } +} + +static void ddr_poll_until_not_busy(void) +{ + volatile UINT reg_tmp = 0; + volatile UINT busy = 1; + + //Extra read to put in delay before starting to poll... + reg_tmp = *(volatile UINT *) C_DDR_STAT_REG; // read + + //POLL DDR_STAT register until no longer busy + //!!! Ideally have a timeout on this. + while (busy == 1) { + reg_tmp = *(volatile UINT *) C_DDR_STAT_REG; // read + + //when bit 31 is clear - core is no longer busy + if ((reg_tmp & 0x80000000) == 0x00000000) { + busy = 0; + } + } +} + +static void ddr_issue_command(int commmand) +{ + *(volatile UINT *) C_DDR_CMD_REG = commmand; + ddr_poll_until_not_busy(); +} + +static void ddr_timing_initialisation( + const T_DDR_TIMING_PARAMETERS *ddr_timing_parameters) +{ + volatile UINT reg_tmp = 0; + /* update the DDR controller registers for timing parameters */ + reg_tmp = (ddr_timing_parameters->holdoff_cmd_A << 0); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_ARW << 4); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_N << 8); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_LM << 12); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_R << 16); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_W << 20); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_cmd_PC << 24); + *(volatile UINT *) C_DDR_REG_TIMING0 = reg_tmp; + + reg_tmp = (ddr_timing_parameters->holdoff_cmd_RF << 0); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_bank_R << 8); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_bank_W << 16); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_dir_RW << 24); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_dir_WR << 28); + *(volatile UINT *) C_DDR_REG_TIMING1 = reg_tmp; + + reg_tmp = (ddr_timing_parameters->latency_CAS << 0); + reg_tmp = reg_tmp + (ddr_timing_parameters->latency_WL << 4); + reg_tmp = reg_tmp + (ddr_timing_parameters->holdoff_FAW << 8); + reg_tmp = reg_tmp + (ddr_timing_parameters->width_update << 16); + reg_tmp = reg_tmp + (ddr_timing_parameters->odt_offset << 21); + reg_tmp = reg_tmp + (ddr_timing_parameters->odt_drive_all << 24); + + *(volatile UINT *) C_DDR_REG_TIMING2 = reg_tmp; + + /* Program the timing parameters in the PHY too */ + reg_tmp = (ddr_timing_parameters->use_fixed_re << 16) + | (ddr_timing_parameters->delay_wr_to_re << 8) + | (ddr_timing_parameters->latency_WL << 4) + | (ddr_timing_parameters->latency_CAS << 0); + + *(volatile UINT *) C_DDR_REG_PHY_TIMING = reg_tmp; + + reg_tmp = ddr_timing_parameters->wr_slave_ratio; + + *(volatile UINT *) C_DDR_REG_PHY_WR_RATIO = reg_tmp; + + reg_tmp = ddr_timing_parameters->rd_slave_ratio0; + reg_tmp += ddr_timing_parameters->rd_slave_ratio1 << 8; + + *(volatile UINT *) C_DDR_REG_PHY_RD_RATIO = reg_tmp; + +} + +static void ddr_normal_initialisation( + const T_DDR_CONFIG_PARAMETERS *ddr_config_parameters, int mhz) +{ + int i; + volatile UINT tmp = 0; + volatile UINT reg_tmp = 0; + volatile UINT emr_cmd = 0; + UINT refresh; + + //Total size of memory in Mbits... + tmp = ddr_config_parameters->rams * ddr_config_parameters->asize + * ddr_config_parameters->width; + //Deduce value to program into DDR_CFG register... + switch (tmp) { + case 16: + reg_tmp = 0x00020000 * 1; + break; + case 32: + reg_tmp = 0x00020000 * 2; + break; + case 64: + reg_tmp = 0x00020000 * 3; + break; + case 128: + reg_tmp = 0x00020000 * 4; + break; + case 256: + reg_tmp = 0x00020000 * 5; + break; + case 512: + reg_tmp = 0x00020000 * 6; + break; + case 1024: + reg_tmp = 0x00020000 * 7; + break; + case 2048: + reg_tmp = 0x00020000 * 8; + break; + default: + reg_tmp = 0; //forces sims not to work if badly configured + } + + //Memory width + tmp = ddr_config_parameters->rams * ddr_config_parameters->width; + switch (tmp) { + case 8: + reg_tmp = reg_tmp + 0x00400000; + break; + case 16: + reg_tmp = reg_tmp + 0x00200000; + break; + case 32: + reg_tmp = reg_tmp + 0x00000000; + break; + default: + reg_tmp = 0; //forces sims not to work if badly configured + } + + //Setup DDR Mode + switch (ddr_config_parameters->ddr_mode) { + case 0: + reg_tmp = reg_tmp + 0x00000000; + break; //SDR + case 1: + reg_tmp = reg_tmp + 0x40000000; + break; //DDR + case 2: + reg_tmp = reg_tmp + 0x80000000; + break; //DDR2 + default: + reg_tmp = 0; //forces sims not to work if badly configured + } + + //Setup Banks + if (ddr_config_parameters->banks8 == 1) { + reg_tmp = reg_tmp + 0x00800000; + } + + //Program DDR_CFG register... + *(volatile UINT *) C_DDR_CFG_REG = reg_tmp; + + //Configure PHY0 reg - se_mode is bit 1, + //needs to be 1 for DDR (single_ended drive) + switch (ddr_config_parameters->ddr_mode) { + case 0: + reg_tmp = 2 + (0 << 4); + break; //SDR + case 1: + reg_tmp = 2 + (4 << 4); + break; //DDR + case 2: + reg_tmp = 0 + (4 << 4); + break; //DDR2 + default: + reg_tmp = 0; + } + + //Program DDR_PHY0 register... + *(volatile UINT *) C_DDR_REG_PHY0 = reg_tmp; + + //Read DDR_PHY* registers to exercise paths for vcd + reg_tmp = *(volatile UINT *) C_DDR_REG_PHY3; + reg_tmp = *(volatile UINT *) C_DDR_REG_PHY2; + reg_tmp = *(volatile UINT *) C_DDR_REG_PHY1; + reg_tmp = *(volatile UINT *) C_DDR_REG_PHY0; + + //Start up sequences - Different dependant on DDR mode + switch (ddr_config_parameters->ddr_mode) { + case 2: //DDR2 + //Start-up sequence: follows procedure described in Micron datasheet. + //start up DDR PHY DLL + reg_tmp = 0x00022828; // dll on, start point and inc = h28 + *(volatile UINT *) C_DDR_REG_PHY2 = reg_tmp; + + reg_tmp = 0x00032828; // start on, dll on, start point and inc = h28 + *(volatile UINT *) C_DDR_REG_PHY2 = reg_tmp; + + ddr_phy_poll_until_locked(); + + udelay(200); //200us + + //Startup SDRAM... + //!!! Software: CK should be running for 200us before wake-up + ddr_issue_command( C_CMD_WAKE_UP); + ddr_issue_command( C_CMD_NOP); + ddr_issue_command( C_CMD_PRECHARGE_ALL); + ddr_issue_command( C_CMD_DDR2_EMR2); + ddr_issue_command( C_CMD_DDR2_EMR3); + + emr_cmd = C_CMD_DDR2_EMR1 + C_CMD_ODT_75 + C_CMD_REDUCED_DRIVE + + C_CMD_ENABLE_DLL; + + ddr_issue_command(emr_cmd); + //Sets CL=3; BL=8 but also reset DLL to trigger a DLL initialisation... + udelay(1); //1us + ddr_issue_command( + ddr_config_parameters->cmd_mode_wr_cl_bl + + C_CMD_RESET_DLL); + udelay(1); //1us + + //!!! Software: Wait 200 CK cycles before... + //for(i=1; i<=2; i++) { + ddr_issue_command(C_CMD_PRECHARGE_ALL); + // !!! Software: Wait here at least 8 CK cycles + //} + //need a wait here to ensure PHY DLL lock before the refresh is issued + udelay(1); //1us + for (i = 1; i <= 2; i++) { + ddr_issue_command( C_CMD_AUTO_REFRESH); + //!!! Software: Wait here at least 8 CK cycles to satify tRFC + udelay(1); //1us + } + //As before but without 'RESET_DLL' bit set... + ddr_issue_command(ddr_config_parameters->cmd_mode_wr_cl_bl); + udelay(1); //1us + // OCD commands + ddr_issue_command(emr_cmd + C_CMD_MODE_DDR2_OCD_DFLT); + ddr_issue_command(emr_cmd + C_CMD_MODE_DDR2_OCD_EXIT); + break; + + default: + break; //Do nothing + } + + //Enable auto-refresh + + // 8192 Refreshes required every 64ms, so maximum refresh period is 7.8125 us + // We have a 400 MHz DDR clock (2.5ns period) so max period is 3125 cycles + // Our core now does 8 refreshes in a go, so we multiply this period by 8 + + refresh = (64000 * mhz) / 8192; // Refresh period in clocks + + reg_tmp = *(volatile UINT *) C_DDR_CFG_REG; // read +#ifdef BURST_REFRESH_ENABLE + reg_tmp |= C_CFG_REFRESH_ENABLE | (refresh * 8); + reg_tmp |= C_CFG_BURST_REFRESH_ENABLE; +#else + reg_tmp |= C_CFG_REFRESH_ENABLE | (refresh * 1); + reg_tmp &= ~C_CFG_BURST_REFRESH_ENABLE; +#endif + *(volatile UINT *) C_DDR_CFG_REG = reg_tmp; + + //Verify register contents + reg_tmp = *(volatile UINT *) C_DDR_REG_PHY2; // read + //printf("Warning XXXXXXXXXXXXXXXXXXXXXX - get bad read data from C_DDR_PHY2_REG, though it looks OK on bus XXXXXXXXXXXXXXXXXX"); + //TBD Check_data (read_data, dll_reg, "Error: bad C_DDR_PHY2_REG read", tb_pass); + reg_tmp = *(volatile UINT *) C_DDR_CFG_REG; // read + //TBD Check_data (read_data, cfg_reg, "Error: bad DDR_CFG read", tb_pass); + + //disable optimised wrapping + if (ddr_config_parameters->ddr_mode == 2) { + reg_tmp = 0xFFFF0000; + *(volatile UINT *) C_DDR_REG_IGNORE = reg_tmp; + } + + //enable midbuffer followon + reg_tmp = *(volatile UINT *) C_DDR_ARB_REG; // read + reg_tmp = 0xFFFF0000 | reg_tmp; + *(volatile UINT *) C_DDR_ARB_REG = reg_tmp; + + // Enable write behind coherency checking for all clients + + reg_tmp = 0xFFFF0000; + *(volatile UINT *) C_DDR_AHB4_REG = reg_tmp; + + //Wait for 200 clock cycles for SDRAM DLL to lock... + udelay(1); //1us +} + +// Function used to Setup DDR core + +void ddr_setup(int mhz) +{ + static const T_DDR_TIMING_PARAMETERS *ddr_timing_parameters = + &C_TP_DDR2_25_CL6_1GB; + static const T_DDR_CONFIG_PARAMETERS *ddr_config_parameters = + &C_CP_DDR2_25_CL6; + + //Bring core out of Reset + *(volatile UINT *) C_DDR_BLKEN_REG = C_BLKEN_DDR_ON; + + //DDR TIMING INITIALISTION + ddr_timing_initialisation(ddr_timing_parameters); + + //DDR NORMAL INITIALISATION + ddr_normal_initialisation(ddr_config_parameters, mhz); + + // route all writes through one client + *(volatile UINT *) C_DDR_TRANSACTION_ROUTING = (0 + << DDR_ROUTE_CPU0_INSTR_SHIFT) + | (1 << DDR_ROUTE_CPU0_RDDATA_SHIFT) + | (3 << DDR_ROUTE_CPU0_WRDATA_SHIFT) + | (2 << DDR_ROUTE_CPU1_INSTR_SHIFT) + | (3 << DDR_ROUTE_CPU1_RDDATA_SHIFT) + | (3 << DDR_ROUTE_CPU1_WRDATA_SHIFT); + + //Bring all clients out of reset + *(volatile UINT *) C_DDR_BLKEN_REG = C_BLKEN_DDR_ON + 0x0000FFFF; + +} + +void set_ddr_timing(unsigned int w, unsigned int i) +{ + unsigned int reg; + unsigned int wnow = 16; + unsigned int inow = 32; + + /* reset all timing controls to known value (31) */ + writel(DDR_PHY_TIMING_W_RST | DDR_PHY_TIMING_I_RST, DDR_PHY_TIMING); + writel(DDR_PHY_TIMING_W_RST | DDR_PHY_TIMING_I_RST | DDR_PHY_TIMING_CK, + DDR_PHY_TIMING); + writel(DDR_PHY_TIMING_W_RST | DDR_PHY_TIMING_I_RST, DDR_PHY_TIMING); + + /* step up or down read delay to the requested value */ + while (wnow != w) { + if (wnow < w) { + reg = DDR_PHY_TIMING_INC; + wnow++; + } else { + reg = 0; + wnow--; + } + writel(DDR_PHY_TIMING_W_CE | reg, DDR_PHY_TIMING); + writel(DDR_PHY_TIMING_CK | DDR_PHY_TIMING_W_CE | reg, + DDR_PHY_TIMING); + writel(DDR_PHY_TIMING_W_CE | reg, DDR_PHY_TIMING); + } + + /* now write delay */ + while (inow != i) { + if (inow < i) { + reg = DDR_PHY_TIMING_INC; + inow++; + } else { + reg = 0; + inow--; + } + writel(DDR_PHY_TIMING_I_CE | reg, DDR_PHY_TIMING); + writel(DDR_PHY_TIMING_CK | DDR_PHY_TIMING_I_CE | reg, + DDR_PHY_TIMING); + writel(DDR_PHY_TIMING_I_CE | reg, DDR_PHY_TIMING); + } +} + +//Function used to Setup SDRAM in DDR/SDR mode +void init_ddr(int mhz) +{ + /* start clocks */ + enable_clock(SYS_CTRL_CLK_DDRPHY); + enable_clock(SYS_CTRL_CLK_DDR); + enable_clock(SYS_CTRL_CLK_DDRCK); + + /* bring phy and core out of reset */ + reset_block(SYS_CTRL_RST_DDR_PHY, 0); + reset_block(SYS_CTRL_RST_DDR, 0); + + /* DDR runs at half the speed of the CPU */ + ddr_setup(mhz >> 1); + return; +} diff --git a/package/boot/uboot-oxnas/files/board/ox820/ddr.h b/package/boot/uboot-oxnas/files/board/ox820/ddr.h new file mode 100644 index 0000000..a3c1990 --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/ddr.h @@ -0,0 +1,148 @@ +/******************************************************************* +* +* File: ddr_oxsemi.h +* +* Description: Declarations for DDR routines and data objects +* +* Author: Julien Margetts +* +* Copyright: Oxford Semiconductor Ltd, 2009 +*/ + +void ddr_oxsemi_setup(int mhz); + +/* define to refresh in bursts of 8 */ +#define BURST_REFRESH_ENABLE + +#define DDR_BASE 0x44700000 + +#define C_DDR_CFG_REG (DDR_BASE + 0x00) +#define C_CFG_DDR 0x80000000 +#define C_CFG_SDR 0x00000000 +#define C_CFG_WIDTH8 0x00200000 +#define C_CFG_WIDTH16 0x00100000 +#define C_CFG_WIDTH32 0x00000000 +#define C_CFG_SIZE_FACTOR 0x00020000 +#define C_CFG_REFRESH_ENABLE 0x00010000 +#define C_CFG_BURST_REFRESH_ENABLE 0x01000000 +#define C_CFG_SIZE(x) (x << 17) +#define CFG_SIZE_2MB 1 +#define CFG_SIZE_4MB 2 +#define CFG_SIZE_8MB 3 +#define CFG_SIZE_16MB 4 +#define CFG_SIZE_32MB 5 +#define CFG_SIZE_64MB 6 +#define CFG_SIZE_128MB 7 + +#define C_DDR_BLKEN_REG (DDR_BASE + 0x04) +#define C_BLKEN_DDR_ON 0x80000000 + +#define C_DDR_STAT_REG (DDR_BASE + 0x08) + +#define C_DDR_CMD_REG (DDR_BASE + 0x0C) +#define C_CMD_SEND_COMMAND (1UL << 31) | (1 << 21) // RAS/CAS/WE/CS all low(active), CKE High, indicates +#define C_CMD_WAKE_UP 0x80FC0000 // Asserts CKE +#define C_CMD_MODE_SDR 0x80200022 // Sets CL=2 BL=4 +#define C_CMD_MODE_DDR 0x80200063 // Sets CL=2.5 BL=8 +#define C_CMD_RESET_DLL 0x00000100 // A8=1 Use in conjunction with C_CMD_MODE_DDR +#define C_CMD_PRECHARGE_ALL 0x80280400 +#define C_CMD_AUTO_REFRESH 0x80240000 +#define C_CMD_SELF_REFRESH 0x80040000 // As AUTO-REFRESH but with CKE low +#define C_CMD_NOP 0x803C0000 // NOP just to insert guaranteed delay +#define C_CMD_DDR2_EMR1 0x80210000 // Load extended mode register 1 with zeros (for init), CKE still set +//#define C_CMD_DDR2_EMR1 0x80210400 // Load extended mode register 1 with zeros (for init), CKE still set +#define C_CMD_ENABLE_DLL 0x00000000 // Values used in conjuction with C_CMD_DDR2_EMR1 +#define C_CMD_DISABLE_DLL 0x00000001 +#define C_CMD_REDUCED_DRIVE 0x00000002 +#define C_CMD_ODT_DISABLED 0x00000000 +#define C_CMD_ODT_50 0x00000044 +#define C_CMD_ODT_75 0x00000004 +#define C_CMD_ODT_150 0x00000040 +#define C_CMD_MODE_DDR2_OCD_DFLT 0x00000380 +#define C_CMD_MODE_DDR2_OCD_EXIT 0x00000000 + +#define C_CMD_DDR2_EMR2 0x80220000 // Load extended mode register 2 with zeros (for init), CKE still set +#define C_CMD_DDR2_EMR3 0x80230000 // Load extended mode register 3 with zeros (for init), CKE still set + +#define C_DDR_AHB_REG (DDR_BASE + 0x10) +#define C_AHB_NO_RCACHES 0xFFFF0000 +#define C_AHB_FLUSH_ALL_RCACHES 0x0000FFFF +#define C_AHB_FLUSH_AHB0_RCACHE 0x00000001 +#define C_AHB_FLUSH_AHB1_RCACHE 0x00000002 + +#define C_DDR_DLL_REG (DDR_BASE + 0x14) +#define C_DLL_DISABLED 0x00000000 +#define C_DLL_MANUAL 0x80000000 +#define C_DLL_AUTO_OFFSET 0xA0000000 +#define C_DLL_AUTO_IN_REFRESH 0xC0000000 +#define C_DLL_AUTOMATIC 0xE0000000 + +#define C_DDR_MON_REG (DDR_BASE + 0x18) +#define C_MON_ALL 0x00000010 +#define C_MON_CLIENT 0x00000000 + +#define C_DDR_DIAG_REG (DDR_BASE + 0x1C) +#define C_DDR_DIAG2_REG (DDR_BASE + 0x20) + +#define C_DDR_IOC_REG (DDR_BASE + 0x24) +#define C_DDR_IOC_PWR_DWN (1 << 10) +#define C_DDR_IOC_SEL_SSTL (1 << 9) +#define C_DDR_IOC_CK_DRIVE(x) ((x) << 6) +#define C_DDR_IOC_DQ_DRIVE(x) ((x) << 3) +#define C_DDR_IOC_XX_DRIVE(x) ((x) << 0) + +#define C_DDR_ARB_REG (DDR_BASE + 0x28) +#define C_DDR_ARB_MIDBUF (1 << 4) +#define C_DDR_ARB_LRUBANK (1 << 3) +#define C_DDR_ARB_REQAGE (1 << 2) +#define C_DDR_ARB_DATDIR (1 << 1) +#define C_DDR_ARB_DATDIR_NC (1 << 0) + +#define C_TOP_ADDRESS_BIT_TEST 22 +#define C_MEM_BASE C_SDRAM_BASE + +#define C_MEM_TEST_BASE 0 +#define C_MEM_TEST_LEN 1920 +#define C_MAX_RAND_ACCESS_LEN 16 + +#define C_DDR_REG_IGNORE (DDR_BASE + 0x2C) +#define C_DDR_AHB4_REG (DDR_BASE + 0x44) + +#define C_DDR_REG_TIMING0 (DDR_BASE + 0x34) +#define C_DDR_REG_TIMING1 (DDR_BASE + 0x38) +#define C_DDR_REG_TIMING2 (DDR_BASE + 0x3C) + +#define C_DDR_REG_PHY0 (DDR_BASE + 0x48) +#define C_DDR_REG_PHY1 (DDR_BASE + 0x4C) +#define C_DDR_REG_PHY2 (DDR_BASE + 0x50) +#define C_DDR_REG_PHY3 (DDR_BASE + 0x54) + +#define C_DDR_REG_GENERIC (DDR_BASE + 0x60) + +#define C_OXSEMI_DDRC_SIGNATURE 0x054415AA + +#define DDR_PHY_BASE (DDR_BASE + 0x80000) +#define DDR_PHY_TIMING (DDR_PHY_BASE + 0x48) +#define DDR_PHY_TIMING_CK (1 << 12) +#define DDR_PHY_TIMING_INC (1 << 13) +#define DDR_PHY_TIMING_W_CE (1 << 14) +#define DDR_PHY_TIMING_W_RST (1 << 15) +#define DDR_PHY_TIMING_I_CE (1 << 16) +#define DDR_PHY_TIMING_I_RST (1 << 17) + +#define C_DDR_REG_PHY_TIMING (DDR_PHY_BASE + 0x50) +#define C_DDR_REG_PHY_WR_RATIO (DDR_PHY_BASE + 0x74) +#define C_DDR_REG_PHY_RD_RATIO (DDR_PHY_BASE + 0x78) + +#define C_DDR_TRANSACTION_ROUTING (DDR_PHY_BASE + 0xC8) +#define DDR_ROUTE_CPU0_INSTR_SHIFT 0 +#define DDR_ROUTE_CPU0_RDDATA_SHIFT 4 +#define DDR_ROUTE_CPU0_WRDATA_SHIFT 6 +#define DDR_ROUTE_CPU1_INSTR_SHIFT 8 +#define DDR_ROUTE_CPU1_RDDATA_SHIFT 12 +#define DDR_ROUTE_CPU1_WRDATA_SHIFT 14 + +unsigned int ddrc_signature(void); +void set_ddr_timing(unsigned int w, unsigned int i); +int pause(unsigned int us); +void set_ddr_sel(int val); diff --git a/package/boot/uboot-oxnas/files/board/ox820/lowlevel_init.S b/package/boot/uboot-oxnas/files/board/ox820/lowlevel_init.S new file mode 100644 index 0000000..3328b7a --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/lowlevel_init.S @@ -0,0 +1,20 @@ +#include +#ifndef CONFIG_SPL_BUILD + +.globl lowlevel_init +lowlevel_init: + /* + * Copy exception table to relocated address in internal SRAM + */ + ldr r0, src /* Address of exception table in flash */ + ldr r1, dest /* Relocated address of exception table */ + ldmia r0!, {r3-r10} /* Copy exception table and jump values from */ + stmia r1!, {r3-r10} /* FLASH to relocated address */ + ldmia r0!, {r3-r10} + stmia r1!, {r3-r10} + mov pc, lr + +src: .word CONFIG_SYS_TEXT_BASE +dest: .word CONFIG_SRAM_BASE + +#endif \ No newline at end of file diff --git a/package/boot/uboot-oxnas/files/board/ox820/ox820.c b/package/boot/uboot-oxnas/files/board/ox820/ox820.c new file mode 100644 index 0000000..f93cc9c --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/ox820.c @@ -0,0 +1,374 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_SPL_BUILD + +#ifdef DEBUG +#define DILIGENCE (1048576/4) +static int test_memory(u32 memory) +{ + volatile u32 *read; + volatile u32 *write; + const u32 INIT_PATTERN = 0xAA55AA55; + const u32 INC_PATTERN = 0x01030507; + u32 pattern; + int check; + int i; + + check = 0; + read = write = (volatile u32 *) memory; + pattern = INIT_PATTERN; + for (i = 0; i < DILIGENCE; i++) { + *write++ = pattern; + pattern += INC_PATTERN; + } + puts("testing\n"); + pattern = INIT_PATTERN; + for (i = 0; i < DILIGENCE; i++) { + check += (pattern == *read++) ? 1 : 0; + pattern += INC_PATTERN; + } + return (check == DILIGENCE) ? 0 : -1; +} +#endif + +void uart_init(void) +{ + /* Reset UART1 */ + reset_block(SYS_CTRL_RST_UART1, 1); + udelay(100); + reset_block(SYS_CTRL_RST_UART1, 0); + udelay(100); + + /* Setup pin mux'ing for UART1 */ + pinmux_set(PINMUX_BANK_MFA, 30, PINMUX_UARTA_SIN); + pinmux_set(PINMUX_BANK_MFA, 31, PINMUX_UARTA_SOUT); +} + +extern void init_ddr(int mhz); + +void board_inithw(void) +{ + int plla_freq; +#ifdef DEBUG + int i; +#endif /* DEBUG */ + + timer_init(); + uart_init(); + preloader_console_init(); + + plla_freq = plla_set_config(CONFIG_PLLA_FREQ_MHZ); + init_ddr(plla_freq); + +#ifdef DEBUG + if(test_memory(CONFIG_SYS_SDRAM_BASE)) { + puts("memory test failed\n"); + } else { + puts("memory test done\n"); + } +#endif /* DEBUG */ +#ifdef CONFIG_SPL_BSS_DRAM_START + extern char __bss_dram_start[]; + extern char __bss_dram_end[]; + memset(&__bss_dram_start, 0, __bss_dram_end - __bss_dram_start); +#endif +} + +void board_init_f(ulong dummy) +{ + /* Set the stack pointer. */ + asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* Set global data pointer. */ + gd = &gdata; + + board_inithw(); + + board_init_r(NULL, 0); +} + +u32 spl_boot_device(void) +{ + return CONFIG_SPL_BOOT_DEVICE; +} + +#ifdef CONFIG_SPL_BLOCK_SUPPORT +void spl_block_device_init(void) +{ + ide_init(); +} +#endif + +#ifdef CONFIG_SPL_OS_BOOT +int spl_start_uboot(void) +{ + /* break into full u-boot on 'c' */ + return (serial_tstc() && serial_getc() == 'c'); +} +#endif + +void spl_display_print(void) +{ + /* print a hint, so that we will not use the wrong SPL by mistake */ + puts(" Boot device: " BOOT_DEVICE_TYPE "\n" ); +} + +void lowlevel_init(void) +{ +} + +#ifdef USE_DL_PREFIX +/* quick and dirty memory allocation */ +static ulong next_mem = CONFIG_SPL_MALLOC_START; + +void *memalign(size_t alignment, size_t bytes) +{ + ulong mem = ALIGN(next_mem, alignment); + + next_mem = mem + bytes; + + if (next_mem > CONFIG_SYS_SDRAM_BASE + CONFIG_MIN_SDRAM_SIZE) { + printf("spl: out of memory\n"); + hang(); + } + + return (void *)mem; +} + +void free(void* mem) +{ +} +#endif + +#endif /* CONFIG_SPL_BUILD */ + +int board_early_init_f(void) +{ + return 0; +} + +#define STATIC_CTL_BANK0 (STATIC_CONTROL_BASE + 4) +#define STATIC_READ_CYCLE_SHIFT 0 +#define STATIC_DELAYED_OE (1 << 7) +#define STATIC_WRITE_CYCLE_SHIFT 8 +#define STATIC_WRITE_PULSE_SHIFT 16 +#define STATIC_WRITE_BURST_EN (1 << 23) +#define STATIC_TURN_AROUND_SHIFT 24 +#define STATIC_BUFFER_PRESENT (1 << 28) +#define STATIC_READ_BURST_EN (1 << 29) +#define STATIC_BUS_WIDTH8 (0 << 30) +#define STATIC_BUS_WIDTH16 (1 << 30) +#define STATIC_BUS_WIDTH32 (2 << 30) + +void nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + unsigned long nandaddr = (unsigned long) this->IO_ADDR_W; + + if (ctrl & NAND_CTRL_CHANGE) { + nandaddr &= ~(BIT(NAND_ALE_ADDR_PIN) | BIT(NAND_CLE_ADDR_PIN)); + if (ctrl & NAND_CLE) + nandaddr |= BIT(NAND_CLE_ADDR_PIN); + else if (ctrl & NAND_ALE) + nandaddr |= BIT(NAND_ALE_ADDR_PIN); + this->IO_ADDR_W = (void __iomem *) nandaddr; + } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, (void __iomem *) nandaddr); +} + +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOOT_FROM_NAND) + +int nand_dev_ready(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + + udelay(chip->chip_delay); + + return 1; +} + +void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + int i; + struct nand_chip *chip = mtd->priv; + + for (i = 0; i < len; i++) + buf[i] = readb(chip->IO_ADDR_R); +} + +void nand_dev_reset(struct nand_chip *chip) +{ + writeb(NAND_CMD_RESET, chip->IO_ADDR_W + BIT(NAND_CLE_ADDR_PIN)); + udelay(chip->chip_delay); + writeb(NAND_CMD_STATUS, chip->IO_ADDR_W + BIT(NAND_CLE_ADDR_PIN)); + while (!(readb(chip->IO_ADDR_R) & NAND_STATUS_READY)) { + ; + } +} + +#else + +#define nand_dev_reset(chip) /* framework will reset the chip anyway */ +#define nand_read_buf NULL /* framework will provide a default one */ +#define nand_dev_ready NULL /* dev_ready is optional */ + +#endif + +int board_nand_init(struct nand_chip *chip) +{ + /* Block reset Static core */ + reset_block(SYS_CTRL_RST_STATIC, 1); + reset_block(SYS_CTRL_RST_STATIC, 0); + + /* Enable clock to Static core */ + enable_clock(SYS_CTRL_CLK_STATIC); + + /* enable flash support on static bus. + * Enable static bus onto GPIOs, only CS0 */ + pinmux_set(PINMUX_BANK_MFA, 12, PINMUX_STATIC_DATA0); + pinmux_set(PINMUX_BANK_MFA, 13, PINMUX_STATIC_DATA1); + pinmux_set(PINMUX_BANK_MFA, 14, PINMUX_STATIC_DATA2); + pinmux_set(PINMUX_BANK_MFA, 15, PINMUX_STATIC_DATA3); + pinmux_set(PINMUX_BANK_MFA, 16, PINMUX_STATIC_DATA4); + pinmux_set(PINMUX_BANK_MFA, 17, PINMUX_STATIC_DATA5); + pinmux_set(PINMUX_BANK_MFA, 18, PINMUX_STATIC_DATA6); + pinmux_set(PINMUX_BANK_MFA, 19, PINMUX_STATIC_DATA7); + + pinmux_set(PINMUX_BANK_MFA, 20, PINMUX_STATIC_NWE); + pinmux_set(PINMUX_BANK_MFA, 21, PINMUX_STATIC_NOE); + pinmux_set(PINMUX_BANK_MFA, 22, PINMUX_STATIC_NCS); + pinmux_set(PINMUX_BANK_MFA, 23, PINMUX_STATIC_ADDR18); + pinmux_set(PINMUX_BANK_MFA, 24, PINMUX_STATIC_ADDR19); + + /* Setup the static bus CS0 to access FLASH */ + + writel((0x3f << STATIC_READ_CYCLE_SHIFT) + | (0x3f << STATIC_WRITE_CYCLE_SHIFT) + | (0x1f << STATIC_WRITE_PULSE_SHIFT) + | (0x03 << STATIC_TURN_AROUND_SHIFT) | + STATIC_BUS_WIDTH16, + STATIC_CTL_BANK0); + + chip->cmd_ctrl = nand_hwcontrol; + chip->ecc.mode = NAND_ECC_SOFT; + chip->chip_delay = 30; + chip->dev_ready = nand_dev_ready; + chip->read_buf = nand_read_buf; + + nand_dev_reset(chip); + + return 0; +} + +int board_init(void) +{ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + gd->bd->bi_arch_number = MACH_TYPE_OXNAS; + + /* assume uart is already initialized by SPL */ + +#if defined(CONFIG_START_IDE) + puts("IDE: "); + ide_init(); +#endif + + return 0; +} + +/* copied from board/evb64260/sdram_init.c */ +/* + * Check memory range for valid RAM. A simple memory test determines + * the actually available RAM size between addresses `base' and + * `base + maxsize'. Some (not all) hardware errors are detected: + * - short between address lines + * - short between data lines + */ +static long int dram_size (long int *base, long int maxsize) +{ + volatile long int *addr, *b = base; + long int cnt, val, save1, save2; + +#define STARTVAL (CONFIG_MIN_SDRAM_SIZE / 2) /* start test at half size */ + for (cnt = STARTVAL / sizeof (long); cnt < maxsize / sizeof (long); + cnt <<= 1) { + addr = base + cnt; /* pointer arith! */ + + save1 = *addr; /* save contents of addr */ + save2 = *b; /* save contents of base */ + + *addr = cnt; /* write cnt to addr */ + *b = 0; /* put null at base */ + + /* check at base address */ + if ((*b) != 0) { + *addr = save1; /* restore *addr */ + *b = save2; /* restore *b */ + return (0); + } + val = *addr; /* read *addr */ + + *addr = save1; + *b = save2; + + if (val != cnt) { + /* fix boundary condition.. STARTVAL means zero */ + if (cnt == STARTVAL / sizeof (long)) + cnt = 0; + return (cnt * sizeof (long)); + } + } + return maxsize; +} + +int dram_init(void) +{ + gd->ram_size = dram_size((long int *)CONFIG_SYS_SDRAM_BASE, + CONFIG_MAX_SDRAM_SIZE); + return 0; +} + +int board_eth_init(bd_t *bis) +{ + u32 value; + + /* set the pin multiplexers to enable talking to Ethernent Phys */ + pinmux_set(PINMUX_BANK_MFA, 3, PINMUX_MACA_MDC); + pinmux_set(PINMUX_BANK_MFA, 4, PINMUX_MACA_MDIO); + + // Ensure the MAC block is properly reset + reset_block(SYS_CTRL_RST_MAC, 1); + udelay(10); + reset_block(SYS_CTRL_RST_MAC, 0); + + // Enable the clock to the MAC block + enable_clock(SYS_CTRL_CLK_MAC); + + value = readl(SYS_CTRL_GMAC_CTRL); + /* Use simple mux for 25/125 Mhz clock switching */ + value |= BIT(SYS_CTRL_GMAC_SIMPLE_MUX); + /* Enable GMII_GTXCLK to follow GMII_REFCLK - required for gigabit PHY */ + value |= BIT(SYS_CTRL_GMAC_CKEN_GTX); + /* set auto tx speed */ + value |= BIT(SYS_CTRL_GMAC_AUTOSPEED); + + writel(value, SYS_CTRL_GMAC_CTRL); + + return designware_initialize(MAC_BASE, PHY_INTERFACE_MODE_RGMII); +} + diff --git a/package/boot/uboot-oxnas/files/board/ox820/spl_start.S b/package/boot/uboot-oxnas/files/board/ox820/spl_start.S new file mode 100644 index 0000000..2eab3f5 --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/spl_start.S @@ -0,0 +1,21 @@ +.section .init +.globl _spl_start +_spl_start: + b _start + b _start+0x4 + b _start+0x8 + b _start+0xc + b _start+0x10 + b _start+0x14 + b _start+0x18 + b _start+0x1c + .space 0x30 - (. - _spl_start) + .ascii "BOOT" /* 0x30 signature*/ + .word 0x50 /* 0x34 header size itself */ + .word 0 /* 0x38 */ + .word 0x5000f000 /* boot report location */ + .word _start /* 0x40 */ + +main_crc_size: .word code_size /* 0x44 filled by linker */ +main_crc: .word 0 /* 0x48 fill later */ +header_crc: .word 0 /* 0x4C header crc*/ diff --git a/package/boot/uboot-oxnas/files/board/ox820/u-boot-spl.lds b/package/boot/uboot-oxnas/files/board/ox820/u-boot-spl.lds new file mode 100644 index 0000000..a8d90df --- /dev/null +++ b/package/boot/uboot-oxnas/files/board/ox820/u-boot-spl.lds @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2011 Marek Vasut + * on behalf of DENX Software Engineering GmbH + * + * January 2004 - Changed to support H4 device + * Copyright (c) 2004-2008 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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 + */ + +MEMORY +{ + sram (rwx) : ORIGIN = CONFIG_SPL_TEXT_BASE, LENGTH = CONFIG_SPL_MAX_SIZE + dram : ORIGIN = CONFIG_SPL_BSS_DRAM_START, LENGTH = CONFIG_SPL_BSS_DRAM_SIZE +} + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_spl_start) +SECTIONS +{ + .text.0 : + { + *(.init*) + } + + + /* Start of the rest of the SPL */ + code_start = . ; + + .text.1 : + { + *(.text*) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { + *(.data*) + } + + . = ALIGN(4); + + __image_copy_end = .; + code_size = . - code_start; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + . = ALIGN(0x800); + + _end = .; + + .bss.sram __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss.stdio_devices) + *(.bss.serial_current) + . = ALIGN(4); + __bss_end = .; + } + + .bss : { + __bss_dram_start = .; + *(.bss*) + __bss_dram_end = .; + } > dram + + /DISCARD/ : { *(.bss*) } + /DISCARD/ : { *(.dynsym) } + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynsym*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.hash*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } +} diff --git a/package/boot/uboot-oxnas/files/common/env_ext4.c b/package/boot/uboot-oxnas/files/common/env_ext4.c new file mode 100644 index 0000000..e98d94d --- /dev/null +++ b/package/boot/uboot-oxnas/files/common/env_ext4.c @@ -0,0 +1,116 @@ +/* + * (c) Copyright 2011 by Tigris Elektronik GmbH + * + * Author: + * Maximilian Schwerin + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +char *env_name_spec = "EXT4"; + +env_t *env_ptr; + +DECLARE_GLOBAL_DATA_PTR; + +int env_init(void) +{ + /* use default */ + gd->env_addr = (ulong)&default_environment[0]; + gd->env_valid = 1; + + return 0; +} + +#ifdef CONFIG_CMD_SAVEENV +int saveenv(void) +{ + env_t env_new; + ssize_t len; + char *res; + block_dev_desc_t *dev_desc = NULL; + int dev = EXT4_ENV_DEVICE; + int part = EXT4_ENV_PART; + int err; + + res = (char *)&env_new.data; + len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + + dev_desc = get_dev(EXT4_ENV_INTERFACE, dev); + if (dev_desc == NULL) { + printf("Failed to find %s%d\n", + EXT4_ENV_INTERFACE, dev); + return 1; + } + + err = ext4_register_device(dev_desc, part); + if (err) { + printf("Failed to register %s%d:%d\n", + EXT4_ENV_INTERFACE, dev, part); + return 1; + } + + env_new.crc = crc32(0, env_new.data, ENV_SIZE); + err = ext4fs_write(EXT4_ENV_FILE, (void *)&env_new, sizeof(env_t)); + ext4fs_close(); + if (err == -1) { + printf("\n** Unable to write \"%s\" from %s%d:%d **\n", + EXT4_ENV_FILE, EXT4_ENV_INTERFACE, dev, part); + return 1; + } + + puts("done\n"); + return 0; +} +#endif /* CONFIG_CMD_SAVEENV */ + +void env_relocate_spec(void) +{ + char buf[CONFIG_ENV_SIZE]; + block_dev_desc_t *dev_desc = NULL; + int dev = EXT4_ENV_DEVICE; + int part = EXT4_ENV_PART; + int err; + + dev_desc = get_dev(EXT4_ENV_INTERFACE, dev); + if (dev_desc == NULL) { + printf("Failed to find %s%d\n", + EXT4_ENV_INTERFACE, dev); + set_default_env(NULL); + return; + } + + err = ext4_register_device(dev_desc, part); + if (err) { + printf("Failed to register %s%d:%d\n", + EXT4_ENV_INTERFACE, dev, part); + set_default_env(NULL); + return; + } + + err = ext4_read_file(EXT4_ENV_FILE, (uchar *)&buf, 0, CONFIG_ENV_SIZE); + ext4fs_close(); + + if (err == -1) { + printf("\n** Unable to read \"%s\" from %s%d:%d **\n", + EXT4_ENV_FILE, EXT4_ENV_INTERFACE, dev, part); + set_default_env(NULL); + return; + } + + env_import(buf, 1); +} diff --git a/package/boot/uboot-oxnas/files/common/spl/spl_block.c b/package/boot/uboot-oxnas/files/common/spl/spl_block.c new file mode 100644 index 0000000..f16413a --- /dev/null +++ b/package/boot/uboot-oxnas/files/common/spl/spl_block.c @@ -0,0 +1,236 @@ +/* + * (C) Copyright 2013 + * + * Ma Haijun + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +/* should be implemented by board */ +extern void spl_block_device_init(void); + +block_dev_desc_t * spl_get_block_device(void) +{ + block_dev_desc_t * device; + + spl_block_device_init(); + + device = get_dev(CONFIG_SPL_BLOCKDEV_INTERFACE, CONFIG_SPL_BLOCKDEV_ID); + if (!device) { + printf("blk device %s%d not exists\n", + CONFIG_SPL_BLOCKDEV_INTERFACE, + CONFIG_SPL_BLOCKDEV_ID); + hang(); + } + + return device; +} + +#ifdef CONFIG_SPL_FAT_SUPPORT +static int block_load_image_fat(const char *filename) +{ + int err; + struct image_header *header; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + err = file_fat_read(filename, header, sizeof(struct image_header)); + if (err <= 0) + goto end; + + spl_parse_image_header(header); + + err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0); + +end: + if (err <= 0) + printf("spl: error reading image %s, err - %d\n", + filename, err); + + return (err <= 0); +} + +#ifdef CONFIG_SPL_OS_BOOT +static int block_load_image_fat_os(void) +{ + int err; + + err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME, + (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); + if (err <= 0) { + return -1; + } + + return block_load_image_fat(CONFIG_SPL_FAT_LOAD_KERNEL_NAME); +} +#endif + +void spl_block_load_image(void) +{ + int err; + block_dev_desc_t * device; + + device = spl_get_block_device(); + err = fat_register_device(device, CONFIG_BLOCKDEV_FAT_BOOT_PARTITION); + if (err) { + printf("spl: fat register err - %d\n", err); + hang(); + } +#ifdef CONFIG_SPL_OS_BOOT + if (spl_start_uboot() || block_load_image_fat_os()) +#endif + { + err = block_load_image_fat(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME); + if (err) + hang(); + } +} +#elif defined(CONFIG_SPL_EXT4_SUPPORT) /* end CONFIG_SPL_FAT_SUPPORT */ +static int block_load_image_ext4(const char *filename) +{ + int err; + struct image_header *header; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + err = ext4_read_file(filename, header, 0, sizeof(struct image_header)); + if (err <= 0) + goto end; + + spl_parse_image_header(header); + + err = ext4_read_file(filename, (u8 *)spl_image.load_addr, 0, 0); + +end: + return (err <= 0); +} + +#ifdef CONFIG_SPL_OS_BOOT +static int block_load_image_ext4_os(void) +{ + int err; + + err = ext4_read_file(CONFIG_SPL_EXT4_LOAD_ARGS_NAME, + (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0, 0); + if (err <= 0) { + return -1; + } + + return block_load_image_ext4(CONFIG_SPL_EXT4_LOAD_KERNEL_NAME); +} +#endif + +void spl_block_load_image(void) +{ + int err; + block_dev_desc_t * device; + + device = spl_get_block_device(); + err = ext4_register_device(device, CONFIG_BLOCKDEV_EXT4_BOOT_PARTITION); + if (err) { + hang(); + } +#ifdef CONFIG_SPL_OS_BOOT + if (spl_start_uboot() || block_load_image_ext4_os()) +#endif + { + err = block_load_image_ext4(CONFIG_SPL_EXT4_LOAD_PAYLOAD_NAME); + if (err) + hang(); + } +} +#else /* end CONFIG_SPL_EXT4_SUPPORT */ +static int block_load_image_raw(block_dev_desc_t * device, lbaint_t sector) +{ + int n; + u32 image_size_sectors; + struct image_header *header; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + /* read image header to find the image size & load address */ + n = device->block_read(device->dev, sector, 1, header); + + if (n != 1) { + printf("spl: blk read err\n"); + return 1; + } + + spl_parse_image_header(header); + + /* convert size to sectors - round up */ + image_size_sectors = (spl_image.size + 512 - 1) / 512; + n = device->block_read(device->dev, sector, image_size_sectors, + (void *)spl_image.load_addr); + + if (n != image_size_sectors) { + printf("spl: blk read err\n"); + return 1; + } + return 0; +} + +#ifdef CONFIG_SPL_OS_BOOT +static int block_load_image_raw_os(block_dev_desc_t * device) +{ + int n; + + n = device->block_read(device->dev, CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTOR, + CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTORS, + (u32 *)CONFIG_SYS_SPL_ARGS_ADDR); + /* flush cache after read */ + flush_cache(addr, CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTORS * 512); + + if (n != CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTORS) { + printf("args blk read error\n"); + return -1; + } + + return block_load_image_raw(device, CONFIG_SYS_BLOCK_RAW_MODE_KERNEL_SECTOR); +} +#endif + +void spl_block_load_image(void) +{ + int err; + block_dev_desc_t * device; + + device = spl_get_block_device(); +#ifdef CONFIG_SPL_OS_BOOT + if (spl_start_uboot() || block_load_image_raw_os(device)) +#endif + { + err = block_load_image_raw(device, + CONFIG_SYS_BLOCK_RAW_MODE_U_BOOT_SECTOR); + if (err) + hang(); + } +} +#endif /* CONFIG_SPL_FAT_SUPPORT */ diff --git a/package/boot/uboot-oxnas/files/configs/ox820_defconfig b/package/boot/uboot-oxnas/files/configs/ox820_defconfig new file mode 100644 index 0000000..48a16d0 --- /dev/null +++ b/package/boot/uboot-oxnas/files/configs/ox820_defconfig @@ -0,0 +1,3 @@ +CONFIG_ARM=y +CONFIG_OX820=y +CONFIG_TARGET_OX820=y diff --git a/package/boot/uboot-oxnas/files/drivers/block/plxsata_ide.c b/package/boot/uboot-oxnas/files/drivers/block/plxsata_ide.c new file mode 100644 index 0000000..7e0e78f --- /dev/null +++ b/package/boot/uboot-oxnas/files/drivers/block/plxsata_ide.c @@ -0,0 +1,1170 @@ +/* + * (C) Copyright 2005 + * Oxford Semiconductor Ltd + * + * 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 +#include + +/** + * SATA related definitions + */ +#define ATA_PORT_CTL 0 +#define ATA_PORT_FEATURE 1 +#define ATA_PORT_NSECT 2 +#define ATA_PORT_LBAL 3 +#define ATA_PORT_LBAM 4 +#define ATA_PORT_LBAH 5 +#define ATA_PORT_DEVICE 6 +#define ATA_PORT_COMMAND 7 + +/* The offsets to the SATA registers */ +#define SATA_ORB1_OFF 0 +#define SATA_ORB2_OFF 1 +#define SATA_ORB3_OFF 2 +#define SATA_ORB4_OFF 3 +#define SATA_ORB5_OFF 4 + +#define SATA_FIS_ACCESS 11 +#define SATA_INT_STATUS_OFF 12 /* Read only */ +#define SATA_INT_CLR_OFF 12 /* Write only */ +#define SATA_INT_ENABLE_OFF 13 /* Read only */ +#define SATA_INT_ENABLE_SET_OFF 13 /* Write only */ +#define SATA_INT_ENABLE_CLR_OFF 14 /* Write only */ +#define SATA_VERSION_OFF 15 +#define SATA_CONTROL_OFF 23 +#define SATA_COMMAND_OFF 24 +#define SATA_PORT_CONTROL_OFF 25 +#define SATA_DRIVE_CONTROL_OFF 26 + +/* The offsets to the link registers that are access in an asynchronous manner */ +#define SATA_LINK_DATA 28 +#define SATA_LINK_RD_ADDR 29 +#define SATA_LINK_WR_ADDR 30 +#define SATA_LINK_CONTROL 31 + +/* SATA interrupt status register fields */ +#define SATA_INT_STATUS_EOC_RAW_BIT ( 0 + 16) +#define SATA_INT_STATUS_ERROR_BIT ( 2 + 16) +#define SATA_INT_STATUS_EOADT_RAW_BIT ( 1 + 16) + +/* SATA core command register commands */ +#define SATA_CMD_WRITE_TO_ORB_REGS 2 +#define SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND 4 + +#define SATA_CMD_BUSY_BIT 7 + +#define SATA_SCTL_CLR_ERR 0x00000316UL + +#define SATA_LBAL_BIT 0 +#define SATA_LBAM_BIT 8 +#define SATA_LBAH_BIT 16 +#define SATA_HOB_LBAH_BIT 24 +#define SATA_DEVICE_BIT 24 +#define SATA_NSECT_BIT 0 +#define SATA_HOB_NSECT_BIT 8 +#define SATA_LBA32_BIT 0 +#define SATA_LBA40_BIT 8 +#define SATA_FEATURE_BIT 16 +#define SATA_COMMAND_BIT 24 +#define SATA_CTL_BIT 24 + +/* ATA status (7) register field definitions */ +#define ATA_STATUS_BSY_BIT 7 +#define ATA_STATUS_DRDY_BIT 6 +#define ATA_STATUS_DF_BIT 5 +#define ATA_STATUS_DRQ_BIT 3 +#define ATA_STATUS_ERR_BIT 0 + +/* ATA device (6) register field definitions */ +#define ATA_DEVICE_FIXED_MASK 0xA0 +#define ATA_DEVICE_DRV_BIT 4 +#define ATA_DEVICE_DRV_NUM_BITS 1 +#define ATA_DEVICE_LBA_BIT 6 + +/* ATA Command register initiated commands */ +#define ATA_CMD_INIT 0x91 +#define ATA_CMD_IDENT 0xEC + +#define SATA_STD_ASYNC_REGS_OFF 0x20 +#define SATA_SCR_STATUS 0 +#define SATA_SCR_ERROR 1 +#define SATA_SCR_CONTROL 2 +#define SATA_SCR_ACTIVE 3 +#define SATA_SCR_NOTIFICAION 4 + +#define SATA_BURST_BUF_FORCE_EOT_BIT 0 +#define SATA_BURST_BUF_DATA_INJ_ENABLE_BIT 1 +#define SATA_BURST_BUF_DIR_BIT 2 +#define SATA_BURST_BUF_DATA_INJ_END_BIT 3 +#define SATA_BURST_BUF_FIFO_DIS_BIT 4 +#define SATA_BURST_BUF_DIS_DREQ_BIT 5 +#define SATA_BURST_BUF_DREQ_BIT 6 + +#define SATA_OPCODE_MASK 0x3 + +#define SATA_DMA_CHANNEL 0 + +#define DMA_CTRL_STATUS (0x0) +#define DMA_BASE_SRC_ADR (0x4) +#define DMA_BASE_DST_ADR (0x8) +#define DMA_BYTE_CNT (0xC) +#define DMA_CURRENT_SRC_ADR (0x10) +#define DMA_CURRENT_DST_ADR (0x14) +#define DMA_CURRENT_BYTE_CNT (0x18) +#define DMA_INTR_ID (0x1C) +#define DMA_INTR_CLEAR_REG (DMA_CURRENT_SRC_ADR) + +#define DMA_CALC_REG_ADR(channel, register) ((volatile u32*)(DMA_BASE + ((channel) << 5) + (register))) + +#define DMA_CTRL_STATUS_FAIR_SHARE_ARB (1 << 0) +#define DMA_CTRL_STATUS_IN_PROGRESS (1 << 1) +#define DMA_CTRL_STATUS_SRC_DREQ_MASK (0x0000003C) +#define DMA_CTRL_STATUS_SRC_DREQ_SHIFT (2) +#define DMA_CTRL_STATUS_DEST_DREQ_MASK (0x000003C0) +#define DMA_CTRL_STATUS_DEST_DREQ_SHIFT (6) +#define DMA_CTRL_STATUS_INTR (1 << 10) +#define DMA_CTRL_STATUS_NXT_FREE (1 << 11) +#define DMA_CTRL_STATUS_RESET (1 << 12) +#define DMA_CTRL_STATUS_DIR_MASK (0x00006000) +#define DMA_CTRL_STATUS_DIR_SHIFT (13) +#define DMA_CTRL_STATUS_SRC_ADR_MODE (1 << 15) +#define DMA_CTRL_STATUS_DEST_ADR_MODE (1 << 16) +#define DMA_CTRL_STATUS_TRANSFER_MODE_A (1 << 17) +#define DMA_CTRL_STATUS_TRANSFER_MODE_B (1 << 18) +#define DMA_CTRL_STATUS_SRC_WIDTH_MASK (0x00380000) +#define DMA_CTRL_STATUS_SRC_WIDTH_SHIFT (19) +#define DMA_CTRL_STATUS_DEST_WIDTH_MASK (0x01C00000) +#define DMA_CTRL_STATUS_DEST_WIDTH_SHIFT (22) +#define DMA_CTRL_STATUS_PAUSE (1 << 25) +#define DMA_CTRL_STATUS_INTERRUPT_ENABLE (1 << 26) +#define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED (1 << 27) +#define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED (1 << 28) +#define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY (1 << 29) +#define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE (1 << 30) + +#define DMA_BYTE_CNT_MASK ((1 << 21) - 1) +#define DMA_BYTE_CNT_WR_EOT_MASK (1 << 30) +#define DMA_BYTE_CNT_RD_EOT_MASK (1 << 31) +#define DMA_BYTE_CNT_BURST_MASK (1 << 28) + +#define MAKE_FIELD(value, num_bits, bit_num) (((value) & ((1 << (num_bits)) - 1)) << (bit_num)) + +typedef enum oxnas_dma_mode { + OXNAS_DMA_MODE_FIXED, OXNAS_DMA_MODE_INC +} oxnas_dma_mode_t; + +typedef enum oxnas_dma_direction { + OXNAS_DMA_TO_DEVICE, OXNAS_DMA_FROM_DEVICE +} oxnas_dma_direction_t; + +/* The available buses to which the DMA controller is attached */ +typedef enum oxnas_dma_transfer_bus { + OXNAS_DMA_SIDE_A, OXNAS_DMA_SIDE_B +} oxnas_dma_transfer_bus_t; + +/* Direction of data flow between the DMA controller's pair of interfaces */ +typedef enum oxnas_dma_transfer_direction { + OXNAS_DMA_A_TO_A, OXNAS_DMA_B_TO_A, OXNAS_DMA_A_TO_B, OXNAS_DMA_B_TO_B +} oxnas_dma_transfer_direction_t; + +/* The available data widths */ +typedef enum oxnas_dma_transfer_width { + OXNAS_DMA_TRANSFER_WIDTH_8BITS, + OXNAS_DMA_TRANSFER_WIDTH_16BITS, + OXNAS_DMA_TRANSFER_WIDTH_32BITS +} oxnas_dma_transfer_width_t; + +/* The mode of the DMA transfer */ +typedef enum oxnas_dma_transfer_mode { + OXNAS_DMA_TRANSFER_MODE_SINGLE, OXNAS_DMA_TRANSFER_MODE_BURST +} oxnas_dma_transfer_mode_t; + +/* The available transfer targets */ +typedef enum oxnas_dma_dreq { + OXNAS_DMA_DREQ_SATA = 0, OXNAS_DMA_DREQ_MEMORY = 15 +} oxnas_dma_dreq_t; + +typedef struct oxnas_dma_device_settings { + unsigned long address_; + unsigned fifo_size_; // Chained transfers must take account of FIFO offset at end of previous transfer + unsigned char dreq_; + unsigned read_eot_ :1; + unsigned read_final_eot_ :1; + unsigned write_eot_ :1; + unsigned write_final_eot_ :1; + unsigned bus_ :1; + unsigned width_ :2; + unsigned transfer_mode_ :1; + unsigned address_mode_ :1; + unsigned address_really_fixed_ :1; +} oxnas_dma_device_settings_t; + +static const int MAX_NO_ERROR_LOOPS = 100000; /* 1 second in units of 10uS */ +static const int MAX_DMA_XFER_LOOPS = 300000; /* 30 seconds in units of 100uS */ +static const int MAX_DMA_ABORT_LOOPS = 10000; /* 0.1 second in units of 10uS */ +static const int MAX_SRC_READ_LOOPS = 10000; /* 0.1 second in units of 10uS */ +static const int MAX_SRC_WRITE_LOOPS = 10000; /* 0.1 second in units of 10uS */ +static const int MAX_NOT_BUSY_LOOPS = 10000; /* 1 second in units of 100uS */ + +/* The internal SATA drive on which we should attempt to find partitions */ +static volatile u32* sata_regs_base[2] = { (volatile u32*) SATA_0_REGS_BASE, + (volatile u32*) SATA_1_REGS_BASE, + +}; +static u32 wr_sata_orb1[2] = { 0, 0 }; +static u32 wr_sata_orb2[2] = { 0, 0 }; +static u32 wr_sata_orb3[2] = { 0, 0 }; +static u32 wr_sata_orb4[2] = { 0, 0 }; + +#ifdef CONFIG_LBA48 +/* need keeping a record of NSECT LBAL LBAM LBAH ide_outb values for lba48 support */ +#define OUT_HISTORY_BASE ATA_PORT_NSECT +#define OUT_HISTORY_MAX ATA_PORT_LBAH +static unsigned char out_history[2][OUT_HISTORY_MAX - OUT_HISTORY_BASE + 1] = {}; +#endif + +static oxnas_dma_device_settings_t oxnas_sata_dma_settings = { .address_ = + SATA_DATA_BASE, .fifo_size_ = 16, .dreq_ = OXNAS_DMA_DREQ_SATA, + .read_eot_ = 0, .read_final_eot_ = 1, .write_eot_ = 0, + .write_final_eot_ = 1, .bus_ = OXNAS_DMA_SIDE_B, .width_ = + OXNAS_DMA_TRANSFER_WIDTH_32BITS, .transfer_mode_ = + OXNAS_DMA_TRANSFER_MODE_BURST, .address_mode_ = + OXNAS_DMA_MODE_FIXED, .address_really_fixed_ = 0 }; + +oxnas_dma_device_settings_t oxnas_ram_dma_settings = { .address_ = 0, + .fifo_size_ = 0, .dreq_ = OXNAS_DMA_DREQ_MEMORY, .read_eot_ = 1, + .read_final_eot_ = 1, .write_eot_ = 1, .write_final_eot_ = 1, + .bus_ = OXNAS_DMA_SIDE_A, .width_ = + OXNAS_DMA_TRANSFER_WIDTH_32BITS, .transfer_mode_ = + OXNAS_DMA_TRANSFER_MODE_BURST, .address_mode_ = + OXNAS_DMA_MODE_FIXED, .address_really_fixed_ = 1 }; + +static void xfer_wr_shadow_to_orbs(int device) +{ + *(sata_regs_base[device] + SATA_ORB1_OFF) = wr_sata_orb1[device]; + *(sata_regs_base[device] + SATA_ORB2_OFF) = wr_sata_orb2[device]; + *(sata_regs_base[device] + SATA_ORB3_OFF) = wr_sata_orb3[device]; + *(sata_regs_base[device] + SATA_ORB4_OFF) = wr_sata_orb4[device]; +} + +static inline void device_select(int device) +{ + /* master/slave has no meaning to SATA core */ +} + +static int disk_present[CONFIG_SYS_IDE_MAXDEVICE]; + +#include + +unsigned char ide_inb(int device, int port) +{ + unsigned char val = 0; + + /* Only permit accesses to disks found to be present during ide_preinit() */ + if (!disk_present[device]) { + return ATA_STAT_FAULT; + } + + device_select(device); + + switch (port) { + case ATA_PORT_CTL: + val = (*(sata_regs_base[device] + SATA_ORB4_OFF) + & (0xFFUL << SATA_CTL_BIT)) >> SATA_CTL_BIT; + break; + case ATA_PORT_FEATURE: + val = (*(sata_regs_base[device] + SATA_ORB2_OFF) + & (0xFFUL << SATA_FEATURE_BIT)) >> SATA_FEATURE_BIT; + break; + case ATA_PORT_NSECT: + val = (*(sata_regs_base[device] + SATA_ORB2_OFF) + & (0xFFUL << SATA_NSECT_BIT)) >> SATA_NSECT_BIT; + break; + case ATA_PORT_LBAL: + val = (*(sata_regs_base[device] + SATA_ORB3_OFF) + & (0xFFUL << SATA_LBAL_BIT)) >> SATA_LBAL_BIT; + break; + case ATA_PORT_LBAM: + val = (*(sata_regs_base[device] + SATA_ORB3_OFF) + & (0xFFUL << SATA_LBAM_BIT)) >> SATA_LBAM_BIT; + break; + case ATA_PORT_LBAH: + val = (*(sata_regs_base[device] + SATA_ORB3_OFF) + & (0xFFUL << SATA_LBAH_BIT)) >> SATA_LBAH_BIT; + break; + case ATA_PORT_DEVICE: + val = (*(sata_regs_base[device] + SATA_ORB3_OFF) + & (0xFFUL << SATA_HOB_LBAH_BIT)) >> SATA_HOB_LBAH_BIT; + val |= (*(sata_regs_base[device] + SATA_ORB1_OFF) + & (0xFFUL << SATA_DEVICE_BIT)) >> SATA_DEVICE_BIT; + break; + case ATA_PORT_COMMAND: + val = (*(sata_regs_base[device] + SATA_ORB2_OFF) + & (0xFFUL << SATA_COMMAND_BIT)) >> SATA_COMMAND_BIT; + val |= ATA_STAT_DRQ; + break; + default: + printf("ide_inb() Unknown port = %d\n", port); + break; + } + + // printf("inb: %d:%01x => %02x\n", device, port, val); + + return val; +} + +/** + * Possible that ATA status will not become no-error, so must have timeout + * @returns An int which is zero on error + */ +static inline int wait_no_error(int device) +{ + int status = 0; + + /* Check for ATA core error */ + if (*(sata_regs_base[device] + SATA_INT_STATUS_OFF) + & (1 << SATA_INT_STATUS_ERROR_BIT)) { + printf("wait_no_error() SATA core flagged error\n"); + } else { + int loops = MAX_NO_ERROR_LOOPS; + do { + /* Check for ATA device error */ + if (!(ide_inb(device, ATA_PORT_COMMAND) + & (1 << ATA_STATUS_ERR_BIT))) { + status = 1; + break; + } + udelay(10); + } while (--loops); + + if (!loops) { + printf("wait_no_error() Timed out of wait for SATA no-error condition\n"); + } + } + + return status; +} + +/** + * Expect SATA command to always finish, perhaps with error + * @returns An int which is zero on error + */ +static inline int wait_sata_command_not_busy(int device) +{ + /* Wait for data to be available */ + int status = 0; + int loops = MAX_NOT_BUSY_LOOPS; + do { + if (!(*(sata_regs_base[device] + SATA_COMMAND_OFF) + & (1 << SATA_CMD_BUSY_BIT))) { + status = 1; + break; + } + udelay(100); + } while (--loops); + + if (!loops) { + printf("wait_sata_command_not_busy() Timed out of wait for SATA command to finish\n"); + } + + return status; +} + +void ide_outb(int device, int port, unsigned char val) +{ + typedef enum send_method { + SEND_NONE, SEND_SIMPLE, SEND_CMD, SEND_CTL, + } send_method_t; + + /* Only permit accesses to disks found to be present during ide_preinit() */ + if (!disk_present[device]) { + return; + } + + // printf("outb: %d:%01x <= %02x\n", device, port, val); + + device_select(device); + +#ifdef CONFIG_LBA48 + if (port >= OUT_HISTORY_BASE && port <= OUT_HISTORY_MAX) { + out_history[0][port - OUT_HISTORY_BASE] = + out_history[1][port - OUT_HISTORY_BASE]; + out_history[1][port - OUT_HISTORY_BASE] = val; + } +#endif + send_method_t send_regs = SEND_NONE; + switch (port) { + case ATA_PORT_CTL: + wr_sata_orb4[device] &= ~(0xFFUL << SATA_CTL_BIT); + wr_sata_orb4[device] |= (val << SATA_CTL_BIT); + send_regs = SEND_CTL; + break; + case ATA_PORT_FEATURE: + wr_sata_orb2[device] &= ~(0xFFUL << SATA_FEATURE_BIT); + wr_sata_orb2[device] |= (val << SATA_FEATURE_BIT); + send_regs = SEND_SIMPLE; + break; + case ATA_PORT_NSECT: + wr_sata_orb2[device] &= ~(0xFFUL << SATA_NSECT_BIT); + wr_sata_orb2[device] |= (val << SATA_NSECT_BIT); + send_regs = SEND_SIMPLE; + break; + case ATA_PORT_LBAL: + wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAL_BIT); + wr_sata_orb3[device] |= (val << SATA_LBAL_BIT); + send_regs = SEND_SIMPLE; + break; + case ATA_PORT_LBAM: + wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAM_BIT); + wr_sata_orb3[device] |= (val << SATA_LBAM_BIT); + send_regs = SEND_SIMPLE; + break; + case ATA_PORT_LBAH: + wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAH_BIT); + wr_sata_orb3[device] |= (val << SATA_LBAH_BIT); + send_regs = SEND_SIMPLE; + break; + case ATA_PORT_DEVICE: + wr_sata_orb1[device] &= ~(0xFFUL << SATA_DEVICE_BIT); + wr_sata_orb1[device] |= (val << SATA_DEVICE_BIT); + send_regs = SEND_SIMPLE; + break; + case ATA_PORT_COMMAND: + wr_sata_orb2[device] &= ~(0xFFUL << SATA_COMMAND_BIT); + wr_sata_orb2[device] |= (val << SATA_COMMAND_BIT); + send_regs = SEND_CMD; +#ifdef CONFIG_LBA48 + if (val == ATA_CMD_READ_EXT || val == ATA_CMD_WRITE_EXT) + { + /* fill high bytes of LBA48 && NSECT */ + wr_sata_orb2[device] &= ~(0xFFUL << SATA_HOB_NSECT_BIT); + wr_sata_orb2[device] |= + (out_history[0][ATA_PORT_NSECT - OUT_HISTORY_BASE] << SATA_HOB_NSECT_BIT); + + wr_sata_orb3[device] &= ~(0xFFUL << SATA_HOB_LBAH_BIT); + wr_sata_orb3[device] |= + (out_history[0][ATA_PORT_LBAL - OUT_HISTORY_BASE] << SATA_HOB_LBAH_BIT); + + wr_sata_orb4[device] &= ~(0xFFUL << SATA_LBA32_BIT); + wr_sata_orb4[device] |= + (out_history[0][ATA_PORT_LBAM - OUT_HISTORY_BASE] << SATA_LBA32_BIT); + + wr_sata_orb4[device] &= ~(0xFFUL << SATA_LBA40_BIT); + wr_sata_orb4[device] |= + (out_history[0][ATA_PORT_LBAH - OUT_HISTORY_BASE] << SATA_LBA40_BIT); + } +#endif + break; + default: + printf("ide_outb() Unknown port = %d\n", port); + } + + u32 command; + switch (send_regs) { + case SEND_CMD: + wait_sata_command_not_busy(device); + command = *(sata_regs_base[device] + SATA_COMMAND_OFF); + command &= ~SATA_OPCODE_MASK; + command |= SATA_CMD_WRITE_TO_ORB_REGS; + xfer_wr_shadow_to_orbs(device); + wait_sata_command_not_busy(device); + *(sata_regs_base[device] + SATA_COMMAND_OFF) = command; + if (!wait_no_error(device)) { + printf("ide_outb() Wait for ATA no-error timed-out\n"); + } + break; + case SEND_CTL: + wait_sata_command_not_busy(device); + command = *(sata_regs_base[device] + SATA_COMMAND_OFF); + command &= ~SATA_OPCODE_MASK; + command |= SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND; + xfer_wr_shadow_to_orbs(device); + wait_sata_command_not_busy(device); + *(sata_regs_base[device] + SATA_COMMAND_OFF) = command; + if (!wait_no_error(device)) { + printf("ide_outb() Wait for ATA no-error timed-out\n"); + } + break; + default: + break; + } +} + +static u32 encode_start(u32 ctrl_status) +{ + return ctrl_status & ~DMA_CTRL_STATUS_PAUSE; +} + +/* start a paused DMA transfer in channel 0 of the SATA DMA core */ +static void dma_start(void) +{ + unsigned int reg; + reg = readl(SATA_DMA_REGS_BASE + DMA_CTRL_STATUS); + reg = encode_start(reg); + writel(reg, SATA_DMA_REGS_BASE + DMA_CTRL_STATUS); +} + +static unsigned long encode_control_status( + oxnas_dma_device_settings_t* src_settings, + oxnas_dma_device_settings_t* dst_settings) +{ + unsigned long ctrl_status; + oxnas_dma_transfer_direction_t direction; + + ctrl_status = DMA_CTRL_STATUS_PAUSE; // Paused + ctrl_status |= DMA_CTRL_STATUS_FAIR_SHARE_ARB; // High priority + ctrl_status |= (src_settings->dreq_ << DMA_CTRL_STATUS_SRC_DREQ_SHIFT); // Dreq + ctrl_status |= (dst_settings->dreq_ << DMA_CTRL_STATUS_DEST_DREQ_SHIFT); // Dreq + ctrl_status &= ~DMA_CTRL_STATUS_RESET; // !RESET + + // Use new interrupt clearing register + ctrl_status |= DMA_CTRL_STATUS_INTR_CLEAR_ENABLE; + + // Setup the transfer direction and burst/single mode for the two DMA busses + if (src_settings->bus_ == OXNAS_DMA_SIDE_A) { + // Set the burst/single mode for bus A based on src device's settings + if (src_settings->transfer_mode_ + == OXNAS_DMA_TRANSFER_MODE_BURST) { + ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A; + } else { + ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A; + } + + if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) { + direction = OXNAS_DMA_A_TO_A; + } else { + direction = OXNAS_DMA_A_TO_B; + + // Set the burst/single mode for bus B based on dst device's settings + if (dst_settings->transfer_mode_ + == OXNAS_DMA_TRANSFER_MODE_BURST) { + ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B; + } else { + ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B; + } + } + } else { + // Set the burst/single mode for bus B based on src device's settings + if (src_settings->transfer_mode_ + == OXNAS_DMA_TRANSFER_MODE_BURST) { + ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B; + } else { + ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B; + } + + if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) { + direction = OXNAS_DMA_B_TO_A; + + // Set the burst/single mode for bus A based on dst device's settings + if (dst_settings->transfer_mode_ + == OXNAS_DMA_TRANSFER_MODE_BURST) { + ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A; + } else { + ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A; + } + } else { + direction = OXNAS_DMA_B_TO_B; + } + } + ctrl_status |= (direction << DMA_CTRL_STATUS_DIR_SHIFT); + + // Setup source address mode fixed or increment + if (src_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) { + // Fixed address + ctrl_status &= ~(DMA_CTRL_STATUS_SRC_ADR_MODE); + + // Set up whether fixed address is _really_ fixed + if (src_settings->address_really_fixed_) { + ctrl_status |= DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED; + } else { + ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED; + } + } else { + // Incrementing address + ctrl_status |= DMA_CTRL_STATUS_SRC_ADR_MODE; + ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED; + } + + // Setup destination address mode fixed or increment + if (dst_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) { + // Fixed address + ctrl_status &= ~(DMA_CTRL_STATUS_DEST_ADR_MODE); + + // Set up whether fixed address is _really_ fixed + if (dst_settings->address_really_fixed_) { + ctrl_status |= + DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED; + } else { + ctrl_status &= + ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED; + } + } else { + // Incrementing address + ctrl_status |= DMA_CTRL_STATUS_DEST_ADR_MODE; + ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED; + } + + // Set up the width of the transfers on the DMA buses + ctrl_status |= + (src_settings->width_ << DMA_CTRL_STATUS_SRC_WIDTH_SHIFT); + ctrl_status |= + (dst_settings->width_ << DMA_CTRL_STATUS_DEST_WIDTH_SHIFT); + + // Setup the priority arbitration scheme + ctrl_status &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY; // !Starve low priority + + return ctrl_status; +} + +static u32 encode_final_eot(oxnas_dma_device_settings_t* src_settings, + oxnas_dma_device_settings_t* dst_settings, + unsigned long length) +{ + // Write the length, with EOT configuration for a final transfer + unsigned long encoded = length; + if (dst_settings->write_final_eot_) { + encoded |= DMA_BYTE_CNT_WR_EOT_MASK; + } else { + encoded &= ~DMA_BYTE_CNT_WR_EOT_MASK; + } + if (src_settings->read_final_eot_) { + encoded |= DMA_BYTE_CNT_RD_EOT_MASK; + } else { + encoded &= ~DMA_BYTE_CNT_RD_EOT_MASK; + } + /* if((src_settings->transfer_mode_) || + (src_settings->transfer_mode_)) { + encoded |= DMA_BYTE_CNT_BURST_MASK; + } else { + encoded &= ~DMA_BYTE_CNT_BURST_MASK; + }*/ + return encoded; +} + +static void dma_start_write(const ulong* buffer, int num_bytes) +{ + // Assemble complete memory settings + oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings; + mem_settings.address_ = (unsigned long) buffer; + mem_settings.address_mode_ = OXNAS_DMA_MODE_INC; + + writel(encode_control_status(&mem_settings, &oxnas_sata_dma_settings), + SATA_DMA_REGS_BASE + DMA_CTRL_STATUS); + writel(mem_settings.address_, SATA_DMA_REGS_BASE + DMA_BASE_SRC_ADR); + writel(oxnas_sata_dma_settings.address_, + SATA_DMA_REGS_BASE + DMA_BASE_DST_ADR); + writel(encode_final_eot(&mem_settings, &oxnas_sata_dma_settings, + num_bytes), + SATA_DMA_REGS_BASE + DMA_BYTE_CNT); + + dma_start(); +} + +static void dma_start_read(ulong* buffer, int num_bytes) +{ + // Assemble complete memory settings + oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings; + mem_settings.address_ = (unsigned long) buffer; + mem_settings.address_mode_ = OXNAS_DMA_MODE_INC; + + writel(encode_control_status(&oxnas_sata_dma_settings, &mem_settings), + SATA_DMA_REGS_BASE + DMA_CTRL_STATUS); + writel(oxnas_sata_dma_settings.address_, + SATA_DMA_REGS_BASE + DMA_BASE_SRC_ADR); + writel(mem_settings.address_, SATA_DMA_REGS_BASE + DMA_BASE_DST_ADR); + writel(encode_final_eot(&oxnas_sata_dma_settings, &mem_settings, + num_bytes), + SATA_DMA_REGS_BASE + DMA_BYTE_CNT); + + dma_start(); +} + +static inline int dma_busy(void) +{ + return readl(SATA_DMA_REGS_BASE + DMA_CTRL_STATUS) + & DMA_CTRL_STATUS_IN_PROGRESS; +} + +static int wait_dma_not_busy(int device) +{ + unsigned int cleanup_required = 0; + + /* Poll for DMA completion */ + int loops = MAX_DMA_XFER_LOOPS; + do { + if (!dma_busy()) { + break; + } + udelay(100); + } while (--loops); + + if (!loops) { + printf("wait_dma_not_busy() Timed out of wait for DMA not busy\n"); + cleanup_required = 1; + } + + if (cleanup_required) { + /* Abort DMA to make sure it has finished. */ + unsigned int ctrl_status = readl( + SATA_DMA_CHANNEL + DMA_CTRL_STATUS); + ctrl_status |= DMA_CTRL_STATUS_RESET; + writel(ctrl_status, SATA_DMA_CHANNEL + DMA_CTRL_STATUS); + + // Wait for the channel to become idle - should be quick as should + // finish after the next AHB single or burst transfer + loops = MAX_DMA_ABORT_LOOPS; + do { + if (!dma_busy()) { + break; + } + udelay(10); + } while (--loops); + + if (!loops) { + printf("wait_dma_not_busy() Timed out of wait for DMA channel abort\n"); + } else { + /* Successfully cleanup the DMA channel */ + cleanup_required = 0; + } + + // Deassert reset for the channel + ctrl_status = readl(SATA_DMA_CHANNEL + DMA_CTRL_STATUS); + ctrl_status &= ~DMA_CTRL_STATUS_RESET; + writel(ctrl_status, SATA_DMA_CHANNEL + DMA_CTRL_STATUS); + } + + return !cleanup_required; +} + +/** + * Possible that ATA status will not become not-busy, so must have timeout + */ +static unsigned int wait_not_busy(int device, unsigned long timeout_secs) +{ + int busy = 1; + unsigned long loops = (timeout_secs * 1000) / 50; + do { + // Test the ATA status register BUSY flag + if (!((*(sata_regs_base[device] + SATA_ORB2_OFF) + >> SATA_COMMAND_BIT) & (1UL << ATA_STATUS_BSY_BIT))) { + /* Not busy, so stop polling */ + busy = 0; + break; + } + + // Wait for 50mS before sampling ATA status register again + udelay(50000); + } while (--loops); + + return busy; +} + +void ide_output_data(int device, const ulong *sect_buf, int words) +{ + /* Only permit accesses to disks found to be present during ide_preinit() */ + if (!disk_present[device]) { + return; + } + + /* Select the required internal SATA drive */ + device_select(device); + + /* Start the DMA channel sending data from the passed buffer to the SATA core */ + dma_start_write(sect_buf, words << 2); + + /* Don't know why we need this delay, but without it the wait for DMA not + busy times soemtimes out, e.g. when saving environment to second disk */ + udelay(1000); + + /* Wait for DMA to finish */ + if (!wait_dma_not_busy(device)) { + printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", + device); + } + + /* Sata core should finish after DMA */ + if (wait_not_busy(device, 30)) { + printf("Timed out of wait for SATA device %d to have BUSY clear\n", + device); + } + if (!wait_no_error(device)) { + printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n"); + } +} + + +#define SATA_DM_DBG1 (SATA_HOST_REGS_BASE + 0) +#define SATA_DATACOUNT_PORT0 (SATA_HOST_REGS_BASE + 0x10) +#define SATA_DATACOUNT_PORT1 (SATA_HOST_REGS_BASE + 0x14) +#define SATA_DATA_MUX_RAM0 (SATA_HOST_REGS_BASE + 0x8000) +#define SATA_DATA_MUX_RAM1 (SATA_HOST_REGS_BASE + 0xA000) +/* Sata core debug1 register bits */ +#define SATA_CORE_PORT0_DATA_DIR_BIT 20 +#define SATA_CORE_PORT1_DATA_DIR_BIT 21 +#define SATA_CORE_PORT0_DATA_DIR (1 << SATA_CORE_PORT0_DATA_DIR_BIT) +#define SATA_CORE_PORT1_DATA_DIR (1 << SATA_CORE_PORT1_DATA_DIR_BIT) + +/** + * Ref bug-6320 + * + * This code is a work around for a DMA hardware bug that will repeat the + * penultimate 8-bytes on some reads. This code will check that the amount + * of data transferred is a multiple of 512 bytes, if not the in it will + * fetch the correct data from a buffer in the SATA core and copy it into + * memory. + * + */ +static void sata_bug_6320_workaround(int port, ulong *candidate) +{ + int is_read; + int quads_transferred; + int remainder; + int sector_quads_remaining; + + /* Only want to apply fix to reads */ + is_read = !(*((unsigned long*) SATA_DM_DBG1) + & (port ? SATA_CORE_PORT1_DATA_DIR : SATA_CORE_PORT0_DATA_DIR)); + + /* Check for an incomplete transfer, i.e. not a multiple of 512 bytes + transferred (datacount_port register counts quads transferred) */ + quads_transferred = *((unsigned long*) ( + port ? SATA_DATACOUNT_PORT1 : SATA_DATACOUNT_PORT0)); + + remainder = quads_transferred & 0x7f; + sector_quads_remaining = remainder ? (0x80 - remainder) : 0; + + if (is_read && (sector_quads_remaining == 2)) { + debug("SATA read fixup, only transfered %d quads, " + "sector_quads_remaining %d, port %d\n", + quads_transferred, sector_quads_remaining, port); + + int total_len = ATA_SECT_SIZE; + ulong *sata_data_ptr = (void*) ( + port ? SATA_DATA_MUX_RAM1 : SATA_DATA_MUX_RAM0) + + ((total_len - 8) % 2048); + + *candidate = *sata_data_ptr; + *(candidate + 1) = *(sata_data_ptr + 1); + } +} + + +void ide_input_data(int device, ulong *sect_buf, int words) +{ + /* Only permit accesses to disks found to be present during ide_preinit() */ + if (!disk_present[device]) { + return; + } + + /* Select the required internal SATA drive */ + device_select(device); + + /* Start the DMA channel receiving data from the SATA core into the passed buffer */ + dma_start_read(sect_buf, words << 2); + + /* Sata core should finish before DMA */ + if (wait_not_busy(device, 30)) { + printf("Timed out of wait for SATA device %d to have BUSY clear\n", + device); + } + if (!wait_no_error(device)) { + printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n"); + } + + /* Wait for DMA to finish */ + if (!wait_dma_not_busy(device)) { + printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", + device); + } + + if (words == ATA_SECTORWORDS) + sata_bug_6320_workaround(device, sect_buf + words - 2); +} + +static u32 scr_read(int device, unsigned int sc_reg) +{ + /* Setup adr of required register. std regs start eight into async region */ + *(sata_regs_base[device] + SATA_LINK_RD_ADDR) = sc_reg + * 4+ SATA_STD_ASYNC_REGS_OFF; + + /* Wait for data to be available */ + int loops = MAX_SRC_READ_LOOPS; + do { + if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) { + break; + } + udelay(10); + } while (--loops); + + if (!loops) { + printf("scr_read() Timed out of wait for read completion\n"); + } + + /* Read the data from the async register */ + return *(sata_regs_base[device] + SATA_LINK_DATA); +} + +static void scr_write(int device, unsigned int sc_reg, u32 val) +{ + /* Setup the data for the write */ + *(sata_regs_base[device] + SATA_LINK_DATA) = val; + + /* Setup adr of required register. std regs start eight into async region */ + *(sata_regs_base[device] + SATA_LINK_WR_ADDR) = sc_reg + * 4+ SATA_STD_ASYNC_REGS_OFF; + + /* Wait for data to be written */ + int loops = MAX_SRC_WRITE_LOOPS; + do { + if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) { + break; + } + udelay(10); + } while (--loops); + + if (!loops) { + printf("scr_write() Timed out of wait for write completion\n"); + } +} +extern void workaround5458(void); + +#define PHY_LOOP_COUNT 25 /* Wait for upto 5 seconds for PHY to be found */ +#define LOS_AND_TX_LVL 0x2988 +#define TX_ATTEN 0x55629 + +static int phy_reset(int device) +{ + int phy_status = 0; + int loops = 0; + + scr_write(device, (0x60 - SATA_STD_ASYNC_REGS_OFF) / 4, LOS_AND_TX_LVL); + scr_write(device, (0x70 - SATA_STD_ASYNC_REGS_OFF) / 4, TX_ATTEN); + + /* limit it to Gen-1 SATA (1.5G) */ + scr_write(device, SATA_SCR_CONTROL, 0x311); /* Issue phy wake & core reset */ + scr_read(device, SATA_SCR_STATUS); /* Dummy read; flush */ + udelay(1000); + scr_write(device, SATA_SCR_CONTROL, 0x310); /* Issue phy wake & clear core reset */ + + /* Wait for upto 5 seconds for PHY to become ready */ + do { + udelay(200000); + if ((scr_read(device, SATA_SCR_STATUS) & 0xf) == 3) { + scr_write(device, SATA_SCR_ERROR, ~0); + phy_status = 1; + break; + } + //printf("No SATA PHY found status:0x%x\n", scr_read(device, SATA_SCR_STATUS)); + } while (++loops < PHY_LOOP_COUNT); + + if (phy_status) { + udelay(500000); /* wait half a second */ + } + + return phy_status; +} + +#define FIS_LOOP_COUNT 25 /* Wait for upto 5 seconds for FIS to be received */ +static int wait_FIS(int device) +{ + int status = 0; + int loops = 0; + + do { + udelay(200000); + if (ide_inb(device, ATA_PORT_NSECT) > 0) { + status = 1; + break; + } + } while (++loops < FIS_LOOP_COUNT); + + return status; +} + + +#define SATA_PHY_ASIC_STAT (0x44900000) +#define SATA_PHY_ASIC_DATA (0x44900004) + +/** + * initialise functions and macros for ASIC implementation + */ +#define PH_GAIN 2 +#define FR_GAIN 3 +#define PH_GAIN_OFFSET 6 +#define FR_GAIN_OFFSET 8 +#define PH_GAIN_MASK (0x3 << PH_GAIN_OFFSET) +#define FR_GAIN_MASK (0x3 << FR_GAIN_OFFSET) +#define USE_INT_SETTING (1<<5) + +#define CR_READ_ENABLE (1<<16) +#define CR_WRITE_ENABLE (1<<17) +#define CR_CAP_DATA (1<<18) + +static void wait_cr_ack(void) +{ + while ((readl(SATA_PHY_ASIC_STAT) >> 16) & 0x1f) + /* wait for an ack bit to be set */; +} + +static unsigned short read_cr(unsigned short address) +{ + writel(address, SATA_PHY_ASIC_STAT); + wait_cr_ack(); + writel(CR_READ_ENABLE, SATA_PHY_ASIC_DATA); + wait_cr_ack(); + return readl(SATA_PHY_ASIC_STAT); +} + +static void write_cr(unsigned short data, unsigned short address) +{ + writel(address, SATA_PHY_ASIC_STAT); + wait_cr_ack(); + writel((data | CR_CAP_DATA), SATA_PHY_ASIC_DATA); + wait_cr_ack(); + writel(CR_WRITE_ENABLE, SATA_PHY_ASIC_DATA); + wait_cr_ack(); + return; +} + +void workaround5458(void) +{ + unsigned i; + + for (i = 0; i < 2; i++) { + unsigned short rx_control = read_cr(0x201d + (i << 8)); + rx_control &= ~(PH_GAIN_MASK | FR_GAIN_MASK); + rx_control |= PH_GAIN << PH_GAIN_OFFSET; + rx_control |= FR_GAIN << FR_GAIN_OFFSET; + rx_control |= USE_INT_SETTING; + write_cr(rx_control, 0x201d + (i << 8)); + } +} + +int ide_preinit(void) +{ + int num_disks_found = 0; + + /* Initialise records of which disks are present to all present */ + int i; + for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; i++) { + disk_present[i] = 1; + } + + /* Block reset SATA and DMA cores */ + reset_block(SYS_CTRL_RST_SATA, 1); + reset_block(SYS_CTRL_RST_SATA_LINK, 1); + reset_block(SYS_CTRL_RST_SATA_PHY, 1); + reset_block(SYS_CTRL_RST_SGDMA, 1); + + /* Enable clocks to SATA and DMA cores */ + enable_clock(SYS_CTRL_CLK_SATA); + enable_clock(SYS_CTRL_CLK_DMA); + + udelay(5000); + reset_block(SYS_CTRL_RST_SATA_PHY, 0); + udelay(50); + reset_block(SYS_CTRL_RST_SATA, 0); + reset_block(SYS_CTRL_RST_SATA_LINK, 0); + udelay(50); + reset_block(SYS_CTRL_RST_SGDMA, 0); + udelay(100); + /* Apply the Synopsis SATA PHY workarounds */ + workaround5458(); + udelay(10000); + + /* disable and clear core interrupts */ + *((unsigned long*) SATA_HOST_REGS_BASE + SATA_INT_ENABLE_CLR_OFF) = + ~0UL; + *((unsigned long*) SATA_HOST_REGS_BASE + SATA_INT_CLR_OFF) = ~0UL; + + int device; + for (device = 0; device < CONFIG_SYS_IDE_MAXDEVICE; device++) { + int found = 0; + int retries = 1; + + /* Disable SATA interrupts */ + *(sata_regs_base[device] + SATA_INT_ENABLE_CLR_OFF) = ~0UL; + + /* Clear any pending SATA interrupts */ + *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL; + + do { + /* clear sector count register for FIS detection */ + ide_outb(device, ATA_PORT_NSECT, 0); + + /* Get the PHY working */ + if (!phy_reset(device)) { + printf("SATA PHY not ready for device %d\n", + device); + break; + } + + if (!wait_FIS(device)) { + printf("No FIS received from device %d\n", + device); + } else { + if ((scr_read(device, SATA_SCR_STATUS) & 0xf) + == 0x3) { + if (wait_not_busy(device, 30)) { + printf("Timed out of wait for SATA device %d to have BUSY clear\n", + device); + } else { + ++num_disks_found; + found = 1; + } + } else { + printf("No SATA device %d found, PHY status = 0x%08x\n", + device, + scr_read( + device, + SATA_SCR_STATUS)); + } + break; + } + } while (retries--); + + /* Record whether disk is present, so won't attempt to access it later */ + disk_present[device] = found; + } + + /* post disk detection clean-up */ + for (device = 0; device < CONFIG_SYS_IDE_MAXDEVICE; device++) { + if (disk_present[device]) { + /* set as ata-5 (28-bit) */ + *(sata_regs_base[device] + SATA_DRIVE_CONTROL_OFF) = + 0UL; + + /* clear phy/link errors */ + scr_write(device, SATA_SCR_ERROR, ~0); + + /* clear host errors */ + *(sata_regs_base[device] + SATA_CONTROL_OFF) |= + SATA_SCTL_CLR_ERR; + + /* clear interrupt register as this clears the error bit in the IDE + status register */ + *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL; + } + } + + return !num_disks_found; +} + diff --git a/package/boot/uboot-oxnas/files/drivers/usb/host/ehci-oxnas.c b/package/boot/uboot-oxnas/files/drivers/usb/host/ehci-oxnas.c new file mode 100644 index 0000000..6ab05c5 --- /dev/null +++ b/package/boot/uboot-oxnas/files/drivers/usb/host/ehci-oxnas.c @@ -0,0 +1,105 @@ +/* + * drivers/usb/host/ehci-oxnas.c + * + * Tzachi Perelstein + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include +#include +#include +#include + +#include "ehci.h" + +static struct ehci_hcor *ghcor; + +static int start_oxnas_usb_ehci(void) +{ +#ifdef CONFIG_USB_PLLB_CLK + reset_block(SYS_CTRL_RST_PLLB, 0); + enable_clock(SYS_CTRL_CLK_REF600); + + writel((1 << PLLB_ENSAT) | (1 << PLLB_OUTDIV) | (2 << PLLB_REFDIV), + SEC_CTRL_PLLB_CTRL0); + /* 600MHz pllb divider for 12MHz */ + writel(PLLB_DIV_INT(50) | PLLB_DIV_FRAC(0), SEC_CTRL_PLLB_DIV_CTRL); +#else + /* ref 300 divider for 12MHz */ + writel(REF300_DIV_INT(25) | REF300_DIV_FRAC(0), SYS_CTRL_REF300_DIV); +#endif + + /* Ensure the USB block is properly reset */ + reset_block(SYS_CTRL_RST_USBHS, 1); + reset_block(SYS_CTRL_RST_USBHS, 0); + + reset_block(SYS_CTRL_RST_USBHSPHYA, 1); + reset_block(SYS_CTRL_RST_USBHSPHYA, 0); + + reset_block(SYS_CTRL_RST_USBHSPHYB, 1); + reset_block(SYS_CTRL_RST_USBHSPHYB, 0); + + /* Force the high speed clock to be generated all the time, via serial + programming of the USB HS PHY */ + writel((2UL << USBHSPHY_TEST_ADD) | + (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL); + + writel((1UL << USBHSPHY_TEST_CLK) | + (2UL << USBHSPHY_TEST_ADD) | + (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL); + + writel((0xfUL << USBHSPHY_TEST_ADD) | + (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL); + + writel((1UL << USBHSPHY_TEST_CLK) | + (0xfUL << USBHSPHY_TEST_ADD) | + (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL); + +#ifdef CONFIG_USB_PLLB_CLK /* use pllb clock */ + writel(USB_CLK_INTERNAL | USB_INT_CLK_PLLB, SYS_CTRL_USB_CTRL); +#else /* use ref300 derived clock */ + writel(USB_CLK_INTERNAL | USB_INT_CLK_REF300, SYS_CTRL_USB_CTRL); +#endif + /* Enable the clock to the USB block */ + enable_clock(SYS_CTRL_CLK_USBHS); + + return 0; +} +int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, + struct ehci_hcor **hcor) +{ + start_oxnas_usb_ehci(); + *hccr = (struct ehci_hccr *)(USB_HOST_BASE + 0x100); + *hcor = (struct ehci_hcor *)((uint32_t)*hccr + + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); + ghcor = *hcor; + return 0; +} + +int ehci_hcd_stop(int index) +{ + reset_block(SYS_CTRL_RST_USBHS, 1); + disable_clock(SYS_CTRL_CLK_USBHS); + return 0; +} + +extern void __ehci_set_usbmode(int index); +void ehci_set_usbmode(int index) +{ + #define or_txttfill_tuning _reserved_1_[0] + u32 tmp; + + __ehci_set_usbmode(index); + + tmp = ehci_readl(&ghcor->or_txfilltuning); + tmp &= ~0x00ff0000; + tmp |= 0x003f0000; /* set burst pre load count to 0x40 (63 * 4 bytes) */ + tmp |= 0x16; /* set sheduler overhead to 22 * 1.267us (HS) or 22 * 6.33us (FS/LS)*/ + ehci_writel(&ghcor->or_txfilltuning, tmp); + + tmp = ehci_readl(&ghcor->or_txttfill_tuning); + tmp |= 0x2; /* set sheduler overhead to 2 * 6.333us */ + ehci_writel(&ghcor->or_txttfill_tuning, tmp); +} diff --git a/package/boot/uboot-oxnas/files/include/configs/ox820.h b/package/boot/uboot-oxnas/files/include/configs/ox820.h new file mode 100644 index 0000000..85ee3b4 --- /dev/null +++ b/package/boot/uboot-oxnas/files/include/configs/ox820.h @@ -0,0 +1,383 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_ARM1136 +#define CONFIG_OX820 +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_BOARD_EARLY_INIT_F + +#include /* get chip and board defs */ + +/* make cmd_ide.c quiet when compile */ +#define __io + +/*#define CONFIG_ARCH_CPU_INIT*/ +/*#define CONFIG_DISPLAY_CPUINFO*/ +/*#define CONFIG_DISPLAY_BOARDINFO*/ +/*#define CONFIG_BOARD_EARLY_INIT_F*/ +/*#define CONFIG_SKIP_LOWLEVEL_INIT*/ + +/* mem */ +#define CONFIG_SYS_SDRAM_BASE 0x60000000 +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_MIN_SDRAM_SIZE (128 * 1024 * 1024) /* 128 MB */ +#define CONFIG_MAX_SDRAM_SIZE (512 * 1024 * 1024) /* 512 MB */ +#define CONFIG_SRAM_BASE 0x50000000 +#define CONFIG_SRAM_SIZE (64 * 1024) + +/* need do dma so better keep dcache off */ +#define CONFIG_SYS_DCACHE_OFF + +/* clock */ +#define CONFIG_PLLA_FREQ_MHZ 800 +#define CONFIG_RPSCLK 6250000 +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_CLK_FREQ CONFIG_RPSCLK +#define CONFIG_SYS_TIMERBASE TIMER1_BASE +#define CONFIG_TIMER_PRESCALE TIMER_PRESCALE_16 + +/* serial */ +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_CLK CONFIG_RPSCLK +#define CONFIG_SYS_NS16550_REG_SIZE 1 +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_NS16550_COM1 UART_1_BASE +#define CONFIG_CONS_INDEX 1 + +/* ide */ +#define CONFIG_SYS_ATA_BASE_ADDR 0 +#define CONFIG_SYS_ATA_DATA_OFFSET 0 +#define CONFIG_SYS_ATA_REG_OFFSET 0 +#define CONFIG_SYS_ATA_ALT_OFFSET 0 +#define CONFIG_IDE_PLX +#define CONFIG_SYS_IDE_MAXDEVICE 2 +#define CONFIG_SYS_IDE_MAXBUS 1 +#define CONFIG_IDE_PREINIT +#define CONFIG_LBA48 + +/* nand */ +#define CONFIG_NAND +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_SYS_NAND_BASE STATIC_CS0_BASE +#define NAND_CLE_ADDR_PIN 19 +#define NAND_ALE_ADDR_PIN 18 +#define MTDPARTS_DEFAULT "mtdparts=41000000.nand:" \ + "14m(boot)," \ + "-(ubi)" +#define MTDIDS_DEFAULT "nand0=41000000.nand" +#define UBIPART_DEFAULT "ubi" + +/* net */ +#define CONFIG_DESIGNWARE_ETH +#define CONFIG_DW_ALTDESCRIPTOR +#define CONFIG_MII +#define CONFIG_CMD_MII +#define CONFIG_PHYLIB +#define CONFIG_PHY_REALTEK +#define CONFIG_PHY_ICPLUS + +/* spl */ +#ifdef CONFIG_SPL_BUILD +#define USE_DL_PREFIX /* rename malloc free etc, so we can override them */ +#endif + +#if defined(CONFIG_BOOT_FROM_NAND) || defined(CONFIG_BOOT_FROM_SATA) +#define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_TEXT_BASE 0x50000000 +#define CONFIG_SPL_STACK (CONFIG_SRAM_BASE + (48 * 1024)) +#define CONFIG_SPL_DISPLAY_PRINT +#define CONFIG_SPL_BSS_DRAM_START 0x65000000 +#define CONFIG_SPL_BSS_DRAM_SIZE 0x01000000 +#define CONFIG_SPL_MALLOC_START 0x66000000 +#endif + +#if defined(CONFIG_BOOT_FROM_NAND) +#define CONFIG_SPL_NAND_SUPPORT +#define BOOT_DEVICE_TYPE "NAND" +#define BOOT_DEVICE_NAND 0xfeedbacc +#define CONFIG_SPL_BOOT_DEVICE BOOT_DEVICE_NAND +#define CONFIG_SPL_NAND_SIMPLE +#define CONFIG_SPL_NAND_ECC +#define CONFIG_SPL_NAND_SOFTECC +#define CONFIG_SYS_NAND_ECCSIZE 512 +#define CONFIG_SYS_NAND_ECCBYTES 6 +#define CONFIG_SYS_NAND_ECCPOS {40, 41, 42, 43, 44, 45, 46, 47, \ + 48, 49, 50, 51, 52, 53, 54, 55, \ + 56, 57, 58, 59, 60, 61, 62, 63} +#define CONFIG_SYS_NAND_PAGE_SIZE 2048 +#define CONFIG_SYS_NAND_OOBSIZE 64 +#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024) +#define CONFIG_SYS_NAND_BAD_BLOCK_POS 0 +/* pages per erase block */ +#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / CONFIG_SYS_NAND_PAGE_SIZE) +/* nand spl use 1 erase block, and use bit to byte encode for reliability */ +#define CONFIG_SPL_MAX_SIZE (128 * 1024 / 8) +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x00040000 +/* spl kernel load is not enabled */ +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000 +#define CONFIG_CMD_SPL_NAND_OFS 0 +#define CONFIG_CMD_SPL_WRITE_SIZE 1024 +#define CONFIG_SYS_SPL_ARGS_ADDR (CONFIG_SYS_SDRAM_BASE + 0x100) +/* CONFIG_BOOT_FROM_NAND end */ + +#elif defined(CONFIG_BOOT_FROM_SATA) +#define CONFIG_SPL_BLOCK_SUPPORT +#define BOOT_DEVICE_TYPE "SATA" +#define BOOT_DEVICE_BLOCK 860202 +#define CONFIG_SPL_BOOT_DEVICE BOOT_DEVICE_BLOCK +#define CONFIG_SPL_MAX_SIZE (36 * 1024) +#define CONFIG_SPL_LIBDISK_SUPPORT +#define CONFIG_SPL_BLOCKDEV_INTERFACE "ide" +#define CONFIG_SPL_BLOCKDEV_ID 0 + +#ifdef CONFIG_BOOT_FROM_FAT /* u-boot in fat partition */ + +#define CONFIG_SPL_FAT_SUPPORT + +#define CONFIG_BLOCKDEV_FAT_BOOT_PARTITION 1 /* first partition */ +#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME "u-boot.img" /* u-boot file name */ +/* enable U-Boot Falcon Mode */ +#define CONFIG_CMD_SPL +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_FAT_LOAD_ARGS_NAME "bootargs.bin" /* boot parameters */ +#define CONFIG_SPL_FAT_LOAD_KERNEL_NAME "falcon.img" /* kernel */ +#define CONFIG_SYS_SPL_ARGS_ADDR (CONFIG_SYS_SDRAM_BASE + 0x100) + +#elif CONFIG_BOOT_FROM_EXT4 + +#define CONFIG_SPL_EXT4_SUPPORT +#define CONFIG_BLOCKDEV_EXT4_BOOT_PARTITION 1 /* first partition */ +#define CONFIG_SPL_EXT4_LOAD_PAYLOAD_NAME "/boot/u-boot.img" /* u-boot file name */ +/* enable U-Boot Falcon Mode */ +#define CONFIG_CMD_SPL +#define CONFIG_SPL_OS_BOOT +#define CONFIG_SPL_EXT4_LOAD_ARGS_NAME "/boot/bootargs.bin" /* boot parameters */ +#define CONFIG_SPL_EXT4_LOAD_KERNEL_NAME "/boot/falcon.img" /* kernel */ +#define CONFIG_SYS_SPL_ARGS_ADDR (CONFIG_SYS_SDRAM_BASE + 0x100) + +#else /* u-boot in raw sectors */ + +#define CONFIG_SYS_BLOCK_RAW_MODE_U_BOOT_SECTOR 1024 +/* spl kernel load is not enabled */ +#define CONFIG_SYS_BLOCK_RAW_MODE_KERNEL_SECTOR 4096 +#define CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTOR 0 +#define CONFIG_SYS_BLOCK_RAW_MODE_ARGS_SECTORS (1024 / 512) +#define CONFIG_SYS_SPL_ARGS_ADDR (CONFIG_SYS_SDRAM_BASE + 0x100) + +#endif /* CONFIG_BOOT_FROM_FAT */ +/* CONFIG_BOOT_FROM_SATA end */ + +#else +/* generic, no spl support */ +#endif + +/* boot */ +#define CONFIG_IDENT_STRING " for OXNAS" +#define CONFIG_MACH_TYPE MACH_TYPE_OXNAS +#ifndef CONFIG_SPL_BUILD +/* Enable devicetree support */ +#define CONFIG_OF_LIBFDT +#endif +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_BOOTDELAY 1 +#define CONFIG_ZERO_BOOTDELAY_CHECK +#define CONFIG_DEFAULT_CONSOLE_PARM "console=ttyS0,115200n8 earlyprintk=serial" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE) +#define CONFIG_SYS_AUTOLOAD "no" + +#define CONFIG_DEFAULT_CONSOLE CONFIG_DEFAULT_CONSOLE_PARM "\0" +#define CONFIG_BOOTARGS CONFIG_DEFAULT_CONSOLE_PARM +#define CONFIG_BOOTCOMMAND "run nandboot" +#define CONFIG_BOOT_RETRY_TIME -1 +#define CONFIG_RESET_TO_RETRY 60 + +#define CONFIG_NETCONSOLE +#define CONFIG_IPADDR 192.168.50.100 +#define CONFIG_SERVERIP 192.168.50.59 + +/* A sane default configuration... + * When booting without a valid environment in ubi, first to loading and booting + * the kernel image directly above U-Boot, maybe both were loaded there by + * another bootloader. + * Also use that same offset (0x90000) to load the rescue image later on (by + * adding it onto the flash address where U-Boot is supposed to be stored by + * the legacy loader, 0x440000, resulting in offset 0x4d0000 on the flash). + * When coming up with a valid environment in ubi, first try to load the + * kernel from a ubi volume kernel, if that fails, fallback to the rescue + * image stored in boot partition. As a last resort try booting via + * DHCP/TFTP. + * In case there is no valid environment, first probe for a uimage in ram left + * behind by the first bootloader on a tftp boot. + * If that fails, switch to normal boot order and save environment. + * The loader is supposed to be written to flash at offset 0x440000 and loaded to + * RAM at 0x64000000 + */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "load_kernel_ubi=ubi readvol 0x62000000 kernel;\0" \ + "load_kernel_rescue=nand read 0x62000000 0x4e0000 0x400000;\0" \ + "load_kernel_dhcp=dhcp 0x62000000 oxnas-rescue.bin;\0" \ + "boot_kernel=bootm 0x62000000;\0" \ + "boot_ubi=run load_kernel_ubi && run boot_kernel;\0" \ + "boot_rescue=run load_kernel_rescue && run boot_kernel;\0" \ + "boot_dhcp=run load_kernel_dhcp && run boot_kernel;\0" \ + "normalboot=run boot_ubi; run boot_rescue; run boot_dhcp;\0" \ + "firstboot=bootm 0x640a0000; setenv bootcmd run normalboot; " \ + "setenv firstboot; saveenv; run bootcmd; \0" \ + "bootcmd=run firstboot; \0" \ + "console=" CONFIG_DEFAULT_CONSOLE \ + "bootargs=" CONFIG_BOOTARGS "\0" \ + "mtdids=" MTDIDS_DEFAULT "\0" \ + "mtdparts=" MTDPARTS_DEFAULT "\0" \ + +/* env */ +#if defined(CONFIG_BOOT_FROM_NAND) +#define CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_OFFSET 0x000C0000 +#define CONFIG_ENV_SIZE 0x00020000 +#define CONFIG_ENV_OFFSET_REDUND 0x00100000 +#define CONFIG_ENV_SIZE_REDUND 0x00020000 +#define CONFIG_ENV_RANGE (CONFIG_ENV_SIZE * 2) +/* CONFIG_BOOT_FROM_NAND end */ + +#elif defined(CONFIG_BOOT_FROM_SATA) +#ifdef CONFIG_BOOT_FROM_EXT4 +#define CONFIG_ENV_IS_IN_EXT4 +#define CONFIG_START_IDE +#define EXT4_ENV_INTERFACE "ide" +#define EXT4_ENV_DEVICE 0 +#define EXT4_ENV_PART 1 +#define EXT4_ENV_FILE "/boot/u-boot.env" +#define CONFIG_ENV_SIZE (16 * 1024) +#else +#define CONFIG_ENV_IS_IN_FAT +#define CONFIG_START_IDE +#define FAT_ENV_INTERFACE "ide" +#define FAT_ENV_DEVICE 0 +#define FAT_ENV_PART 1 +#define FAT_ENV_FILE "u-boot.env" +#define CONFIG_ENV_SIZE (16 * 1024) +#endif +/* CONFIG_BOOT_FROM_SATA end */ +#elif defined(CONFIG_BOOT_FROM_SATA) + +#else +/* generic */ +#define CONFIG_ENV_IS_IN_UBI 1 +#define CONFIG_ENV_UBI_PART UBIPART_DEFAULT +#define CONFIG_ENV_UBI_VOLUME "ubootenv" +#define CONFIG_ENV_UBI_VOLUME_REDUND "ubootenv2" +#define CONFIG_ENV_SIZE (16 * 1024) +#endif + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) +#define CONFIG_SYS_TEXT_BASE 0x64000000 +#define CONFIG_SYS_INIT_SP_ADDR 0x65000000 +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (1 * 1024 * 1024) + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "OX820 # " +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size*/ +#define CONFIG_SYS_PBSIZE 1024 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 32 /* max number of command args */ +#define CONFIG_CMDLINE_EDITING +#define CONFIG_AUTO_COMPLETE + +/* usb */ +#define CONFIG_USB_MAX_CONTROLLER_COUNT 1 +#define CONFIG_USB_EHCI +#define CONFIG_EHCI_IS_TDI +/* #define CONFIG_USB_EHCI_TXFIFO_THRESH 0x3F */ +#define CONFIG_USB_PLLB_CLK +#define CONFIG_USB_EHCI_OXNAS +#ifndef CONFIG_SPL_BUILD +#define CONFIG_USB_STORAGE +#endif +#define CONFIG_CMD_USB + +/* cmds */ +#define CONFIG_SYS_NO_FLASH +#include + +#define CONFIG_CMD_SAVEENV +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_GREPENV +#define CONFIG_CMD_ENV_FLAGS + +#define CONFIG_CMD_NET +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_NFS +#define CONFIG_CMD_PING +#define CONFIG_CMD_PXE + +#define CONFIG_CMD_NAND +#define CONFIG_CMD_MTDPARTS +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS + +#define CONFIG_CMD_IDE +#define CONFIG_CMD_FAT +#define CONFIG_FAT_WRITE +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_EXT4 +#ifndef CONFIG_SPL_BUILD +#define CONFIG_CMD_EXT4_WRITE +#endif + +#define CONFIG_CMD_ZIP +#define CONFIG_CMD_UNZIP +#define CONFIG_CMD_TIME +#define CONFIG_CMD_SETEXPR +#define CONFIG_CMD_MD5SUM +#define CONFIG_CMD_HASH +#define CONFIG_CMD_INI +#define CONFIG_CMD_GETTIME +#define CONFIG_CMD_BOOTMENU +#define CONFIG_CMD_ELF + +#define CONFIG_DOS_PARTITION +#define CONFIG_EFI_PARTITION + +/* for CONFIG_CMD_MTDPARTS */ +#define CONFIG_MTD_DEVICE +/* for CONFIG_CMD_UBI */ +#define CONFIG_MTD_PARTITIONS +/* for CONFIG_CMD_UBI */ +#define CONFIG_RBTREE + +/* optional, for CONFIG_CMD_BOOTM & required by CONFIG_CMD_UBIFS */ +#define CONFIG_LZO +#define CONFIG_LZMA +#define CONFIG_BZIP2 + +/* for CONFIG_CMD_ZIP */ +#define CONFIG_GZIP_COMPRESSED +/* for CONFIG_CMD_MD5SUM */ +#define CONFIG_MD5 +#define CONFIG_MD5SUM_VERIFY +/* enable CONFIG_CMD_HASH's verification feature */ +#define CONFIG_HASH_VERIFY +#define CONFIG_REGEX +/* for CONFIG_CMD_BOOTMENU & CONFIG_CMD_PXE */ +#define CONFIG_MENU + +/* for new FIT uImage format generated in OpenWrt */ +#define CONFIG_FIT + +#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-oxnas/files/tools/mkox820crc.c b/package/boot/uboot-oxnas/files/tools/mkox820crc.c new file mode 100644 index 0000000..d100191 --- /dev/null +++ b/package/boot/uboot-oxnas/files/tools/mkox820crc.c @@ -0,0 +1,123 @@ +/* J J Larworthy 27 September 2006 */ + +/* file to read the boot sector of a dis and the loaded image and report + * if the boot rom would accept the data as intact and suitable for use + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +extern uint32_t crc32(uint32_t, const unsigned char *, unsigned int); + +#define NUMBER_VECTORS 12 +struct { + unsigned int start_vector[NUMBER_VECTORS]; + char code[4]; + unsigned int header_length; + unsigned int reserved[3]; + unsigned int length; + unsigned int img_CRC; + unsigned int CRC; +} img_header; + +void print_usage(void) +{ + printf("update_header file.bin\n"); +} + +void print_header(void) +{ + int i; + + printf("vectors in header\n"); + for (i = 0; i < NUMBER_VECTORS; i++) { + printf("%d:0x%08x\n", i, img_header.start_vector[i]); + } + printf("length:%8x\nimg_CRC:0x%08x\nHeader CRC:0x%08x\n", + img_header.length, img_header.img_CRC, img_header.CRC); +} + +int main(int argc, char **argv) +{ + int in_file; + int status; + int unsigned crc; + int file_length; + int len; + + struct stat file_stat; + + void *executable; + + in_file = open(argv[1], O_RDWR); + + if (in_file < 0) { + printf("failed to open file:%s\n", argv[optind]); + return -ENOENT; + } + + status = fstat(in_file, &file_stat); + + /* read header and obtain size of image */ + status = read(in_file, &img_header, sizeof(img_header)); + + file_length = file_stat.st_size - sizeof(img_header); + + if (img_header.length != file_length) { + printf("size in header:%d, size of file: %d\n", + img_header.length, file_length); + } + img_header.length = file_length; + + /* read working image and CRC */ + executable = malloc(file_length); + + status = read(in_file, executable, file_length); + + if (status != file_length) { + printf("Failed to load image\n"); + return -ENOENT; + } + + /* verify image CRC */ + crc = crc32(0, (const unsigned char *) executable, img_header.length); + + if (crc != img_header.img_CRC) { + printf("New Image CRC:0x%08x, hdr:0x%08x\n", crc, + img_header.img_CRC); + img_header.img_CRC = crc; + } + memcpy(img_header.code, "BOOT", 4); + img_header.header_length = sizeof(img_header); + + /* check header CRC */ + crc = crc32(0, (const unsigned char *) &img_header, + sizeof(img_header) - sizeof(unsigned int)); + if (crc != img_header.CRC) { + printf("New header CRC - crc:0x%08x hdr:0x%08x\n", crc, + img_header.CRC); + img_header.CRC = crc; + } + + /* re-write the file */ + status = lseek(in_file, 0, SEEK_SET); + if (status != 0) { + printf("failed to rewind\n"); + return 1; + } + len = write(in_file, &img_header, sizeof(img_header)); + assert(len == sizeof(img_header)); + len = write(in_file, executable, file_length); + assert(len == file_length); + close(in_file); + + return 0; +} diff --git a/package/boot/uboot-oxnas/patches/010-capacity-is-unsigned.patch b/package/boot/uboot-oxnas/patches/010-capacity-is-unsigned.patch new file mode 100644 index 0000000..3990aa9 --- /dev/null +++ b/package/boot/uboot-oxnas/patches/010-capacity-is-unsigned.patch @@ -0,0 +1,42 @@ +From df9fb90120423c4c55b66a5dc09af23f605a406b Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 1 Dec 2014 21:37:25 +0100 +Subject: [PATCH] disk/part.c: use unsigned format when printing capacity +To: u-boot@lists.denx.de + +Large disks otherwise produce highly unplausible output such as + Capacity: 1907729.0 MB = 1863.0 GB (-387938128 x 512) + +As supposedly all size-related decimals are unsigned, use unsigned +format in printf statement, resulting in a correct capacity being +displayed: + Capacity: 1907729.0 MB = 1863.0 GB (3907029168 x 512) + +Signed-off-by: Daniel Golle +--- + disk/part.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/disk/part.c b/disk/part.c +index 43485c9..7c67ea6 100644 +--- a/disk/part.c ++++ b/disk/part.c +@@ -229,13 +229,13 @@ void dev_print (block_dev_desc_t *dev_desc) + printf (" Supports 48-bit addressing\n"); + #endif + #if defined(CONFIG_SYS_64BIT_LBA) +- printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%Ld x %ld)\n", ++ printf (" Capacity: %lu.%lu MB = %lu.%lu GB (%Lu x %lu)\n", + mb_quot, mb_rem, + gb_quot, gb_rem, + lba, + dev_desc->blksz); + #else +- printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n", ++ printf (" Capacity: %lu.%lu MB = %lu.%lu GB (%lu x %lu)\n", + mb_quot, mb_rem, + gb_quot, gb_rem, + (ulong)lba, +-- +2.1.3 + diff --git a/package/boot/uboot-oxnas/patches/150-spl-block.patch b/package/boot/uboot-oxnas/patches/150-spl-block.patch new file mode 100644 index 0000000..5d76084 --- /dev/null +++ b/package/boot/uboot-oxnas/patches/150-spl-block.patch @@ -0,0 +1,54 @@ +--- a/common/spl/Makefile ++++ b/common/spl/Makefile +@@ -19,4 +19,5 @@ obj-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc + obj-$(CONFIG_SPL_USB_SUPPORT) += spl_usb.o + obj-$(CONFIG_SPL_FAT_SUPPORT) += spl_fat.o + obj-$(CONFIG_SPL_SATA_SUPPORT) += spl_sata.o ++obj-$(CONFIG_SPL_BLOCK_SUPPORT) += spl_block.o + endif +--- a/common/spl/spl.c ++++ b/common/spl/spl.c +@@ -191,6 +191,14 @@ void board_init_r(gd_t *dummy1, ulong du + spl_spi_load_image(); + break; + #endif ++#ifdef CONFIG_SPL_BLOCK_SUPPORT ++ case BOOT_DEVICE_BLOCK: ++ { ++ extern void spl_block_load_image(void); ++ spl_block_load_image(); ++ break; ++ } ++#endif + #ifdef CONFIG_SPL_ETH_SUPPORT + case BOOT_DEVICE_CPGMAC: + #ifdef CONFIG_SPL_ETH_DEVICE +--- a/common/cmd_nvedit.c ++++ b/common/cmd_nvedit.c +@@ -49,6 +49,7 @@ DECLARE_GLOBAL_DATA_PTR; + !defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \ + !defined(CONFIG_ENV_IS_IN_REMOTE) && \ + !defined(CONFIG_ENV_IS_IN_UBI) && \ ++ !defined(CONFIG_ENV_IS_IN_EXT4) && \ + !defined(CONFIG_ENV_IS_NOWHERE) + # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\ + SPI_FLASH|NVRAM|MMC|FAT|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE +--- a/common/Makefile ++++ b/common/Makefile +@@ -63,6 +63,7 @@ obj-$(CONFIG_ENV_IS_IN_ONENAND) += env_o + obj-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o + obj-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o + obj-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o ++obj-$(CONFIG_ENV_IS_IN_EXT4) += env_ext4.o + obj-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o + + # command +@@ -213,6 +214,8 @@ obj-$(CONFIG_UPDATE_TFTP) += update.o + obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o + obj-$(CONFIG_CMD_DFU) += cmd_dfu.o + obj-$(CONFIG_CMD_GPT) += cmd_gpt.o ++else ++obj-$(CONFIG_SPL_BLOCK_SUPPORT) += cmd_ide.o + endif + + ifdef CONFIG_SPL_BUILD diff --git a/package/boot/uboot-oxnas/patches/200-icplus-phy.patch b/package/boot/uboot-oxnas/patches/200-icplus-phy.patch new file mode 100644 index 0000000..b378331 --- /dev/null +++ b/package/boot/uboot-oxnas/patches/200-icplus-phy.patch @@ -0,0 +1,142 @@ +From e719404ee1241af679a51879eaad291bc27e4817 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 2 Dec 2014 14:46:05 +0100 +Subject: [PATCH] net/phy: add back icplus driver + +IC+ phy driver was removed due to the lack of users some time ago. +Add it back, so we can use it. +--- + drivers/net/phy/Makefile | 1 + + drivers/net/phy/icplus.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ + drivers/net/phy/phy.c | 3 ++ + 3 files changed, 84 insertions(+) + create mode 100644 drivers/net/phy/icplus.c + +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_PHY_ATHEROS) += atheros.o + obj-$(CONFIG_PHY_BROADCOM) += broadcom.o + obj-$(CONFIG_PHY_DAVICOM) += davicom.o + obj-$(CONFIG_PHY_ET1011C) += et1011c.o ++obj-$(CONFIG_PHY_ICPLUS) += icplus.o + obj-$(CONFIG_PHY_LXT) += lxt.o + obj-$(CONFIG_PHY_MARVELL) += marvell.o + obj-$(CONFIG_PHY_MICREL) += micrel.o +--- /dev/null ++++ b/drivers/net/phy/icplus.c +@@ -0,0 +1,93 @@ ++/* ++ * ICPlus PHY drivers ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * ++ * Copyright (c) 2007 Freescale Semiconductor, Inc. ++ */ ++#include ++ ++/* IP101A/G - IP1001 */ ++#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ ++#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ ++#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ ++#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ ++#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ ++#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ ++#define IP101A_G_IRQ_PIN_USED (1<<15) /* INTR pin used */ ++#define IP101A_G_IRQ_DEFAULT IP101A_G_IRQ_PIN_USED ++#define IP1001LF_DRIVE_MASK (15 << 5) ++#define IP1001LF_RXCLKDRIVE_HI (2 << 5) ++#define IP1001LF_RXDDRIVE_HI (2 << 7) ++#define IP1001LF_RXCLKDRIVE_M (1 << 5) ++#define IP1001LF_RXDDRIVE_M (1 << 7) ++#define IP1001LF_RXCLKDRIVE_L (0 << 5) ++#define IP1001LF_RXDDRIVE_L (0 << 7) ++#define IP1001LF_RXCLKDRIVE_VL (3 << 5) ++#define IP1001LF_RXDDRIVE_VL (3 << 7) ++ ++static int ip1001_config(struct phy_device *phydev) ++{ ++ int c; ++ ++ /* Enable Auto Power Saving mode */ ++ c = phy_read(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2); ++ if (c < 0) ++ return c; ++ c |= IP1001_APS_ON; ++ c = phy_write(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2, c); ++ if (c < 0) ++ return c; ++ ++ /* INTR pin used: speed/link/duplex will cause an interrupt */ ++ c = phy_write(phydev, MDIO_DEVAD_NONE, IP101A_G_IRQ_CONF_STATUS, ++ IP101A_G_IRQ_DEFAULT); ++ if (c < 0) ++ return c; ++ ++ if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { ++ /* ++ * Additional delay (2ns) used to adjust RX clock phase ++ * at RGMII interface ++ */ ++ c = phy_read(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS); ++ if (c < 0) ++ return c; ++ ++ c |= IP1001_PHASE_SEL_MASK; ++ /* adjust digtial drive strength */ ++ c &= ~IP1001LF_DRIVE_MASK; ++ c |= IP1001LF_RXCLKDRIVE_M; ++ c |= IP1001LF_RXDDRIVE_M; ++ c = phy_write(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS, ++ c); ++ if (c < 0) ++ return c; ++ } ++ ++ return 0; ++} ++ ++static int ip1001_startup(struct phy_device *phydev) ++{ ++ genphy_update_link(phydev); ++ genphy_parse_link(phydev); ++ ++ return 0; ++} ++static struct phy_driver IP1001_driver = { ++ .name = "ICPlus IP1001", ++ .uid = 0x02430d90, ++ .mask = 0x0ffffff0, ++ .features = PHY_GBIT_FEATURES, ++ .config = &ip1001_config, ++ .startup = &ip1001_startup, ++ .shutdown = &genphy_shutdown, ++}; ++ ++int phy_icplus_init(void) ++{ ++ phy_register(&IP1001_driver); ++ ++ return 0; ++} +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -454,6 +454,9 @@ int phy_init(void) + #ifdef CONFIG_PHY_ET1011C + phy_et1011c_init(); + #endif ++#ifdef CONFIG_PHY_ICPLUS ++ phy_icplus_init(); ++#endif + #ifdef CONFIG_PHY_LXT + phy_lxt_init(); + #endif +--- a/include/phy.h ++++ b/include/phy.h +@@ -225,6 +225,7 @@ int phy_atheros_init(void); + int phy_broadcom_init(void); + int phy_davicom_init(void); + int phy_et1011c_init(void); ++int phy_icplus_init(void); + int phy_lxt_init(void); + int phy_marvell_init(void); + int phy_micrel_init(void); diff --git a/package/boot/uboot-oxnas/patches/300-oxnas-target.patch b/package/boot/uboot-oxnas/patches/300-oxnas-target.patch new file mode 100644 index 0000000..44e5842 --- /dev/null +++ b/package/boot/uboot-oxnas/patches/300-oxnas-target.patch @@ -0,0 +1,101 @@ +--- a/arch/arm/include/asm/mach-types.h ++++ b/arch/arm/include/asm/mach-types.h +@@ -212,6 +212,7 @@ extern unsigned int __machine_arch_type; + #define MACH_TYPE_EDB9307A 1128 + #define MACH_TYPE_OMAP_3430SDP 1138 + #define MACH_TYPE_VSTMS 1140 ++#define MACH_TYPE_OXNAS 1152 + #define MACH_TYPE_MICRO9M 1169 + #define MACH_TYPE_BUG 1179 + #define MACH_TYPE_AT91SAM9263EK 1202 +--- a/drivers/block/Makefile ++++ b/drivers/block/Makefile +@@ -21,3 +21,4 @@ obj-$(CONFIG_IDE_SIL680) += sil680.o + obj-$(CONFIG_SANDBOX) += sandbox.o + obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o + obj-$(CONFIG_SYSTEMACE) += systemace.o ++obj-$(CONFIG_IDE_PLX) += plxsata_ide.o +--- a/drivers/usb/host/Makefile ++++ b/drivers/usb/host/Makefile +@@ -33,6 +33,7 @@ obj-$(CONFIG_USB_EHCI_MX6) += ehci-mx6.o + obj-$(CONFIG_USB_EHCI_OMAP) += ehci-omap.o + obj-$(CONFIG_USB_EHCI_PPC4XX) += ehci-ppc4xx.o + obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o ++obj-$(CONFIG_USB_EHCI_OXNAS) += ehci-oxnas.o + obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o + obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o + obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o +--- a/tools/.gitignore ++++ b/tools/.gitignore +@@ -9,6 +9,7 @@ + /mkenvimage + /mkimage + /mkexynosspl ++/mkox820crc + /mpc86x_clk + /mxsboot + /mksunxiboot +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -143,6 +143,12 @@ hostprogs-$(CONFIG_KIRKWOOD) += kwboot + hostprogs-y += proftool + hostprogs-$(CONFIG_STATIC_RELA) += relocate-rela + ++ ++hostprogs-$(CONFIG_OX820) += mkox820crc$(SFX) ++ ++mkox820crc$(SFX)-objs := mkox820crc.o lib/crc32.o ++ ++ + # We build some files with extra pedantic flags to try to minimize things + # that won't build on some weird host compiler -- though there are lots of + # exceptions for files that aren't complaint. +--- a/drivers/serial/ns16550.c ++++ b/drivers/serial/ns16550.c +@@ -118,6 +118,14 @@ int ns16550_calc_divisor(NS16550_t port, + } + port->osc_12m_sel = 0; /* clear if previsouly set */ + #endif ++#ifdef CONFIG_OX820 ++ { ++ /* with additional 3 bit fractional */ ++ u32 div = (CONFIG_SYS_NS16550_CLK + baudrate) / (baudrate * 2); ++ port->reg9 = (div & 7) << 5; ++ return (div >> 3); ++ } ++#endif + + return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate); + } +--- a/scripts/Makefile.spl ++++ b/scripts/Makefile.spl +@@ -202,6 +202,9 @@ OBJCOPYFLAGS_$(SPL_BIN).bin = $(SPL_OBJC + + $(obj)/$(SPL_BIN).bin: $(obj)/$(SPL_BIN) FORCE + $(call if_changed,objcopy) ++ifdef CONFIG_OX820 ++ $(OBJTREE)/tools/mkox820crc $@ ++endef + + LDFLAGS_$(SPL_BIN) += -T u-boot-spl.lds $(LDFLAGS_FINAL) + ifneq ($(CONFIG_SPL_TEXT_BASE),) +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -488,6 +488,9 @@ config TARGET_BALLOON3 + config TARGET_H2200 + bool "Support h2200" + ++config TARGET_OX820 ++ bool "Support ox820" ++ + config TARGET_PALMLD + bool "Support palmld" + +@@ -650,6 +653,7 @@ source "board/logicpd/imx27lite/Kconfig" + source "board/logicpd/imx31_litekit/Kconfig" + source "board/mpl/vcma9/Kconfig" + source "board/olimex/mx23_olinuxino/Kconfig" ++source "board/ox820/Kconfig" + source "board/palmld/Kconfig" + source "board/palmtc/Kconfig" + source "board/palmtreo680/Kconfig" diff --git a/package/boot/uboot-oxnas/patches/800-fix-bootm-assertion.patch b/package/boot/uboot-oxnas/patches/800-fix-bootm-assertion.patch new file mode 100644 index 0000000..957c492 --- /dev/null +++ b/package/boot/uboot-oxnas/patches/800-fix-bootm-assertion.patch @@ -0,0 +1,11 @@ +--- a/common/cmd_bootm.c ++++ b/common/cmd_bootm.c +@@ -77,7 +77,7 @@ static int do_bootm_subcommand(cmd_tbl_t + return CMD_RET_USAGE; + } + +- if (state != BOOTM_STATE_START && images.state >= state) { ++ if (!(state & BOOTM_STATE_START) && images.state >= state) { + printf("Trying to execute a command out of order\n"); + return CMD_RET_USAGE; + } diff --git a/package/boot/uboot-pxa/Makefile b/package/boot/uboot-pxa/Makefile new file mode 100644 index 0000000..9dae1af --- /dev/null +++ b/package/boot/uboot-pxa/Makefile @@ -0,0 +1,92 @@ +# +# 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 + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +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 +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/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-sunxi/Makefile b/package/boot/uboot-sunxi/Makefile new file mode 100644 index 0000000..b08f9ed --- /dev/null +++ b/package/boot/uboot-sunxi/Makefile @@ -0,0 +1,166 @@ +# +# Copyright (C) 2013-2014 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:=2015.07 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:= \ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot + +PKG_MD5SUM:=3dac9a0b46fed77fc768ad3bd2d68c05 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/A10-OLinuXino-Lime + TITLE:=U-Boot for the A10 OLinuXino LIME +endef + +define uboot/A13-OLinuXino + TITLE:=U-Boot for the A13 OlinuXino +endef + +define uboot/A20-OLinuXino-Lime + TITLE:=U-Boot for the A20 OLinuXino LIME +endef + +define uboot/A20-OLinuXino_MICRO + TITLE:=U-Boot for A20 OLinuXino MICRO +endef + +define uboot/Bananapi + TITLE:=U-Boot for Bananapi +endef + +define uboot/Bananapro + TITLE:=U-Boot for Bananapro +endef + +define uboot/Cubieboard + TITLE:=U-Boot for Cubieboard +endef + +define uboot/Cubieboard2 + TITLE:=U-Boot for Cubieboard2 +endef + +define uboot/Cubietruck + TITLE:=U-Boot for Cubietruck +endef + +define uboot/Mele_M9 + TITLE:=U-Boot for the Mele M9 (A31) +endef + +define uboot/OLIMEX_A13_SOM + TITLE:=U-Boot for the Olimex A13 SOM +endef + +define uboot/Linksprite_pcDuino + TITLE:=U-Boot for Linksprite pcDuino +endef + +define uboot/Linksprite_pcDuino3 + TITLE:=U-Boot for Linksprite pcDuino3 +endef + +define uboot/Lamobo_R1 + TITLE:=U-Boot for Lamobo R1 +endef + +UBOOTS:= \ + A10-OLinuXino-Lime \ + A13-OLinuXino \ + A20-OLinuXino-Lime \ + A20-OLinuXino_MICRO \ + Bananapi \ + Bananapro \ + Cubieboard \ + Cubieboard2 \ + Cubietruck \ + Mele_M9 \ + OLIMEX_A13_SOM \ + Linksprite_pcDuino \ + Linksprite_pcDuino3 \ + Lamobo_R1 \ + +define Package/uboot/template +define Package/uboot-sunxi-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_sunxi + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Zoltan HERPAI +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) \ + USE_PRIVATE_LIBGCC=yes $(UBOOT_CONFIG)_defconfig +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) \ + DTCDIR=$(LINUX_DIR)/scripts/dtc/ +endef + +define Package/uboot/install/default + $(CP) $(PKG_BUILD_DIR)/u-boot.bin \ + $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-u-boot.bin + $(CP) $(PKG_BUILD_DIR)/spl/sunxi-spl.bin \ + $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-spl.bin + $(CP) $(PKG_BUILD_DIR)/u-boot-sunxi-with-spl.bin \ + $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-u-boot-with-spl.bin + $(CP) uEnv.txt \ + $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-uEnv.txt + mkimage -C none -A arm -T script -d $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-uEnv.txt \ + $(KERNEL_BUILD_DIR)/uboot-$(BOARD)-$(1)-boot.scr +endef + +define Package/uboot/install/template +define Package/uboot-sunxi-$(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-sunxi-$(u))) \ +) diff --git a/package/boot/uboot-sunxi/patches/001-use-dtc-in-kernel.patch b/package/boot/uboot-sunxi/patches/001-use-dtc-in-kernel.patch new file mode 100644 index 0000000..afcb37c --- /dev/null +++ b/package/boot/uboot-sunxi/patches/001-use-dtc-in-kernel.patch @@ -0,0 +1,12 @@ +diff -ruN old/Makefile new/Makefile +--- old/Makefile 2015-04-13 16:53:03.000000000 +0200 ++++ new/Makefile 2015-07-31 15:52:08.920097812 +0200 +@@ -346,7 +346,7 @@ + AWK = awk + PERL = perl + PYTHON = python +-DTC = dtc ++DTC = $(DTCDIR)dtc + CHECK = sparse + + CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ diff --git a/package/boot/uboot-sunxi/patches/002-add-lamobo-r1.diff b/package/boot/uboot-sunxi/patches/002-add-lamobo-r1.diff new file mode 100644 index 0000000..5dd816c --- /dev/null +++ b/package/boot/uboot-sunxi/patches/002-add-lamobo-r1.diff @@ -0,0 +1,277 @@ +diff -ruN old/arch/arm/dts/Makefile new/arch/arm/dts/Makefile +--- old/arch/arm/dts/Makefile 2015-07-14 19:32:21.000000000 +0200 ++++ new/arch/arm/dts/Makefile 2015-07-31 23:23:33.518767858 +0200 +@@ -107,6 +107,7 @@ + sun7i-a20-cubietruck.dtb \ + sun7i-a20-hummingbird.dtb \ + sun7i-a20-i12-tvbox.dtb \ ++ sun7i-a20-lamobo-r1.dtb \ + sun7i-a20-m3.dtb \ + sun7i-a20-m5.dtb \ + sun7i-a20-mk808c.dtb \ +diff -ruN old/arch/arm/dts/sun7i-a20-lamobo-r1.dts new/arch/arm/dts/sun7i-a20-lamobo-r1.dts +--- old/arch/arm/dts/sun7i-a20-lamobo-r1.dts 1970-01-01 01:00:00.000000000 +0100 ++++ new/arch/arm/dts/sun7i-a20-lamobo-r1.dts 2015-07-31 23:19:30.811206714 +0200 +@@ -0,0 +1,239 @@ ++/* ++ * Copyright 2014 Hans de Goede ++ * ++ * Hans de Goede ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This file is free software; you can redistribute 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 file 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 file; if not, write to the Free ++ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ++ * MA 02110-1301 USA ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++/dts-v1/; ++#include "sun7i-a20.dtsi" ++#include "sunxi-common-regulators.dtsi" ++ ++#include ++#include ++#include ++ ++/ { ++ model = "Lamobo R1"; ++ compatible = "lamobo,lamobo-r1", "allwinner,sun7i-a20"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart3; ++ serial2 = &uart7; ++ }; ++ ++ soc@01c00000 { ++ spi0: spi@01c05000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins_a>; ++ status = "okay"; ++ }; ++ ++ mmc0: mmc@01c0f000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bananapi>; ++ vmmc-supply = <®_vcc3v3>; ++ bus-width = <4>; ++ cd-gpios = <&pio 7 10 0>; /* PH10 */ ++ cd-inverted; ++ status = "okay"; ++ }; ++ ++ usbphy: phy@01c13400 { ++ usb1_vbus-supply = <®_usb1_vbus>; ++ usb2_vbus-supply = <®_usb2_vbus>; ++ status = "okay"; ++ }; ++ ++ ehci0: usb@01c14000 { ++ status = "okay"; ++ }; ++ ++ ohci0: usb@01c14400 { ++ status = "okay"; ++ }; ++ ++ ahci: sata@01c18000 { ++ status = "okay"; ++ }; ++ ++ ehci1: usb@01c1c000 { ++ status = "okay"; ++ }; ++ ++ ohci1: usb@01c1c400 { ++ status = "okay"; ++ }; ++ ++ pinctrl@01c20800 { ++ mmc0_cd_pin_bananapi: mmc0_cd_pin@0 { ++ allwinner,pins = "PH10"; ++ allwinner,function = "gpio_in"; ++ allwinner,drive = <0>; ++ allwinner,pull = <1>; ++ }; ++ ++ gmac_power_pin_bananapi: gmac_power_pin@0 { ++ allwinner,pins = "PH23"; ++ allwinner,function = "gpio_out"; ++ allwinner,drive = <0>; ++ allwinner,pull = <0>; ++ }; ++ ++ led_pins_bananapi: led_pins@0 { ++ allwinner,pins = "PH24"; ++ allwinner,function = "gpio_out"; ++ allwinner,drive = <0>; ++ allwinner,pull = <0>; ++ }; ++ ++ ahci_pwr_pin_a: ahci_pwr_pin@0 { ++ allwinner,pins = "PB3"; ++ allwinner,function = "gpio_out"; ++ allwinner,drive = <0>; ++ allwinner,pull = <0>; ++ }; ++ ++ }; ++ ++ ++ uart0: serial@01c28000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins_a>; ++ status = "okay"; ++ }; ++ ++ uart3: serial@01c28c00 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins_b>; ++ status = "okay"; ++ }; ++ ++ uart7: serial@01c29c00 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart7_pins_a>; ++ status = "okay"; ++ }; ++ ++ i2c0: i2c@01c2ac00 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins_a>; ++ status = "okay"; ++ ++ axp209: pmic@34 { ++ compatible = "x-powers,axp209"; ++ reg = <0x34>; ++ interrupt-parent = <&nmi_intc>; ++ interrupts = <0 8>; ++ ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ }; ++ }; ++ ++ i2c2: i2c@01c2b400 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins_a>; ++ status = "okay"; ++ }; ++ ++ gmac: ethernet@01c50000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac_pins_rgmii_a>; ++ phy = <&phy1>; ++ phy-mode = "rgmii"; ++ phy-supply = <®_gmac_3v3>; ++ status = "okay"; ++ ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_pins_bananapi>; ++ ++ green { ++ label = "bananapi:green:usr"; ++ gpios = <&pio 7 24 0>; ++ }; ++ }; ++ ++ reg_usb1_vbus: usb1-vbus { ++ status = "okay"; ++ }; ++ ++ reg_usb2_vbus: usb2-vbus { ++ status = "okay"; ++ }; ++ ++ reg_gmac_3v3: gmac-3v3 { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac_power_pin_bananapi>; ++ regulator-name = "gmac-3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <100000>; ++ enable-active-high; ++ gpio = <&pio 7 23 0>; ++ }; ++ ++ reg_ahci_5v: ahci-5v { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ahci_pwr_pin_a>; ++ regulator-name = "ahci-5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ gpio = <&pio 1 3 0>; ++ status = "okay"; ++ }; ++}; +diff -ruN old/configs/Lamobo_R1_defconfig new/configs/Lamobo_R1_defconfig +--- old/configs/Lamobo_R1_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ new/configs/Lamobo_R1_defconfig 2015-07-31 23:02:06.000000000 +0200 +@@ -0,0 +1,19 @@ ++CONFIG_SPL=y ++CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI,USB_EHCI,SATAPWR=SUNXI_GPB(3)" ++CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-lamobo-r1" ++CONFIG_GMAC_TX_DELAY=4 ++CONFIG_ARM=y ++CONFIG_ARCH_SUNXI=y ++CONFIG_MACH_SUN7I=y ++CONFIG_DRAM_CLK=432 ++CONFIG_DRAM_ZQ=127 ++CONFIG_DRAM_EMR1=4 ++CONFIG_ETH_DESIGNWARE=y ++CONFIG_NETDEVICES=y ++CONFIG_NET=y ++# CONFIG_CMD_IMLS is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_CMD_FPGA is not set ++CONFIG_DM_SERIAL=y ++CONFIG_USB=y ++CONFIG_DM_USB=y diff --git a/package/boot/uboot-sunxi/patches/003-add-olimex-a13-som.diff b/package/boot/uboot-sunxi/patches/003-add-olimex-a13-som.diff new file mode 100644 index 0000000..e160b3d --- /dev/null +++ b/package/boot/uboot-sunxi/patches/003-add-olimex-a13-som.diff @@ -0,0 +1,19 @@ +diff -ruN u-boot-2015.01.old/configs/OLIMEX_A13_SOM_defconfig u-boot-2015.01/configs/OLIMEX_A13_SOM_defconfig +--- u-boot-2015.01.old/configs/OLIMEX_A13_SOM_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-2015.01/configs/OLIMEX_A13_SOM_defconfig 2015-01-18 16:25:11.908986082 +0100 +@@ -0,0 +1,15 @@ ++CONFIG_SPL=y ++CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,NO_AXP,USB_EHCI" ++CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino" ++CONFIG_ARM=y ++CONFIG_ARCH_SUNXI=y ++CONFIG_MACH_SUN5I=y ++CONFIG_DRAM_CLK=408 ++CONFIG_DRAM_ZQ=123 ++CONFIG_DRAM_EMR1=0 ++# CONFIG_CMD_IMLS is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_CMD_FPGA is not set ++CONFIG_DM_SERIAL=y ++CONFIG_USB=y ++CONFIG_DM_USB=y diff --git a/package/boot/uboot-sunxi/patches/004-sunxi-mmc-set-transfer-timeout-according-to-byte_cnt.patch b/package/boot/uboot-sunxi/patches/004-sunxi-mmc-set-transfer-timeout-according-to-byte_cnt.patch new file mode 100644 index 0000000..964aa57 --- /dev/null +++ b/package/boot/uboot-sunxi/patches/004-sunxi-mmc-set-transfer-timeout-according-to-byte_cnt.patch @@ -0,0 +1,42 @@ +diff --git a/package/boot/uboot-sunxi/patches/004-sunxi-mmc-set-transfer-timeout-according-to-byte_cnt.patch b/package/boot/uboot-sunxi/patches/004-sunxi-mmc-set-transfer-timeout-according-to-byte_cnt.patch +new file mode 100644 +index 0000000..180b60b +--- /dev/null ++++ b/package/boot/uboot-sunxi/patches/004-sunxi-mmc-set-transfer-timeout-according-to-byte_cnt.patch +@@ -0,0 +1,36 @@ ++From 8a5481e2e51a86e858c4f1481729421f26cc240c Mon Sep 17 00:00:00 2001 ++From: Yousong Zhou ++Date: Sat, 29 Aug 2015 21:26:11 +0800 ++Subject: [PATCH] sunxi: mmc: set transfer timeout according to byte_cnt. ++ ++Originally a timeout value of 2 seconds was used regardless of the size ++of data to be transfered. This prevented slow devices from working ++correctly while there was no much gain for faster devices, e.g. it takes ++3708ms for a transfer of uImage of size 1899008 bytes. ++ ++Signed-off-by: Yousong Zhou ++--- ++ drivers/mmc/sunxi_mmc.c | 6 ++++-- ++ 1 file changed, 4 insertions(+), 2 deletions(-) ++ ++diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c ++index e7ab828..7a990f7 100644 ++--- a/drivers/mmc/sunxi_mmc.c +++++ b/drivers/mmc/sunxi_mmc.c ++@@ -257,9 +257,11 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) ++ const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : ++ SUNXI_MMC_STATUS_FIFO_FULL; ++ unsigned i; ++- unsigned byte_cnt = data->blocksize * data->blocks; ++- unsigned timeout_msecs = 2000; ++ unsigned *buff = (unsigned int *)(reading ? data->dest : data->src); +++ unsigned byte_cnt = data->blocksize * data->blocks; +++ unsigned timeout_msecs = byte_cnt >> 8; +++ if (timeout_msecs < 2000) +++ timeout_msecs = 2000; ++ ++ /* Always read / write data through the CPU */ ++ setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB); ++-- ++1.7.10.4 ++ diff --git a/package/boot/uboot-sunxi/uEnv.txt b/package/boot/uboot-sunxi/uEnv.txt new file mode 100644 index 0000000..e024954 --- /dev/null +++ b/package/boot/uboot-sunxi/uEnv.txt @@ -0,0 +1,6 @@ +setenv fdt_high ffffffff +setenv loadkernel fatload mmc 0 \$kernel_addr_r uImage +setenv loaddtb fatload mmc 0 \$fdt_addr_r dtb +setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait +setenv uenvcmd run loadkernel \&\& run loaddtb \&\& bootm \$kernel_addr_r - \$fdt_addr_r +run uenvcmd diff --git a/package/boot/uboot-xburst/Makefile b/package/boot/uboot-xburst/Makefile new file mode 100644 index 0000000..4a701f8 --- /dev/null +++ b/package/boot/uboot-xburst/Makefile @@ -0,0 +1,88 @@ +# +# 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:= \ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=451c07271940016cec6f5ad8a155263b +PKG_TARGETS:=bin + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +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/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 +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 +--- + 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 ++# ++# 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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++ .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 ++ * ++ * This program is free software; you can 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 ++#include ++#include ++#include ++ ++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 ++ * Authors: Xiangfu Liu + * + * 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 ++ * ++ * This program is free software; you can redistribute 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 + #include + ++#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 ++ * Authors: Xiangfu Liu + * + * 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 +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 +--- + 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 + #include + ++#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: ++ * ++ * 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 +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 ++#include ++#include ++#include ++ ++#include ++#include ++#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 +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 +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 : ""); + +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 +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 ++ * ++ * This program is free software; you can redistribute 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 ++#include ++#include ++ ++#include /* virt_to_phys() */ ++#include ++ ++#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 ++ * ++ * This program is free software; you can redistribute 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 +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/Makefile b/package/boot/yamonenv/Makefile new file mode 100644 index 0000000..5fd25ad --- /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 +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/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 + #include + +-#define DEFAULT_YAMON_ENV_FILE "/dev/mtd/3" ++#define DEFAULT_YAMON_ENV_FILE "/dev/mtd3" + + + // control byte definitions: -- cgit v1.2.3