diff options
Diffstat (limited to 'package/boot')
259 files changed, 54108 insertions, 0 deletions
diff --git a/package/boot/.svn/entries b/package/boot/.svn/entries new file mode 100644 index 0000000..4d0cef9 --- /dev/null +++ b/package/boot/.svn/entries @@ -0,0 +1,67 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot +svn://svn.openwrt.org/openwrt + + + +2013-03-15T01:36:53.833391Z +36033 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +uboot-envtools +dir + +uboot-kirkwood +dir + +uboot-ar71xx +dir + +grub2 +dir + +rbcfg +dir + +uboot-omap4 +dir + +uboot-omap35xx +dir + +fconfig +dir + +yamonenv +dir + +kexec-tools +dir + +uboot-xburst +dir + +uboot-lantiq +dir + +uboot-pxa +dir + diff --git a/package/boot/fconfig/.svn/entries b/package/boot/fconfig/.svn/entries new file mode 100644 index 0000000..43502aa --- /dev/null +++ b/package/boot/fconfig/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/fconfig +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +ce975dc74a1a3684527983fd088edae2 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +990 + diff --git a/package/boot/fconfig/.svn/prop-base/Makefile.svn-base b/package/boot/fconfig/.svn/prop-base/Makefile.svn-base new file mode 100644 index 0000000..4179626 --- /dev/null +++ b/package/boot/fconfig/.svn/prop-base/Makefile.svn-base @@ -0,0 +1,9 @@ +K 9 +copyright +V 30 +Copyright (C) 2006 OpenWrt.org +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/fconfig/.svn/text-base/Makefile.svn-base b/package/boot/fconfig/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..14bbec5 --- /dev/null +++ b/package/boot/fconfig/.svn/text-base/Makefile.svn-base @@ -0,0 +1,45 @@ +# +# Copyright (C) 2006-2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=fconfig +PKG_VERSION:=20080329 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://andrzejekiert.ovh.org/software/fconfig/ +PKG_MD5SUM:=dac355e9f2a0f48c414c52e2034b6346 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/fconfig + SECTION:=utils + CATEGORY:=Utilities + TITLE:=RedBoot configuration editor + URL:=http://andrzejekiert.ovh.org/software.html.en +endef + +define Package/fconfig/description + displays and (if writable) also edits the RedBoot configuration. +endef + +define Build/Configure +endef + +define Build/Compile + $(call Build/Compile/Default) +endef + +define Package/fconfig/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/fconfig $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,fconfig)) diff --git a/package/boot/fconfig/Makefile b/package/boot/fconfig/Makefile new file mode 100644 index 0000000..14bbec5 --- /dev/null +++ b/package/boot/fconfig/Makefile @@ -0,0 +1,45 @@ +# +# Copyright (C) 2006-2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=fconfig +PKG_VERSION:=20080329 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://andrzejekiert.ovh.org/software/fconfig/ +PKG_MD5SUM:=dac355e9f2a0f48c414c52e2034b6346 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/fconfig + SECTION:=utils + CATEGORY:=Utilities + TITLE:=RedBoot configuration editor + URL:=http://andrzejekiert.ovh.org/software.html.en +endef + +define Package/fconfig/description + displays and (if writable) also edits the RedBoot configuration. +endef + +define Build/Configure +endef + +define Build/Compile + $(call Build/Compile/Default) +endef + +define Package/fconfig/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/fconfig $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,fconfig)) diff --git a/package/boot/grub2/.svn/entries b/package/boot/grub2/.svn/entries new file mode 100644 index 0000000..1fbbf4b --- /dev/null +++ b/package/boot/grub2/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/grub2 +svn://svn.openwrt.org/openwrt + + + +2012-11-26T16:03:40.540832Z +34389 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +0b28cdcaf03ae3f53f28ce7026102dcb +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +1147 + diff --git a/package/boot/grub2/.svn/text-base/Makefile.svn-base b/package/boot/grub2/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..b606f54 --- /dev/null +++ b/package/boot/grub2/.svn/text-base/Makefile.svn-base @@ -0,0 +1,51 @@ +# +# Copyright (C) 2006-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=grub +PKG_VERSION:=2.00 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@GNU/grub +PKG_MD5SUM:=e927540b6eda8b024fb0391eeaa4091c + +PKG_HOST_ONLY:=1 +HOST_BUILD_PARALLEL:=1 +PKG_BUILD_DEPENDS:=grub2/host + +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/package.mk + +define Package/grub2 + SUBMENU:=Boot Loaders + CATEGORY:=Utilities + SECTION:=utils + TITLE:=GRand Unified Bootloader + URL:=http://www.gnu.org/software/grub/ + DEPENDS:=@TARGET_x86 +endef + +HOST_CONFIGURE_ARGS += \ + --target=$(REAL_GNU_TARGET_NAME) \ + --sbindir="$(STAGING_DIR_HOST)/bin" \ + --disable-werror \ + --disable-nls + +HOST_MAKE_FLAGS += \ + TARGET_RANLIB=$(TARGET_RANLIB) \ + LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a + +define Host/Configure + $(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in + $(Host/Configure/Default) +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,grub2)) diff --git a/package/boot/grub2/Makefile b/package/boot/grub2/Makefile new file mode 100644 index 0000000..b606f54 --- /dev/null +++ b/package/boot/grub2/Makefile @@ -0,0 +1,51 @@ +# +# Copyright (C) 2006-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=grub +PKG_VERSION:=2.00 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@GNU/grub +PKG_MD5SUM:=e927540b6eda8b024fb0391eeaa4091c + +PKG_HOST_ONLY:=1 +HOST_BUILD_PARALLEL:=1 +PKG_BUILD_DEPENDS:=grub2/host + +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/package.mk + +define Package/grub2 + SUBMENU:=Boot Loaders + CATEGORY:=Utilities + SECTION:=utils + TITLE:=GRand Unified Bootloader + URL:=http://www.gnu.org/software/grub/ + DEPENDS:=@TARGET_x86 +endef + +HOST_CONFIGURE_ARGS += \ + --target=$(REAL_GNU_TARGET_NAME) \ + --sbindir="$(STAGING_DIR_HOST)/bin" \ + --disable-werror \ + --disable-nls + +HOST_MAKE_FLAGS += \ + TARGET_RANLIB=$(TARGET_RANLIB) \ + LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a + +define Host/Configure + $(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in + $(Host/Configure/Default) +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,grub2)) diff --git a/package/boot/grub2/patches/.svn/entries b/package/boot/grub2/patches/.svn/entries new file mode 100644 index 0000000..aa580af --- /dev/null +++ b/package/boot/grub2/patches/.svn/entries @@ -0,0 +1,130 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/grub2/patches +svn://svn.openwrt.org/openwrt + + + +2012-11-26T16:03:40.540832Z +34389 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +200-fix-gets-removal.patch +file + + + + +2013-03-17T12:13:21.000000Z +4347c13528381c1ebf68d183a9cc0165 +2012-11-26T16:03:40.540832Z +34389 +jow + + + + + + + + + + + + + + + + + + + + + +560 + +200-grub_musl.patch +file + + + + +2013-03-17T12:13:21.000000Z +eae2474dbd84e1bcbe72e4b91f9f79be +2012-11-23T20:01:53.954168Z +34306 +florian + + + + + + + + + + + + + + + + + + + + + +1059 + +100-grub_setup_root.patch +file + + + + +2013-03-17T12:13:21.000000Z +aec4834762dc8e05bb7c862cc82aab40 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +2328 + diff --git a/package/boot/grub2/patches/.svn/text-base/100-grub_setup_root.patch.svn-base b/package/boot/grub2/patches/.svn/text-base/100-grub_setup_root.patch.svn-base new file mode 100644 index 0000000..7775b2a --- /dev/null +++ b/package/boot/grub2/patches/.svn/text-base/100-grub_setup_root.patch.svn-base @@ -0,0 +1,77 @@ +--- a/util/grub-setup.c ++++ b/util/grub-setup.c +@@ -141,12 +141,11 @@ write_rootdev (char *core_img, grub_devi + static void + setup (const char *dir, + const char *boot_file, const char *core_file, +- const char *dest, int force, ++ const char *root, const char *dest, int force, + int fs_probe, int allow_floppy) + { + char *boot_path, *core_path, *core_path_dev, *core_path_dev_full; + char *boot_img, *core_img; +- char *root = 0; + size_t boot_size, core_size; + grub_uint16_t core_sectors; + grub_device_t root_dev = 0, dest_dev, core_dev; +@@ -253,7 +252,10 @@ setup (const char *dir, + + core_dev = dest_dev; + +- { ++ if (root) ++ root_dev = grub_device_open(root); ++ ++ if (!root_dev) { + char **root_devices = grub_guess_root_devices (dir); + char **cur; + int found = 0; +@@ -263,6 +265,8 @@ setup (const char *dir, + char *drive; + grub_device_t try_dev; + ++ if (root_dev) ++ break; + drive = grub_util_get_grub_dev (*cur); + if (!drive) + continue; +@@ -956,6 +960,8 @@ static struct argp_option options[] = { + N_("install even if problems are detected"), 0}, + {"skip-fs-probe",'s',0, 0, + N_("do not probe for filesystems in DEVICE"), 0}, ++ {"root-device", 'r', N_("DEVICE"), 0, ++ N_("use DEVICE as the root device"), 0}, + {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, + {"allow-floppy", 'a', 0, 0, + /* TRANSLATORS: The potential breakage isn't limited to floppies but it's +@@ -993,6 +999,7 @@ struct arguments + char *core_file; + char *dir; + char *dev_map; ++ char *root_dev; + int force; + int fs_probe; + int allow_floppy; +@@ -1040,6 +1047,13 @@ argp_parser (int key, char *arg, struct + arguments->dev_map = xstrdup (arg); + break; + ++ case 'r': ++ if (arguments->root_dev) ++ free (arguments->root_dev); ++ ++ arguments->root_dev = xstrdup (arg); ++ break; ++ + case 'f': + arguments->force = 1; + break; +@@ -1172,7 +1186,7 @@ main (int argc, char *argv[]) + setup (arguments.dir ? : DEFAULT_DIRECTORY, + arguments.boot_file ? : DEFAULT_BOOT_FILE, + arguments.core_file ? : DEFAULT_CORE_FILE, +- dest_dev, arguments.force, ++ arguments.root_dev, dest_dev, arguments.force, + arguments.fs_probe, arguments.allow_floppy); + + /* Free resources. */ diff --git a/package/boot/grub2/patches/.svn/text-base/200-fix-gets-removal.patch.svn-base b/package/boot/grub2/patches/.svn/text-base/200-fix-gets-removal.patch.svn-base new file mode 100644 index 0000000..4370fb5 --- /dev/null +++ b/package/boot/grub2/patches/.svn/text-base/200-fix-gets-removal.patch.svn-base @@ -0,0 +1,15 @@ +--- a/grub-core/gnulib/stdio.in.h ++++ b/grub-core/gnulib/stdio.in.h +@@ -137,12 +137,6 @@ + "use gnulib module fflush for portable POSIX compliance"); + #endif + +-/* It is very rare that the developer ever has full control of stdin, +- so any use of gets warrants an unconditional warning. Assume it is +- always declared, since it is required by C89. */ +-#undef gets +-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); +- + #if @GNULIB_FOPEN@ + # if @REPLACE_FOPEN@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) diff --git a/package/boot/grub2/patches/.svn/text-base/200-grub_musl.patch.svn-base b/package/boot/grub2/patches/.svn/text-base/200-grub_musl.patch.svn-base new file mode 100644 index 0000000..b1ff63a --- /dev/null +++ b/package/boot/grub2/patches/.svn/text-base/200-grub_musl.patch.svn-base @@ -0,0 +1,22 @@ +diff -urN grub-2.00/build-aux/config.sub grub-2.00.new/build-aux/config.sub +--- grub-2.00/build-aux/config.sub 2012-06-18 23:08:46.000000000 +0200 ++++ grub-2.00.new/build-aux/config.sub 2012-11-22 14:12:12.190748353 +0100 +@@ -126,7 +126,8 @@ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ +- storm-chaos* | os2-emx* | rtmk-nova*) ++ storm-chaos* | os2-emx* | rtmk-nova* | \ ++ linux-musl*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; +@@ -1360,7 +1361,7 @@ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ +- | -linux-newlib* | -linux-uclibc* \ ++ | -linux-newlib* | -linux-uclibc* | -linux-musl* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ diff --git a/package/boot/grub2/patches/100-grub_setup_root.patch b/package/boot/grub2/patches/100-grub_setup_root.patch new file mode 100644 index 0000000..7775b2a --- /dev/null +++ b/package/boot/grub2/patches/100-grub_setup_root.patch @@ -0,0 +1,77 @@ +--- a/util/grub-setup.c ++++ b/util/grub-setup.c +@@ -141,12 +141,11 @@ write_rootdev (char *core_img, grub_devi + static void + setup (const char *dir, + const char *boot_file, const char *core_file, +- const char *dest, int force, ++ const char *root, const char *dest, int force, + int fs_probe, int allow_floppy) + { + char *boot_path, *core_path, *core_path_dev, *core_path_dev_full; + char *boot_img, *core_img; +- char *root = 0; + size_t boot_size, core_size; + grub_uint16_t core_sectors; + grub_device_t root_dev = 0, dest_dev, core_dev; +@@ -253,7 +252,10 @@ setup (const char *dir, + + core_dev = dest_dev; + +- { ++ if (root) ++ root_dev = grub_device_open(root); ++ ++ if (!root_dev) { + char **root_devices = grub_guess_root_devices (dir); + char **cur; + int found = 0; +@@ -263,6 +265,8 @@ setup (const char *dir, + char *drive; + grub_device_t try_dev; + ++ if (root_dev) ++ break; + drive = grub_util_get_grub_dev (*cur); + if (!drive) + continue; +@@ -956,6 +960,8 @@ static struct argp_option options[] = { + N_("install even if problems are detected"), 0}, + {"skip-fs-probe",'s',0, 0, + N_("do not probe for filesystems in DEVICE"), 0}, ++ {"root-device", 'r', N_("DEVICE"), 0, ++ N_("use DEVICE as the root device"), 0}, + {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, + {"allow-floppy", 'a', 0, 0, + /* TRANSLATORS: The potential breakage isn't limited to floppies but it's +@@ -993,6 +999,7 @@ struct arguments + char *core_file; + char *dir; + char *dev_map; ++ char *root_dev; + int force; + int fs_probe; + int allow_floppy; +@@ -1040,6 +1047,13 @@ argp_parser (int key, char *arg, struct + arguments->dev_map = xstrdup (arg); + break; + ++ case 'r': ++ if (arguments->root_dev) ++ free (arguments->root_dev); ++ ++ arguments->root_dev = xstrdup (arg); ++ break; ++ + case 'f': + arguments->force = 1; + break; +@@ -1172,7 +1186,7 @@ main (int argc, char *argv[]) + setup (arguments.dir ? : DEFAULT_DIRECTORY, + arguments.boot_file ? : DEFAULT_BOOT_FILE, + arguments.core_file ? : DEFAULT_CORE_FILE, +- dest_dev, arguments.force, ++ arguments.root_dev, dest_dev, arguments.force, + arguments.fs_probe, arguments.allow_floppy); + + /* Free resources. */ diff --git a/package/boot/grub2/patches/200-fix-gets-removal.patch b/package/boot/grub2/patches/200-fix-gets-removal.patch new file mode 100644 index 0000000..4370fb5 --- /dev/null +++ b/package/boot/grub2/patches/200-fix-gets-removal.patch @@ -0,0 +1,15 @@ +--- a/grub-core/gnulib/stdio.in.h ++++ b/grub-core/gnulib/stdio.in.h +@@ -137,12 +137,6 @@ + "use gnulib module fflush for portable POSIX compliance"); + #endif + +-/* It is very rare that the developer ever has full control of stdin, +- so any use of gets warrants an unconditional warning. Assume it is +- always declared, since it is required by C89. */ +-#undef gets +-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); +- + #if @GNULIB_FOPEN@ + # if @REPLACE_FOPEN@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) diff --git a/package/boot/grub2/patches/200-grub_musl.patch b/package/boot/grub2/patches/200-grub_musl.patch new file mode 100644 index 0000000..b1ff63a --- /dev/null +++ b/package/boot/grub2/patches/200-grub_musl.patch @@ -0,0 +1,22 @@ +diff -urN grub-2.00/build-aux/config.sub grub-2.00.new/build-aux/config.sub +--- grub-2.00/build-aux/config.sub 2012-06-18 23:08:46.000000000 +0200 ++++ grub-2.00.new/build-aux/config.sub 2012-11-22 14:12:12.190748353 +0100 +@@ -126,7 +126,8 @@ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ +- storm-chaos* | os2-emx* | rtmk-nova*) ++ storm-chaos* | os2-emx* | rtmk-nova* | \ ++ linux-musl*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; +@@ -1360,7 +1361,7 @@ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ +- | -linux-newlib* | -linux-uclibc* \ ++ | -linux-newlib* | -linux-uclibc* | -linux-musl* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ diff --git a/package/boot/kexec-tools/.svn/entries b/package/boot/kexec-tools/.svn/entries new file mode 100644 index 0000000..491df3a --- /dev/null +++ b/package/boot/kexec-tools/.svn/entries @@ -0,0 +1,99 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/kexec-tools +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +patches +dir + +Config.in +file + + + + +2013-03-17T12:13:21.000000Z +feb1f5431985cc3122a22da7a6949801 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +450 + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +9cf805153359d6a9fd758b0ba696c92c +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +1988 + diff --git a/package/boot/kexec-tools/.svn/prop-base/Config.in.svn-base b/package/boot/kexec-tools/.svn/prop-base/Config.in.svn-base new file mode 100644 index 0000000..3160658 --- /dev/null +++ b/package/boot/kexec-tools/.svn/prop-base/Config.in.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mergeinfo +V 0 + +END diff --git a/package/boot/kexec-tools/.svn/prop-base/Makefile.svn-base b/package/boot/kexec-tools/.svn/prop-base/Makefile.svn-base new file mode 100644 index 0000000..8e522ae --- /dev/null +++ b/package/boot/kexec-tools/.svn/prop-base/Makefile.svn-base @@ -0,0 +1,9 @@ +K 13 +svn:copyright +V 30 +Copyright (C) 2006 OpenWrt.org +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/kexec-tools/.svn/text-base/Config.in.svn-base b/package/boot/kexec-tools/.svn/text-base/Config.in.svn-base new file mode 100644 index 0000000..60c819d --- /dev/null +++ b/package/boot/kexec-tools/.svn/text-base/Config.in.svn-base @@ -0,0 +1,21 @@ +menu "Configuration" + depends on PACKAGE_kexec-tools + +config KEXEC_TOOLS_TARGET_NAME + string + prompt "Target name for kexec kernel" + default EXTRA_TARGET_ARCH_NAME if powerpc64 + default ARCH + help + Defines the target type of the kernels that kexec deals + with. This should be the target specification of + the kernel you're booting. + +config KEXEC_TOOLS_kdump + bool + prompt "kdump support" + default n + help + Include the kdump utility. + +endmenu diff --git a/package/boot/kexec-tools/.svn/text-base/Makefile.svn-base b/package/boot/kexec-tools/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..fa4f4d8 --- /dev/null +++ b/package/boot/kexec-tools/.svn/text-base/Makefile.svn-base @@ -0,0 +1,80 @@ +# +# Copyright (C) 2006-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=kexec-tools +PKG_VERSION:=2.0.3 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=@KERNEL/linux/utils/kernel/kexec +PKG_MD5SUM:=b3ced2097ce3981abba38ceedc84f939 + +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk + +define Package/kexec-tools + SECTION:=utils + CATEGORY:=Utilities + DEPENDS:=@armeb||@arm||@i386||@powerpc64||@mipsel||@mips +zlib + TITLE:=Kernel boots kernel + URL:=http://kernel.org/pub/linux/kernel/people/horms/kexec-tools/ + MAINTAINER:=Florian Fainelli <florian@openwrt.org> + MENU:=1 +endef + +define Package/kexec-tools/description + kexec is a set of systems call that allows you to load + another kernel from the currently executing Linux kernel. +endef + +define Package/kexec-tools/config + source "$(SOURCE)/Config.in" +endef + +KEXEC_TARGET_NAME:=$(call qstrip,$(CONFIG_KEXEC_TOOLS_TARGET_NAME))-linux-$(TARGET_SUFFIX) + +CONFIGURE_ARGS = \ + --target=$(KEXEC_TARGET_NAME) \ + --host=$(REAL_GNU_TARGET_NAME) \ + --build=$(GNU_HOST_NAME) \ + --program-prefix="" \ + --program-suffix="" \ + --prefix=/usr \ + --exec-prefix=/usr \ + --bindir=/usr/bin \ + --sbindir=/usr/sbin \ + --libexecdir=/usr/lib \ + --sysconfdir=/etc + +CONFIGURE_VARS += \ + BUILD_CC="$(HOSTCC)" \ + TARGET_CC="$(TARGET_CC)" + +kexec-extra-sbin-$(CONFIG_KEXEC_TOOLS_kdump) += kdump + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) DESTDIR="$(PKG_INSTALL_DIR)" all install +endef + +define Package/kexec-tools/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) \ + $(addprefix $(PKG_INSTALL_DIR)/usr/sbin/, \ + $(kexec-extra-sbin-y)) \ + $(kexec-extra-bin-y) \ + $(PKG_INSTALL_DIR)/usr/sbin/kexec \ + $(1)/usr/sbin + +# make a link for compatability with other distros + $(INSTALL_DIR) $(1)/sbin + ln -s /usr/sbin/kexec $(1)/sbin/kexec +endef + +$(eval $(call BuildPackage,kexec-tools)) diff --git a/package/boot/kexec-tools/Config.in b/package/boot/kexec-tools/Config.in new file mode 100644 index 0000000..60c819d --- /dev/null +++ b/package/boot/kexec-tools/Config.in @@ -0,0 +1,21 @@ +menu "Configuration" + depends on PACKAGE_kexec-tools + +config KEXEC_TOOLS_TARGET_NAME + string + prompt "Target name for kexec kernel" + default EXTRA_TARGET_ARCH_NAME if powerpc64 + default ARCH + help + Defines the target type of the kernels that kexec deals + with. This should be the target specification of + the kernel you're booting. + +config KEXEC_TOOLS_kdump + bool + prompt "kdump support" + default n + help + Include the kdump utility. + +endmenu diff --git a/package/boot/kexec-tools/Makefile b/package/boot/kexec-tools/Makefile new file mode 100644 index 0000000..fa4f4d8 --- /dev/null +++ b/package/boot/kexec-tools/Makefile @@ -0,0 +1,80 @@ +# +# Copyright (C) 2006-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=kexec-tools +PKG_VERSION:=2.0.3 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=@KERNEL/linux/utils/kernel/kexec +PKG_MD5SUM:=b3ced2097ce3981abba38ceedc84f939 + +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk + +define Package/kexec-tools + SECTION:=utils + CATEGORY:=Utilities + DEPENDS:=@armeb||@arm||@i386||@powerpc64||@mipsel||@mips +zlib + TITLE:=Kernel boots kernel + URL:=http://kernel.org/pub/linux/kernel/people/horms/kexec-tools/ + MAINTAINER:=Florian Fainelli <florian@openwrt.org> + MENU:=1 +endef + +define Package/kexec-tools/description + kexec is a set of systems call that allows you to load + another kernel from the currently executing Linux kernel. +endef + +define Package/kexec-tools/config + source "$(SOURCE)/Config.in" +endef + +KEXEC_TARGET_NAME:=$(call qstrip,$(CONFIG_KEXEC_TOOLS_TARGET_NAME))-linux-$(TARGET_SUFFIX) + +CONFIGURE_ARGS = \ + --target=$(KEXEC_TARGET_NAME) \ + --host=$(REAL_GNU_TARGET_NAME) \ + --build=$(GNU_HOST_NAME) \ + --program-prefix="" \ + --program-suffix="" \ + --prefix=/usr \ + --exec-prefix=/usr \ + --bindir=/usr/bin \ + --sbindir=/usr/sbin \ + --libexecdir=/usr/lib \ + --sysconfdir=/etc + +CONFIGURE_VARS += \ + BUILD_CC="$(HOSTCC)" \ + TARGET_CC="$(TARGET_CC)" + +kexec-extra-sbin-$(CONFIG_KEXEC_TOOLS_kdump) += kdump + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) DESTDIR="$(PKG_INSTALL_DIR)" all install +endef + +define Package/kexec-tools/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) \ + $(addprefix $(PKG_INSTALL_DIR)/usr/sbin/, \ + $(kexec-extra-sbin-y)) \ + $(kexec-extra-bin-y) \ + $(PKG_INSTALL_DIR)/usr/sbin/kexec \ + $(1)/usr/sbin + +# make a link for compatability with other distros + $(INSTALL_DIR) $(1)/sbin + ln -s /usr/sbin/kexec $(1)/sbin/kexec +endef + +$(eval $(call BuildPackage,kexec-tools)) diff --git a/package/boot/kexec-tools/patches/.svn/entries b/package/boot/kexec-tools/patches/.svn/entries new file mode 100644 index 0000000..a6d2354 --- /dev/null +++ b/package/boot/kexec-tools/patches/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/kexec-tools/patches +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +0004-mips_regdefs.patch +file + + + + +2013-03-17T12:13:21.000000Z +33113e08f846ec68e08370825d881eab +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +2919 + diff --git a/package/boot/kexec-tools/patches/.svn/text-base/0004-mips_regdefs.patch.svn-base b/package/boot/kexec-tools/patches/.svn/text-base/0004-mips_regdefs.patch.svn-base new file mode 100644 index 0000000..7e21349 --- /dev/null +++ b/package/boot/kexec-tools/patches/.svn/text-base/0004-mips_regdefs.patch.svn-base @@ -0,0 +1,103 @@ +--- /dev/null ++++ b/kexec/arch/mips/regdef.h +@@ -0,0 +1,100 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1985 MIPS Computer Systems, Inc. ++ * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle ++ * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. ++ */ ++#ifndef _ASM_REGDEF_H ++#define _ASM_REGDEF_H ++ ++#include <asm/sgidefs.h> ++ ++#if _MIPS_SIM == _MIPS_SIM_ABI32 ++ ++/* ++ * Symbolic register names for 32 bit ABI ++ */ ++#define zero $0 /* wired zero */ ++#define AT $1 /* assembler temp - uppercase because of ".set at" */ ++#define v0 $2 /* return value */ ++#define v1 $3 ++#define a0 $4 /* argument registers */ ++#define a1 $5 ++#define a2 $6 ++#define a3 $7 ++#define t0 $8 /* caller saved */ ++#define t1 $9 ++#define t2 $10 ++#define t3 $11 ++#define t4 $12 ++#define t5 $13 ++#define t6 $14 ++#define t7 $15 ++#define s0 $16 /* callee saved */ ++#define s1 $17 ++#define s2 $18 ++#define s3 $19 ++#define s4 $20 ++#define s5 $21 ++#define s6 $22 ++#define s7 $23 ++#define t8 $24 /* caller saved */ ++#define t9 $25 ++#define jp $25 /* PIC jump register */ ++#define k0 $26 /* kernel scratch */ ++#define k1 $27 ++#define gp $28 /* global pointer */ ++#define sp $29 /* stack pointer */ ++#define fp $30 /* frame pointer */ ++#define s8 $30 /* same like fp! */ ++#define ra $31 /* return address */ ++ ++#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ ++ ++#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 ++ ++#define zero $0 /* wired zero */ ++#define AT $at /* assembler temp - uppercase because of ".set at" */ ++#define v0 $2 /* return value - caller saved */ ++#define v1 $3 ++#define a0 $4 /* argument registers */ ++#define a1 $5 ++#define a2 $6 ++#define a3 $7 ++#define a4 $8 /* arg reg 64 bit; caller saved in 32 bit */ ++#define ta0 $8 ++#define a5 $9 ++#define ta1 $9 ++#define a6 $10 ++#define ta2 $10 ++#define a7 $11 ++#define ta3 $11 ++#define t0 $12 /* caller saved */ ++#define t1 $13 ++#define t2 $14 ++#define t3 $15 ++#define s0 $16 /* callee saved */ ++#define s1 $17 ++#define s2 $18 ++#define s3 $19 ++#define s4 $20 ++#define s5 $21 ++#define s6 $22 ++#define s7 $23 ++#define t8 $24 /* caller saved */ ++#define t9 $25 /* callee address for PIC/temp */ ++#define jp $25 /* PIC jump register */ ++#define k0 $26 /* kernel temporary */ ++#define k1 $27 ++#define gp $28 /* global pointer - caller saved for PIC */ ++#define sp $29 /* stack pointer */ ++#define fp $30 /* frame pointer */ ++#define s8 $30 /* callee saved */ ++#define ra $31 /* return address */ ++ ++#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */ ++ ++#endif /* _ASM_REGDEF_H */ diff --git a/package/boot/kexec-tools/patches/0004-mips_regdefs.patch b/package/boot/kexec-tools/patches/0004-mips_regdefs.patch new file mode 100644 index 0000000..7e21349 --- /dev/null +++ b/package/boot/kexec-tools/patches/0004-mips_regdefs.patch @@ -0,0 +1,103 @@ +--- /dev/null ++++ b/kexec/arch/mips/regdef.h +@@ -0,0 +1,100 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1985 MIPS Computer Systems, Inc. ++ * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle ++ * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. ++ */ ++#ifndef _ASM_REGDEF_H ++#define _ASM_REGDEF_H ++ ++#include <asm/sgidefs.h> ++ ++#if _MIPS_SIM == _MIPS_SIM_ABI32 ++ ++/* ++ * Symbolic register names for 32 bit ABI ++ */ ++#define zero $0 /* wired zero */ ++#define AT $1 /* assembler temp - uppercase because of ".set at" */ ++#define v0 $2 /* return value */ ++#define v1 $3 ++#define a0 $4 /* argument registers */ ++#define a1 $5 ++#define a2 $6 ++#define a3 $7 ++#define t0 $8 /* caller saved */ ++#define t1 $9 ++#define t2 $10 ++#define t3 $11 ++#define t4 $12 ++#define t5 $13 ++#define t6 $14 ++#define t7 $15 ++#define s0 $16 /* callee saved */ ++#define s1 $17 ++#define s2 $18 ++#define s3 $19 ++#define s4 $20 ++#define s5 $21 ++#define s6 $22 ++#define s7 $23 ++#define t8 $24 /* caller saved */ ++#define t9 $25 ++#define jp $25 /* PIC jump register */ ++#define k0 $26 /* kernel scratch */ ++#define k1 $27 ++#define gp $28 /* global pointer */ ++#define sp $29 /* stack pointer */ ++#define fp $30 /* frame pointer */ ++#define s8 $30 /* same like fp! */ ++#define ra $31 /* return address */ ++ ++#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ ++ ++#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 ++ ++#define zero $0 /* wired zero */ ++#define AT $at /* assembler temp - uppercase because of ".set at" */ ++#define v0 $2 /* return value - caller saved */ ++#define v1 $3 ++#define a0 $4 /* argument registers */ ++#define a1 $5 ++#define a2 $6 ++#define a3 $7 ++#define a4 $8 /* arg reg 64 bit; caller saved in 32 bit */ ++#define ta0 $8 ++#define a5 $9 ++#define ta1 $9 ++#define a6 $10 ++#define ta2 $10 ++#define a7 $11 ++#define ta3 $11 ++#define t0 $12 /* caller saved */ ++#define t1 $13 ++#define t2 $14 ++#define t3 $15 ++#define s0 $16 /* callee saved */ ++#define s1 $17 ++#define s2 $18 ++#define s3 $19 ++#define s4 $20 ++#define s5 $21 ++#define s6 $22 ++#define s7 $23 ++#define t8 $24 /* caller saved */ ++#define t9 $25 /* callee address for PIC/temp */ ++#define jp $25 /* PIC jump register */ ++#define k0 $26 /* kernel temporary */ ++#define k1 $27 ++#define gp $28 /* global pointer - caller saved for PIC */ ++#define sp $29 /* stack pointer */ ++#define fp $30 /* frame pointer */ ++#define s8 $30 /* callee saved */ ++#define ra $31 /* return address */ ++ ++#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */ ++ ++#endif /* _ASM_REGDEF_H */ diff --git a/package/boot/rbcfg/.svn/entries b/package/boot/rbcfg/.svn/entries new file mode 100644 index 0000000..a16907b --- /dev/null +++ b/package/boot/rbcfg/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/rbcfg +svn://svn.openwrt.org/openwrt + + + +2012-10-17T21:53:23.143554Z +33824 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +src +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +54ebd1734c602f5d5c63ed6b37cd830c +2012-10-17T21:53:23.143554Z +33824 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +1009 + diff --git a/package/boot/rbcfg/.svn/prop-base/Makefile.svn-base b/package/boot/rbcfg/.svn/prop-base/Makefile.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/rbcfg/.svn/prop-base/Makefile.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/rbcfg/.svn/text-base/Makefile.svn-base b/package/boot/rbcfg/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..51fefd5 --- /dev/null +++ b/package/boot/rbcfg/.svn/text-base/Makefile.svn-base @@ -0,0 +1,49 @@ +# +# Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=rbcfg +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/rbcfg + SECTION:=utils + CATEGORY:=Utilities + TITLE:=RouterBOOT configuration tool + DEPENDS:=@TARGET_ar71xx +endef + +define Package/rbcfg/description + This package contains an utility to manipulate RouterBOOT configuration on the + MikroTIK RB-4XX devices. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Configure +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS) -Wall" \ + LDFLAGS="$(TARGET_LDFLAGS)" +endef + +define Package/rbcfg/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/rbcfg $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,rbcfg)) diff --git a/package/boot/rbcfg/Makefile b/package/boot/rbcfg/Makefile new file mode 100644 index 0000000..51fefd5 --- /dev/null +++ b/package/boot/rbcfg/Makefile @@ -0,0 +1,49 @@ +# +# Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=rbcfg +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/rbcfg + SECTION:=utils + CATEGORY:=Utilities + TITLE:=RouterBOOT configuration tool + DEPENDS:=@TARGET_ar71xx +endef + +define Package/rbcfg/description + This package contains an utility to manipulate RouterBOOT configuration on the + MikroTIK RB-4XX devices. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Configure +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS) -Wall" \ + LDFLAGS="$(TARGET_LDFLAGS)" +endef + +define Package/rbcfg/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/rbcfg $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,rbcfg)) diff --git a/package/boot/rbcfg/src/.svn/entries b/package/boot/rbcfg/src/.svn/entries new file mode 100644 index 0000000..2f111cd --- /dev/null +++ b/package/boot/rbcfg/src/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/rbcfg/src +svn://svn.openwrt.org/openwrt + + + +2012-10-17T21:53:23.143554Z +33824 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +cyg_crc.h +file + + + + +2013-03-17T12:13:21.000000Z +ba9d1cf06e7d26d19e67fff283506d18 +2012-10-17T21:53:23.143554Z +33824 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +3372 + +cyg_crc32.c +file + + + + +2013-03-17T12:13:21.000000Z +2005e143bb82ddc198ca4e919a800aee +2012-10-17T21:53:23.143554Z +33824 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +7963 + +main.c +file + + + + +2013-03-17T12:13:21.000000Z +7acc0c5073dc83633e151d35618baa2f +2012-10-17T21:53:23.143554Z +33824 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +15073 + +rbcfg.h +file + + + + +2013-03-17T12:13:21.000000Z +c2945a0eae01cc2749251ab0e3c959b2 +2012-10-17T21:53:23.143554Z +33824 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +1759 + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +0496a56c341577ddcd18f510c963447f +2012-10-17T21:53:23.143554Z +33824 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +163 + diff --git a/package/boot/rbcfg/src/.svn/prop-base/Makefile.svn-base b/package/boot/rbcfg/src/.svn/prop-base/Makefile.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/rbcfg/src/.svn/prop-base/Makefile.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/rbcfg/src/.svn/prop-base/cyg_crc.h.svn-base b/package/boot/rbcfg/src/.svn/prop-base/cyg_crc.h.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/rbcfg/src/.svn/prop-base/cyg_crc.h.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/rbcfg/src/.svn/prop-base/cyg_crc32.c.svn-base b/package/boot/rbcfg/src/.svn/prop-base/cyg_crc32.c.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/rbcfg/src/.svn/prop-base/cyg_crc32.c.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/rbcfg/src/.svn/prop-base/main.c.svn-base b/package/boot/rbcfg/src/.svn/prop-base/main.c.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/rbcfg/src/.svn/prop-base/main.c.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/rbcfg/src/.svn/prop-base/rbcfg.h.svn-base b/package/boot/rbcfg/src/.svn/prop-base/rbcfg.h.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/rbcfg/src/.svn/prop-base/rbcfg.h.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/rbcfg/src/.svn/text-base/Makefile.svn-base b/package/boot/rbcfg/src/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..62c74b2 --- /dev/null +++ b/package/boot/rbcfg/src/.svn/text-base/Makefile.svn-base @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -Wall +OBJS = main.o cyg_crc32.o + +all: rbcfg + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +rbcfg: $(OBJS) + $(CC) -o $@ $(OBJS) + +clean: + rm -f rbcfg *.o diff --git a/package/boot/rbcfg/src/.svn/text-base/cyg_crc.h.svn-base b/package/boot/rbcfg/src/.svn/text-base/cyg_crc.h.svn-base new file mode 100644 index 0000000..7b59803 --- /dev/null +++ b/package/boot/rbcfg/src/.svn/text-base/cyg_crc.h.svn-base @@ -0,0 +1,109 @@ +//========================================================================== +// +// crc.h +// +// Interface for the CRC algorithms. +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Andrew Lunn +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): Andrew Lunn +// Contributors: Andrew Lunn +// Date: 2002-08-06 +// Purpose: +// Description: +// +// This code is part of eCos (tm). +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#ifndef _SERVICES_CRC_CRC_H_ +#define _SERVICES_CRC_CRC_H_ + +#if 0 +#include <cyg/infra/cyg_type.h> +#else +#include <stdint.h> +typedef uint32_t cyg_uint32; +typedef uint16_t cyg_uint16; +#endif + +#ifndef __externC +# ifdef __cplusplus +# define __externC extern "C" +# else +# define __externC extern +# endif +#endif + +// Compute a CRC, using the POSIX 1003 definition + +__externC cyg_uint32 +cyg_posix_crc32(unsigned char *s, int len); + +// Gary S. Brown's 32 bit CRC + +__externC cyg_uint32 +cyg_crc32(unsigned char *s, int len); + +// Gary S. Brown's 32 bit CRC, but accumulate the result from a +// previous CRC calculation + +__externC cyg_uint32 +cyg_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len); + +// Ethernet FCS Algorithm + +__externC cyg_uint32 +cyg_ether_crc32(unsigned char *s, int len); + +// Ethernet FCS algorithm, but accumulate the result from a previous +// CRC calculation. + +__externC cyg_uint32 +cyg_ether_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len); + +// 16 bit CRC with polynomial x^16+x^12+x^5+1 + +__externC cyg_uint16 +cyg_crc16(unsigned char *s, int len); + +#endif // _SERVICES_CRC_CRC_H_ + + + diff --git a/package/boot/rbcfg/src/.svn/text-base/cyg_crc32.c.svn-base b/package/boot/rbcfg/src/.svn/text-base/cyg_crc32.c.svn-base new file mode 100644 index 0000000..9462598 --- /dev/null +++ b/package/boot/rbcfg/src/.svn/text-base/cyg_crc32.c.svn-base @@ -0,0 +1,172 @@ +//========================================================================== +// +// crc32.c +// +// Gary S. Brown's 32 bit CRC +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 2002 Gary Thomas +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas,asl +// Date: 2001-01-31 +// Purpose: +// Description: +// +// This code is part of eCos (tm). +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#if 0 +#include <cyg/crc/crc.h> +#else +#include "cyg_crc.h" +#endif + + /* ====================================================================== */ + /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ + /* code or tables extracted from it, as desired without restriction. */ + /* */ + /* First, the polynomial itself and its table of feedback terms. The */ + /* polynomial is */ + /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ + /* */ + /* ====================================================================== */ + +static const cyg_uint32 crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL + }; + +/* This is the standard Gary S. Brown's 32 bit CRC algorithm, but + accumulate the CRC into the result of a previous CRC. */ +cyg_uint32 +cyg_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len) +{ + int i; + + for (i = 0; i < len; i++) { + crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); + } + return crc32val; +} + +/* This is the standard Gary S. Brown's 32 bit CRC algorithm */ +cyg_uint32 +cyg_crc32(unsigned char *s, int len) +{ + return (cyg_crc32_accumulate(0,s,len)); +} + +/* Return a 32-bit CRC of the contents of the buffer accumulating the + result from a previous CRC calculation. This uses the Ethernet FCS + algorithm.*/ +cyg_uint32 +cyg_ether_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len) +{ + int i; + + if (s == 0) return 0L; + + crc32val = crc32val ^ 0xffffffff; + for (i = 0; i < len; i++) { + crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); + } + return crc32val ^ 0xffffffff; +} + +/* Return a 32-bit CRC of the contents of the buffer, using the + Ethernet FCS algorithm. */ +cyg_uint32 +cyg_ether_crc32(unsigned char *s, int len) +{ + return cyg_ether_crc32_accumulate(0,s,len); +} + + diff --git a/package/boot/rbcfg/src/.svn/text-base/main.c.svn-base b/package/boot/rbcfg/src/.svn/text-base/main.c.svn-base new file mode 100644 index 0000000..5614a6c --- /dev/null +++ b/package/boot/rbcfg/src/.svn/text-base/main.c.svn-base @@ -0,0 +1,791 @@ +/* + * RouterBOOT configuration utility + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> +#include <linux/limits.h> + +#include "rbcfg.h" +#include "cyg_crc.h" + +#define RBCFG_TMP_FILE "/tmp/.rbcfg" +#define RBCFG_MTD_NAME "soft_config" + +#define RB_ERR_NOTFOUND 1 +#define RB_ERR_INVALID 2 +#define RB_ERR_NOMEM 3 +#define RB_ERR_IO 4 + +#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0])) + +struct rbcfg_ctx { + char *mtd_device; + char *tmp_file; + char *buf; + unsigned buflen; +}; + +struct rbcfg_value { + const char *name; + const char *desc; + union { + uint32_t u32; + const char *raw; + } val; +}; + +#define RBCFG_ENV_TYPE_U32 0 + +struct rbcfg_env { + const char *name; + int type; + uint16_t id; + const struct rbcfg_value *values; + int num_values; +}; + +#define CMD_FLAG_USES_CFG 0x01 + +struct rbcfg_command { + const char *command; + const char *usage; + int flags; + int (*exec)(int argc, const char *argv[]); +}; + +static void usage(void); + +/* Globals */ + +static struct rbcfg_ctx *rbcfg_ctx; +static char *rbcfg_name; + +#define CFG_U32(_name, _desc, _val) { \ + .name = (_name), \ + .desc = (_desc), \ + .val.u32 = (_val), \ +} + +static const struct rbcfg_value rbcfg_boot_delay[] = { + CFG_U32("1", "1 second", RB_BOOT_DELAY_1SEC), + CFG_U32("2", "2 seconds", RB_BOOT_DELAY_2SEC), + CFG_U32("3", "3 seconds", RB_BOOT_DELAY_3SEC), + CFG_U32("4", "4 seconds", RB_BOOT_DELAY_4SEC), + CFG_U32("5", "5 seconds", RB_BOOT_DELAY_5SEC), + CFG_U32("6", "6 seconds", RB_BOOT_DELAY_6SEC), + CFG_U32("7", "7 seconds", RB_BOOT_DELAY_7SEC), + CFG_U32("8", "8 seconds", RB_BOOT_DELAY_8SEC), + CFG_U32("9", "9 seconds", RB_BOOT_DELAY_9SEC), +}; + +static const struct rbcfg_value rbcfg_boot_device[] = { + CFG_U32("eth", "boot over Ethernet", + RB_BOOT_DEVICE_ETHER), + CFG_U32("nandeth", "boot from NAND, if fail then Ethernet", + RB_BOOT_DEVICE_NANDETH), + CFG_U32("ethnand", "boot Ethernet once, then NAND", + RB_BOOT_DEVICE_ETHONCE), + CFG_U32("nand", "boot from NAND only", + RB_BOOT_DEVICE_NANDONLY), +}; + +static const struct rbcfg_value rbcfg_boot_key[] = { + CFG_U32("any", "any key", RB_BOOT_KEY_ANY), + CFG_U32("del", "<Delete> key only", RB_BOOT_KEY_DEL), +}; + +static const struct rbcfg_value rbcfg_boot_protocol[] = { + CFG_U32("bootp", "BOOTP protocol", RB_BOOT_PROTOCOL_BOOTP), + CFG_U32("dhcp", "DHCP protocol", RB_BOOT_PROTOCOL_DHCP), +}; + +static const struct rbcfg_value rbcfg_uart_speed[] = { + CFG_U32("115200", "", RB_UART_SPEED_115200), + CFG_U32("57600", "", RB_UART_SPEED_57600), + CFG_U32("38400", "", RB_UART_SPEED_38400), + CFG_U32("19200", "", RB_UART_SPEED_19200), + CFG_U32("9600", "", RB_UART_SPEED_9600), + CFG_U32("4800", "", RB_UART_SPEED_4800), + CFG_U32("2400", "", RB_UART_SPEED_2400), + CFG_U32("1200", "", RB_UART_SPEED_1200), + CFG_U32("off", "disable console output", RB_UART_SPEED_OFF), +}; + +static const struct rbcfg_value rbcfg_cpu_mode[] = { + CFG_U32("powersave", "power save", RB_CPU_MODE_POWERSAVE), + CFG_U32("regular", "regular (better for -0c environment)", + RB_CPU_MODE_REGULAR), +}; + +static const struct rbcfg_value rbcfg_booter[] = { + CFG_U32("regular", "load regular booter", RB_BOOTER_REGULAR), + CFG_U32("backup", "force backup-booter loading", RB_BOOTER_BACKUP), +}; + +static const struct rbcfg_env rbcfg_envs[] = { + { + .name = "boot_delay", + .id = RB_ID_BOOT_DELAY, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_boot_delay, + .num_values = ARRAY_SIZE(rbcfg_boot_delay), + }, { + .name = "boot_device", + .id = RB_ID_BOOT_DEVICE, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_boot_device, + .num_values = ARRAY_SIZE(rbcfg_boot_device), + }, { + .name = "boot_key", + .id = RB_ID_BOOT_KEY, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_boot_key, + .num_values = ARRAY_SIZE(rbcfg_boot_key), + }, { + .name = "boot_protocol", + .id = RB_ID_BOOT_PROTOCOL, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_boot_protocol, + .num_values = ARRAY_SIZE(rbcfg_boot_protocol), + }, { + .name = "booter", + .id = RB_ID_BOOTER, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_booter, + .num_values = ARRAY_SIZE(rbcfg_booter), + }, { + .name = "cpu_mode", + .id = RB_ID_CPU_MODE, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_cpu_mode, + .num_values = ARRAY_SIZE(rbcfg_cpu_mode), + }, { + .name = "uart_speed", + .id = RB_ID_UART_SPEED, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_uart_speed, + .num_values = ARRAY_SIZE(rbcfg_uart_speed), + } +}; + +static inline uint16_t +get_u16(const void *buf) +{ + const uint8_t *p = buf; + + return ((uint16_t) p[1] + ((uint16_t) p[0] << 8)); +} + +static inline uint32_t +get_u32(const void *buf) +{ + const uint8_t *p = buf; + + return ((uint32_t) p[3] + ((uint32_t) p[2] << 8) + + ((uint32_t) p[1] << 16) + ((uint32_t) p[0] << 24)); +} + +static inline void +put_u32(void *buf, uint32_t val) +{ + uint8_t *p = buf; + + p[3] = val & 0xff; + p[2] = (val >> 8) & 0xff; + p[1] = (val >> 16) & 0xff; + p[0] = (val >> 24) & 0xff; +} + +static int +rbcfg_find_tag(struct rbcfg_ctx *ctx, uint16_t tag_id, uint16_t *tag_len, + void **tag_data) +{ + uint16_t id; + uint16_t len; + char *buf = ctx->buf; + unsigned int buflen = ctx->buflen; + int ret = RB_ERR_NOTFOUND; + + /* skip magic and CRC value */ + buf += 8; + buflen -= 8; + + while (buflen > 2) { + len = get_u16(buf); + buf += 2; + buflen -= 2; + + if (buflen < 2) + break; + + id = get_u16(buf); + buf += 2; + buflen -= 2; + + if (id == RB_ID_TERMINATOR) + break; + + if (buflen < len) + break; + + if (id == tag_id) { + *tag_len = len; + *tag_data = buf; + ret = 0; + break; + } + + buf += len; + buflen -= len; + } + + if (ret) + fprintf(stderr, "no tag found with id=%u\n", tag_id); + + return ret; +} + +static int +rbcfg_get_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t *val) +{ + void *tag_data; + uint16_t tag_len; + int err; + + err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data); + if (err) + return err; + + *val = get_u32(tag_data); + return 0; +} + +static int +rbcfg_set_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t val) +{ + void *tag_data; + uint16_t tag_len; + int err; + + err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data); + if (err) + return err; + + put_u32(tag_data, val); + return 0; +} + +char *rbcfg_find_mtd(const char *name, int *erase_size) +{ + FILE *f; + int mtd_num; + char dev[PATH_MAX]; + char *ret = NULL; + struct stat s; + int err; + + f = fopen("/proc/mtd", "r"); + if (!f) + return NULL; + + while (1) { + char *p; + p = fgets(dev, sizeof(dev), f); + if (!p) + break; + + if (!strstr(dev, name)) + continue; + + err = sscanf(dev, "mtd%d: %08x", &mtd_num, erase_size); + if (err != 2) + break; + + sprintf(dev, "/dev/mtdblock%d", mtd_num); + err = stat(dev, &s); + if (err < 0) + break; + + if ((s.st_mode & S_IFBLK) == 0) + break; + + ret = malloc(strlen(dev) + 1); + if (ret == NULL) + break; + + strncpy(ret, dev, strlen(dev) + 1); + break; + } + + fclose(f); + return ret; +} + +static int +rbcfg_check_tmp(struct rbcfg_ctx *ctx) +{ + struct stat s; + int err; + + err = stat(ctx->tmp_file, &s); + if (err < 0) + return 0; + + if ((s.st_mode & S_IFREG) == 0) + return 0; + + if (s.st_size != ctx->buflen) + return 0; + + return 1; +} + +static int +rbcfg_load(struct rbcfg_ctx *ctx) +{ + uint32_t magic; + uint32_t crc_orig, crc; + char *name; + int tmp; + int fd; + int err; + + tmp = rbcfg_check_tmp(ctx); + name = (tmp) ? ctx->tmp_file : ctx->mtd_device; + + fd = open(name, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "unable to open %s\n", name); + err = RB_ERR_IO; + goto err; + } + + err = read(fd, ctx->buf, ctx->buflen); + if (err != ctx->buflen) { + fprintf(stderr, "unable to read from %s\n", name); + err = RB_ERR_IO; + goto err_close; + } + + magic = get_u32(ctx->buf); + if (magic != RB_MAGIC_SOFT) { + fprintf(stderr, "invalid configuration\n"); + err = RB_ERR_INVALID; + goto err_close; + } + + crc_orig = get_u32(ctx->buf + 4); + put_u32(ctx->buf + 4, 0); + crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen); + if (crc != crc_orig) { + fprintf(stderr, "configuration has CRC error\n"); + err = RB_ERR_INVALID; + goto err_close; + } + + err = 0; + + err_close: + close(fd); + err: + return err; +} + +static int +rbcfg_open() +{ + char *mtd_device; + struct rbcfg_ctx *ctx; + int buflen; + int err; + + mtd_device = rbcfg_find_mtd(RBCFG_MTD_NAME, &buflen); + if (!mtd_device) { + fprintf(stderr, "unable to find configuration\n"); + return RB_ERR_NOTFOUND; + } + + ctx = malloc(sizeof(struct rbcfg_ctx) + buflen); + if (ctx == NULL) { + err = RB_ERR_NOMEM; + goto err_free_mtd; + } + + ctx->mtd_device = mtd_device; + ctx->tmp_file = RBCFG_TMP_FILE; + ctx->buflen = buflen; + ctx->buf = (char *) &ctx[1]; + + err = rbcfg_load(ctx); + if (err) + goto err_free_ctx; + + rbcfg_ctx = ctx; + return 0; + + err_free_ctx: + free(ctx); + err_free_mtd: + free(mtd_device); + return err; +} + +static int +rbcfg_update(int tmp) +{ + struct rbcfg_ctx *ctx = rbcfg_ctx; + char *name; + uint32_t crc; + int fd; + int err; + + put_u32(ctx->buf, RB_MAGIC_SOFT); + put_u32(ctx->buf + 4, 0); + crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen); + put_u32(ctx->buf + 4, crc); + + name = (tmp) ? ctx->tmp_file : ctx->mtd_device; + fd = open(name, O_WRONLY | O_CREAT); + if (fd < 0) { + fprintf(stderr, "unable to open %s for writing\n", name); + err = RB_ERR_IO; + goto out; + } + + err = write(fd, ctx->buf, ctx->buflen); + if (err != ctx->buflen) { + err = RB_ERR_IO; + goto out_close; + } + + fsync(fd); + err = 0; + + out_close: + close(fd); + out: + return err; +} + +static void +rbcfg_close(void) +{ + struct rbcfg_ctx *ctx; + + ctx = rbcfg_ctx; + free(ctx->mtd_device); + free(ctx); +} + +static const struct rbcfg_value * +rbcfg_env_find(const struct rbcfg_env *env, const char *name) +{ + unsigned i; + + for (i = 0; i < env->num_values; i++) { + const struct rbcfg_value *v = &env->values[i]; + + if (strcmp(v->name, name) == 0) + return v; + } + + return NULL; +} + +static const struct rbcfg_value * +rbcfg_env_find_u32(const struct rbcfg_env *env, uint32_t val) +{ + unsigned i; + + for (i = 0; i < env->num_values; i++) { + const struct rbcfg_value *v = &env->values[i]; + + if (v->val.u32 == val) + return v; + } + + return NULL; +} + +static const char * +rbcfg_env_get_u32(const struct rbcfg_env *env) +{ + const struct rbcfg_value *v; + uint32_t val; + int err; + + err = rbcfg_get_u32(rbcfg_ctx, env->id, &val); + if (err) + return NULL; + + v = rbcfg_env_find_u32(env, val); + if (v == NULL) { + fprintf(stderr, "unknown value %08x found for %s\n", + val, env->name); + return NULL; + } + + return v->name; +} + +static int +rbcfg_env_set_u32(const struct rbcfg_env *env, const char *data) +{ + const struct rbcfg_value *v; + int err; + + v = rbcfg_env_find(env, data); + if (v == NULL) { + fprintf(stderr, "invalid value '%s'\n", data); + return RB_ERR_INVALID; + } + + err = rbcfg_set_u32(rbcfg_ctx, env->id, v->val.u32); + return err; +} + +static const char * +rbcfg_env_get(const struct rbcfg_env *env) +{ + const char *ret = NULL; + + switch (env->type) { + case RBCFG_ENV_TYPE_U32: + ret = rbcfg_env_get_u32(env); + break; + } + + return ret; +} + +static int +rbcfg_env_set(const struct rbcfg_env *env, const char *data) +{ + int ret = 0; + + switch (env->type) { + case RBCFG_ENV_TYPE_U32: + ret = rbcfg_env_set_u32(env, data); + break; + } + + return ret; +} + +static int +rbcfg_cmd_apply(int argc, const char *argv[]) +{ + return rbcfg_update(0); +} + +static int +rbcfg_cmd_help(int argc, const char *argv[]) +{ + usage(); + return 0; +} + +static int +rbcfg_cmd_get(int argc, const char *argv[]) +{ + int err = RB_ERR_NOTFOUND; + int i; + + if (argc != 1) { + usage(); + return RB_ERR_INVALID; + } + + for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) { + const struct rbcfg_env *env = &rbcfg_envs[i]; + const char *value; + + if (strcmp(env->name, argv[0])) + continue; + + value = rbcfg_env_get(env); + if (value) { + fprintf(stdout, "%s\n", value); + err = 0; + } + break; + } + + return err; +} + +static int +rbcfg_cmd_set(int argc, const char *argv[]) +{ + int err = RB_ERR_INVALID; + int i; + + if (argc != 2) { + /* not enough parameters */ + usage(); + return RB_ERR_INVALID; + } + + for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) { + const struct rbcfg_env *env = &rbcfg_envs[i]; + + if (strcmp(env->name, argv[0])) + continue; + + err = rbcfg_env_set(env, argv[1]); + if (err == 0) + err = rbcfg_update(1); + break; + } + + return err; +} + +static int +rbcfg_cmd_show(int argc, const char *argv[]) +{ + int i; + + if (argc != 0) { + usage(); + return RB_ERR_INVALID; + } + + for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) { + const struct rbcfg_env *env = &rbcfg_envs[i]; + const char *value; + + value = rbcfg_env_get(env); + if (value) + fprintf(stdout, "%s=%s\n", env->name, value); + } + + return 0; +} + +static const struct rbcfg_command rbcfg_commands[] = { + { + .command = "apply", + .usage = "apply\n" + "\t- write configuration to the mtd device", + .flags = CMD_FLAG_USES_CFG, + .exec = rbcfg_cmd_apply, + }, { + .command = "help", + .usage = "help\n" + "\t- show this screen", + .exec = rbcfg_cmd_help, + }, { + .command = "get", + .usage = "get <name>\n" + "\t- get value of the configuration option <name>", + .flags = CMD_FLAG_USES_CFG, + .exec = rbcfg_cmd_get, + }, { + .command = "set", + .usage = "set <name> <value>\n" + "\t- set value of the configuration option <name> to <value>", + .flags = CMD_FLAG_USES_CFG, + .exec = rbcfg_cmd_set, + }, { + .command = "show", + .usage = "show\n" + "\t- show value of all configuration options", + .flags = CMD_FLAG_USES_CFG, + .exec = rbcfg_cmd_show, + } +}; + +static void +usage(void) +{ + char buf[255]; + int len; + int i; + + fprintf(stderr, "Usage: %s <command>\n", rbcfg_name); + + fprintf(stderr, "\nCommands:\n"); + for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) { + const struct rbcfg_command *cmd; + cmd = &rbcfg_commands[i]; + + len = snprintf(buf, sizeof(buf), cmd->usage); + buf[len] = '\0'; + fprintf(stderr, "%s\n", buf); + } + + fprintf(stderr, "\nConfiguration options:\n"); + for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) { + const struct rbcfg_env *env; + int j; + + env = &rbcfg_envs[i]; + fprintf(stderr, "\n%s:\n", env->name); + for (j = 0; j < env->num_values; j++) { + const struct rbcfg_value *v = &env->values[j]; + fprintf(stderr, "\t%-12s %s\n", v->name, v->desc); + } + } + fprintf(stderr, "\n"); +} + +int main(int argc, const char *argv[]) +{ + const struct rbcfg_command *cmd = NULL; + int ret; + int i; + + rbcfg_name = (char *) argv[0]; + + if (argc < 2) { + usage(); + return EXIT_FAILURE; + } + + for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) { + if (strcmp(rbcfg_commands[i].command, argv[1]) == 0) { + cmd = &rbcfg_commands[i]; + break; + } + } + + if (cmd == NULL) { + fprintf(stderr, "unknown command '%s'\n", argv[1]); + usage(); + return EXIT_FAILURE; + } + + argc -= 2; + argv += 2; + + if (cmd->flags & CMD_FLAG_USES_CFG) { + ret = rbcfg_open(); + if (ret) + return EXIT_FAILURE; + } + + ret = cmd->exec(argc, argv); + + if (cmd->flags & CMD_FLAG_USES_CFG) + rbcfg_close(); + + if (ret) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/package/boot/rbcfg/src/.svn/text-base/rbcfg.h.svn-base b/package/boot/rbcfg/src/.svn/text-base/rbcfg.h.svn-base new file mode 100644 index 0000000..899161a --- /dev/null +++ b/package/boot/rbcfg/src/.svn/text-base/rbcfg.h.svn-base @@ -0,0 +1,75 @@ +/* + * Mikrotik's RouterBOOT configuration defines + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#ifndef _RBCFG_H +#define _RBCFG_H + +/* + * Magic numbers + */ +#define RB_MAGIC_SOFT 0x74666f53 /* 'Soft' */ + +/* + * ID values for Software settings + */ +#define RB_ID_TERMINATOR 0 +#define RB_ID_UART_SPEED 1 +#define RB_ID_BOOT_DELAY 2 +#define RB_ID_BOOT_DEVICE 3 +#define RB_ID_BOOT_KEY 4 +#define RB_ID_CPU_MODE 5 +#define RB_ID_FW_VERSION 6 +#define RB_ID_SOFT_07 7 +#define RB_ID_SOFT_08 8 +#define RB_ID_BOOT_PROTOCOL 9 +#define RB_ID_SOFT_10 10 +#define RB_ID_SOFT_11 11 +#define RB_ID_BOOTER 13 + +#define RB_UART_SPEED_115200 0 +#define RB_UART_SPEED_57600 1 +#define RB_UART_SPEED_38400 2 +#define RB_UART_SPEED_19200 3 +#define RB_UART_SPEED_9600 4 +#define RB_UART_SPEED_4800 5 +#define RB_UART_SPEED_2400 6 +#define RB_UART_SPEED_1200 7 +#define RB_UART_SPEED_OFF 8 + +#define RB_BOOT_DELAY_1SEC 1 +#define RB_BOOT_DELAY_2SEC 2 +#define RB_BOOT_DELAY_3SEC 3 +#define RB_BOOT_DELAY_4SEC 4 +#define RB_BOOT_DELAY_5SEC 5 +#define RB_BOOT_DELAY_6SEC 6 +#define RB_BOOT_DELAY_7SEC 7 +#define RB_BOOT_DELAY_8SEC 8 +#define RB_BOOT_DELAY_9SEC 9 + +#define RB_BOOT_DEVICE_ETHER 0 +#define RB_BOOT_DEVICE_NANDETH 1 +#define RB_BOOT_DEVICE_CFCARD 2 +#define RB_BOOT_DEVICE_ETHONCE 3 +#define RB_BOOT_DEVICE_NANDONLY 5 + +#define RB_BOOT_KEY_ANY 0 +#define RB_BOOT_KEY_DEL 1 + +#define RB_CPU_MODE_POWERSAVE 0 +#define RB_CPU_MODE_REGULAR 1 + +#define RB_BOOT_PROTOCOL_BOOTP 0 +#define RB_BOOT_PROTOCOL_DHCP 1 + +#define RB_BOOTER_REGULAR 0 +#define RB_BOOTER_BACKUP 1 + +#endif /* _RBCFG_H */ diff --git a/package/boot/rbcfg/src/Makefile b/package/boot/rbcfg/src/Makefile new file mode 100644 index 0000000..62c74b2 --- /dev/null +++ b/package/boot/rbcfg/src/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -Wall +OBJS = main.o cyg_crc32.o + +all: rbcfg + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +rbcfg: $(OBJS) + $(CC) -o $@ $(OBJS) + +clean: + rm -f rbcfg *.o diff --git a/package/boot/rbcfg/src/cyg_crc.h b/package/boot/rbcfg/src/cyg_crc.h new file mode 100644 index 0000000..7b59803 --- /dev/null +++ b/package/boot/rbcfg/src/cyg_crc.h @@ -0,0 +1,109 @@ +//========================================================================== +// +// crc.h +// +// Interface for the CRC algorithms. +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2002 Andrew Lunn +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): Andrew Lunn +// Contributors: Andrew Lunn +// Date: 2002-08-06 +// Purpose: +// Description: +// +// This code is part of eCos (tm). +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#ifndef _SERVICES_CRC_CRC_H_ +#define _SERVICES_CRC_CRC_H_ + +#if 0 +#include <cyg/infra/cyg_type.h> +#else +#include <stdint.h> +typedef uint32_t cyg_uint32; +typedef uint16_t cyg_uint16; +#endif + +#ifndef __externC +# ifdef __cplusplus +# define __externC extern "C" +# else +# define __externC extern +# endif +#endif + +// Compute a CRC, using the POSIX 1003 definition + +__externC cyg_uint32 +cyg_posix_crc32(unsigned char *s, int len); + +// Gary S. Brown's 32 bit CRC + +__externC cyg_uint32 +cyg_crc32(unsigned char *s, int len); + +// Gary S. Brown's 32 bit CRC, but accumulate the result from a +// previous CRC calculation + +__externC cyg_uint32 +cyg_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len); + +// Ethernet FCS Algorithm + +__externC cyg_uint32 +cyg_ether_crc32(unsigned char *s, int len); + +// Ethernet FCS algorithm, but accumulate the result from a previous +// CRC calculation. + +__externC cyg_uint32 +cyg_ether_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len); + +// 16 bit CRC with polynomial x^16+x^12+x^5+1 + +__externC cyg_uint16 +cyg_crc16(unsigned char *s, int len); + +#endif // _SERVICES_CRC_CRC_H_ + + + diff --git a/package/boot/rbcfg/src/cyg_crc32.c b/package/boot/rbcfg/src/cyg_crc32.c new file mode 100644 index 0000000..9462598 --- /dev/null +++ b/package/boot/rbcfg/src/cyg_crc32.c @@ -0,0 +1,172 @@ +//========================================================================== +// +// crc32.c +// +// Gary S. Brown's 32 bit CRC +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 2002 Gary Thomas +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas,asl +// Date: 2001-01-31 +// Purpose: +// Description: +// +// This code is part of eCos (tm). +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#if 0 +#include <cyg/crc/crc.h> +#else +#include "cyg_crc.h" +#endif + + /* ====================================================================== */ + /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ + /* code or tables extracted from it, as desired without restriction. */ + /* */ + /* First, the polynomial itself and its table of feedback terms. The */ + /* polynomial is */ + /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ + /* */ + /* ====================================================================== */ + +static const cyg_uint32 crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL + }; + +/* This is the standard Gary S. Brown's 32 bit CRC algorithm, but + accumulate the CRC into the result of a previous CRC. */ +cyg_uint32 +cyg_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len) +{ + int i; + + for (i = 0; i < len; i++) { + crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); + } + return crc32val; +} + +/* This is the standard Gary S. Brown's 32 bit CRC algorithm */ +cyg_uint32 +cyg_crc32(unsigned char *s, int len) +{ + return (cyg_crc32_accumulate(0,s,len)); +} + +/* Return a 32-bit CRC of the contents of the buffer accumulating the + result from a previous CRC calculation. This uses the Ethernet FCS + algorithm.*/ +cyg_uint32 +cyg_ether_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len) +{ + int i; + + if (s == 0) return 0L; + + crc32val = crc32val ^ 0xffffffff; + for (i = 0; i < len; i++) { + crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); + } + return crc32val ^ 0xffffffff; +} + +/* Return a 32-bit CRC of the contents of the buffer, using the + Ethernet FCS algorithm. */ +cyg_uint32 +cyg_ether_crc32(unsigned char *s, int len) +{ + return cyg_ether_crc32_accumulate(0,s,len); +} + + diff --git a/package/boot/rbcfg/src/main.c b/package/boot/rbcfg/src/main.c new file mode 100644 index 0000000..5614a6c --- /dev/null +++ b/package/boot/rbcfg/src/main.c @@ -0,0 +1,791 @@ +/* + * RouterBOOT configuration utility + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> +#include <linux/limits.h> + +#include "rbcfg.h" +#include "cyg_crc.h" + +#define RBCFG_TMP_FILE "/tmp/.rbcfg" +#define RBCFG_MTD_NAME "soft_config" + +#define RB_ERR_NOTFOUND 1 +#define RB_ERR_INVALID 2 +#define RB_ERR_NOMEM 3 +#define RB_ERR_IO 4 + +#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0])) + +struct rbcfg_ctx { + char *mtd_device; + char *tmp_file; + char *buf; + unsigned buflen; +}; + +struct rbcfg_value { + const char *name; + const char *desc; + union { + uint32_t u32; + const char *raw; + } val; +}; + +#define RBCFG_ENV_TYPE_U32 0 + +struct rbcfg_env { + const char *name; + int type; + uint16_t id; + const struct rbcfg_value *values; + int num_values; +}; + +#define CMD_FLAG_USES_CFG 0x01 + +struct rbcfg_command { + const char *command; + const char *usage; + int flags; + int (*exec)(int argc, const char *argv[]); +}; + +static void usage(void); + +/* Globals */ + +static struct rbcfg_ctx *rbcfg_ctx; +static char *rbcfg_name; + +#define CFG_U32(_name, _desc, _val) { \ + .name = (_name), \ + .desc = (_desc), \ + .val.u32 = (_val), \ +} + +static const struct rbcfg_value rbcfg_boot_delay[] = { + CFG_U32("1", "1 second", RB_BOOT_DELAY_1SEC), + CFG_U32("2", "2 seconds", RB_BOOT_DELAY_2SEC), + CFG_U32("3", "3 seconds", RB_BOOT_DELAY_3SEC), + CFG_U32("4", "4 seconds", RB_BOOT_DELAY_4SEC), + CFG_U32("5", "5 seconds", RB_BOOT_DELAY_5SEC), + CFG_U32("6", "6 seconds", RB_BOOT_DELAY_6SEC), + CFG_U32("7", "7 seconds", RB_BOOT_DELAY_7SEC), + CFG_U32("8", "8 seconds", RB_BOOT_DELAY_8SEC), + CFG_U32("9", "9 seconds", RB_BOOT_DELAY_9SEC), +}; + +static const struct rbcfg_value rbcfg_boot_device[] = { + CFG_U32("eth", "boot over Ethernet", + RB_BOOT_DEVICE_ETHER), + CFG_U32("nandeth", "boot from NAND, if fail then Ethernet", + RB_BOOT_DEVICE_NANDETH), + CFG_U32("ethnand", "boot Ethernet once, then NAND", + RB_BOOT_DEVICE_ETHONCE), + CFG_U32("nand", "boot from NAND only", + RB_BOOT_DEVICE_NANDONLY), +}; + +static const struct rbcfg_value rbcfg_boot_key[] = { + CFG_U32("any", "any key", RB_BOOT_KEY_ANY), + CFG_U32("del", "<Delete> key only", RB_BOOT_KEY_DEL), +}; + +static const struct rbcfg_value rbcfg_boot_protocol[] = { + CFG_U32("bootp", "BOOTP protocol", RB_BOOT_PROTOCOL_BOOTP), + CFG_U32("dhcp", "DHCP protocol", RB_BOOT_PROTOCOL_DHCP), +}; + +static const struct rbcfg_value rbcfg_uart_speed[] = { + CFG_U32("115200", "", RB_UART_SPEED_115200), + CFG_U32("57600", "", RB_UART_SPEED_57600), + CFG_U32("38400", "", RB_UART_SPEED_38400), + CFG_U32("19200", "", RB_UART_SPEED_19200), + CFG_U32("9600", "", RB_UART_SPEED_9600), + CFG_U32("4800", "", RB_UART_SPEED_4800), + CFG_U32("2400", "", RB_UART_SPEED_2400), + CFG_U32("1200", "", RB_UART_SPEED_1200), + CFG_U32("off", "disable console output", RB_UART_SPEED_OFF), +}; + +static const struct rbcfg_value rbcfg_cpu_mode[] = { + CFG_U32("powersave", "power save", RB_CPU_MODE_POWERSAVE), + CFG_U32("regular", "regular (better for -0c environment)", + RB_CPU_MODE_REGULAR), +}; + +static const struct rbcfg_value rbcfg_booter[] = { + CFG_U32("regular", "load regular booter", RB_BOOTER_REGULAR), + CFG_U32("backup", "force backup-booter loading", RB_BOOTER_BACKUP), +}; + +static const struct rbcfg_env rbcfg_envs[] = { + { + .name = "boot_delay", + .id = RB_ID_BOOT_DELAY, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_boot_delay, + .num_values = ARRAY_SIZE(rbcfg_boot_delay), + }, { + .name = "boot_device", + .id = RB_ID_BOOT_DEVICE, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_boot_device, + .num_values = ARRAY_SIZE(rbcfg_boot_device), + }, { + .name = "boot_key", + .id = RB_ID_BOOT_KEY, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_boot_key, + .num_values = ARRAY_SIZE(rbcfg_boot_key), + }, { + .name = "boot_protocol", + .id = RB_ID_BOOT_PROTOCOL, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_boot_protocol, + .num_values = ARRAY_SIZE(rbcfg_boot_protocol), + }, { + .name = "booter", + .id = RB_ID_BOOTER, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_booter, + .num_values = ARRAY_SIZE(rbcfg_booter), + }, { + .name = "cpu_mode", + .id = RB_ID_CPU_MODE, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_cpu_mode, + .num_values = ARRAY_SIZE(rbcfg_cpu_mode), + }, { + .name = "uart_speed", + .id = RB_ID_UART_SPEED, + .type = RBCFG_ENV_TYPE_U32, + .values = rbcfg_uart_speed, + .num_values = ARRAY_SIZE(rbcfg_uart_speed), + } +}; + +static inline uint16_t +get_u16(const void *buf) +{ + const uint8_t *p = buf; + + return ((uint16_t) p[1] + ((uint16_t) p[0] << 8)); +} + +static inline uint32_t +get_u32(const void *buf) +{ + const uint8_t *p = buf; + + return ((uint32_t) p[3] + ((uint32_t) p[2] << 8) + + ((uint32_t) p[1] << 16) + ((uint32_t) p[0] << 24)); +} + +static inline void +put_u32(void *buf, uint32_t val) +{ + uint8_t *p = buf; + + p[3] = val & 0xff; + p[2] = (val >> 8) & 0xff; + p[1] = (val >> 16) & 0xff; + p[0] = (val >> 24) & 0xff; +} + +static int +rbcfg_find_tag(struct rbcfg_ctx *ctx, uint16_t tag_id, uint16_t *tag_len, + void **tag_data) +{ + uint16_t id; + uint16_t len; + char *buf = ctx->buf; + unsigned int buflen = ctx->buflen; + int ret = RB_ERR_NOTFOUND; + + /* skip magic and CRC value */ + buf += 8; + buflen -= 8; + + while (buflen > 2) { + len = get_u16(buf); + buf += 2; + buflen -= 2; + + if (buflen < 2) + break; + + id = get_u16(buf); + buf += 2; + buflen -= 2; + + if (id == RB_ID_TERMINATOR) + break; + + if (buflen < len) + break; + + if (id == tag_id) { + *tag_len = len; + *tag_data = buf; + ret = 0; + break; + } + + buf += len; + buflen -= len; + } + + if (ret) + fprintf(stderr, "no tag found with id=%u\n", tag_id); + + return ret; +} + +static int +rbcfg_get_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t *val) +{ + void *tag_data; + uint16_t tag_len; + int err; + + err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data); + if (err) + return err; + + *val = get_u32(tag_data); + return 0; +} + +static int +rbcfg_set_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t val) +{ + void *tag_data; + uint16_t tag_len; + int err; + + err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data); + if (err) + return err; + + put_u32(tag_data, val); + return 0; +} + +char *rbcfg_find_mtd(const char *name, int *erase_size) +{ + FILE *f; + int mtd_num; + char dev[PATH_MAX]; + char *ret = NULL; + struct stat s; + int err; + + f = fopen("/proc/mtd", "r"); + if (!f) + return NULL; + + while (1) { + char *p; + p = fgets(dev, sizeof(dev), f); + if (!p) + break; + + if (!strstr(dev, name)) + continue; + + err = sscanf(dev, "mtd%d: %08x", &mtd_num, erase_size); + if (err != 2) + break; + + sprintf(dev, "/dev/mtdblock%d", mtd_num); + err = stat(dev, &s); + if (err < 0) + break; + + if ((s.st_mode & S_IFBLK) == 0) + break; + + ret = malloc(strlen(dev) + 1); + if (ret == NULL) + break; + + strncpy(ret, dev, strlen(dev) + 1); + break; + } + + fclose(f); + return ret; +} + +static int +rbcfg_check_tmp(struct rbcfg_ctx *ctx) +{ + struct stat s; + int err; + + err = stat(ctx->tmp_file, &s); + if (err < 0) + return 0; + + if ((s.st_mode & S_IFREG) == 0) + return 0; + + if (s.st_size != ctx->buflen) + return 0; + + return 1; +} + +static int +rbcfg_load(struct rbcfg_ctx *ctx) +{ + uint32_t magic; + uint32_t crc_orig, crc; + char *name; + int tmp; + int fd; + int err; + + tmp = rbcfg_check_tmp(ctx); + name = (tmp) ? ctx->tmp_file : ctx->mtd_device; + + fd = open(name, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "unable to open %s\n", name); + err = RB_ERR_IO; + goto err; + } + + err = read(fd, ctx->buf, ctx->buflen); + if (err != ctx->buflen) { + fprintf(stderr, "unable to read from %s\n", name); + err = RB_ERR_IO; + goto err_close; + } + + magic = get_u32(ctx->buf); + if (magic != RB_MAGIC_SOFT) { + fprintf(stderr, "invalid configuration\n"); + err = RB_ERR_INVALID; + goto err_close; + } + + crc_orig = get_u32(ctx->buf + 4); + put_u32(ctx->buf + 4, 0); + crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen); + if (crc != crc_orig) { + fprintf(stderr, "configuration has CRC error\n"); + err = RB_ERR_INVALID; + goto err_close; + } + + err = 0; + + err_close: + close(fd); + err: + return err; +} + +static int +rbcfg_open() +{ + char *mtd_device; + struct rbcfg_ctx *ctx; + int buflen; + int err; + + mtd_device = rbcfg_find_mtd(RBCFG_MTD_NAME, &buflen); + if (!mtd_device) { + fprintf(stderr, "unable to find configuration\n"); + return RB_ERR_NOTFOUND; + } + + ctx = malloc(sizeof(struct rbcfg_ctx) + buflen); + if (ctx == NULL) { + err = RB_ERR_NOMEM; + goto err_free_mtd; + } + + ctx->mtd_device = mtd_device; + ctx->tmp_file = RBCFG_TMP_FILE; + ctx->buflen = buflen; + ctx->buf = (char *) &ctx[1]; + + err = rbcfg_load(ctx); + if (err) + goto err_free_ctx; + + rbcfg_ctx = ctx; + return 0; + + err_free_ctx: + free(ctx); + err_free_mtd: + free(mtd_device); + return err; +} + +static int +rbcfg_update(int tmp) +{ + struct rbcfg_ctx *ctx = rbcfg_ctx; + char *name; + uint32_t crc; + int fd; + int err; + + put_u32(ctx->buf, RB_MAGIC_SOFT); + put_u32(ctx->buf + 4, 0); + crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen); + put_u32(ctx->buf + 4, crc); + + name = (tmp) ? ctx->tmp_file : ctx->mtd_device; + fd = open(name, O_WRONLY | O_CREAT); + if (fd < 0) { + fprintf(stderr, "unable to open %s for writing\n", name); + err = RB_ERR_IO; + goto out; + } + + err = write(fd, ctx->buf, ctx->buflen); + if (err != ctx->buflen) { + err = RB_ERR_IO; + goto out_close; + } + + fsync(fd); + err = 0; + + out_close: + close(fd); + out: + return err; +} + +static void +rbcfg_close(void) +{ + struct rbcfg_ctx *ctx; + + ctx = rbcfg_ctx; + free(ctx->mtd_device); + free(ctx); +} + +static const struct rbcfg_value * +rbcfg_env_find(const struct rbcfg_env *env, const char *name) +{ + unsigned i; + + for (i = 0; i < env->num_values; i++) { + const struct rbcfg_value *v = &env->values[i]; + + if (strcmp(v->name, name) == 0) + return v; + } + + return NULL; +} + +static const struct rbcfg_value * +rbcfg_env_find_u32(const struct rbcfg_env *env, uint32_t val) +{ + unsigned i; + + for (i = 0; i < env->num_values; i++) { + const struct rbcfg_value *v = &env->values[i]; + + if (v->val.u32 == val) + return v; + } + + return NULL; +} + +static const char * +rbcfg_env_get_u32(const struct rbcfg_env *env) +{ + const struct rbcfg_value *v; + uint32_t val; + int err; + + err = rbcfg_get_u32(rbcfg_ctx, env->id, &val); + if (err) + return NULL; + + v = rbcfg_env_find_u32(env, val); + if (v == NULL) { + fprintf(stderr, "unknown value %08x found for %s\n", + val, env->name); + return NULL; + } + + return v->name; +} + +static int +rbcfg_env_set_u32(const struct rbcfg_env *env, const char *data) +{ + const struct rbcfg_value *v; + int err; + + v = rbcfg_env_find(env, data); + if (v == NULL) { + fprintf(stderr, "invalid value '%s'\n", data); + return RB_ERR_INVALID; + } + + err = rbcfg_set_u32(rbcfg_ctx, env->id, v->val.u32); + return err; +} + +static const char * +rbcfg_env_get(const struct rbcfg_env *env) +{ + const char *ret = NULL; + + switch (env->type) { + case RBCFG_ENV_TYPE_U32: + ret = rbcfg_env_get_u32(env); + break; + } + + return ret; +} + +static int +rbcfg_env_set(const struct rbcfg_env *env, const char *data) +{ + int ret = 0; + + switch (env->type) { + case RBCFG_ENV_TYPE_U32: + ret = rbcfg_env_set_u32(env, data); + break; + } + + return ret; +} + +static int +rbcfg_cmd_apply(int argc, const char *argv[]) +{ + return rbcfg_update(0); +} + +static int +rbcfg_cmd_help(int argc, const char *argv[]) +{ + usage(); + return 0; +} + +static int +rbcfg_cmd_get(int argc, const char *argv[]) +{ + int err = RB_ERR_NOTFOUND; + int i; + + if (argc != 1) { + usage(); + return RB_ERR_INVALID; + } + + for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) { + const struct rbcfg_env *env = &rbcfg_envs[i]; + const char *value; + + if (strcmp(env->name, argv[0])) + continue; + + value = rbcfg_env_get(env); + if (value) { + fprintf(stdout, "%s\n", value); + err = 0; + } + break; + } + + return err; +} + +static int +rbcfg_cmd_set(int argc, const char *argv[]) +{ + int err = RB_ERR_INVALID; + int i; + + if (argc != 2) { + /* not enough parameters */ + usage(); + return RB_ERR_INVALID; + } + + for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) { + const struct rbcfg_env *env = &rbcfg_envs[i]; + + if (strcmp(env->name, argv[0])) + continue; + + err = rbcfg_env_set(env, argv[1]); + if (err == 0) + err = rbcfg_update(1); + break; + } + + return err; +} + +static int +rbcfg_cmd_show(int argc, const char *argv[]) +{ + int i; + + if (argc != 0) { + usage(); + return RB_ERR_INVALID; + } + + for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) { + const struct rbcfg_env *env = &rbcfg_envs[i]; + const char *value; + + value = rbcfg_env_get(env); + if (value) + fprintf(stdout, "%s=%s\n", env->name, value); + } + + return 0; +} + +static const struct rbcfg_command rbcfg_commands[] = { + { + .command = "apply", + .usage = "apply\n" + "\t- write configuration to the mtd device", + .flags = CMD_FLAG_USES_CFG, + .exec = rbcfg_cmd_apply, + }, { + .command = "help", + .usage = "help\n" + "\t- show this screen", + .exec = rbcfg_cmd_help, + }, { + .command = "get", + .usage = "get <name>\n" + "\t- get value of the configuration option <name>", + .flags = CMD_FLAG_USES_CFG, + .exec = rbcfg_cmd_get, + }, { + .command = "set", + .usage = "set <name> <value>\n" + "\t- set value of the configuration option <name> to <value>", + .flags = CMD_FLAG_USES_CFG, + .exec = rbcfg_cmd_set, + }, { + .command = "show", + .usage = "show\n" + "\t- show value of all configuration options", + .flags = CMD_FLAG_USES_CFG, + .exec = rbcfg_cmd_show, + } +}; + +static void +usage(void) +{ + char buf[255]; + int len; + int i; + + fprintf(stderr, "Usage: %s <command>\n", rbcfg_name); + + fprintf(stderr, "\nCommands:\n"); + for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) { + const struct rbcfg_command *cmd; + cmd = &rbcfg_commands[i]; + + len = snprintf(buf, sizeof(buf), cmd->usage); + buf[len] = '\0'; + fprintf(stderr, "%s\n", buf); + } + + fprintf(stderr, "\nConfiguration options:\n"); + for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) { + const struct rbcfg_env *env; + int j; + + env = &rbcfg_envs[i]; + fprintf(stderr, "\n%s:\n", env->name); + for (j = 0; j < env->num_values; j++) { + const struct rbcfg_value *v = &env->values[j]; + fprintf(stderr, "\t%-12s %s\n", v->name, v->desc); + } + } + fprintf(stderr, "\n"); +} + +int main(int argc, const char *argv[]) +{ + const struct rbcfg_command *cmd = NULL; + int ret; + int i; + + rbcfg_name = (char *) argv[0]; + + if (argc < 2) { + usage(); + return EXIT_FAILURE; + } + + for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) { + if (strcmp(rbcfg_commands[i].command, argv[1]) == 0) { + cmd = &rbcfg_commands[i]; + break; + } + } + + if (cmd == NULL) { + fprintf(stderr, "unknown command '%s'\n", argv[1]); + usage(); + return EXIT_FAILURE; + } + + argc -= 2; + argv += 2; + + if (cmd->flags & CMD_FLAG_USES_CFG) { + ret = rbcfg_open(); + if (ret) + return EXIT_FAILURE; + } + + ret = cmd->exec(argc, argv); + + if (cmd->flags & CMD_FLAG_USES_CFG) + rbcfg_close(); + + if (ret) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/package/boot/rbcfg/src/rbcfg.h b/package/boot/rbcfg/src/rbcfg.h new file mode 100644 index 0000000..899161a --- /dev/null +++ b/package/boot/rbcfg/src/rbcfg.h @@ -0,0 +1,75 @@ +/* + * Mikrotik's RouterBOOT configuration defines + * + * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#ifndef _RBCFG_H +#define _RBCFG_H + +/* + * Magic numbers + */ +#define RB_MAGIC_SOFT 0x74666f53 /* 'Soft' */ + +/* + * ID values for Software settings + */ +#define RB_ID_TERMINATOR 0 +#define RB_ID_UART_SPEED 1 +#define RB_ID_BOOT_DELAY 2 +#define RB_ID_BOOT_DEVICE 3 +#define RB_ID_BOOT_KEY 4 +#define RB_ID_CPU_MODE 5 +#define RB_ID_FW_VERSION 6 +#define RB_ID_SOFT_07 7 +#define RB_ID_SOFT_08 8 +#define RB_ID_BOOT_PROTOCOL 9 +#define RB_ID_SOFT_10 10 +#define RB_ID_SOFT_11 11 +#define RB_ID_BOOTER 13 + +#define RB_UART_SPEED_115200 0 +#define RB_UART_SPEED_57600 1 +#define RB_UART_SPEED_38400 2 +#define RB_UART_SPEED_19200 3 +#define RB_UART_SPEED_9600 4 +#define RB_UART_SPEED_4800 5 +#define RB_UART_SPEED_2400 6 +#define RB_UART_SPEED_1200 7 +#define RB_UART_SPEED_OFF 8 + +#define RB_BOOT_DELAY_1SEC 1 +#define RB_BOOT_DELAY_2SEC 2 +#define RB_BOOT_DELAY_3SEC 3 +#define RB_BOOT_DELAY_4SEC 4 +#define RB_BOOT_DELAY_5SEC 5 +#define RB_BOOT_DELAY_6SEC 6 +#define RB_BOOT_DELAY_7SEC 7 +#define RB_BOOT_DELAY_8SEC 8 +#define RB_BOOT_DELAY_9SEC 9 + +#define RB_BOOT_DEVICE_ETHER 0 +#define RB_BOOT_DEVICE_NANDETH 1 +#define RB_BOOT_DEVICE_CFCARD 2 +#define RB_BOOT_DEVICE_ETHONCE 3 +#define RB_BOOT_DEVICE_NANDONLY 5 + +#define RB_BOOT_KEY_ANY 0 +#define RB_BOOT_KEY_DEL 1 + +#define RB_CPU_MODE_POWERSAVE 0 +#define RB_CPU_MODE_REGULAR 1 + +#define RB_BOOT_PROTOCOL_BOOTP 0 +#define RB_BOOT_PROTOCOL_DHCP 1 + +#define RB_BOOTER_REGULAR 0 +#define RB_BOOTER_BACKUP 1 + +#endif /* _RBCFG_H */ diff --git a/package/boot/uboot-ar71xx/.svn/entries b/package/boot/uboot-ar71xx/.svn/entries new file mode 100644 index 0000000..c22743c --- /dev/null +++ b/package/boot/uboot-ar71xx/.svn/entries @@ -0,0 +1,68 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +0bd109b1804aa08c7b5d06154eec7560 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +2105 + diff --git a/package/boot/uboot-ar71xx/.svn/prop-base/Makefile.svn-base b/package/boot/uboot-ar71xx/.svn/prop-base/Makefile.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/.svn/prop-base/Makefile.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/.svn/text-base/Makefile.svn-base b/package/boot/uboot-ar71xx/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..ab692d5 --- /dev/null +++ b/package/boot/uboot-ar71xx/.svn/text-base/Makefile.svn-base @@ -0,0 +1,90 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2010.03 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:= +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/nbg460n_550n_550nh + TITLE:=U-boot for the NBG460N/550N/550NH routers +endef + +UBOOTS:=nbg460n_550n_550nh + +define Package/uboot/template +define Package/uboot-ar71xx-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + TITLE:=$(2) + DEPENDS:=@TARGET_ar71xx + URL:=http://www.denx.de/wiki/U-Boot + DEFAULT:=y if (TARGET_ar71xx_generic_NBG_460N_550N_550NH || TARGET_ar71xx_generic_Default || CONFIG_TARGET_ar71xx_generic_Minimal) + VARIANT:=$(1) +endef +endef + +define BuildUbootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Prepare + $(call Build/Prepare/Default) + $(CP) ./files/* $(PKG_BUILD_DIR) + find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf +endef + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/template +define Package/uboot-ar71xx-$(1)/install + $(INSTALL_DIR) $$(1) + $(CP) $(PKG_BUILD_DIR)/u-boot.bin $(BIN_DIR)/$(2) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(SUBTARGET)-$(u)-u-boot.bin)) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUbootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-ar71xx-$(u))) \ +) diff --git a/package/boot/uboot-ar71xx/Makefile b/package/boot/uboot-ar71xx/Makefile new file mode 100644 index 0000000..ab692d5 --- /dev/null +++ b/package/boot/uboot-ar71xx/Makefile @@ -0,0 +1,90 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2010.03 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:= +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/nbg460n_550n_550nh + TITLE:=U-boot for the NBG460N/550N/550NH routers +endef + +UBOOTS:=nbg460n_550n_550nh + +define Package/uboot/template +define Package/uboot-ar71xx-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + TITLE:=$(2) + DEPENDS:=@TARGET_ar71xx + URL:=http://www.denx.de/wiki/U-Boot + DEFAULT:=y if (TARGET_ar71xx_generic_NBG_460N_550N_550NH || TARGET_ar71xx_generic_Default || CONFIG_TARGET_ar71xx_generic_Minimal) + VARIANT:=$(1) +endef +endef + +define BuildUbootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Prepare + $(call Build/Prepare/Default) + $(CP) ./files/* $(PKG_BUILD_DIR) + find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf +endef + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/template +define Package/uboot-ar71xx-$(1)/install + $(INSTALL_DIR) $$(1) + $(CP) $(PKG_BUILD_DIR)/u-boot.bin $(BIN_DIR)/$(2) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(SUBTARGET)-$(u)-u-boot.bin)) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUbootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-ar71xx-$(u))) \ +) diff --git a/package/boot/uboot-ar71xx/files/.svn/entries b/package/boot/uboot-ar71xx/files/.svn/entries new file mode 100644 index 0000000..11e092f --- /dev/null +++ b/package/boot/uboot-ar71xx/files/.svn/entries @@ -0,0 +1,40 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +include +dir + +board +dir + +cpu +dir + +drivers +dir + diff --git a/package/boot/uboot-ar71xx/files/board/.svn/entries b/package/boot/uboot-ar71xx/files/board/.svn/entries new file mode 100644 index 0000000..fe48131 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/board +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +zyxel +dir + diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/.svn/entries b/package/boot/uboot-ar71xx/files/board/zyxel/.svn/entries new file mode 100644 index 0000000..2067997 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/board/zyxel +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +nbg460n +dir + diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/entries b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/entries new file mode 100644 index 0000000..2cd7eba --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +nbg460n.c +file + + + + +2013-03-17T12:13:21.000000Z +4ca6c195407e477c7ce5e894b0047bd7 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +2519 + +u-boot.lds +file + + + + +2013-03-17T12:13:21.000000Z +189327e68f6732474873394c31ecb392 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +644 + +config.mk +file + + + + +2013-03-17T12:13:21.000000Z +e0a9c9382bb06ca19e6e6277bd6cb25e +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +23 + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +adb668f790f345afd4d82777c8bd28e0 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +1403 + +lowlevel_init.S +file + + + + +2013-03-17T12:13:21.000000Z +6bcc57bddec47e9957d0b00bd2755913 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +1089 + diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/Makefile.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/Makefile.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/Makefile.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/config.mk.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/config.mk.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/config.mk.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/nbg460n.c.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/nbg460n.c.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/prop-base/nbg460n.c.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/Makefile.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..b0a385b --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/Makefile.svn-base @@ -0,0 +1,46 @@ +# +# (C) Copyright 2003-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS-y += $(BOARD).o +SOBJS-y += lowlevel_init.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/config.mk.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/config.mk.svn-base new file mode 100644 index 0000000..e042e78 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/config.mk.svn-base @@ -0,0 +1 @@ +TEXT_BASE = 0x81E00000 diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/lowlevel_init.S.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/lowlevel_init.S.svn-base new file mode 100644 index 0000000..83084c8 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/lowlevel_init.S.svn-base @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <version.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> + + + +.globl lowlevel_init +/* + All done by Bootbase, nothing to do +*/ +lowlevel_init: + jr ra + nop + diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/nbg460n.c.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/nbg460n.c.svn-base new file mode 100644 index 0000000..03a479d --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/nbg460n.c.svn-base @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <netdev.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/reboot.h> +#include <asm/ar71xx.h> +#include <asm/ar71xx_gpio.h> + +#define NBG460N_WAN_LED 19 + +phys_size_t initdram(int board_type) +{ + return (32*1024*1024); +} + +int checkboard(void) +{ + // Set pin 19 to 1, to stop WAN LED blinking + ar71xx_setpindir(NBG460N_WAN_LED, 1); + ar71xx_setpin(NBG460N_WAN_LED, 1); + + printf("U-boot on Zyxel NBG460N\n"); + return 0; +} + +void _machine_restart(void) +{ + for (;;) { + writel((RESET_MODULE_FULL_CHIP | RESET_MODULE_DDR), + KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE)); + readl(KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE)); + } +} + +int board_eth_init(bd_t *bis) +{ + char *phynames[] = {RTL8366_DEVNAME, RTL8366_DEVNAME}; + u16 phyids[] = {RTL8366_LANPHY_ID, RTL8366_WANPHY_ID}; + u16 phyfixed[] = {1, 0}; + + if (ag71xx_register(bis, phynames, phyids, phyfixed) <= 0) + return -1; + + if (rtl8366s_initialize()) + return -1; + + if (rtl8366_mii_register(bis)) + return -1; + + return 0; +} + +int misc_init_r(void) { + uint8_t macaddr[6]; + uint8_t enetaddr[6]; + + debug("Testing mac addresses\n"); + + memcpy(macaddr, (uint8_t *) CONFIG_ETHADDR_ADDR, 6); + + if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { + debug("Setting eth0 mac addr to %pM\n", macaddr); + eth_setenv_enetaddr("ethaddr", macaddr); + } + + if (!eth_getenv_enetaddr("eth1addr", enetaddr)) { + macaddr[5] += 1; + debug("Setting eth1 mac addr to %pM\n", macaddr); + eth_setenv_enetaddr("eth1addr", macaddr); + } + + return 0; +} diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/u-boot.lds.svn-base b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/u-boot.lds.svn-base new file mode 100644 index 0000000..8dc2b76 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/.svn/text-base/u-boot.lds.svn-base @@ -0,0 +1,42 @@ +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips") +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .sdata : { *(.sdata) } + + _gp = ALIGN(16); + + __got_start = .; + .got : { *(.got) } + __got_end = .; + + .sdata : { *(.sdata) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + uboot_end_data = .; + num_got_entries = (__got_end - __got_start) >> 2; + + . = ALIGN(4); + .sbss : { *(.sbss) } + .bss : { *(.bss) } + uboot_end = .; +} diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile new file mode 100644 index 0000000..b0a385b --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2003-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS-y += $(BOARD).o +SOBJS-y += lowlevel_init.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk new file mode 100644 index 0000000..e042e78 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk @@ -0,0 +1 @@ +TEXT_BASE = 0x81E00000 diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S new file mode 100644 index 0000000..83084c8 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <version.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> + + + +.globl lowlevel_init +/* + All done by Bootbase, nothing to do +*/ +lowlevel_init: + jr ra + nop + diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c new file mode 100644 index 0000000..03a479d --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <netdev.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/reboot.h> +#include <asm/ar71xx.h> +#include <asm/ar71xx_gpio.h> + +#define NBG460N_WAN_LED 19 + +phys_size_t initdram(int board_type) +{ + return (32*1024*1024); +} + +int checkboard(void) +{ + // Set pin 19 to 1, to stop WAN LED blinking + ar71xx_setpindir(NBG460N_WAN_LED, 1); + ar71xx_setpin(NBG460N_WAN_LED, 1); + + printf("U-boot on Zyxel NBG460N\n"); + return 0; +} + +void _machine_restart(void) +{ + for (;;) { + writel((RESET_MODULE_FULL_CHIP | RESET_MODULE_DDR), + KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE)); + readl(KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE)); + } +} + +int board_eth_init(bd_t *bis) +{ + char *phynames[] = {RTL8366_DEVNAME, RTL8366_DEVNAME}; + u16 phyids[] = {RTL8366_LANPHY_ID, RTL8366_WANPHY_ID}; + u16 phyfixed[] = {1, 0}; + + if (ag71xx_register(bis, phynames, phyids, phyfixed) <= 0) + return -1; + + if (rtl8366s_initialize()) + return -1; + + if (rtl8366_mii_register(bis)) + return -1; + + return 0; +} + +int misc_init_r(void) { + uint8_t macaddr[6]; + uint8_t enetaddr[6]; + + debug("Testing mac addresses\n"); + + memcpy(macaddr, (uint8_t *) CONFIG_ETHADDR_ADDR, 6); + + if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { + debug("Setting eth0 mac addr to %pM\n", macaddr); + eth_setenv_enetaddr("ethaddr", macaddr); + } + + if (!eth_getenv_enetaddr("eth1addr", enetaddr)) { + macaddr[5] += 1; + debug("Setting eth1 mac addr to %pM\n", macaddr); + eth_setenv_enetaddr("eth1addr", macaddr); + } + + return 0; +} diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds new file mode 100644 index 0000000..8dc2b76 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds @@ -0,0 +1,42 @@ +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips") +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .sdata : { *(.sdata) } + + _gp = ALIGN(16); + + __got_start = .; + .got : { *(.got) } + __got_end = .; + + .sdata : { *(.sdata) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + uboot_end_data = .; + num_got_entries = (__got_end - __got_start) >> 2; + + . = ALIGN(4); + .sbss : { *(.sbss) } + .bss : { *(.bss) } + uboot_end = .; +} diff --git a/package/boot/uboot-ar71xx/files/cpu/.svn/entries b/package/boot/uboot-ar71xx/files/cpu/.svn/entries new file mode 100644 index 0000000..b2aff8b --- /dev/null +++ b/package/boot/uboot-ar71xx/files/cpu/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/cpu +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +mips +dir + diff --git a/package/boot/uboot-ar71xx/files/cpu/mips/.svn/entries b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/entries new file mode 100644 index 0000000..d93fd35 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/cpu/mips +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +ar71xx_serial.c +file + + + + +2013-03-17T12:13:21.000000Z +f5711b1fa72d76b55261c16e7d73d225 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +4579 + diff --git a/package/boot/uboot-ar71xx/files/cpu/mips/.svn/prop-base/ar71xx_serial.c.svn-base b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/prop-base/ar71xx_serial.c.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/prop-base/ar71xx_serial.c.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/cpu/mips/.svn/text-base/ar71xx_serial.c.svn-base b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/text-base/ar71xx_serial.c.svn-base new file mode 100644 index 0000000..f093318 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/cpu/mips/.svn/text-base/ar71xx_serial.c.svn-base @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm/addrspace.h> +#include <asm/types.h> +#include <config.h> +#include <asm/ar71xx.h> + +#define REG_SIZE 4 + +/* === END OF CONFIG === */ + +/* register offset */ +#define OFS_RCV_BUFFER (0*REG_SIZE) +#define OFS_TRANS_HOLD (0*REG_SIZE) +#define OFS_SEND_BUFFER (0*REG_SIZE) +#define OFS_INTR_ENABLE (1*REG_SIZE) +#define OFS_INTR_ID (2*REG_SIZE) +#define OFS_DATA_FORMAT (3*REG_SIZE) +#define OFS_LINE_CONTROL (3*REG_SIZE) +#define OFS_MODEM_CONTROL (4*REG_SIZE) +#define OFS_RS232_OUTPUT (4*REG_SIZE) +#define OFS_LINE_STATUS (5*REG_SIZE) +#define OFS_MODEM_STATUS (6*REG_SIZE) +#define OFS_RS232_INPUT (6*REG_SIZE) +#define OFS_SCRATCH_PAD (7*REG_SIZE) + +#define OFS_DIVISOR_LSB (0*REG_SIZE) +#define OFS_DIVISOR_MSB (1*REG_SIZE) + +#define UART16550_READ(y) readl(KSEG1ADDR(AR71XX_UART_BASE+y)) +#define UART16550_WRITE(x, z) writel(z, KSEG1ADDR((AR71XX_UART_BASE+x))) + +void +ar71xx_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq) +{ +#ifndef CONFIG_AR91XX + u32 pll, pll_div, cpu_div, ahb_div, ddr_div, freq; + + pll = readl(KSEG1ADDR(AR71XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE)); + + pll_div = + ((pll & AR71XX_PLL_DIV_MASK) >> AR71XX_PLL_DIV_SHIFT) + 1; + + cpu_div = + ((pll & AR71XX_CPU_DIV_MASK) >> AR71XX_CPU_DIV_SHIFT) + 1; + + ddr_div = + ((pll & AR71XX_DDR_DIV_MASK) >> AR71XX_DDR_DIV_SHIFT) + 1; + + ahb_div = + (((pll & AR71XX_AHB_DIV_MASK) >> AR71XX_AHB_DIV_SHIFT) + 1)*2; + + freq = pll_div * 40000000; + + if (cpu_freq) + *cpu_freq = freq/cpu_div; + + if (ddr_freq) + *ddr_freq = freq/ddr_div; + + if (ahb_freq) + *ahb_freq = (freq/cpu_div)/ahb_div; + +#else + u32 pll, pll_div, ahb_div, ddr_div, freq; + + pll = readl(KSEG1ADDR(AR91XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE)); + + pll_div = + ((pll & AR91XX_PLL_DIV_MASK) >> AR91XX_PLL_DIV_SHIFT); + + ddr_div = + ((pll & AR91XX_DDR_DIV_MASK) >> AR91XX_DDR_DIV_SHIFT) + 1; + + ahb_div = + (((pll & AR91XX_AHB_DIV_MASK) >> AR91XX_AHB_DIV_SHIFT) + 1)*2; + + freq = pll_div * 5000000; + + if (cpu_freq) + *cpu_freq = freq; + + if (ddr_freq) + *ddr_freq = freq/ddr_div; + + if (ahb_freq) + *ahb_freq = freq/ahb_div; +#endif +} + + +int serial_init(void) +{ + u32 div; + u32 ahb_freq = 100000000; + + ar71xx_sys_frequency (0, 0, &ahb_freq); + div = ahb_freq/(16 * CONFIG_BAUDRATE); + + // enable uart pins +#ifndef CONFIG_AR91XX + writel(AR71XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC)); +#else + writel(AR91XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC)); +#endif + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + UART16550_WRITE(OFS_DIVISOR_LSB, (div & 0xff)); + UART16550_WRITE(OFS_DIVISOR_MSB, ((div >> 8) & 0xff)); + + /* clear DIAB bit*/ + UART16550_WRITE(OFS_LINE_CONTROL, 0x00); + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, 0x3); + + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + return 0; +} + +int serial_tstc (void) +{ + return(UART16550_READ(OFS_LINE_STATUS) & 0x1); +} + +int serial_getc(void) +{ + while(!serial_tstc()); + + return UART16550_READ(OFS_RCV_BUFFER); +} + + +void serial_putc(const char byte) +{ + if (byte == '\n') serial_putc ('\r'); + + while (((UART16550_READ(OFS_LINE_STATUS)) & 0x20) == 0x0); + UART16550_WRITE(OFS_SEND_BUFFER, byte); +} + +void serial_setbrg (void) +{ +} + +void serial_puts (const char *s) +{ + while (*s) + { + serial_putc (*s++); + } +} diff --git a/package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c b/package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c new file mode 100644 index 0000000..f093318 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm/addrspace.h> +#include <asm/types.h> +#include <config.h> +#include <asm/ar71xx.h> + +#define REG_SIZE 4 + +/* === END OF CONFIG === */ + +/* register offset */ +#define OFS_RCV_BUFFER (0*REG_SIZE) +#define OFS_TRANS_HOLD (0*REG_SIZE) +#define OFS_SEND_BUFFER (0*REG_SIZE) +#define OFS_INTR_ENABLE (1*REG_SIZE) +#define OFS_INTR_ID (2*REG_SIZE) +#define OFS_DATA_FORMAT (3*REG_SIZE) +#define OFS_LINE_CONTROL (3*REG_SIZE) +#define OFS_MODEM_CONTROL (4*REG_SIZE) +#define OFS_RS232_OUTPUT (4*REG_SIZE) +#define OFS_LINE_STATUS (5*REG_SIZE) +#define OFS_MODEM_STATUS (6*REG_SIZE) +#define OFS_RS232_INPUT (6*REG_SIZE) +#define OFS_SCRATCH_PAD (7*REG_SIZE) + +#define OFS_DIVISOR_LSB (0*REG_SIZE) +#define OFS_DIVISOR_MSB (1*REG_SIZE) + +#define UART16550_READ(y) readl(KSEG1ADDR(AR71XX_UART_BASE+y)) +#define UART16550_WRITE(x, z) writel(z, KSEG1ADDR((AR71XX_UART_BASE+x))) + +void +ar71xx_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq) +{ +#ifndef CONFIG_AR91XX + u32 pll, pll_div, cpu_div, ahb_div, ddr_div, freq; + + pll = readl(KSEG1ADDR(AR71XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE)); + + pll_div = + ((pll & AR71XX_PLL_DIV_MASK) >> AR71XX_PLL_DIV_SHIFT) + 1; + + cpu_div = + ((pll & AR71XX_CPU_DIV_MASK) >> AR71XX_CPU_DIV_SHIFT) + 1; + + ddr_div = + ((pll & AR71XX_DDR_DIV_MASK) >> AR71XX_DDR_DIV_SHIFT) + 1; + + ahb_div = + (((pll & AR71XX_AHB_DIV_MASK) >> AR71XX_AHB_DIV_SHIFT) + 1)*2; + + freq = pll_div * 40000000; + + if (cpu_freq) + *cpu_freq = freq/cpu_div; + + if (ddr_freq) + *ddr_freq = freq/ddr_div; + + if (ahb_freq) + *ahb_freq = (freq/cpu_div)/ahb_div; + +#else + u32 pll, pll_div, ahb_div, ddr_div, freq; + + pll = readl(KSEG1ADDR(AR91XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE)); + + pll_div = + ((pll & AR91XX_PLL_DIV_MASK) >> AR91XX_PLL_DIV_SHIFT); + + ddr_div = + ((pll & AR91XX_DDR_DIV_MASK) >> AR91XX_DDR_DIV_SHIFT) + 1; + + ahb_div = + (((pll & AR91XX_AHB_DIV_MASK) >> AR91XX_AHB_DIV_SHIFT) + 1)*2; + + freq = pll_div * 5000000; + + if (cpu_freq) + *cpu_freq = freq; + + if (ddr_freq) + *ddr_freq = freq/ddr_div; + + if (ahb_freq) + *ahb_freq = freq/ahb_div; +#endif +} + + +int serial_init(void) +{ + u32 div; + u32 ahb_freq = 100000000; + + ar71xx_sys_frequency (0, 0, &ahb_freq); + div = ahb_freq/(16 * CONFIG_BAUDRATE); + + // enable uart pins +#ifndef CONFIG_AR91XX + writel(AR71XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC)); +#else + writel(AR91XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC)); +#endif + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + UART16550_WRITE(OFS_DIVISOR_LSB, (div & 0xff)); + UART16550_WRITE(OFS_DIVISOR_MSB, ((div >> 8) & 0xff)); + + /* clear DIAB bit*/ + UART16550_WRITE(OFS_LINE_CONTROL, 0x00); + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, 0x3); + + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + return 0; +} + +int serial_tstc (void) +{ + return(UART16550_READ(OFS_LINE_STATUS) & 0x1); +} + +int serial_getc(void) +{ + while(!serial_tstc()); + + return UART16550_READ(OFS_RCV_BUFFER); +} + + +void serial_putc(const char byte) +{ + if (byte == '\n') serial_putc ('\r'); + + while (((UART16550_READ(OFS_LINE_STATUS)) & 0x20) == 0x0); + UART16550_WRITE(OFS_SEND_BUFFER, byte); +} + +void serial_setbrg (void) +{ +} + +void serial_puts (const char *s) +{ + while (*s) + { + serial_putc (*s++); + } +} diff --git a/package/boot/uboot-ar71xx/files/drivers/.svn/entries b/package/boot/uboot-ar71xx/files/drivers/.svn/entries new file mode 100644 index 0000000..47154e2 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/drivers +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +net +dir + +spi +dir + diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/entries b/package/boot/uboot-ar71xx/files/drivers/net/.svn/entries new file mode 100644 index 0000000..66da141 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/entries @@ -0,0 +1,99 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/drivers/net +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +phy +dir + +ag71xx.c +file + + + + +2013-03-17T12:13:21.000000Z +6e570423f54b0897dd2636e34c017bda +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +19204 + +ag71xx.h +file + + + + +2013-03-17T12:13:21.000000Z +a50b2a6d1638274b6bd66f8718d059e3 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +10463 + diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.c.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.c.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.h.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.h.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/prop-base/ag71xx.h.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.c.svn-base new file mode 100644 index 0000000..b3324c0 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.c.svn-base @@ -0,0 +1,809 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com> + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> + * + * Based on Atheros' AG7100 driver + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include <common.h> +#include <malloc.h> +#include <net.h> +#include <miiphy.h> + +#include <asm/ar71xx.h> + +#include "ag71xx.h" + +#ifdef AG71XX_DEBUG +#define DBG(fmt,args...) printf(fmt ,##args) +#else +#define DBG(fmt,args...) +#endif + + +static struct ag71xx agtable[] = { + { + .mac_base = KSEG1ADDR(AR71XX_GE0_BASE), + .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII0_CTRL), + .mii_if = CONFIG_AG71XX_MII0_IIF, + } , { + .mac_base = KSEG1ADDR(AR71XX_GE1_BASE), + .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII1_CTRL), + .mii_if = CONFIG_AG71XX_MII1_IIF, + } +}; + +static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size) +{ + int err; + int i; + int rsize; + + ring->desc_size = sizeof(struct ag71xx_desc); + if (ring->desc_size % (CONFIG_SYS_CACHELINE_SIZE)) { + rsize = roundup(ring->desc_size, CONFIG_SYS_CACHELINE_SIZE); + DBG("ag71xx: ring %p, desc size %u rounded to %u\n", + ring, ring->desc_size, + rsize); + ring->desc_size = rsize; + } + + ring->descs_cpu = (u8 *) malloc((size * ring->desc_size) + + CONFIG_SYS_CACHELINE_SIZE - 1); + if (!ring->descs_cpu) { + err = -1; + goto err; + } + ring->descs_cpu = (u8 *) UNCACHED_SDRAM((((u32) ring->descs_cpu + + CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1))); + ring->descs_dma = (u8 *) virt_to_phys(ring->descs_cpu); + + ring->size = size; + + ring->buf = malloc(size * sizeof(*ring->buf)); + if (!ring->buf) { + err = -1; + goto err; + } + memset(ring->buf, 0, size * sizeof(*ring->buf)); + + for (i = 0; i < size; i++) { + ring->buf[i].desc = + (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size]; + DBG("ag71xx: ring %p, desc %d at %p\n", + ring, i, ring->buf[i].desc); + } + + flush_cache( (u32) ring->buf, size * sizeof(*ring->buf)); + + return 0; + + err: + return err; +} + +static void ag71xx_ring_tx_init(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->tx_ring; + int i; + + for (i = 0; i < AG71XX_TX_RING_SIZE; i++) { + ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma + + ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE))); + + ring->buf[i].desc->ctrl = DESC_EMPTY; + ring->buf[i].skb = NULL; + } + + ring->curr = 0; +} + +static void ag71xx_ring_rx_clean(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->rx_ring; + int i; + + if (!ring->buf) + return; + + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { + ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]); + flush_cache((u32) NetRxPackets[i], PKTSIZE_ALIGN); + ring->buf[i].desc->ctrl = DESC_EMPTY; + } + + ring->curr = 0; +} + +static int ag71xx_ring_rx_init(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->rx_ring; + unsigned int i; + + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { + ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma + + ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE))); + + DBG("ag71xx: RX desc at %p, next is %08x\n", + ring->buf[i].desc, + ring->buf[i].desc->next); + } + + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { + ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]); + ring->buf[i].desc->ctrl = DESC_EMPTY; + } + + ring->curr = 0; + + return 0; +} + +static int ag71xx_rings_init(struct ag71xx *ag) +{ + int ret; + + ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE); + if (ret) + return ret; + + ag71xx_ring_tx_init(ag); + + ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE); + if (ret) + return ret; + + ret = ag71xx_ring_rx_init(ag); + return ret; +} + +static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) +{ + uint32_t base = KSEG1ADDR(AR71XX_PLL_BASE); + u32 t; + + t = readl(base + cfg_reg); + t &= ~(3 << shift); + t |= (2 << shift); + writel(t, base + cfg_reg); + udelay(100); + + writel(pll_val, base + pll_reg); + + t |= (3 << shift); + writel(t, base + cfg_reg); + udelay(100); + + t &= ~(3 << shift); + writel(t, base + cfg_reg); + udelay(100); + + debug("ar71xx: pll_reg %#x: %#x\n", (unsigned int)(base + pll_reg), + readl(base + pll_reg)); +} + +static void ar91xx_set_pll_ge0(int speed) +{ + //u32 val = ar71xx_get_eth_pll(0, speed); + u32 pll_val; + + switch (speed) { + case SPEED_10: + pll_val = 0x00441099; + break; + case SPEED_100: + pll_val = 0x13000a44; + break; + case SPEED_1000: + pll_val = 0x1a000000; + break; + default: + BUG(); + } + + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK, + pll_val, AR91XX_ETH0_PLL_SHIFT); +} + +static void ar91xx_set_pll_ge1(int speed) +{ + //u32 val = ar71xx_get_eth_pll(1, speed); + u32 pll_val; + + switch (speed) { + case SPEED_10: + pll_val = 0x00441099; + break; + case SPEED_100: + pll_val = 0x13000a44; + break; + case SPEED_1000: + pll_val = 0x1a000000; + break; + default: + BUG(); + } + + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK, + pll_val, AR91XX_ETH1_PLL_SHIFT); +} + +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) +{ + u32 t; + + t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) + | (((u32) mac[3]) << 8) | ((u32) mac[2]); + + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); + + t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); +} + +static void ag71xx_dma_reset(struct ag71xx *ag) +{ + u32 val; + int i; + + DBG("%s: txdesc reg: 0x%08x rxdesc reg: 0x%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_TX_DESC), + ag71xx_rr(ag, AG71XX_REG_RX_DESC)); + + /* stop RX and TX */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); + + /* clear descriptor addresses */ + ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0); + ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0); + + /* clear pending RX/TX interrupts */ + for (i = 0; i < 256; i++) { + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); + } + + /* clear pending errors */ + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); + + val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); + if (val) + printf("%s: unable to clear DMA Rx status: %08x\n", + ag->dev->name, val); + + val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); + + /* mask out reserved bits */ + val &= ~0xff000000; + + if (val) + printf("%s: unable to clear DMA Tx status: %08x\n", + ag->dev->name, val); +} + +static void ag71xx_halt(struct eth_device *dev) +{ + struct ag71xx *ag = (struct ag71xx *) dev->priv; + + /* stop RX engine */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); + + ag71xx_dma_reset(ag); +} + +#define MAX_WAIT 1000 + +static int ag71xx_send(struct eth_device *dev, volatile void *packet, + int length) +{ + struct ag71xx *ag = (struct ag71xx *) dev->priv; + struct ag71xx_ring *ring = &ag->tx_ring; + struct ag71xx_desc *desc; + int i; + + i = ring->curr % AG71XX_TX_RING_SIZE; + desc = ring->buf[i].desc; + + if (!ag71xx_desc_empty(desc)) { + printf("%s: tx buffer full\n", ag->dev->name); + return 1; + } + + flush_cache((u32) packet, length); + desc->data = (u32) virt_to_phys(packet); + desc->ctrl = (length & DESC_PKTLEN_M); + + DBG("%s: sending %#08x length %#08x\n", + ag->dev->name, desc->data, desc->ctrl); + + ring->curr++; + if (ring->curr >= AG71XX_TX_RING_SIZE){ + ring->curr = 0; + } + + /* enable TX engine */ + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); + + for (i = 0; i < MAX_WAIT; i++) + { + if (ag71xx_desc_empty(desc)) + break; + udelay(10); + } + if (i == MAX_WAIT) { + printf("%s: tx timed out!\n", ag->dev->name); + return -1; + } + + /* disable TX engine */ + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); + desc->data = 0; + desc->ctrl = DESC_EMPTY; + + return 0; +} + +static int ag71xx_recv(struct eth_device *dev) +{ + struct ag71xx *ag = (struct ag71xx *) dev->priv; + struct ag71xx_ring *ring = &ag->rx_ring; + + for (;;) { + unsigned int i = ring->curr % AG71XX_RX_RING_SIZE; + struct ag71xx_desc *desc = ring->buf[i].desc; + int pktlen; + + if (ag71xx_desc_empty(desc)) + break; + + DBG("%s: rx packets, curr=%u\n", dev->name, ring->curr); + + pktlen = ag71xx_desc_pktlen(desc); + pktlen -= ETH_FCS_LEN; + + + NetReceive(NetRxPackets[i] , pktlen); + flush_cache( (u32) NetRxPackets[i], PKTSIZE_ALIGN); + + ring->buf[i].desc->ctrl = DESC_EMPTY; + ring->curr++; + if (ring->curr >= AG71XX_RX_RING_SIZE){ + ring->curr = 0; + } + + } + + if ((ag71xx_rr(ag, AG71XX_REG_RX_CTRL) & RX_CTRL_RXE) == 0) { + /* start RX engine */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); + } + + return 0; +} + +#ifdef AG71XX_DEBUG +static char *ag71xx_speed_str(struct ag71xx *ag) +{ + switch (ag->speed) { + case SPEED_1000: + return "1000"; + case SPEED_100: + return "100"; + case SPEED_10: + return "10"; + } + + return "?"; +} +#endif + +void ag71xx_link_adjust(struct ag71xx *ag) +{ + u32 cfg2; + u32 ifctl; + u32 fifo5; + u32 mii_speed; + + if (!ag->link) { + DBG("%s: link down\n", ag->dev->name); + return; + } + + cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); + cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); + cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; + + ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); + ifctl &= ~(MAC_IFCTL_SPEED); + + fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); + fifo5 &= ~FIFO_CFG5_BM; + + switch (ag->speed) { + case SPEED_1000: + mii_speed = MII_CTRL_SPEED_1000; + cfg2 |= MAC_CFG2_IF_1000; + fifo5 |= FIFO_CFG5_BM; + break; + case SPEED_100: + mii_speed = MII_CTRL_SPEED_100; + cfg2 |= MAC_CFG2_IF_10_100; + ifctl |= MAC_IFCTL_SPEED; + break; + case SPEED_10: + mii_speed = MII_CTRL_SPEED_10; + cfg2 |= MAC_CFG2_IF_10_100; + break; + default: + BUG(); + return; + } + + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); + + if (ag->macNum == 0) + ar91xx_set_pll_ge0(ag->speed); + else + ar91xx_set_pll_ge1(ag->speed); + + ag71xx_mii_ctrl_set_speed(ag, mii_speed); + + ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); + ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); + + DBG("%s: link up (%sMbps/%s duplex)\n", + ag->dev->name, + ag71xx_speed_str(ag), + (1 == ag->duplex) ? "Full" : "Half"); + + DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); + + DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); + + DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), + ag71xx_mii_ctrl_rr(ag)); +} + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +static int ag71xx_getMiiSpeed(struct ag71xx *ag) +{ + uint16_t phyreg, cap; + + if (miiphy_read(ag->phyname, ag->phyid, + PHY_BMSR, &phyreg)) { + puts("PHY_BMSR read failed, assuming no link\n"); + return -1; + } + + if ((phyreg & PHY_BMSR_LS) == 0) { + return -1; + } + + if (miiphy_read(ag->phyname, ag->phyid, + PHY_1000BTSR, &phyreg)) + return -1; + + if (phyreg & PHY_1000BTSR_1000FD) { + ag->speed = SPEED_1000; + ag->duplex = 1; + } else if (phyreg & PHY_1000BTSR_1000HD) { + ag->speed = SPEED_1000; + ag->duplex = 0; + } else { + if (miiphy_read(ag->phyname, ag->phyid, + PHY_ANAR, &cap)) + return -1; + + if (miiphy_read(ag->phyname, ag->phyid, + PHY_ANLPAR, &phyreg)) + return -1; + + cap &= phyreg; + if (cap & PHY_ANLPAR_TXFD) { + ag->speed = SPEED_100; + ag->duplex = 1; + } else if (cap & PHY_ANLPAR_TX) { + ag->speed = SPEED_100; + ag->duplex = 0; + } else if (cap & PHY_ANLPAR_10FD) { + ag->speed = SPEED_10; + ag->duplex = 1; + } else { + ag->speed = SPEED_10; + ag->duplex = 0; + } + } + + ag->link = 1; + + return 0; +} +#endif + +static int ag71xx_hw_start(struct eth_device *dev, bd_t * bd) +{ + struct ag71xx *ag = (struct ag71xx *) dev->priv; + + ag71xx_dma_reset(ag); + + ag71xx_ring_rx_clean(ag); + ag71xx_ring_tx_init(ag); + + ag71xx_wr(ag, AG71XX_REG_TX_DESC, + (u32) virt_to_phys(ag->tx_ring.descs_dma)); + ag71xx_wr(ag, AG71XX_REG_RX_DESC, + (u32) virt_to_phys(ag->rx_ring.descs_dma)); + + ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr); + + if (ag->phyfixed) { + ag->link = 1; + ag->duplex = 1; + ag->speed = SPEED_1000; + } else { + +#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) + if (ag71xx_getMiiSpeed(ag)) + return -1; +#else + /* only fixed, without mii */ + return -1; +#endif + + } + ag71xx_link_adjust(ag); + + DBG("%s: txdesc reg: %#08x rxdesc reg: %#08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_TX_DESC), + ag71xx_rr(ag, AG71XX_REG_RX_DESC)); + + /* start RX engine */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); + + return 0; +} + +#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) + +#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ + FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ + FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ + FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ + FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ + FIFO_CFG4_VT) + +#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ + FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ + FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ + FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ + FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ + FIFO_CFG5_17 | FIFO_CFG5_SF) + +static int ag71xx_hw_init(struct ag71xx *ag) +{ + int ret = 0; + uint32_t reg; + uint32_t mask, mii_type; + + if (ag->macNum == 0) { + mask = (RESET_MODULE_GE0_MAC | RESET_MODULE_GE0_PHY); + mii_type = 0x13; + } else { + mask = (RESET_MODULE_GE1_MAC | RESET_MODULE_GE1_PHY); + mii_type = 0x11; + } + + // mac soft reset + ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); + udelay(20); + + // device stop + reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg | mask); + udelay(100 * 1000); + + // device start + reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg & ~mask); + udelay(100 * 1000); + + /* setup MAC configuration registers */ + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, (MAC_CFG1_RXE | MAC_CFG1_TXE)); + + ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, + MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); + + /* setup FIFO configuration register 0 */ + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); + + /* setup MII interface type */ + ag71xx_mii_ctrl_set_if(ag, ag->mii_if); + + /* setup mdio clock divisor */ + ag71xx_wr(ag, AG71XX_REG_MII_CFG, MII_CFG_CLK_DIV_20); + + /* setup FIFO configuration registers */ + ag71xx_sb(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); + + ag71xx_dma_reset(ag); + + ret = ag71xx_rings_init(ag); + if (ret) + return -1; + + ag71xx_wr(ag, AG71XX_REG_TX_DESC, + (u32) virt_to_phys(ag->tx_ring.descs_dma)); + ag71xx_wr(ag, AG71XX_REG_RX_DESC, + (u32) virt_to_phys(ag->rx_ring.descs_dma)); + + ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr); + + return 0; +} + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +#define AG71XX_MDIO_RETRY 1000 +#define AG71XX_MDIO_DELAY 5 + +static inline struct ag71xx *ag71xx_name2mac(char *devname) +{ + if (strcmp(devname, agtable[0].dev->name) == 0) + return &agtable[0]; + else if (strcmp(devname, agtable[1].dev->name) == 0) + return &agtable[1]; + else + return NULL; +} + +static inline void ag71xx_mdio_wr(struct ag71xx *ag, unsigned reg, + u32 value) +{ + uint32_t r; + + r = ag->mac_base + reg; + writel(value, r); + + /* flush write */ + (void) readl(r); +} + +static inline u32 ag71xx_mdio_rr(struct ag71xx *ag, unsigned reg) +{ + return readl(ag->mac_base + reg); +} + +static int ag71xx_mdio_read(char *devname, unsigned char addr, + unsigned char reg, unsigned short *val) +{ + struct ag71xx *ag = ag71xx_name2mac(devname); + uint16_t regData; + int i; + + ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE); + ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR, + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); + ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_READ); + + i = AG71XX_MDIO_RETRY; + while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) { + if (i-- == 0) { + printf("%s: mii_read timed out\n", + ag->dev->name); + return -1; + } + udelay(AG71XX_MDIO_DELAY); + } + + regData = (uint16_t) ag71xx_mdio_rr(ag, AG71XX_REG_MII_STATUS) & 0xffff; + ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE); + + DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, regData); + + if (val) + *val = regData; + + return 0; +} + +static int ag71xx_mdio_write(char *devname, unsigned char addr, + unsigned char reg, unsigned short val) +{ + struct ag71xx *ag = ag71xx_name2mac(devname); + int i; + + if (ag == NULL) + return 1; + + DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); + + ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR, + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); + ag71xx_mdio_wr(ag, AG71XX_REG_MII_CTRL, val); + + i = AG71XX_MDIO_RETRY; + while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) { + if (i-- == 0) { + printf("%s: mii_write timed out\n", + ag->dev->name); + break; + } + udelay(AG71XX_MDIO_DELAY); + } + + return 0; +} +#endif + +int ag71xx_register(bd_t * bis, char *phyname[], uint16_t phyid[], uint16_t phyfixed[]) +{ + int i, num = 0; + u8 used_ports[MAX_AG71XX_DEVS] = CONFIG_AG71XX_PORTS; + + for (i = 0; i < MAX_AG71XX_DEVS; i++) { + /*skip if port is configured not to use */ + if (used_ports[i] == 0) + continue; + + agtable[i].dev = malloc(sizeof(struct eth_device)); + if (agtable[i].dev == NULL) { + puts("malloc failed\n"); + return 0; + } + memset(agtable[i].dev, 0, sizeof(struct eth_device)); + sprintf(agtable[i].dev->name, "eth%d", i); + + agtable[i].dev->iobase = 0; + agtable[i].dev->init = ag71xx_hw_start; + agtable[i].dev->halt = ag71xx_halt; + agtable[i].dev->send = ag71xx_send; + agtable[i].dev->recv = ag71xx_recv; + agtable[i].dev->priv = (void *) (&agtable[i]); + agtable[i].macNum = i; + eth_register(agtable[i].dev); +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + + if ((phyname == NULL) || (phyid == NULL) || (phyfixed == NULL)) + return -1; + + agtable[i].phyname = strdup(phyname[i]); + agtable[i].phyid = phyid[i]; + agtable[i].phyfixed = phyfixed[i]; + + miiphy_register(agtable[i].dev->name, ag71xx_mdio_read, + ag71xx_mdio_write); +#endif + + if (ag71xx_hw_init(&agtable[i])) + continue; + + num++; + } + + return num; +} diff --git a/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.h.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.h.svn-base new file mode 100644 index 0000000..edce429 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/.svn/text-base/ag71xx.h.svn-base @@ -0,0 +1,374 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> + * + * Based on Atheros' AG7100 driver + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __AG71XX_H +#define __AG71XX_H + +#include <linux/types.h> +#include <linux/bitops.h> + +#include <asm/ar71xx.h> + +// controller has 2 ports +#define MAX_AG71XX_DEVS 2 + +#define ETH_FCS_LEN 4 + +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 + + +#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) +#define AG71XX_INT_TX (AG71XX_INT_TX_PS) +#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) + +#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) +#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) + +#define AG71XX_TX_FIFO_LEN 2048 +#define AG71XX_TX_MTU_LEN 1536 +#define AG71XX_RX_PKT_RESERVE 64 +#define AG71XX_RX_PKT_SIZE \ + (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN) + +#ifndef CONFIG_SYS_RX_ETH_BUFFER +#define AG71XX_TX_RING_SIZE 4 +#define AG71XX_RX_RING_SIZE 4 +#else +#define AG71XX_TX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER +#define AG71XX_RX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER +#endif + +#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4) +#define AG71XX_TX_THRES_WAKEUP \ + (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4)) + + + + +struct ag71xx_desc { + u32 data; + u32 ctrl; +#define DESC_EMPTY BIT(31) +#define DESC_MORE BIT(24) +#define DESC_PKTLEN_M 0xfff + u32 next; + u32 pad; +} __attribute__((aligned(4))); + +struct ag71xx_buf { + struct sk_buff *skb; + struct ag71xx_desc *desc; + dma_addr_t dma_addr; + u32 pad; +}; + +struct ag71xx_ring { + struct ag71xx_buf *buf; + u8 *descs_cpu; + u8 *descs_dma; + unsigned int desc_size; + unsigned int curr; + unsigned int size; +}; + +struct ag71xx { + uint32_t mac_base; + uint32_t mii_ctrl; + + struct eth_device *dev; + + struct ag71xx_ring rx_ring; + struct ag71xx_ring tx_ring; + + char *phyname; + u16 phyid; + u16 phyfixed; + uint32_t link; + uint32_t speed; + int32_t duplex; + uint32_t macNum; + uint32_t mii_if; +}; + +void ag71xx_link_adjust(struct ag71xx *ag); + +int ag71xx_phy_connect(struct ag71xx *ag); +void ag71xx_phy_disconnect(struct ag71xx *ag); +void ag71xx_phy_start(struct ag71xx *ag); +void ag71xx_phy_stop(struct ag71xx *ag); + +static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) +{ + return ((desc->ctrl & DESC_EMPTY) != 0); +} + +static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc) +{ + return (desc->ctrl & DESC_PKTLEN_M); +} + +/* Register offsets */ +#define AG71XX_REG_MAC_CFG1 0x0000 +#define AG71XX_REG_MAC_CFG2 0x0004 +#define AG71XX_REG_MAC_IPG 0x0008 +#define AG71XX_REG_MAC_HDX 0x000c +#define AG71XX_REG_MAC_MFL 0x0010 +#define AG71XX_REG_MII_CFG 0x0020 +#define AG71XX_REG_MII_CMD 0x0024 +#define AG71XX_REG_MII_ADDR 0x0028 +#define AG71XX_REG_MII_CTRL 0x002c +#define AG71XX_REG_MII_STATUS 0x0030 +#define AG71XX_REG_MII_IND 0x0034 +#define AG71XX_REG_MAC_IFCTL 0x0038 +#define AG71XX_REG_MAC_ADDR1 0x0040 +#define AG71XX_REG_MAC_ADDR2 0x0044 +#define AG71XX_REG_FIFO_CFG0 0x0048 +#define AG71XX_REG_FIFO_CFG1 0x004c +#define AG71XX_REG_FIFO_CFG2 0x0050 +#define AG71XX_REG_FIFO_CFG3 0x0054 +#define AG71XX_REG_FIFO_CFG4 0x0058 +#define AG71XX_REG_FIFO_CFG5 0x005c +#define AG71XX_REG_FIFO_RAM0 0x0060 +#define AG71XX_REG_FIFO_RAM1 0x0064 +#define AG71XX_REG_FIFO_RAM2 0x0068 +#define AG71XX_REG_FIFO_RAM3 0x006c +#define AG71XX_REG_FIFO_RAM4 0x0070 +#define AG71XX_REG_FIFO_RAM5 0x0074 +#define AG71XX_REG_FIFO_RAM6 0x0078 +#define AG71XX_REG_FIFO_RAM7 0x007c + +#define AG71XX_REG_TX_CTRL 0x0180 +#define AG71XX_REG_TX_DESC 0x0184 +#define AG71XX_REG_TX_STATUS 0x0188 +#define AG71XX_REG_RX_CTRL 0x018c +#define AG71XX_REG_RX_DESC 0x0190 +#define AG71XX_REG_RX_STATUS 0x0194 +#define AG71XX_REG_INT_ENABLE 0x0198 +#define AG71XX_REG_INT_STATUS 0x019c + +#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ +#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ +#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ +#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ +#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ +#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ +#define MAC_CFG1_LB BIT(8) /* Loopback mode */ +#define MAC_CFG1_SR BIT(31) /* Soft Reset */ + +#define MAC_CFG2_FDX BIT(0) +#define MAC_CFG2_CRC_EN BIT(1) +#define MAC_CFG2_PAD_CRC_EN BIT(2) +#define MAC_CFG2_LEN_CHECK BIT(4) +#define MAC_CFG2_HUGE_FRAME_EN BIT(5) +#define MAC_CFG2_IF_1000 BIT(9) +#define MAC_CFG2_IF_10_100 BIT(8) + +#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ +#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ +#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ +#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ +#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ +#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ + | FIFO_CFG0_TXS | FIFO_CFG0_TXF) + +#define FIFO_CFG0_ENABLE_SHIFT 8 + +#define FIFO_CFG4_DE BIT(0) /* Drop Event */ +#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ +#define FIFO_CFG4_FC BIT(2) /* False Carrier */ +#define FIFO_CFG4_CE BIT(3) /* Code Error */ +#define FIFO_CFG4_CR BIT(4) /* CRC error */ +#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ +#define FIFO_CFG4_LO BIT(6) /* Length out of range */ +#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ +#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ +#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ +#define FIFO_CFG4_DR BIT(10) /* Dribble */ +#define FIFO_CFG4_LE BIT(11) /* Long Event */ +#define FIFO_CFG4_CF BIT(12) /* Control Frame */ +#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ +#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ +#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ +#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ +#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ + +#define FIFO_CFG5_DE BIT(0) /* Drop Event */ +#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ +#define FIFO_CFG5_FC BIT(2) /* False Carrier */ +#define FIFO_CFG5_CE BIT(3) /* Code Error */ +#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ +#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ +#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ +#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ +#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ +#define FIFO_CFG5_DR BIT(9) /* Dribble */ +#define FIFO_CFG5_CF BIT(10) /* Control Frame */ +#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ +#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ +#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ +#define FIFO_CFG5_LE BIT(14) /* Long Event */ +#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ +#define FIFO_CFG5_16 BIT(16) /* unknown */ +#define FIFO_CFG5_17 BIT(17) /* unknown */ +#define FIFO_CFG5_SF BIT(18) /* Short Frame */ +#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ + +#define AG71XX_INT_TX_PS BIT(0) +#define AG71XX_INT_TX_UR BIT(1) +#define AG71XX_INT_TX_BE BIT(3) +#define AG71XX_INT_RX_PR BIT(4) +#define AG71XX_INT_RX_OF BIT(6) +#define AG71XX_INT_RX_BE BIT(7) + +#define MAC_IFCTL_SPEED BIT(16) + +#define MII_CFG_CLK_DIV_4 0 +#define MII_CFG_CLK_DIV_6 2 +#define MII_CFG_CLK_DIV_8 3 +#define MII_CFG_CLK_DIV_10 4 +#define MII_CFG_CLK_DIV_14 5 +#define MII_CFG_CLK_DIV_20 6 +#define MII_CFG_CLK_DIV_28 7 +#define MII_CFG_RESET BIT(31) + +#define MII_CMD_WRITE 0x0 +#define MII_CMD_READ 0x1 +#define MII_ADDR_SHIFT 8 +#define MII_IND_BUSY BIT(0) +#define MII_IND_INVALID BIT(2) + +#define TX_CTRL_TXE BIT(0) /* Tx Enable */ + +#define TX_STATUS_PS BIT(0) /* Packet Sent */ +#define TX_STATUS_UR BIT(1) /* Tx Underrun */ +#define TX_STATUS_BE BIT(3) /* Bus Error */ + +#define RX_CTRL_RXE BIT(0) /* Rx Enable */ + +#define RX_STATUS_PR BIT(0) /* Packet Received */ +#define RX_STATUS_OF BIT(2) /* Rx Overflow */ +#define RX_STATUS_BE BIT(3) /* Bus Error */ + +#define MII_CTRL_IF_MASK 3 +#define MII_CTRL_SPEED_SHIFT 4 +#define MII_CTRL_SPEED_MASK 3 +#define MII_CTRL_SPEED_10 0 +#define MII_CTRL_SPEED_100 1 +#define MII_CTRL_SPEED_1000 2 + +static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) +{ + __raw_writel(value, ag->mac_base + reg); + /* flush write */ + (void) __raw_readl(ag->mac_base + reg); +} + +static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) +{ + return __raw_readl(ag->mac_base + reg); +} + +static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) +{ + uint32_t r; + + r = ag->mac_base + reg; + __raw_writel(__raw_readl(r) | mask, r); + /* flush write */ + (void)__raw_readl(r); +} + +static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) +{ + uint32_t r; + + r = ag->mac_base + reg; + __raw_writel(__raw_readl(r) & ~mask, r); + /* flush write */ + (void) __raw_readl(r); +} + +static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) +{ + ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); +} + +static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) +{ + ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); +} + +static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value) +{ + __raw_writel(value, ag->mii_ctrl); + + /* flush write */ + __raw_readl(ag->mii_ctrl); +} + +static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag) +{ + return __raw_readl(ag->mii_ctrl); +} + +static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag, + unsigned int mii_if) +{ + u32 t; + + t = ag71xx_mii_ctrl_rr(ag); + t &= ~(MII_CTRL_IF_MASK); + t |= (mii_if & MII_CTRL_IF_MASK); + ag71xx_mii_ctrl_wr(ag, t); +} + +static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, + unsigned int speed) +{ + u32 t; + + t = ag71xx_mii_ctrl_rr(ag); + t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT); + t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT; + ag71xx_mii_ctrl_wr(ag, t); +} + +#ifdef CONFIG_AG71XX_AR8216_SUPPORT +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, + int pktlen); +static inline int ag71xx_has_ar8216(struct ag71xx *ag) +{ + return ag71xx_get_pdata(ag)->has_ar8216; +} +#else +static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, + struct sk_buff *skb) +{ +} + +static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, + struct sk_buff *skb, + int pktlen) +{ + return 0; +} +static inline int ag71xx_has_ar8216(struct ag71xx *ag) +{ + return 0; +} +#endif + +#endif /* _AG71XX_H */ diff --git a/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c new file mode 100644 index 0000000..b3324c0 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c @@ -0,0 +1,809 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com> + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> + * + * Based on Atheros' AG7100 driver + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include <common.h> +#include <malloc.h> +#include <net.h> +#include <miiphy.h> + +#include <asm/ar71xx.h> + +#include "ag71xx.h" + +#ifdef AG71XX_DEBUG +#define DBG(fmt,args...) printf(fmt ,##args) +#else +#define DBG(fmt,args...) +#endif + + +static struct ag71xx agtable[] = { + { + .mac_base = KSEG1ADDR(AR71XX_GE0_BASE), + .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII0_CTRL), + .mii_if = CONFIG_AG71XX_MII0_IIF, + } , { + .mac_base = KSEG1ADDR(AR71XX_GE1_BASE), + .mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII1_CTRL), + .mii_if = CONFIG_AG71XX_MII1_IIF, + } +}; + +static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size) +{ + int err; + int i; + int rsize; + + ring->desc_size = sizeof(struct ag71xx_desc); + if (ring->desc_size % (CONFIG_SYS_CACHELINE_SIZE)) { + rsize = roundup(ring->desc_size, CONFIG_SYS_CACHELINE_SIZE); + DBG("ag71xx: ring %p, desc size %u rounded to %u\n", + ring, ring->desc_size, + rsize); + ring->desc_size = rsize; + } + + ring->descs_cpu = (u8 *) malloc((size * ring->desc_size) + + CONFIG_SYS_CACHELINE_SIZE - 1); + if (!ring->descs_cpu) { + err = -1; + goto err; + } + ring->descs_cpu = (u8 *) UNCACHED_SDRAM((((u32) ring->descs_cpu + + CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1))); + ring->descs_dma = (u8 *) virt_to_phys(ring->descs_cpu); + + ring->size = size; + + ring->buf = malloc(size * sizeof(*ring->buf)); + if (!ring->buf) { + err = -1; + goto err; + } + memset(ring->buf, 0, size * sizeof(*ring->buf)); + + for (i = 0; i < size; i++) { + ring->buf[i].desc = + (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size]; + DBG("ag71xx: ring %p, desc %d at %p\n", + ring, i, ring->buf[i].desc); + } + + flush_cache( (u32) ring->buf, size * sizeof(*ring->buf)); + + return 0; + + err: + return err; +} + +static void ag71xx_ring_tx_init(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->tx_ring; + int i; + + for (i = 0; i < AG71XX_TX_RING_SIZE; i++) { + ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma + + ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE))); + + ring->buf[i].desc->ctrl = DESC_EMPTY; + ring->buf[i].skb = NULL; + } + + ring->curr = 0; +} + +static void ag71xx_ring_rx_clean(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->rx_ring; + int i; + + if (!ring->buf) + return; + + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { + ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]); + flush_cache((u32) NetRxPackets[i], PKTSIZE_ALIGN); + ring->buf[i].desc->ctrl = DESC_EMPTY; + } + + ring->curr = 0; +} + +static int ag71xx_ring_rx_init(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->rx_ring; + unsigned int i; + + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { + ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma + + ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE))); + + DBG("ag71xx: RX desc at %p, next is %08x\n", + ring->buf[i].desc, + ring->buf[i].desc->next); + } + + for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { + ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]); + ring->buf[i].desc->ctrl = DESC_EMPTY; + } + + ring->curr = 0; + + return 0; +} + +static int ag71xx_rings_init(struct ag71xx *ag) +{ + int ret; + + ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE); + if (ret) + return ret; + + ag71xx_ring_tx_init(ag); + + ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE); + if (ret) + return ret; + + ret = ag71xx_ring_rx_init(ag); + return ret; +} + +static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) +{ + uint32_t base = KSEG1ADDR(AR71XX_PLL_BASE); + u32 t; + + t = readl(base + cfg_reg); + t &= ~(3 << shift); + t |= (2 << shift); + writel(t, base + cfg_reg); + udelay(100); + + writel(pll_val, base + pll_reg); + + t |= (3 << shift); + writel(t, base + cfg_reg); + udelay(100); + + t &= ~(3 << shift); + writel(t, base + cfg_reg); + udelay(100); + + debug("ar71xx: pll_reg %#x: %#x\n", (unsigned int)(base + pll_reg), + readl(base + pll_reg)); +} + +static void ar91xx_set_pll_ge0(int speed) +{ + //u32 val = ar71xx_get_eth_pll(0, speed); + u32 pll_val; + + switch (speed) { + case SPEED_10: + pll_val = 0x00441099; + break; + case SPEED_100: + pll_val = 0x13000a44; + break; + case SPEED_1000: + pll_val = 0x1a000000; + break; + default: + BUG(); + } + + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK, + pll_val, AR91XX_ETH0_PLL_SHIFT); +} + +static void ar91xx_set_pll_ge1(int speed) +{ + //u32 val = ar71xx_get_eth_pll(1, speed); + u32 pll_val; + + switch (speed) { + case SPEED_10: + pll_val = 0x00441099; + break; + case SPEED_100: + pll_val = 0x13000a44; + break; + case SPEED_1000: + pll_val = 0x1a000000; + break; + default: + BUG(); + } + + ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK, + pll_val, AR91XX_ETH1_PLL_SHIFT); +} + +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) +{ + u32 t; + + t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) + | (((u32) mac[3]) << 8) | ((u32) mac[2]); + + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); + + t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); +} + +static void ag71xx_dma_reset(struct ag71xx *ag) +{ + u32 val; + int i; + + DBG("%s: txdesc reg: 0x%08x rxdesc reg: 0x%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_TX_DESC), + ag71xx_rr(ag, AG71XX_REG_RX_DESC)); + + /* stop RX and TX */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); + + /* clear descriptor addresses */ + ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0); + ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0); + + /* clear pending RX/TX interrupts */ + for (i = 0; i < 256; i++) { + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); + } + + /* clear pending errors */ + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); + + val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); + if (val) + printf("%s: unable to clear DMA Rx status: %08x\n", + ag->dev->name, val); + + val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); + + /* mask out reserved bits */ + val &= ~0xff000000; + + if (val) + printf("%s: unable to clear DMA Tx status: %08x\n", + ag->dev->name, val); +} + +static void ag71xx_halt(struct eth_device *dev) +{ + struct ag71xx *ag = (struct ag71xx *) dev->priv; + + /* stop RX engine */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); + + ag71xx_dma_reset(ag); +} + +#define MAX_WAIT 1000 + +static int ag71xx_send(struct eth_device *dev, volatile void *packet, + int length) +{ + struct ag71xx *ag = (struct ag71xx *) dev->priv; + struct ag71xx_ring *ring = &ag->tx_ring; + struct ag71xx_desc *desc; + int i; + + i = ring->curr % AG71XX_TX_RING_SIZE; + desc = ring->buf[i].desc; + + if (!ag71xx_desc_empty(desc)) { + printf("%s: tx buffer full\n", ag->dev->name); + return 1; + } + + flush_cache((u32) packet, length); + desc->data = (u32) virt_to_phys(packet); + desc->ctrl = (length & DESC_PKTLEN_M); + + DBG("%s: sending %#08x length %#08x\n", + ag->dev->name, desc->data, desc->ctrl); + + ring->curr++; + if (ring->curr >= AG71XX_TX_RING_SIZE){ + ring->curr = 0; + } + + /* enable TX engine */ + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); + + for (i = 0; i < MAX_WAIT; i++) + { + if (ag71xx_desc_empty(desc)) + break; + udelay(10); + } + if (i == MAX_WAIT) { + printf("%s: tx timed out!\n", ag->dev->name); + return -1; + } + + /* disable TX engine */ + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); + desc->data = 0; + desc->ctrl = DESC_EMPTY; + + return 0; +} + +static int ag71xx_recv(struct eth_device *dev) +{ + struct ag71xx *ag = (struct ag71xx *) dev->priv; + struct ag71xx_ring *ring = &ag->rx_ring; + + for (;;) { + unsigned int i = ring->curr % AG71XX_RX_RING_SIZE; + struct ag71xx_desc *desc = ring->buf[i].desc; + int pktlen; + + if (ag71xx_desc_empty(desc)) + break; + + DBG("%s: rx packets, curr=%u\n", dev->name, ring->curr); + + pktlen = ag71xx_desc_pktlen(desc); + pktlen -= ETH_FCS_LEN; + + + NetReceive(NetRxPackets[i] , pktlen); + flush_cache( (u32) NetRxPackets[i], PKTSIZE_ALIGN); + + ring->buf[i].desc->ctrl = DESC_EMPTY; + ring->curr++; + if (ring->curr >= AG71XX_RX_RING_SIZE){ + ring->curr = 0; + } + + } + + if ((ag71xx_rr(ag, AG71XX_REG_RX_CTRL) & RX_CTRL_RXE) == 0) { + /* start RX engine */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); + } + + return 0; +} + +#ifdef AG71XX_DEBUG +static char *ag71xx_speed_str(struct ag71xx *ag) +{ + switch (ag->speed) { + case SPEED_1000: + return "1000"; + case SPEED_100: + return "100"; + case SPEED_10: + return "10"; + } + + return "?"; +} +#endif + +void ag71xx_link_adjust(struct ag71xx *ag) +{ + u32 cfg2; + u32 ifctl; + u32 fifo5; + u32 mii_speed; + + if (!ag->link) { + DBG("%s: link down\n", ag->dev->name); + return; + } + + cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); + cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); + cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; + + ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); + ifctl &= ~(MAC_IFCTL_SPEED); + + fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); + fifo5 &= ~FIFO_CFG5_BM; + + switch (ag->speed) { + case SPEED_1000: + mii_speed = MII_CTRL_SPEED_1000; + cfg2 |= MAC_CFG2_IF_1000; + fifo5 |= FIFO_CFG5_BM; + break; + case SPEED_100: + mii_speed = MII_CTRL_SPEED_100; + cfg2 |= MAC_CFG2_IF_10_100; + ifctl |= MAC_IFCTL_SPEED; + break; + case SPEED_10: + mii_speed = MII_CTRL_SPEED_10; + cfg2 |= MAC_CFG2_IF_10_100; + break; + default: + BUG(); + return; + } + + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); + + if (ag->macNum == 0) + ar91xx_set_pll_ge0(ag->speed); + else + ar91xx_set_pll_ge1(ag->speed); + + ag71xx_mii_ctrl_set_speed(ag, mii_speed); + + ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); + ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); + + DBG("%s: link up (%sMbps/%s duplex)\n", + ag->dev->name, + ag71xx_speed_str(ag), + (1 == ag->duplex) ? "Full" : "Half"); + + DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); + + DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); + + DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), + ag71xx_mii_ctrl_rr(ag)); +} + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +static int ag71xx_getMiiSpeed(struct ag71xx *ag) +{ + uint16_t phyreg, cap; + + if (miiphy_read(ag->phyname, ag->phyid, + PHY_BMSR, &phyreg)) { + puts("PHY_BMSR read failed, assuming no link\n"); + return -1; + } + + if ((phyreg & PHY_BMSR_LS) == 0) { + return -1; + } + + if (miiphy_read(ag->phyname, ag->phyid, + PHY_1000BTSR, &phyreg)) + return -1; + + if (phyreg & PHY_1000BTSR_1000FD) { + ag->speed = SPEED_1000; + ag->duplex = 1; + } else if (phyreg & PHY_1000BTSR_1000HD) { + ag->speed = SPEED_1000; + ag->duplex = 0; + } else { + if (miiphy_read(ag->phyname, ag->phyid, + PHY_ANAR, &cap)) + return -1; + + if (miiphy_read(ag->phyname, ag->phyid, + PHY_ANLPAR, &phyreg)) + return -1; + + cap &= phyreg; + if (cap & PHY_ANLPAR_TXFD) { + ag->speed = SPEED_100; + ag->duplex = 1; + } else if (cap & PHY_ANLPAR_TX) { + ag->speed = SPEED_100; + ag->duplex = 0; + } else if (cap & PHY_ANLPAR_10FD) { + ag->speed = SPEED_10; + ag->duplex = 1; + } else { + ag->speed = SPEED_10; + ag->duplex = 0; + } + } + + ag->link = 1; + + return 0; +} +#endif + +static int ag71xx_hw_start(struct eth_device *dev, bd_t * bd) +{ + struct ag71xx *ag = (struct ag71xx *) dev->priv; + + ag71xx_dma_reset(ag); + + ag71xx_ring_rx_clean(ag); + ag71xx_ring_tx_init(ag); + + ag71xx_wr(ag, AG71XX_REG_TX_DESC, + (u32) virt_to_phys(ag->tx_ring.descs_dma)); + ag71xx_wr(ag, AG71XX_REG_RX_DESC, + (u32) virt_to_phys(ag->rx_ring.descs_dma)); + + ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr); + + if (ag->phyfixed) { + ag->link = 1; + ag->duplex = 1; + ag->speed = SPEED_1000; + } else { + +#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) + if (ag71xx_getMiiSpeed(ag)) + return -1; +#else + /* only fixed, without mii */ + return -1; +#endif + + } + ag71xx_link_adjust(ag); + + DBG("%s: txdesc reg: %#08x rxdesc reg: %#08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_TX_DESC), + ag71xx_rr(ag, AG71XX_REG_RX_DESC)); + + /* start RX engine */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); + + return 0; +} + +#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) + +#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ + FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ + FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ + FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ + FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ + FIFO_CFG4_VT) + +#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ + FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ + FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ + FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ + FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ + FIFO_CFG5_17 | FIFO_CFG5_SF) + +static int ag71xx_hw_init(struct ag71xx *ag) +{ + int ret = 0; + uint32_t reg; + uint32_t mask, mii_type; + + if (ag->macNum == 0) { + mask = (RESET_MODULE_GE0_MAC | RESET_MODULE_GE0_PHY); + mii_type = 0x13; + } else { + mask = (RESET_MODULE_GE1_MAC | RESET_MODULE_GE1_PHY); + mii_type = 0x11; + } + + // mac soft reset + ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); + udelay(20); + + // device stop + reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg | mask); + udelay(100 * 1000); + + // device start + reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE); + ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg & ~mask); + udelay(100 * 1000); + + /* setup MAC configuration registers */ + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, (MAC_CFG1_RXE | MAC_CFG1_TXE)); + + ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, + MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); + + /* setup FIFO configuration register 0 */ + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); + + /* setup MII interface type */ + ag71xx_mii_ctrl_set_if(ag, ag->mii_if); + + /* setup mdio clock divisor */ + ag71xx_wr(ag, AG71XX_REG_MII_CFG, MII_CFG_CLK_DIV_20); + + /* setup FIFO configuration registers */ + ag71xx_sb(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); + + ag71xx_dma_reset(ag); + + ret = ag71xx_rings_init(ag); + if (ret) + return -1; + + ag71xx_wr(ag, AG71XX_REG_TX_DESC, + (u32) virt_to_phys(ag->tx_ring.descs_dma)); + ag71xx_wr(ag, AG71XX_REG_RX_DESC, + (u32) virt_to_phys(ag->rx_ring.descs_dma)); + + ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr); + + return 0; +} + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +#define AG71XX_MDIO_RETRY 1000 +#define AG71XX_MDIO_DELAY 5 + +static inline struct ag71xx *ag71xx_name2mac(char *devname) +{ + if (strcmp(devname, agtable[0].dev->name) == 0) + return &agtable[0]; + else if (strcmp(devname, agtable[1].dev->name) == 0) + return &agtable[1]; + else + return NULL; +} + +static inline void ag71xx_mdio_wr(struct ag71xx *ag, unsigned reg, + u32 value) +{ + uint32_t r; + + r = ag->mac_base + reg; + writel(value, r); + + /* flush write */ + (void) readl(r); +} + +static inline u32 ag71xx_mdio_rr(struct ag71xx *ag, unsigned reg) +{ + return readl(ag->mac_base + reg); +} + +static int ag71xx_mdio_read(char *devname, unsigned char addr, + unsigned char reg, unsigned short *val) +{ + struct ag71xx *ag = ag71xx_name2mac(devname); + uint16_t regData; + int i; + + ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE); + ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR, + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); + ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_READ); + + i = AG71XX_MDIO_RETRY; + while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) { + if (i-- == 0) { + printf("%s: mii_read timed out\n", + ag->dev->name); + return -1; + } + udelay(AG71XX_MDIO_DELAY); + } + + regData = (uint16_t) ag71xx_mdio_rr(ag, AG71XX_REG_MII_STATUS) & 0xffff; + ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE); + + DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, regData); + + if (val) + *val = regData; + + return 0; +} + +static int ag71xx_mdio_write(char *devname, unsigned char addr, + unsigned char reg, unsigned short val) +{ + struct ag71xx *ag = ag71xx_name2mac(devname); + int i; + + if (ag == NULL) + return 1; + + DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); + + ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR, + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); + ag71xx_mdio_wr(ag, AG71XX_REG_MII_CTRL, val); + + i = AG71XX_MDIO_RETRY; + while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) { + if (i-- == 0) { + printf("%s: mii_write timed out\n", + ag->dev->name); + break; + } + udelay(AG71XX_MDIO_DELAY); + } + + return 0; +} +#endif + +int ag71xx_register(bd_t * bis, char *phyname[], uint16_t phyid[], uint16_t phyfixed[]) +{ + int i, num = 0; + u8 used_ports[MAX_AG71XX_DEVS] = CONFIG_AG71XX_PORTS; + + for (i = 0; i < MAX_AG71XX_DEVS; i++) { + /*skip if port is configured not to use */ + if (used_ports[i] == 0) + continue; + + agtable[i].dev = malloc(sizeof(struct eth_device)); + if (agtable[i].dev == NULL) { + puts("malloc failed\n"); + return 0; + } + memset(agtable[i].dev, 0, sizeof(struct eth_device)); + sprintf(agtable[i].dev->name, "eth%d", i); + + agtable[i].dev->iobase = 0; + agtable[i].dev->init = ag71xx_hw_start; + agtable[i].dev->halt = ag71xx_halt; + agtable[i].dev->send = ag71xx_send; + agtable[i].dev->recv = ag71xx_recv; + agtable[i].dev->priv = (void *) (&agtable[i]); + agtable[i].macNum = i; + eth_register(agtable[i].dev); +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + + if ((phyname == NULL) || (phyid == NULL) || (phyfixed == NULL)) + return -1; + + agtable[i].phyname = strdup(phyname[i]); + agtable[i].phyid = phyid[i]; + agtable[i].phyfixed = phyfixed[i]; + + miiphy_register(agtable[i].dev->name, ag71xx_mdio_read, + ag71xx_mdio_write); +#endif + + if (ag71xx_hw_init(&agtable[i])) + continue; + + num++; + } + + return num; +} diff --git a/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h new file mode 100644 index 0000000..edce429 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h @@ -0,0 +1,374 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> + * + * Based on Atheros' AG7100 driver + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __AG71XX_H +#define __AG71XX_H + +#include <linux/types.h> +#include <linux/bitops.h> + +#include <asm/ar71xx.h> + +// controller has 2 ports +#define MAX_AG71XX_DEVS 2 + +#define ETH_FCS_LEN 4 + +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 + + +#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) +#define AG71XX_INT_TX (AG71XX_INT_TX_PS) +#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) + +#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) +#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) + +#define AG71XX_TX_FIFO_LEN 2048 +#define AG71XX_TX_MTU_LEN 1536 +#define AG71XX_RX_PKT_RESERVE 64 +#define AG71XX_RX_PKT_SIZE \ + (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN) + +#ifndef CONFIG_SYS_RX_ETH_BUFFER +#define AG71XX_TX_RING_SIZE 4 +#define AG71XX_RX_RING_SIZE 4 +#else +#define AG71XX_TX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER +#define AG71XX_RX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER +#endif + +#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4) +#define AG71XX_TX_THRES_WAKEUP \ + (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4)) + + + + +struct ag71xx_desc { + u32 data; + u32 ctrl; +#define DESC_EMPTY BIT(31) +#define DESC_MORE BIT(24) +#define DESC_PKTLEN_M 0xfff + u32 next; + u32 pad; +} __attribute__((aligned(4))); + +struct ag71xx_buf { + struct sk_buff *skb; + struct ag71xx_desc *desc; + dma_addr_t dma_addr; + u32 pad; +}; + +struct ag71xx_ring { + struct ag71xx_buf *buf; + u8 *descs_cpu; + u8 *descs_dma; + unsigned int desc_size; + unsigned int curr; + unsigned int size; +}; + +struct ag71xx { + uint32_t mac_base; + uint32_t mii_ctrl; + + struct eth_device *dev; + + struct ag71xx_ring rx_ring; + struct ag71xx_ring tx_ring; + + char *phyname; + u16 phyid; + u16 phyfixed; + uint32_t link; + uint32_t speed; + int32_t duplex; + uint32_t macNum; + uint32_t mii_if; +}; + +void ag71xx_link_adjust(struct ag71xx *ag); + +int ag71xx_phy_connect(struct ag71xx *ag); +void ag71xx_phy_disconnect(struct ag71xx *ag); +void ag71xx_phy_start(struct ag71xx *ag); +void ag71xx_phy_stop(struct ag71xx *ag); + +static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) +{ + return ((desc->ctrl & DESC_EMPTY) != 0); +} + +static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc) +{ + return (desc->ctrl & DESC_PKTLEN_M); +} + +/* Register offsets */ +#define AG71XX_REG_MAC_CFG1 0x0000 +#define AG71XX_REG_MAC_CFG2 0x0004 +#define AG71XX_REG_MAC_IPG 0x0008 +#define AG71XX_REG_MAC_HDX 0x000c +#define AG71XX_REG_MAC_MFL 0x0010 +#define AG71XX_REG_MII_CFG 0x0020 +#define AG71XX_REG_MII_CMD 0x0024 +#define AG71XX_REG_MII_ADDR 0x0028 +#define AG71XX_REG_MII_CTRL 0x002c +#define AG71XX_REG_MII_STATUS 0x0030 +#define AG71XX_REG_MII_IND 0x0034 +#define AG71XX_REG_MAC_IFCTL 0x0038 +#define AG71XX_REG_MAC_ADDR1 0x0040 +#define AG71XX_REG_MAC_ADDR2 0x0044 +#define AG71XX_REG_FIFO_CFG0 0x0048 +#define AG71XX_REG_FIFO_CFG1 0x004c +#define AG71XX_REG_FIFO_CFG2 0x0050 +#define AG71XX_REG_FIFO_CFG3 0x0054 +#define AG71XX_REG_FIFO_CFG4 0x0058 +#define AG71XX_REG_FIFO_CFG5 0x005c +#define AG71XX_REG_FIFO_RAM0 0x0060 +#define AG71XX_REG_FIFO_RAM1 0x0064 +#define AG71XX_REG_FIFO_RAM2 0x0068 +#define AG71XX_REG_FIFO_RAM3 0x006c +#define AG71XX_REG_FIFO_RAM4 0x0070 +#define AG71XX_REG_FIFO_RAM5 0x0074 +#define AG71XX_REG_FIFO_RAM6 0x0078 +#define AG71XX_REG_FIFO_RAM7 0x007c + +#define AG71XX_REG_TX_CTRL 0x0180 +#define AG71XX_REG_TX_DESC 0x0184 +#define AG71XX_REG_TX_STATUS 0x0188 +#define AG71XX_REG_RX_CTRL 0x018c +#define AG71XX_REG_RX_DESC 0x0190 +#define AG71XX_REG_RX_STATUS 0x0194 +#define AG71XX_REG_INT_ENABLE 0x0198 +#define AG71XX_REG_INT_STATUS 0x019c + +#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ +#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ +#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ +#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ +#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ +#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ +#define MAC_CFG1_LB BIT(8) /* Loopback mode */ +#define MAC_CFG1_SR BIT(31) /* Soft Reset */ + +#define MAC_CFG2_FDX BIT(0) +#define MAC_CFG2_CRC_EN BIT(1) +#define MAC_CFG2_PAD_CRC_EN BIT(2) +#define MAC_CFG2_LEN_CHECK BIT(4) +#define MAC_CFG2_HUGE_FRAME_EN BIT(5) +#define MAC_CFG2_IF_1000 BIT(9) +#define MAC_CFG2_IF_10_100 BIT(8) + +#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ +#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ +#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ +#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ +#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ +#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ + | FIFO_CFG0_TXS | FIFO_CFG0_TXF) + +#define FIFO_CFG0_ENABLE_SHIFT 8 + +#define FIFO_CFG4_DE BIT(0) /* Drop Event */ +#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ +#define FIFO_CFG4_FC BIT(2) /* False Carrier */ +#define FIFO_CFG4_CE BIT(3) /* Code Error */ +#define FIFO_CFG4_CR BIT(4) /* CRC error */ +#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ +#define FIFO_CFG4_LO BIT(6) /* Length out of range */ +#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ +#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ +#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ +#define FIFO_CFG4_DR BIT(10) /* Dribble */ +#define FIFO_CFG4_LE BIT(11) /* Long Event */ +#define FIFO_CFG4_CF BIT(12) /* Control Frame */ +#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ +#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ +#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ +#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ +#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ + +#define FIFO_CFG5_DE BIT(0) /* Drop Event */ +#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ +#define FIFO_CFG5_FC BIT(2) /* False Carrier */ +#define FIFO_CFG5_CE BIT(3) /* Code Error */ +#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ +#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ +#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ +#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ +#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ +#define FIFO_CFG5_DR BIT(9) /* Dribble */ +#define FIFO_CFG5_CF BIT(10) /* Control Frame */ +#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ +#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ +#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ +#define FIFO_CFG5_LE BIT(14) /* Long Event */ +#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ +#define FIFO_CFG5_16 BIT(16) /* unknown */ +#define FIFO_CFG5_17 BIT(17) /* unknown */ +#define FIFO_CFG5_SF BIT(18) /* Short Frame */ +#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ + +#define AG71XX_INT_TX_PS BIT(0) +#define AG71XX_INT_TX_UR BIT(1) +#define AG71XX_INT_TX_BE BIT(3) +#define AG71XX_INT_RX_PR BIT(4) +#define AG71XX_INT_RX_OF BIT(6) +#define AG71XX_INT_RX_BE BIT(7) + +#define MAC_IFCTL_SPEED BIT(16) + +#define MII_CFG_CLK_DIV_4 0 +#define MII_CFG_CLK_DIV_6 2 +#define MII_CFG_CLK_DIV_8 3 +#define MII_CFG_CLK_DIV_10 4 +#define MII_CFG_CLK_DIV_14 5 +#define MII_CFG_CLK_DIV_20 6 +#define MII_CFG_CLK_DIV_28 7 +#define MII_CFG_RESET BIT(31) + +#define MII_CMD_WRITE 0x0 +#define MII_CMD_READ 0x1 +#define MII_ADDR_SHIFT 8 +#define MII_IND_BUSY BIT(0) +#define MII_IND_INVALID BIT(2) + +#define TX_CTRL_TXE BIT(0) /* Tx Enable */ + +#define TX_STATUS_PS BIT(0) /* Packet Sent */ +#define TX_STATUS_UR BIT(1) /* Tx Underrun */ +#define TX_STATUS_BE BIT(3) /* Bus Error */ + +#define RX_CTRL_RXE BIT(0) /* Rx Enable */ + +#define RX_STATUS_PR BIT(0) /* Packet Received */ +#define RX_STATUS_OF BIT(2) /* Rx Overflow */ +#define RX_STATUS_BE BIT(3) /* Bus Error */ + +#define MII_CTRL_IF_MASK 3 +#define MII_CTRL_SPEED_SHIFT 4 +#define MII_CTRL_SPEED_MASK 3 +#define MII_CTRL_SPEED_10 0 +#define MII_CTRL_SPEED_100 1 +#define MII_CTRL_SPEED_1000 2 + +static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) +{ + __raw_writel(value, ag->mac_base + reg); + /* flush write */ + (void) __raw_readl(ag->mac_base + reg); +} + +static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) +{ + return __raw_readl(ag->mac_base + reg); +} + +static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) +{ + uint32_t r; + + r = ag->mac_base + reg; + __raw_writel(__raw_readl(r) | mask, r); + /* flush write */ + (void)__raw_readl(r); +} + +static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) +{ + uint32_t r; + + r = ag->mac_base + reg; + __raw_writel(__raw_readl(r) & ~mask, r); + /* flush write */ + (void) __raw_readl(r); +} + +static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) +{ + ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); +} + +static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) +{ + ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); +} + +static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value) +{ + __raw_writel(value, ag->mii_ctrl); + + /* flush write */ + __raw_readl(ag->mii_ctrl); +} + +static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag) +{ + return __raw_readl(ag->mii_ctrl); +} + +static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag, + unsigned int mii_if) +{ + u32 t; + + t = ag71xx_mii_ctrl_rr(ag); + t &= ~(MII_CTRL_IF_MASK); + t |= (mii_if & MII_CTRL_IF_MASK); + ag71xx_mii_ctrl_wr(ag, t); +} + +static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, + unsigned int speed) +{ + u32 t; + + t = ag71xx_mii_ctrl_rr(ag); + t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT); + t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT; + ag71xx_mii_ctrl_wr(ag, t); +} + +#ifdef CONFIG_AG71XX_AR8216_SUPPORT +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, + int pktlen); +static inline int ag71xx_has_ar8216(struct ag71xx *ag) +{ + return ag71xx_get_pdata(ag)->has_ar8216; +} +#else +static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, + struct sk_buff *skb) +{ +} + +static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, + struct sk_buff *skb, + int pktlen) +{ + return 0; +} +static inline int ag71xx_has_ar8216(struct ag71xx *ag) +{ + return 0; +} +#endif + +#endif /* _AG71XX_H */ diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/entries b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/entries new file mode 100644 index 0000000..ad8ef18 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/drivers/net/phy +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +rtl8366_mii.c +file + + + + +2013-03-17T12:13:21.000000Z +2075819b75c9da42261c89c49b53bf2d +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +18599 + +rtl8366.h +file + + + + +2013-03-17T12:13:21.000000Z +6bca21a0bce104b8b2de10207b04b584 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +6036 + diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366.h.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366.h.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366.h.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366_mii.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366_mii.c.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/prop-base/rtl8366_mii.c.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366.h.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366.h.svn-base new file mode 100644 index 0000000..f0567dd --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366.h.svn-base @@ -0,0 +1,188 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef RTL8366_MII_H +#define RTL8366_MII_H + +#define MII_CONTROL_REG 0 +#define MII_STATUS_REG 1 +#define MII_PHY_ID0 2 +#define MII_PHY_ID1 3 +#define MII_LOCAL_CAP 4 +#define MII_REMOTE_CAP 5 +#define MII_EXT_AUTONEG 6 +#define MII_LOCAL_NEXT_PAGE 7 +#define MII_REMOTE_NEXT_PAGE 8 +#define MII_GIGA_CONTROL 9 +#define MII_GIGA_STATUS 10 +#define MII_EXT_STATUS_REG 15 + +/* Control register */ +#define MII_CONTROL_1000MBPS 6 +#define MII_CONTROL_COLL_TEST 7 +#define MII_CONTROL_FULLDUPLEX 8 +#define MII_CONTROL_RENEG 9 +#define MII_CONTROL_ISOLATE 10 +#define MII_CONTROL_POWERDOWN 11 +#define MII_CONTROL_AUTONEG 12 +#define MII_CONTROL_100MBPS 13 +#define MII_CONTROL_LOOPBACK 14 +#define MII_CONTROL_RESET 15 + +/* Status/Extended status register */ +/* Basic status */ +#define MII_STATUS_CAPABILITY 0 +#define MII_STATUS_JABBER 1 +#define MII_STATUS_LINK_UP 2 +#define MII_STATUS_AUTONEG_ABLE 3 +#define MII_STATUS_REMOTE_FAULT 4 +#define MII_STATUS_AUTONEG_DONE 5 +#define MII_STATUS_NO_PREAMBLE 6 +#define MII_STATUS_RESERVED 7 +#define MII_STATUS_EXTENDED 8 +#define MII_STATUS_100_T2_HALF 9 +#define MII_STATUS_100_T2_FULL 10 +#define MII_STATUS_10_TX_HALF 11 +#define MII_STATUS_10_TX_FULL 12 +#define MII_STATUS_100_TX_HALF 13 +#define MII_STATUS_100_TX_FULL 14 +#define MII_STATUS_100_T4 15 + +#define MII_GIGA_CONTROL_HALF 8 +#define MII_GIGA_CONTROL_FULL 9 +#define MII_GIGA_STATUS_HALF 10 +#define MII_GIGA_STATUS_FULL 11 + +/* Extended status */ +#define MII_STATUS_1000_T_HALF 12 +#define MII_STATUS_1000_T_FULL 13 +#define MII_STATUS_1000_X_HALF 14 +#define MII_STATUS_1000_X_FULL 15 + +/* Local/Remmote capability register */ +#define MII_CAP_10BASE_TX 5 +#define MII_CAP_10BASE_TX_FULL 6 +#define MII_CAP_100BASE_TX 7 +#define MII_CAP_100BASE_TX_FULL 8 +#define MII_CAP_100BASE_T4 9 +#define MII_CAP_SYMM_PAUSE 10 +#define MII_CAP_ASYMM_PAUSE 11 +#define MII_CAP_RESERVED 12 +#define MII_CAP_REMOTE_FAULT 13 +#define MII_CAP_ACKNOWLEDGE 14 +#define MII_CAP_NEXT_PAGE 15 +#define MII_CAP_IEEE_802_3 0x0001 + +#define MII_LINK_MODE_MASK 0x1f + +#define REALTEK_RTL8366_CHIP_ID0 0x001C +#define REALTEK_RTL8366_CHIP_ID1 0xC940 +#define REALTEK_RTL8366_CHIP_ID1_MP 0xC960 + +#define REALTEK_MIN_PORT_ID 0 +#define REALTEK_MAX_PORT_ID 5 +#define REALTEK_MIN_PHY_ID REALTEK_MIN_PORT_ID +#define REALTEK_MAX_PHY_ID 4 +#define REALTEK_CPU_PORT_ID REALTEK_MAX_PORT_ID +#define REALTEK_PHY_PORT_MASK ((1<<(REALTEK_MAX_PHY_ID+1)) - (1<<REALTEK_MIN_PHY_ID)) +#define REALTEK_CPU_PORT_MASK (1<<REALTEK_CPU_PORT_ID) +#define REALTEK_ALL_PORT_MASK (REALTEK_PHY_PORT_MASK | REALTEK_CPU_PORT_MASK) + +/* port ability */ +#define RTL8366S_PORT_ABILITY_BASE 0x0011 + +/* port vlan control register */ +#define RTL8366S_PORT_VLAN_CTRL_BASE 0x0058 + +/* port linking status */ +#define RTL8366S_PORT_LINK_STATUS_BASE 0x0060 +#define RTL8366S_PORT_STATUS_SPEED_BIT 0 +#define RTL8366S_PORT_STATUS_SPEED_MSK 0x0003 +#define RTL8366S_PORT_STATUS_DUPLEX_BIT 2 +#define RTL8366S_PORT_STATUS_DUPLEX_MSK 0x0004 +#define RTL8366S_PORT_STATUS_LINK_BIT 4 +#define RTL8366S_PORT_STATUS_LINK_MSK 0x0010 +#define RTL8366S_PORT_STATUS_TXPAUSE_BIT 5 +#define RTL8366S_PORT_STATUS_TXPAUSE_MSK 0x0020 +#define RTL8366S_PORT_STATUS_RXPAUSE_BIT 6 +#define RTL8366S_PORT_STATUS_RXPAUSE_MSK 0x0040 +#define RTL8366S_PORT_STATUS_AN_BIT 7 +#define RTL8366S_PORT_STATUS_AN_MSK 0x0080 + +/* internal control */ +#define RTL8366S_RESET_CONTROL_REG 0x0100 +#define RTL8366S_RESET_QUEUE_BIT 2 + +#define RTL8366S_CHIP_ID_REG 0x0105 + +/* MAC control */ +#define RTL8366S_MAC_FORCE_CTRL0_REG 0x0F04 +#define RTL8366S_MAC_FORCE_CTRL1_REG 0x0F05 + + +/* PHY registers control */ +#define RTL8366S_PHY_ACCESS_CTRL_REG 0x8028 +#define RTL8366S_PHY_ACCESS_DATA_REG 0x8029 + +#define RTL8366S_PHY_CTRL_READ 1 +#define RTL8366S_PHY_CTRL_WRITE 0 + +#define RTL8366S_PHY_REG_MASK 0x1F +#define RTL8366S_PHY_PAGE_OFFSET 5 +#define RTL8366S_PHY_PAGE_MASK (0x7<<5) +#define RTL8366S_PHY_NO_OFFSET 9 +#define RTL8366S_PHY_NO_MASK (0x1F<<9) + +#define RTL8366S_PHY_NO_MAX 4 +#define RTL8366S_PHY_PAGE_MAX 7 +#define RTL8366S_PHY_ADDR_MAX 31 + +/* cpu port control reg */ +#define RTL8366S_CPU_CTRL_REG 0x004F +#define RTL8366S_CPU_DRP_BIT 14 +#define RTL8366S_CPU_DRP_MSK 0x4000 +#define RTL8366S_CPU_INSTAG_BIT 15 +#define RTL8366S_CPU_INSTAG_MSK 0x8000 + +/* LED registers*/ +#define RTL8366S_LED_BLINK_REG 0x420 +#define RTL8366S_LED_BLINKRATE_BIT 0 +#define RTL8366S_LED_BLINKRATE_MSK 0x0007 +#define RTL8366S_LED_INDICATED_CONF_REG 0x421 +#define RTL8366S_LED_0_1_FORCE_REG 0x422 +#define RTL8366S_LED_2_3_FORCE_REG 0x423 +#define RTL8366S_LEDCONF_LEDFORCE 0x1F +#define RTL8366S_LED_GROUP_MAX 4 + +#define RTL8366S_GREEN_FEATURE_REG 0x000A +#define RTL8366S_GREEN_FEATURE_TX_BIT 3 +#define RTL8366S_GREEN_FEATURE_TX_MSK 0x0008 +#define RTL8366S_GREEN_FEATURE_RX_BIT 4 +#define RTL8366S_GREEN_FEATURE_RX_MSK 0x0010 + +#define RTL8366S_MODEL_ID_REG 0x5C +#define RTL8366S_REV_ID_REG 0x5D +#define RTL8366S_MODEL_8366SR 0x6027 +#define RTL8366S_MODEL_8366RB 0x5937 + +#endif diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366_mii.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366_mii.c.svn-base new file mode 100644 index 0000000..e3c5316 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/.svn/text-base/rtl8366_mii.c.svn-base @@ -0,0 +1,786 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include <common.h> +#include <net.h> +#include <netdev.h> +#include <miiphy.h> +#include MII_GPIOINCLUDE + +#include "rtl8366.h" + +#ifdef DEBUG_RTL8366 + #define DBG(fmt,args...) printf (fmt ,##args) +#else + #define DBG(fmt,args...) +#endif + + +//------------------------------------------------------------------- +// Soft SMI functions +//------------------------------------------------------------------- + +#define DELAY 2 + +static void smi_init(void) +{ + MII_SDAINPUT; + MII_SCKINPUT; + + MII_SETSDA(1); + MII_SETSCK(1); + + udelay(20); +} + +static void smi_start(void) +{ +/* + * rtl8366 chip needs a extra clock with + * SDA high before start condition + */ + + /* set gpio pins output */ + MII_SDAOUTPUT; + MII_SCKOUTPUT; + udelay(DELAY); + + /* set initial state: SCK:0, SDA:1 */ + MII_SETSCK(0); + MII_SETSDA(1); + udelay(DELAY); + + /* toggle clock */ + MII_SETSCK(1); + udelay(DELAY); + MII_SETSCK(0); + udelay(DELAY); + + /* start condition */ + MII_SETSCK(1); + udelay(DELAY); + MII_SETSDA(0); + udelay(DELAY); + MII_SETSCK(0); + udelay(DELAY); + MII_SETSDA(1); +} + +static void smi_stop(void) +{ +/* + * rtl8366 chip needs a extra clock with + * SDA high after stop condition + */ + + /* stop condition */ + udelay(DELAY); + MII_SETSDA(0); + MII_SETSCK(1); + udelay(DELAY); + MII_SETSDA(1); + udelay(DELAY); + MII_SETSCK(1); + udelay(DELAY); + MII_SETSCK(0); + udelay(DELAY); + + /* toggle clock */ + MII_SETSCK(1); + udelay(DELAY); + MII_SETSCK(0); + udelay(DELAY); + MII_SETSCK(1); + + /* set gpio pins input */ + MII_SDAINPUT; + MII_SCKINPUT; +} + +static void smi_writeBits(uint32_t data, uint8_t length) +{ + uint8_t test; + + for( ; length > 0; length--) { + udelay(DELAY); + + /* output data */ + test = (((data & (1 << (length - 1))) != 0) ? 1 : 0); + MII_SETSDA(test); + udelay(DELAY); + + /* toogle clock */ + MII_SETSCK(1); + udelay(DELAY); + MII_SETSCK(0); + } +} + +static uint32_t smi_readBits(uint8_t length) +{ + uint32_t ret; + + MII_SDAINPUT; + + for(ret = 0 ; length > 0; length--) { + udelay(DELAY); + + ret <<= 1; + + /* toogle clock */ + MII_SETSCK(1); + udelay(DELAY); + ret |= MII_GETSDA; + MII_SETSCK(0); + } + + MII_SDAOUTPUT; + + return ret; +} + +static int smi_waitAck(void) +{ + uint32_t retry = 0; + + while (smi_readBits(1)) { + if (retry++ == 5) + return -1; + } + + return 0; + +} + +static int smi_read(uint32_t reg, uint32_t *data) +{ + uint32_t rawData; + + /* send start condition */ + smi_start(); + /* send CTRL1 code: 0b1010*/ + smi_writeBits(0x0a, 4); + /* send CTRL2 code: 0b100 */ + smi_writeBits(0x04, 3); + /* send READ command */ + smi_writeBits(0x01, 1); + + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* send address low */ + smi_writeBits(reg & 0xFF, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + /* send address high */ + smi_writeBits((reg & 0xFF00) >> 8, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* read data low */ + rawData = (smi_readBits(8) & 0xFF); + /* send ACK */ + smi_writeBits(0, 1); + /* read data high */ + rawData |= (smi_readBits(8) & 0xFF) << 8; + /* send NACK */ + smi_writeBits(1, 1); + + /* send stop condition */ + smi_stop(); + + if (data) + *data = rawData; + + return 0; +} + +static int smi_write(uint32_t reg, uint32_t data) +{ + /* send start condition */ + smi_start(); + /* send CTRL1 code: 0b1010*/ + smi_writeBits(0x0a, 4); + /* send CTRL2 code: 0b100 */ + smi_writeBits(0x04, 3); + /* send WRITE command */ + smi_writeBits(0x00, 1); + + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* send address low */ + smi_writeBits(reg & 0xFF, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + /* send address high */ + smi_writeBits((reg & 0xFF00) >> 8, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* send data low */ + smi_writeBits(data & 0xFF, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + /* send data high */ + smi_writeBits((data & 0xFF00) >> 8, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* send stop condition */ + smi_stop(); + + return 0; +} + + +//------------------------------------------------------------------- +// Switch register read / write functions +//------------------------------------------------------------------- +static int rtl8366_readRegister(uint32_t reg, uint16_t *data) +{ + uint32_t regData; + + DBG("rtl8366: read register=%#04x, data=", reg); + + if (smi_read(reg, ®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/net/phy/rtl8366.h b/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h new file mode 100644 index 0000000..f0567dd --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h @@ -0,0 +1,188 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef RTL8366_MII_H +#define RTL8366_MII_H + +#define MII_CONTROL_REG 0 +#define MII_STATUS_REG 1 +#define MII_PHY_ID0 2 +#define MII_PHY_ID1 3 +#define MII_LOCAL_CAP 4 +#define MII_REMOTE_CAP 5 +#define MII_EXT_AUTONEG 6 +#define MII_LOCAL_NEXT_PAGE 7 +#define MII_REMOTE_NEXT_PAGE 8 +#define MII_GIGA_CONTROL 9 +#define MII_GIGA_STATUS 10 +#define MII_EXT_STATUS_REG 15 + +/* Control register */ +#define MII_CONTROL_1000MBPS 6 +#define MII_CONTROL_COLL_TEST 7 +#define MII_CONTROL_FULLDUPLEX 8 +#define MII_CONTROL_RENEG 9 +#define MII_CONTROL_ISOLATE 10 +#define MII_CONTROL_POWERDOWN 11 +#define MII_CONTROL_AUTONEG 12 +#define MII_CONTROL_100MBPS 13 +#define MII_CONTROL_LOOPBACK 14 +#define MII_CONTROL_RESET 15 + +/* Status/Extended status register */ +/* Basic status */ +#define MII_STATUS_CAPABILITY 0 +#define MII_STATUS_JABBER 1 +#define MII_STATUS_LINK_UP 2 +#define MII_STATUS_AUTONEG_ABLE 3 +#define MII_STATUS_REMOTE_FAULT 4 +#define MII_STATUS_AUTONEG_DONE 5 +#define MII_STATUS_NO_PREAMBLE 6 +#define MII_STATUS_RESERVED 7 +#define MII_STATUS_EXTENDED 8 +#define MII_STATUS_100_T2_HALF 9 +#define MII_STATUS_100_T2_FULL 10 +#define MII_STATUS_10_TX_HALF 11 +#define MII_STATUS_10_TX_FULL 12 +#define MII_STATUS_100_TX_HALF 13 +#define MII_STATUS_100_TX_FULL 14 +#define MII_STATUS_100_T4 15 + +#define MII_GIGA_CONTROL_HALF 8 +#define MII_GIGA_CONTROL_FULL 9 +#define MII_GIGA_STATUS_HALF 10 +#define MII_GIGA_STATUS_FULL 11 + +/* Extended status */ +#define MII_STATUS_1000_T_HALF 12 +#define MII_STATUS_1000_T_FULL 13 +#define MII_STATUS_1000_X_HALF 14 +#define MII_STATUS_1000_X_FULL 15 + +/* Local/Remmote capability register */ +#define MII_CAP_10BASE_TX 5 +#define MII_CAP_10BASE_TX_FULL 6 +#define MII_CAP_100BASE_TX 7 +#define MII_CAP_100BASE_TX_FULL 8 +#define MII_CAP_100BASE_T4 9 +#define MII_CAP_SYMM_PAUSE 10 +#define MII_CAP_ASYMM_PAUSE 11 +#define MII_CAP_RESERVED 12 +#define MII_CAP_REMOTE_FAULT 13 +#define MII_CAP_ACKNOWLEDGE 14 +#define MII_CAP_NEXT_PAGE 15 +#define MII_CAP_IEEE_802_3 0x0001 + +#define MII_LINK_MODE_MASK 0x1f + +#define REALTEK_RTL8366_CHIP_ID0 0x001C +#define REALTEK_RTL8366_CHIP_ID1 0xC940 +#define REALTEK_RTL8366_CHIP_ID1_MP 0xC960 + +#define REALTEK_MIN_PORT_ID 0 +#define REALTEK_MAX_PORT_ID 5 +#define REALTEK_MIN_PHY_ID REALTEK_MIN_PORT_ID +#define REALTEK_MAX_PHY_ID 4 +#define REALTEK_CPU_PORT_ID REALTEK_MAX_PORT_ID +#define REALTEK_PHY_PORT_MASK ((1<<(REALTEK_MAX_PHY_ID+1)) - (1<<REALTEK_MIN_PHY_ID)) +#define REALTEK_CPU_PORT_MASK (1<<REALTEK_CPU_PORT_ID) +#define REALTEK_ALL_PORT_MASK (REALTEK_PHY_PORT_MASK | REALTEK_CPU_PORT_MASK) + +/* port ability */ +#define RTL8366S_PORT_ABILITY_BASE 0x0011 + +/* port vlan control register */ +#define RTL8366S_PORT_VLAN_CTRL_BASE 0x0058 + +/* port linking status */ +#define RTL8366S_PORT_LINK_STATUS_BASE 0x0060 +#define RTL8366S_PORT_STATUS_SPEED_BIT 0 +#define RTL8366S_PORT_STATUS_SPEED_MSK 0x0003 +#define RTL8366S_PORT_STATUS_DUPLEX_BIT 2 +#define RTL8366S_PORT_STATUS_DUPLEX_MSK 0x0004 +#define RTL8366S_PORT_STATUS_LINK_BIT 4 +#define RTL8366S_PORT_STATUS_LINK_MSK 0x0010 +#define RTL8366S_PORT_STATUS_TXPAUSE_BIT 5 +#define RTL8366S_PORT_STATUS_TXPAUSE_MSK 0x0020 +#define RTL8366S_PORT_STATUS_RXPAUSE_BIT 6 +#define RTL8366S_PORT_STATUS_RXPAUSE_MSK 0x0040 +#define RTL8366S_PORT_STATUS_AN_BIT 7 +#define RTL8366S_PORT_STATUS_AN_MSK 0x0080 + +/* internal control */ +#define RTL8366S_RESET_CONTROL_REG 0x0100 +#define RTL8366S_RESET_QUEUE_BIT 2 + +#define RTL8366S_CHIP_ID_REG 0x0105 + +/* MAC control */ +#define RTL8366S_MAC_FORCE_CTRL0_REG 0x0F04 +#define RTL8366S_MAC_FORCE_CTRL1_REG 0x0F05 + + +/* PHY registers control */ +#define RTL8366S_PHY_ACCESS_CTRL_REG 0x8028 +#define RTL8366S_PHY_ACCESS_DATA_REG 0x8029 + +#define RTL8366S_PHY_CTRL_READ 1 +#define RTL8366S_PHY_CTRL_WRITE 0 + +#define RTL8366S_PHY_REG_MASK 0x1F +#define RTL8366S_PHY_PAGE_OFFSET 5 +#define RTL8366S_PHY_PAGE_MASK (0x7<<5) +#define RTL8366S_PHY_NO_OFFSET 9 +#define RTL8366S_PHY_NO_MASK (0x1F<<9) + +#define RTL8366S_PHY_NO_MAX 4 +#define RTL8366S_PHY_PAGE_MAX 7 +#define RTL8366S_PHY_ADDR_MAX 31 + +/* cpu port control reg */ +#define RTL8366S_CPU_CTRL_REG 0x004F +#define RTL8366S_CPU_DRP_BIT 14 +#define RTL8366S_CPU_DRP_MSK 0x4000 +#define RTL8366S_CPU_INSTAG_BIT 15 +#define RTL8366S_CPU_INSTAG_MSK 0x8000 + +/* LED registers*/ +#define RTL8366S_LED_BLINK_REG 0x420 +#define RTL8366S_LED_BLINKRATE_BIT 0 +#define RTL8366S_LED_BLINKRATE_MSK 0x0007 +#define RTL8366S_LED_INDICATED_CONF_REG 0x421 +#define RTL8366S_LED_0_1_FORCE_REG 0x422 +#define RTL8366S_LED_2_3_FORCE_REG 0x423 +#define RTL8366S_LEDCONF_LEDFORCE 0x1F +#define RTL8366S_LED_GROUP_MAX 4 + +#define RTL8366S_GREEN_FEATURE_REG 0x000A +#define RTL8366S_GREEN_FEATURE_TX_BIT 3 +#define RTL8366S_GREEN_FEATURE_TX_MSK 0x0008 +#define RTL8366S_GREEN_FEATURE_RX_BIT 4 +#define RTL8366S_GREEN_FEATURE_RX_MSK 0x0010 + +#define RTL8366S_MODEL_ID_REG 0x5C +#define RTL8366S_REV_ID_REG 0x5D +#define RTL8366S_MODEL_8366SR 0x6027 +#define RTL8366S_MODEL_8366RB 0x5937 + +#endif diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366_mii.c b/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366_mii.c new file mode 100644 index 0000000..e3c5316 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366_mii.c @@ -0,0 +1,786 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include <common.h> +#include <net.h> +#include <netdev.h> +#include <miiphy.h> +#include MII_GPIOINCLUDE + +#include "rtl8366.h" + +#ifdef DEBUG_RTL8366 + #define DBG(fmt,args...) printf (fmt ,##args) +#else + #define DBG(fmt,args...) +#endif + + +//------------------------------------------------------------------- +// Soft SMI functions +//------------------------------------------------------------------- + +#define DELAY 2 + +static void smi_init(void) +{ + MII_SDAINPUT; + MII_SCKINPUT; + + MII_SETSDA(1); + MII_SETSCK(1); + + udelay(20); +} + +static void smi_start(void) +{ +/* + * rtl8366 chip needs a extra clock with + * SDA high before start condition + */ + + /* set gpio pins output */ + MII_SDAOUTPUT; + MII_SCKOUTPUT; + udelay(DELAY); + + /* set initial state: SCK:0, SDA:1 */ + MII_SETSCK(0); + MII_SETSDA(1); + udelay(DELAY); + + /* toggle clock */ + MII_SETSCK(1); + udelay(DELAY); + MII_SETSCK(0); + udelay(DELAY); + + /* start condition */ + MII_SETSCK(1); + udelay(DELAY); + MII_SETSDA(0); + udelay(DELAY); + MII_SETSCK(0); + udelay(DELAY); + MII_SETSDA(1); +} + +static void smi_stop(void) +{ +/* + * rtl8366 chip needs a extra clock with + * SDA high after stop condition + */ + + /* stop condition */ + udelay(DELAY); + MII_SETSDA(0); + MII_SETSCK(1); + udelay(DELAY); + MII_SETSDA(1); + udelay(DELAY); + MII_SETSCK(1); + udelay(DELAY); + MII_SETSCK(0); + udelay(DELAY); + + /* toggle clock */ + MII_SETSCK(1); + udelay(DELAY); + MII_SETSCK(0); + udelay(DELAY); + MII_SETSCK(1); + + /* set gpio pins input */ + MII_SDAINPUT; + MII_SCKINPUT; +} + +static void smi_writeBits(uint32_t data, uint8_t length) +{ + uint8_t test; + + for( ; length > 0; length--) { + udelay(DELAY); + + /* output data */ + test = (((data & (1 << (length - 1))) != 0) ? 1 : 0); + MII_SETSDA(test); + udelay(DELAY); + + /* toogle clock */ + MII_SETSCK(1); + udelay(DELAY); + MII_SETSCK(0); + } +} + +static uint32_t smi_readBits(uint8_t length) +{ + uint32_t ret; + + MII_SDAINPUT; + + for(ret = 0 ; length > 0; length--) { + udelay(DELAY); + + ret <<= 1; + + /* toogle clock */ + MII_SETSCK(1); + udelay(DELAY); + ret |= MII_GETSDA; + MII_SETSCK(0); + } + + MII_SDAOUTPUT; + + return ret; +} + +static int smi_waitAck(void) +{ + uint32_t retry = 0; + + while (smi_readBits(1)) { + if (retry++ == 5) + return -1; + } + + return 0; + +} + +static int smi_read(uint32_t reg, uint32_t *data) +{ + uint32_t rawData; + + /* send start condition */ + smi_start(); + /* send CTRL1 code: 0b1010*/ + smi_writeBits(0x0a, 4); + /* send CTRL2 code: 0b100 */ + smi_writeBits(0x04, 3); + /* send READ command */ + smi_writeBits(0x01, 1); + + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* send address low */ + smi_writeBits(reg & 0xFF, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + /* send address high */ + smi_writeBits((reg & 0xFF00) >> 8, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* read data low */ + rawData = (smi_readBits(8) & 0xFF); + /* send ACK */ + smi_writeBits(0, 1); + /* read data high */ + rawData |= (smi_readBits(8) & 0xFF) << 8; + /* send NACK */ + smi_writeBits(1, 1); + + /* send stop condition */ + smi_stop(); + + if (data) + *data = rawData; + + return 0; +} + +static int smi_write(uint32_t reg, uint32_t data) +{ + /* send start condition */ + smi_start(); + /* send CTRL1 code: 0b1010*/ + smi_writeBits(0x0a, 4); + /* send CTRL2 code: 0b100 */ + smi_writeBits(0x04, 3); + /* send WRITE command */ + smi_writeBits(0x00, 1); + + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* send address low */ + smi_writeBits(reg & 0xFF, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + /* send address high */ + smi_writeBits((reg & 0xFF00) >> 8, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* send data low */ + smi_writeBits(data & 0xFF, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + /* send data high */ + smi_writeBits((data & 0xFF00) >> 8, 8); + /* wait for ACK */ + if (smi_waitAck()) + return -1; + + /* send stop condition */ + smi_stop(); + + return 0; +} + + +//------------------------------------------------------------------- +// Switch register read / write functions +//------------------------------------------------------------------- +static int rtl8366_readRegister(uint32_t reg, uint16_t *data) +{ + uint32_t regData; + + DBG("rtl8366: read register=%#04x, data=", reg); + + if (smi_read(reg, ®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/.svn/entries b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/entries new file mode 100644 index 0000000..cce4027 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/drivers/spi +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +ar71xx_spi.c +file + + + + +2013-03-17T12:13:21.000000Z +05e08eafb6374d1bcb71b0086f1da38f +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +4553 + diff --git a/package/boot/uboot-ar71xx/files/drivers/spi/.svn/prop-base/ar71xx_spi.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/prop-base/ar71xx_spi.c.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/prop-base/ar71xx_spi.c.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/drivers/spi/.svn/text-base/ar71xx_spi.c.svn-base b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/text-base/ar71xx_spi.c.svn-base new file mode 100644 index 0000000..bbe27b1 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/spi/.svn/text-base/ar71xx_spi.c.svn-base @@ -0,0 +1,191 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <malloc.h> +#include <spi.h> + +#include <asm/addrspace.h> +#include <asm/types.h> +#include <asm/ar71xx.h> + +/*----------------------------------------------------------------------- + * Definitions + */ + +#ifdef DEBUG_SPI +#define PRINTD(fmt,args...) printf (fmt ,##args) +#else +#define PRINTD(fmt,args...) +#endif + +struct ar71xx_spi_slave { + struct spi_slave slave; + unsigned int mode; +}; + +static inline struct ar71xx_spi_slave *to_ar71xx_spi(struct spi_slave *slave) +{ + return container_of(slave, struct ar71xx_spi_slave, slave); +} + +/*=====================================================================*/ +/* Public Functions */ +/*=====================================================================*/ + +/*----------------------------------------------------------------------- + * Initialization + */ + +void spi_init() +{ + PRINTD("ar71xx_spi: spi_init"); + + // Init SPI Hardware, disable remap, set clock + __raw_writel(0x43, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_CTRL)); + + PRINTD(" ---> out\n"); +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct ar71xx_spi_slave *ss; + + PRINTD("ar71xx_spi: spi_setup_slave"); + + if ((bus != 0) || (cs > 2)) + return NULL; + + ss = malloc(sizeof(struct ar71xx_spi_slave)); + if (!ss) + return NULL; + + ss->slave.bus = bus; + ss->slave.cs = cs; + ss->mode = mode; + + /* TODO: Use max_hz to limit the SCK rate */ + + PRINTD(" ---> out\n"); + + return &ss->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave); + + free(ss); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave); + uint8_t *rx = din; + const uint8_t *tx = dout; + uint8_t curbyte, curbitlen, restbits; + uint32_t bytes = bitlen / 8; + uint32_t out; + uint32_t in; + + PRINTD("ar71xx_spi: spi_xfer: slave:%p bitlen:%08x dout:%p din:%p flags:%08x\n", slave, bitlen, dout, din, flags); + + if (flags & SPI_XFER_BEGIN) { + __raw_writel(SPI_FS_GPIO, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS)); + __raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + } + + restbits = (bitlen % 8); + if (restbits != 0) + bytes++; + + // enable chip select + out = SPI_IOC_CS_ALL & ~(SPI_IOC_CS(slave->cs)); + + while (bytes--) { + + curbyte = 0; + if (tx) { + curbyte = *tx++; + } + + if (restbits != 0) { + curbitlen = restbits; + curbyte <<= 8 - restbits; + } else { + curbitlen = 8; + } + + PRINTD("ar71xx_spi: sending: data:%02x length:%d\n", curbyte, curbitlen); + + /* clock starts at inactive polarity */ + for (curbyte <<= (8 - curbitlen); curbitlen; curbitlen--) { + + if (curbyte & (1 << 7)) + out |= SPI_IOC_DO; + else + out &= ~(SPI_IOC_DO); + + /* setup MSB (to slave) on trailing edge */ + __raw_writel(out, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + + __raw_writel(out | SPI_IOC_CLK, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + + curbyte <<= 1; + } + + in = __raw_readl(KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_RDS)); + PRINTD("ar71xx_spi: received:%02x\n", in); + + if (rx) { + if (restbits == 0) { + *rx++ = in; + } else { + *rx++ = (in << (8 - restbits)); + } + } + } + + if (flags & SPI_XFER_END) { + __raw_writel(SPI_IOC_CS(slave->cs), KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + __raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + __raw_writel(0, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS)); + } + + PRINTD(" ---> out\n"); + + return 0; +} diff --git a/package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c b/package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c new file mode 100644 index 0000000..bbe27b1 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c @@ -0,0 +1,191 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <malloc.h> +#include <spi.h> + +#include <asm/addrspace.h> +#include <asm/types.h> +#include <asm/ar71xx.h> + +/*----------------------------------------------------------------------- + * Definitions + */ + +#ifdef DEBUG_SPI +#define PRINTD(fmt,args...) printf (fmt ,##args) +#else +#define PRINTD(fmt,args...) +#endif + +struct ar71xx_spi_slave { + struct spi_slave slave; + unsigned int mode; +}; + +static inline struct ar71xx_spi_slave *to_ar71xx_spi(struct spi_slave *slave) +{ + return container_of(slave, struct ar71xx_spi_slave, slave); +} + +/*=====================================================================*/ +/* Public Functions */ +/*=====================================================================*/ + +/*----------------------------------------------------------------------- + * Initialization + */ + +void spi_init() +{ + PRINTD("ar71xx_spi: spi_init"); + + // Init SPI Hardware, disable remap, set clock + __raw_writel(0x43, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_CTRL)); + + PRINTD(" ---> out\n"); +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct ar71xx_spi_slave *ss; + + PRINTD("ar71xx_spi: spi_setup_slave"); + + if ((bus != 0) || (cs > 2)) + return NULL; + + ss = malloc(sizeof(struct ar71xx_spi_slave)); + if (!ss) + return NULL; + + ss->slave.bus = bus; + ss->slave.cs = cs; + ss->mode = mode; + + /* TODO: Use max_hz to limit the SCK rate */ + + PRINTD(" ---> out\n"); + + return &ss->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave); + + free(ss); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave); + uint8_t *rx = din; + const uint8_t *tx = dout; + uint8_t curbyte, curbitlen, restbits; + uint32_t bytes = bitlen / 8; + uint32_t out; + uint32_t in; + + PRINTD("ar71xx_spi: spi_xfer: slave:%p bitlen:%08x dout:%p din:%p flags:%08x\n", slave, bitlen, dout, din, flags); + + if (flags & SPI_XFER_BEGIN) { + __raw_writel(SPI_FS_GPIO, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS)); + __raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + } + + restbits = (bitlen % 8); + if (restbits != 0) + bytes++; + + // enable chip select + out = SPI_IOC_CS_ALL & ~(SPI_IOC_CS(slave->cs)); + + while (bytes--) { + + curbyte = 0; + if (tx) { + curbyte = *tx++; + } + + if (restbits != 0) { + curbitlen = restbits; + curbyte <<= 8 - restbits; + } else { + curbitlen = 8; + } + + PRINTD("ar71xx_spi: sending: data:%02x length:%d\n", curbyte, curbitlen); + + /* clock starts at inactive polarity */ + for (curbyte <<= (8 - curbitlen); curbitlen; curbitlen--) { + + if (curbyte & (1 << 7)) + out |= SPI_IOC_DO; + else + out &= ~(SPI_IOC_DO); + + /* setup MSB (to slave) on trailing edge */ + __raw_writel(out, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + + __raw_writel(out | SPI_IOC_CLK, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + + curbyte <<= 1; + } + + in = __raw_readl(KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_RDS)); + PRINTD("ar71xx_spi: received:%02x\n", in); + + if (rx) { + if (restbits == 0) { + *rx++ = in; + } else { + *rx++ = (in << (8 - restbits)); + } + } + } + + if (flags & SPI_XFER_END) { + __raw_writel(SPI_IOC_CS(slave->cs), KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + __raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC)); + __raw_writel(0, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS)); + } + + PRINTD(" ---> out\n"); + + return 0; +} diff --git a/package/boot/uboot-ar71xx/files/include/.svn/entries b/package/boot/uboot-ar71xx/files/include/.svn/entries new file mode 100644 index 0000000..cbf4917 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/include +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +asm-mips +dir + +configs +dir + diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/entries b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/entries new file mode 100644 index 0000000..809e843 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/include/asm-mips +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +ar71xx.h +file + + + + +2013-03-17T12:13:21.000000Z +e270582146693e6df5a2d8040e54fb39 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +15446 + +ar71xx_gpio.h +file + + + + +2013-03-17T12:13:21.000000Z +7cdaa64219ae76e79afff6ad44338dc2 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +1842 + diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx.h.svn-base b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx.h.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx.h.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx_gpio.h.svn-base b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx_gpio.h.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/prop-base/ar71xx_gpio.h.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx.h.svn-base b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx.h.svn-base new file mode 100644 index 0000000..e8f3f61 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx.h.svn-base @@ -0,0 +1,515 @@ +/* + * Atheros AR71xx SoC specific definitions + * + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> + * + * Parts of this file are based on Atheros' 2.6.15 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __ASM_MACH_AR71XX_H +#define __ASM_MACH_AR71XX_H + +#include <linux/types.h> +#include <asm/io.h> +#include <linux/bitops.h> + +#ifndef __ASSEMBLER__ + +#define BIT(x) (1<<(x)) + +#define AR71XX_PCI_MEM_BASE 0x10000000 +#define AR71XX_PCI_MEM_SIZE 0x08000000 +#define AR71XX_APB_BASE 0x18000000 +#define AR71XX_GE0_BASE 0x19000000 +#define AR71XX_GE0_SIZE 0x01000000 +#define AR71XX_GE1_BASE 0x1a000000 +#define AR71XX_GE1_SIZE 0x01000000 +#define AR71XX_EHCI_BASE 0x1b000000 +#define AR71XX_EHCI_SIZE 0x01000000 +#define AR71XX_OHCI_BASE 0x1c000000 +#define AR71XX_OHCI_SIZE 0x01000000 +#define AR7240_OHCI_BASE 0x1b000000 +#define AR7240_OHCI_SIZE 0x01000000 +#define AR71XX_SPI_BASE 0x1f000000 +#define AR71XX_SPI_SIZE 0x01000000 + +#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) +#define AR71XX_DDR_CTRL_SIZE 0x10000 +#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000) +#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) +#define AR71XX_UART_SIZE 0x10000 +#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) +#define AR71XX_USB_CTRL_SIZE 0x10000 +#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000) +#define AR71XX_GPIO_SIZE 0x10000 +#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) +#define AR71XX_PLL_SIZE 0x10000 +#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) +#define AR71XX_RESET_SIZE 0x10000 +#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) +#define AR71XX_MII_SIZE 0x10000 +#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000) +#define AR71XX_SLIC_SIZE 0x10000 +#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000) +#define AR71XX_DMA_SIZE 0x10000 +#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000) +#define AR71XX_STEREO_SIZE 0x10000 + +#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000) +#define AR724X_PCI_CRP_SIZE 0x100 + +#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000) +#define AR724X_PCI_CTRL_SIZE 0x100 + +#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) +#define AR91XX_WMAC_SIZE 0x30000 + +#define AR71XX_MEM_SIZE_MIN 0x0200000 +#define AR71XX_MEM_SIZE_MAX 0x10000000 + +#define AR71XX_CPU_IRQ_BASE 0 +#define AR71XX_MISC_IRQ_BASE 8 +#define AR71XX_MISC_IRQ_COUNT 8 +#define AR71XX_GPIO_IRQ_BASE 16 +#define AR71XX_GPIO_IRQ_COUNT 32 +#define AR71XX_PCI_IRQ_BASE 48 +#define AR71XX_PCI_IRQ_COUNT 8 + +#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2) +#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3) +#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4) +#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5) +#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6) +#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7) + +#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0) +#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1) +#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2) +#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3) +#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4) +#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5) +#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6) +#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7) + +#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x)) + +#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0) +#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1) +#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2) +#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4) + +extern u32 ar71xx_ahb_freq; +extern u32 ar71xx_cpu_freq; +extern u32 ar71xx_ddr_freq; + +enum ar71xx_soc_type { + AR71XX_SOC_UNKNOWN, + AR71XX_SOC_AR7130, + AR71XX_SOC_AR7141, + AR71XX_SOC_AR7161, + AR71XX_SOC_AR7240, + AR71XX_SOC_AR7241, + AR71XX_SOC_AR7242, + AR71XX_SOC_AR9130, + AR71XX_SOC_AR9132 +}; + +extern enum ar71xx_soc_type ar71xx_soc; + +/* + * PLL block + */ +#define AR71XX_PLL_REG_CPU_CONFIG 0x00 +#define AR71XX_PLL_REG_SEC_CONFIG 0x04 +#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 +#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 + +#define AR71XX_PLL_DIV_SHIFT 3 +#define AR71XX_PLL_DIV_MASK 0x1f +#define AR71XX_CPU_DIV_SHIFT 16 +#define AR71XX_CPU_DIV_MASK 0x3 +#define AR71XX_DDR_DIV_SHIFT 18 +#define AR71XX_DDR_DIV_MASK 0x3 +#define AR71XX_AHB_DIV_SHIFT 20 +#define AR71XX_AHB_DIV_MASK 0x7 + +#define AR71XX_ETH0_PLL_SHIFT 17 +#define AR71XX_ETH1_PLL_SHIFT 19 + +#define AR724X_PLL_REG_CPU_CONFIG 0x00 +#define AR724X_PLL_REG_PCIE_CONFIG 0x18 + +#define AR724X_PLL_DIV_SHIFT 0 +#define AR724X_PLL_DIV_MASK 0x3ff +#define AR724X_PLL_REF_DIV_SHIFT 10 +#define AR724X_PLL_REF_DIV_MASK 0xf +#define AR724X_AHB_DIV_SHIFT 19 +#define AR724X_AHB_DIV_MASK 0x1 +#define AR724X_DDR_DIV_SHIFT 22 +#define AR724X_DDR_DIV_MASK 0x3 + +#define AR91XX_PLL_REG_CPU_CONFIG 0x00 +#define AR91XX_PLL_REG_ETH_CONFIG 0x04 +#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14 +#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18 + +#define AR91XX_PLL_DIV_SHIFT 0 +#define AR91XX_PLL_DIV_MASK 0x3ff +#define AR91XX_DDR_DIV_SHIFT 22 +#define AR91XX_DDR_DIV_MASK 0x3 +#define AR91XX_AHB_DIV_SHIFT 19 +#define AR91XX_AHB_DIV_MASK 0x1 + +#define AR91XX_ETH0_PLL_SHIFT 20 +#define AR91XX_ETH1_PLL_SHIFT 22 + +// extern void __iomem *ar71xx_pll_base; + +// static inline void ar71xx_pll_wr(unsigned reg, u32 val) +// { + // __raw_writel(val, ar71xx_pll_base + reg); +// } + +// static inline u32 ar71xx_pll_rr(unsigned reg) +// { + // return __raw_readl(ar71xx_pll_base + reg); +// } + +/* + * USB_CONFIG block + */ +#define USB_CTRL_REG_FLADJ 0x00 +#define USB_CTRL_REG_CONFIG 0x04 + +// extern void __iomem *ar71xx_usb_ctrl_base; + +// static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val) +// { + // __raw_writel(val, ar71xx_usb_ctrl_base + reg); +// } + +// static inline u32 ar71xx_usb_ctrl_rr(unsigned reg) +// { + // return __raw_readl(ar71xx_usb_ctrl_base + reg); +// } + +/* + * GPIO block + */ +#define GPIO_REG_OE 0x00 +#define GPIO_REG_IN 0x04 +#define GPIO_REG_OUT 0x08 +#define GPIO_REG_SET 0x0c +#define GPIO_REG_CLEAR 0x10 +#define GPIO_REG_INT_MODE 0x14 +#define GPIO_REG_INT_TYPE 0x18 +#define GPIO_REG_INT_POLARITY 0x1c +#define GPIO_REG_INT_PENDING 0x20 +#define GPIO_REG_INT_ENABLE 0x24 +#define GPIO_REG_FUNC 0x28 + +#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) +#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) +#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) +#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) +#define AR71XX_GPIO_FUNC_UART_EN BIT(8) +#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) +#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) + +#define AR71XX_GPIO_COUNT 16 + +#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) +#define AR724X_GPIO_FUNC_SPI_EN BIT(18) +#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) +#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) +#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) +#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) +#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) +#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) +#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) +#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) +#define AR724X_GPIO_FUNC_UART_EN BIT(1) +#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) + +#define AR724X_GPIO_COUNT 18 + +#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22) +#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) +#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20) +#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19) +#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18) +#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17) +#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16) +#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9) +#define AR91XX_GPIO_FUNC_UART_EN BIT(8) +#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4) + +#define AR91XX_GPIO_COUNT 22 + +// extern void __iomem *ar71xx_gpio_base; + +// static inline void ar71xx_gpio_wr(unsigned reg, u32 value) +// { + // __raw_writel(value, ar71xx_gpio_base + reg); +// } + +// static inline u32 ar71xx_gpio_rr(unsigned reg) +// { + // return __raw_readl(ar71xx_gpio_base + reg); +// } + +// void ar71xx_gpio_init(void) __init; +// void ar71xx_gpio_function_enable(u32 mask); +// void ar71xx_gpio_function_disable(u32 mask); +// void ar71xx_gpio_function_setup(u32 set, u32 clear); + +/* + * DDR_CTRL block + */ +#define AR71XX_DDR_REG_PCI_WIN0 0x7c +#define AR71XX_DDR_REG_PCI_WIN1 0x80 +#define AR71XX_DDR_REG_PCI_WIN2 0x84 +#define AR71XX_DDR_REG_PCI_WIN3 0x88 +#define AR71XX_DDR_REG_PCI_WIN4 0x8c +#define AR71XX_DDR_REG_PCI_WIN5 0x90 +#define AR71XX_DDR_REG_PCI_WIN6 0x94 +#define AR71XX_DDR_REG_PCI_WIN7 0x98 +#define AR71XX_DDR_REG_FLUSH_GE0 0x9c +#define AR71XX_DDR_REG_FLUSH_GE1 0xa0 +#define AR71XX_DDR_REG_FLUSH_USB 0xa4 +#define AR71XX_DDR_REG_FLUSH_PCI 0xa8 + +#define AR724X_DDR_REG_FLUSH_GE0 0x7c +#define AR724X_DDR_REG_FLUSH_GE1 0x80 +#define AR724X_DDR_REG_FLUSH_USB 0x84 +#define AR724X_DDR_REG_FLUSH_PCIE 0x88 + +#define AR91XX_DDR_REG_FLUSH_GE0 0x7c +#define AR91XX_DDR_REG_FLUSH_GE1 0x80 +#define AR91XX_DDR_REG_FLUSH_USB 0x84 +#define AR91XX_DDR_REG_FLUSH_WMAC 0x88 + +#define PCI_WIN0_OFFS 0x10000000 +#define PCI_WIN1_OFFS 0x11000000 +#define PCI_WIN2_OFFS 0x12000000 +#define PCI_WIN3_OFFS 0x13000000 +#define PCI_WIN4_OFFS 0x14000000 +#define PCI_WIN5_OFFS 0x15000000 +#define PCI_WIN6_OFFS 0x16000000 +#define PCI_WIN7_OFFS 0x07000000 + +// extern void __iomem *ar71xx_ddr_base; + +// static inline void ar71xx_ddr_wr(unsigned reg, u32 val) +// { + // __raw_writel(val, ar71xx_ddr_base + reg); +// } + +// static inline u32 ar71xx_ddr_rr(unsigned reg) +// { + // return __raw_readl(ar71xx_ddr_base + reg); +// } + +// void ar71xx_ddr_flush(u32 reg); + +/* + * PCI block + */ +#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000) +#define AR71XX_PCI_CFG_SIZE 0x100 + +#define PCI_REG_CRP_AD_CBE 0x00 +#define PCI_REG_CRP_WRDATA 0x04 +#define PCI_REG_CRP_RDDATA 0x08 +#define PCI_REG_CFG_AD 0x0c +#define PCI_REG_CFG_CBE 0x10 +#define PCI_REG_CFG_WRDATA 0x14 +#define PCI_REG_CFG_RDDATA 0x18 +#define PCI_REG_PCI_ERR 0x1c +#define PCI_REG_PCI_ERR_ADDR 0x20 +#define PCI_REG_AHB_ERR 0x24 +#define PCI_REG_AHB_ERR_ADDR 0x28 + +#define PCI_CRP_CMD_WRITE 0x00010000 +#define PCI_CRP_CMD_READ 0x00000000 +#define PCI_CFG_CMD_READ 0x0000000a +#define PCI_CFG_CMD_WRITE 0x0000000b + +#define PCI_IDSEL_ADL_START 17 + +#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000) +#define AR724X_PCI_CFG_SIZE 0x1000 + +#define AR724X_PCI_REG_APP 0x00 +#define AR724X_PCI_REG_RESET 0x18 +#define AR724X_PCI_REG_INT_STATUS 0x4c +#define AR724X_PCI_REG_INT_MASK 0x50 + +#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0) +#define AR724X_PCI_RESET_LINK_UP BIT(0) + +#define AR724X_PCI_INT_DEV0 BIT(14) + +/* + * RESET block + */ +#define AR71XX_RESET_REG_TIMER 0x00 +#define AR71XX_RESET_REG_TIMER_RELOAD 0x04 +#define AR71XX_RESET_REG_WDOG_CTRL 0x08 +#define AR71XX_RESET_REG_WDOG 0x0c +#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10 +#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14 +#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18 +#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c +#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20 +#define AR71XX_RESET_REG_RESET_MODULE 0x24 +#define AR71XX_RESET_REG_PERFC_CTRL 0x2c +#define AR71XX_RESET_REG_PERFC0 0x30 +#define AR71XX_RESET_REG_PERFC1 0x34 +#define AR71XX_RESET_REG_REV_ID 0x90 + +#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18 +#define AR91XX_RESET_REG_RESET_MODULE 0x1c +#define AR91XX_RESET_REG_PERF_CTRL 0x20 +#define AR91XX_RESET_REG_PERFC0 0x24 +#define AR91XX_RESET_REG_PERFC1 0x28 + +#define AR724X_RESET_REG_RESET_MODULE 0x1c + +#define WDOG_CTRL_LAST_RESET BIT(31) +#define WDOG_CTRL_ACTION_MASK 3 +#define WDOG_CTRL_ACTION_NONE 0 /* no action */ +#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */ +#define WDOG_CTRL_ACTION_NMI 2 /* NMI */ +#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */ + +#define MISC_INT_DMA BIT(7) +#define MISC_INT_OHCI BIT(6) +#define MISC_INT_PERFC BIT(5) +#define MISC_INT_WDOG BIT(4) +#define MISC_INT_UART BIT(3) +#define MISC_INT_GPIO BIT(2) +#define MISC_INT_ERROR BIT(1) +#define MISC_INT_TIMER BIT(0) + +#define PCI_INT_CORE BIT(4) +#define PCI_INT_DEV2 BIT(2) +#define PCI_INT_DEV1 BIT(1) +#define PCI_INT_DEV0 BIT(0) + +#define RESET_MODULE_EXTERNAL BIT(28) +#define RESET_MODULE_FULL_CHIP BIT(24) +#define RESET_MODULE_AMBA2WMAC BIT(22) +#define RESET_MODULE_CPU_NMI BIT(21) +#define RESET_MODULE_CPU_COLD BIT(20) +#define RESET_MODULE_DMA BIT(19) +#define RESET_MODULE_SLIC BIT(18) +#define RESET_MODULE_STEREO BIT(17) +#define RESET_MODULE_DDR BIT(16) +#define RESET_MODULE_GE1_MAC BIT(13) +#define RESET_MODULE_GE1_PHY BIT(12) +#define RESET_MODULE_USBSUS_OVERRIDE BIT(10) +#define RESET_MODULE_GE0_MAC BIT(9) +#define RESET_MODULE_GE0_PHY BIT(8) +#define RESET_MODULE_USB_OHCI_DLL BIT(6) +#define RESET_MODULE_USB_HOST BIT(5) +#define RESET_MODULE_USB_PHY BIT(4) +#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3) +#define RESET_MODULE_PCI_BUS BIT(1) +#define RESET_MODULE_PCI_CORE BIT(0) + +#define AR724X_RESET_GE1_MDIO BIT(23) +#define AR724X_RESET_GE0_MDIO BIT(22) +#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10) +#define AR724X_RESET_PCIE_PHY BIT(7) +#define AR724X_RESET_PCIE BIT(6) + +#define REV_ID_MAJOR_MASK 0xfff0 +#define REV_ID_MAJOR_AR71XX 0x00a0 +#define REV_ID_MAJOR_AR913X 0x00b0 +#define REV_ID_MAJOR_AR7240 0x00c0 +#define REV_ID_MAJOR_AR7241 0x0100 +#define REV_ID_MAJOR_AR7242 0x1100 + +#define AR71XX_REV_ID_MINOR_MASK 0x3 +#define AR71XX_REV_ID_MINOR_AR7130 0x0 +#define AR71XX_REV_ID_MINOR_AR7141 0x1 +#define AR71XX_REV_ID_MINOR_AR7161 0x2 +#define AR71XX_REV_ID_REVISION_MASK 0x3 +#define AR71XX_REV_ID_REVISION_SHIFT 2 + +#define AR91XX_REV_ID_MINOR_MASK 0x3 +#define AR91XX_REV_ID_MINOR_AR9130 0x0 +#define AR91XX_REV_ID_MINOR_AR9132 0x1 +#define AR91XX_REV_ID_REVISION_MASK 0x3 +#define AR91XX_REV_ID_REVISION_SHIFT 2 + +#define AR724X_REV_ID_REVISION_MASK 0x3 + +// extern void __iomem *ar71xx_reset_base; + +static inline void ar71xx_reset_wr(unsigned reg, u32 val) +{ + __raw_writel(val, KSEG1ADDR(AR71XX_RESET_BASE) + reg); +} + +static inline u32 ar71xx_reset_rr(unsigned reg) +{ + return __raw_readl(KSEG1ADDR(AR71XX_RESET_BASE) + reg); +} + +// void ar71xx_device_stop(u32 mask); +// void ar71xx_device_start(u32 mask); +// int ar71xx_device_stopped(u32 mask); + +/* + * SPI block + */ +#define SPI_REG_FS 0x00 /* Function Select */ +#define SPI_REG_CTRL 0x04 /* SPI Control */ +#define SPI_REG_IOC 0x08 /* SPI I/O Control */ +#define SPI_REG_RDS 0x0c /* Read Data Shift */ + +#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */ + +#define SPI_CTRL_RD BIT(6) /* Remap Disable */ +#define SPI_CTRL_DIV_MASK 0x3f + +#define SPI_IOC_DO BIT(0) /* Data Out pin */ +#define SPI_IOC_CLK BIT(8) /* CLK pin */ +#define SPI_IOC_CS(n) BIT(16 + (n)) +#define SPI_IOC_CS0 SPI_IOC_CS(0) +#define SPI_IOC_CS1 SPI_IOC_CS(1) +#define SPI_IOC_CS2 SPI_IOC_CS(2) +#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2) + +// void ar71xx_flash_acquire(void); +// void ar71xx_flash_release(void); + +/* + * MII_CTRL block + */ +#define MII_REG_MII0_CTRL 0x00 +#define MII_REG_MII1_CTRL 0x04 + +#define MII0_CTRL_IF_GMII 0 +#define MII0_CTRL_IF_MII 1 +#define MII0_CTRL_IF_RGMII 2 +#define MII0_CTRL_IF_RMII 3 + +#define MII1_CTRL_IF_RGMII 0 +#define MII1_CTRL_IF_RMII 1 + +#endif /* __ASSEMBLER__ */ + +#endif /* __ASM_MACH_AR71XX_H */ diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx_gpio.h.svn-base b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx_gpio.h.svn-base new file mode 100644 index 0000000..c92364b --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/asm-mips/.svn/text-base/ar71xx_gpio.h.svn-base @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _AR71XX_GPIO_H +#define _AR71XX_GPIO_H + +#include <common.h> +#include <asm/ar71xx.h> + +static inline void ar71xx_setpin(uint8_t pin, uint8_t state) +{ + uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT)); + + if (state != 0) { + reg |= (1 << pin); + } else { + reg &= ~(1 << pin); + } + + writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT)); + readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT)); +} + +static inline uint32_t ar71xx_getpin(uint8_t pin) +{ + uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_IN)); + return (((reg & (1 << pin)) != 0) ? 1 : 0); +} + +static inline void ar71xx_setpindir(uint8_t pin, uint8_t direction) +{ + uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE)); + + if (direction != 0) { + reg |= (1 << pin); + } else { + reg &= ~(1 << pin); + } + + writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE)); + readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE)); +} + + +#endif /* AR71XX_GPIO_H */ diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h new file mode 100644 index 0000000..e8f3f61 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h @@ -0,0 +1,515 @@ +/* + * Atheros AR71xx SoC specific definitions + * + * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> + * + * Parts of this file are based on Atheros' 2.6.15 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __ASM_MACH_AR71XX_H +#define __ASM_MACH_AR71XX_H + +#include <linux/types.h> +#include <asm/io.h> +#include <linux/bitops.h> + +#ifndef __ASSEMBLER__ + +#define BIT(x) (1<<(x)) + +#define AR71XX_PCI_MEM_BASE 0x10000000 +#define AR71XX_PCI_MEM_SIZE 0x08000000 +#define AR71XX_APB_BASE 0x18000000 +#define AR71XX_GE0_BASE 0x19000000 +#define AR71XX_GE0_SIZE 0x01000000 +#define AR71XX_GE1_BASE 0x1a000000 +#define AR71XX_GE1_SIZE 0x01000000 +#define AR71XX_EHCI_BASE 0x1b000000 +#define AR71XX_EHCI_SIZE 0x01000000 +#define AR71XX_OHCI_BASE 0x1c000000 +#define AR71XX_OHCI_SIZE 0x01000000 +#define AR7240_OHCI_BASE 0x1b000000 +#define AR7240_OHCI_SIZE 0x01000000 +#define AR71XX_SPI_BASE 0x1f000000 +#define AR71XX_SPI_SIZE 0x01000000 + +#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) +#define AR71XX_DDR_CTRL_SIZE 0x10000 +#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000) +#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) +#define AR71XX_UART_SIZE 0x10000 +#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) +#define AR71XX_USB_CTRL_SIZE 0x10000 +#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000) +#define AR71XX_GPIO_SIZE 0x10000 +#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) +#define AR71XX_PLL_SIZE 0x10000 +#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) +#define AR71XX_RESET_SIZE 0x10000 +#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) +#define AR71XX_MII_SIZE 0x10000 +#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000) +#define AR71XX_SLIC_SIZE 0x10000 +#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000) +#define AR71XX_DMA_SIZE 0x10000 +#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000) +#define AR71XX_STEREO_SIZE 0x10000 + +#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000) +#define AR724X_PCI_CRP_SIZE 0x100 + +#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000) +#define AR724X_PCI_CTRL_SIZE 0x100 + +#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) +#define AR91XX_WMAC_SIZE 0x30000 + +#define AR71XX_MEM_SIZE_MIN 0x0200000 +#define AR71XX_MEM_SIZE_MAX 0x10000000 + +#define AR71XX_CPU_IRQ_BASE 0 +#define AR71XX_MISC_IRQ_BASE 8 +#define AR71XX_MISC_IRQ_COUNT 8 +#define AR71XX_GPIO_IRQ_BASE 16 +#define AR71XX_GPIO_IRQ_COUNT 32 +#define AR71XX_PCI_IRQ_BASE 48 +#define AR71XX_PCI_IRQ_COUNT 8 + +#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2) +#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3) +#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4) +#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5) +#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6) +#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7) + +#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0) +#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1) +#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2) +#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3) +#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4) +#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5) +#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6) +#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7) + +#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x)) + +#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0) +#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1) +#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2) +#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4) + +extern u32 ar71xx_ahb_freq; +extern u32 ar71xx_cpu_freq; +extern u32 ar71xx_ddr_freq; + +enum ar71xx_soc_type { + AR71XX_SOC_UNKNOWN, + AR71XX_SOC_AR7130, + AR71XX_SOC_AR7141, + AR71XX_SOC_AR7161, + AR71XX_SOC_AR7240, + AR71XX_SOC_AR7241, + AR71XX_SOC_AR7242, + AR71XX_SOC_AR9130, + AR71XX_SOC_AR9132 +}; + +extern enum ar71xx_soc_type ar71xx_soc; + +/* + * PLL block + */ +#define AR71XX_PLL_REG_CPU_CONFIG 0x00 +#define AR71XX_PLL_REG_SEC_CONFIG 0x04 +#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 +#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 + +#define AR71XX_PLL_DIV_SHIFT 3 +#define AR71XX_PLL_DIV_MASK 0x1f +#define AR71XX_CPU_DIV_SHIFT 16 +#define AR71XX_CPU_DIV_MASK 0x3 +#define AR71XX_DDR_DIV_SHIFT 18 +#define AR71XX_DDR_DIV_MASK 0x3 +#define AR71XX_AHB_DIV_SHIFT 20 +#define AR71XX_AHB_DIV_MASK 0x7 + +#define AR71XX_ETH0_PLL_SHIFT 17 +#define AR71XX_ETH1_PLL_SHIFT 19 + +#define AR724X_PLL_REG_CPU_CONFIG 0x00 +#define AR724X_PLL_REG_PCIE_CONFIG 0x18 + +#define AR724X_PLL_DIV_SHIFT 0 +#define AR724X_PLL_DIV_MASK 0x3ff +#define AR724X_PLL_REF_DIV_SHIFT 10 +#define AR724X_PLL_REF_DIV_MASK 0xf +#define AR724X_AHB_DIV_SHIFT 19 +#define AR724X_AHB_DIV_MASK 0x1 +#define AR724X_DDR_DIV_SHIFT 22 +#define AR724X_DDR_DIV_MASK 0x3 + +#define AR91XX_PLL_REG_CPU_CONFIG 0x00 +#define AR91XX_PLL_REG_ETH_CONFIG 0x04 +#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14 +#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18 + +#define AR91XX_PLL_DIV_SHIFT 0 +#define AR91XX_PLL_DIV_MASK 0x3ff +#define AR91XX_DDR_DIV_SHIFT 22 +#define AR91XX_DDR_DIV_MASK 0x3 +#define AR91XX_AHB_DIV_SHIFT 19 +#define AR91XX_AHB_DIV_MASK 0x1 + +#define AR91XX_ETH0_PLL_SHIFT 20 +#define AR91XX_ETH1_PLL_SHIFT 22 + +// extern void __iomem *ar71xx_pll_base; + +// static inline void ar71xx_pll_wr(unsigned reg, u32 val) +// { + // __raw_writel(val, ar71xx_pll_base + reg); +// } + +// static inline u32 ar71xx_pll_rr(unsigned reg) +// { + // return __raw_readl(ar71xx_pll_base + reg); +// } + +/* + * USB_CONFIG block + */ +#define USB_CTRL_REG_FLADJ 0x00 +#define USB_CTRL_REG_CONFIG 0x04 + +// extern void __iomem *ar71xx_usb_ctrl_base; + +// static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val) +// { + // __raw_writel(val, ar71xx_usb_ctrl_base + reg); +// } + +// static inline u32 ar71xx_usb_ctrl_rr(unsigned reg) +// { + // return __raw_readl(ar71xx_usb_ctrl_base + reg); +// } + +/* + * GPIO block + */ +#define GPIO_REG_OE 0x00 +#define GPIO_REG_IN 0x04 +#define GPIO_REG_OUT 0x08 +#define GPIO_REG_SET 0x0c +#define GPIO_REG_CLEAR 0x10 +#define GPIO_REG_INT_MODE 0x14 +#define GPIO_REG_INT_TYPE 0x18 +#define GPIO_REG_INT_POLARITY 0x1c +#define GPIO_REG_INT_PENDING 0x20 +#define GPIO_REG_INT_ENABLE 0x24 +#define GPIO_REG_FUNC 0x28 + +#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) +#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) +#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) +#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) +#define AR71XX_GPIO_FUNC_UART_EN BIT(8) +#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) +#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) + +#define AR71XX_GPIO_COUNT 16 + +#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) +#define AR724X_GPIO_FUNC_SPI_EN BIT(18) +#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) +#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) +#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) +#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) +#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) +#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) +#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) +#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) +#define AR724X_GPIO_FUNC_UART_EN BIT(1) +#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) + +#define AR724X_GPIO_COUNT 18 + +#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22) +#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) +#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20) +#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19) +#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18) +#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17) +#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16) +#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9) +#define AR91XX_GPIO_FUNC_UART_EN BIT(8) +#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4) + +#define AR91XX_GPIO_COUNT 22 + +// extern void __iomem *ar71xx_gpio_base; + +// static inline void ar71xx_gpio_wr(unsigned reg, u32 value) +// { + // __raw_writel(value, ar71xx_gpio_base + reg); +// } + +// static inline u32 ar71xx_gpio_rr(unsigned reg) +// { + // return __raw_readl(ar71xx_gpio_base + reg); +// } + +// void ar71xx_gpio_init(void) __init; +// void ar71xx_gpio_function_enable(u32 mask); +// void ar71xx_gpio_function_disable(u32 mask); +// void ar71xx_gpio_function_setup(u32 set, u32 clear); + +/* + * DDR_CTRL block + */ +#define AR71XX_DDR_REG_PCI_WIN0 0x7c +#define AR71XX_DDR_REG_PCI_WIN1 0x80 +#define AR71XX_DDR_REG_PCI_WIN2 0x84 +#define AR71XX_DDR_REG_PCI_WIN3 0x88 +#define AR71XX_DDR_REG_PCI_WIN4 0x8c +#define AR71XX_DDR_REG_PCI_WIN5 0x90 +#define AR71XX_DDR_REG_PCI_WIN6 0x94 +#define AR71XX_DDR_REG_PCI_WIN7 0x98 +#define AR71XX_DDR_REG_FLUSH_GE0 0x9c +#define AR71XX_DDR_REG_FLUSH_GE1 0xa0 +#define AR71XX_DDR_REG_FLUSH_USB 0xa4 +#define AR71XX_DDR_REG_FLUSH_PCI 0xa8 + +#define AR724X_DDR_REG_FLUSH_GE0 0x7c +#define AR724X_DDR_REG_FLUSH_GE1 0x80 +#define AR724X_DDR_REG_FLUSH_USB 0x84 +#define AR724X_DDR_REG_FLUSH_PCIE 0x88 + +#define AR91XX_DDR_REG_FLUSH_GE0 0x7c +#define AR91XX_DDR_REG_FLUSH_GE1 0x80 +#define AR91XX_DDR_REG_FLUSH_USB 0x84 +#define AR91XX_DDR_REG_FLUSH_WMAC 0x88 + +#define PCI_WIN0_OFFS 0x10000000 +#define PCI_WIN1_OFFS 0x11000000 +#define PCI_WIN2_OFFS 0x12000000 +#define PCI_WIN3_OFFS 0x13000000 +#define PCI_WIN4_OFFS 0x14000000 +#define PCI_WIN5_OFFS 0x15000000 +#define PCI_WIN6_OFFS 0x16000000 +#define PCI_WIN7_OFFS 0x07000000 + +// extern void __iomem *ar71xx_ddr_base; + +// static inline void ar71xx_ddr_wr(unsigned reg, u32 val) +// { + // __raw_writel(val, ar71xx_ddr_base + reg); +// } + +// static inline u32 ar71xx_ddr_rr(unsigned reg) +// { + // return __raw_readl(ar71xx_ddr_base + reg); +// } + +// void ar71xx_ddr_flush(u32 reg); + +/* + * PCI block + */ +#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000) +#define AR71XX_PCI_CFG_SIZE 0x100 + +#define PCI_REG_CRP_AD_CBE 0x00 +#define PCI_REG_CRP_WRDATA 0x04 +#define PCI_REG_CRP_RDDATA 0x08 +#define PCI_REG_CFG_AD 0x0c +#define PCI_REG_CFG_CBE 0x10 +#define PCI_REG_CFG_WRDATA 0x14 +#define PCI_REG_CFG_RDDATA 0x18 +#define PCI_REG_PCI_ERR 0x1c +#define PCI_REG_PCI_ERR_ADDR 0x20 +#define PCI_REG_AHB_ERR 0x24 +#define PCI_REG_AHB_ERR_ADDR 0x28 + +#define PCI_CRP_CMD_WRITE 0x00010000 +#define PCI_CRP_CMD_READ 0x00000000 +#define PCI_CFG_CMD_READ 0x0000000a +#define PCI_CFG_CMD_WRITE 0x0000000b + +#define PCI_IDSEL_ADL_START 17 + +#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000) +#define AR724X_PCI_CFG_SIZE 0x1000 + +#define AR724X_PCI_REG_APP 0x00 +#define AR724X_PCI_REG_RESET 0x18 +#define AR724X_PCI_REG_INT_STATUS 0x4c +#define AR724X_PCI_REG_INT_MASK 0x50 + +#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0) +#define AR724X_PCI_RESET_LINK_UP BIT(0) + +#define AR724X_PCI_INT_DEV0 BIT(14) + +/* + * RESET block + */ +#define AR71XX_RESET_REG_TIMER 0x00 +#define AR71XX_RESET_REG_TIMER_RELOAD 0x04 +#define AR71XX_RESET_REG_WDOG_CTRL 0x08 +#define AR71XX_RESET_REG_WDOG 0x0c +#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10 +#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14 +#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18 +#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c +#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20 +#define AR71XX_RESET_REG_RESET_MODULE 0x24 +#define AR71XX_RESET_REG_PERFC_CTRL 0x2c +#define AR71XX_RESET_REG_PERFC0 0x30 +#define AR71XX_RESET_REG_PERFC1 0x34 +#define AR71XX_RESET_REG_REV_ID 0x90 + +#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18 +#define AR91XX_RESET_REG_RESET_MODULE 0x1c +#define AR91XX_RESET_REG_PERF_CTRL 0x20 +#define AR91XX_RESET_REG_PERFC0 0x24 +#define AR91XX_RESET_REG_PERFC1 0x28 + +#define AR724X_RESET_REG_RESET_MODULE 0x1c + +#define WDOG_CTRL_LAST_RESET BIT(31) +#define WDOG_CTRL_ACTION_MASK 3 +#define WDOG_CTRL_ACTION_NONE 0 /* no action */ +#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */ +#define WDOG_CTRL_ACTION_NMI 2 /* NMI */ +#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */ + +#define MISC_INT_DMA BIT(7) +#define MISC_INT_OHCI BIT(6) +#define MISC_INT_PERFC BIT(5) +#define MISC_INT_WDOG BIT(4) +#define MISC_INT_UART BIT(3) +#define MISC_INT_GPIO BIT(2) +#define MISC_INT_ERROR BIT(1) +#define MISC_INT_TIMER BIT(0) + +#define PCI_INT_CORE BIT(4) +#define PCI_INT_DEV2 BIT(2) +#define PCI_INT_DEV1 BIT(1) +#define PCI_INT_DEV0 BIT(0) + +#define RESET_MODULE_EXTERNAL BIT(28) +#define RESET_MODULE_FULL_CHIP BIT(24) +#define RESET_MODULE_AMBA2WMAC BIT(22) +#define RESET_MODULE_CPU_NMI BIT(21) +#define RESET_MODULE_CPU_COLD BIT(20) +#define RESET_MODULE_DMA BIT(19) +#define RESET_MODULE_SLIC BIT(18) +#define RESET_MODULE_STEREO BIT(17) +#define RESET_MODULE_DDR BIT(16) +#define RESET_MODULE_GE1_MAC BIT(13) +#define RESET_MODULE_GE1_PHY BIT(12) +#define RESET_MODULE_USBSUS_OVERRIDE BIT(10) +#define RESET_MODULE_GE0_MAC BIT(9) +#define RESET_MODULE_GE0_PHY BIT(8) +#define RESET_MODULE_USB_OHCI_DLL BIT(6) +#define RESET_MODULE_USB_HOST BIT(5) +#define RESET_MODULE_USB_PHY BIT(4) +#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3) +#define RESET_MODULE_PCI_BUS BIT(1) +#define RESET_MODULE_PCI_CORE BIT(0) + +#define AR724X_RESET_GE1_MDIO BIT(23) +#define AR724X_RESET_GE0_MDIO BIT(22) +#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10) +#define AR724X_RESET_PCIE_PHY BIT(7) +#define AR724X_RESET_PCIE BIT(6) + +#define REV_ID_MAJOR_MASK 0xfff0 +#define REV_ID_MAJOR_AR71XX 0x00a0 +#define REV_ID_MAJOR_AR913X 0x00b0 +#define REV_ID_MAJOR_AR7240 0x00c0 +#define REV_ID_MAJOR_AR7241 0x0100 +#define REV_ID_MAJOR_AR7242 0x1100 + +#define AR71XX_REV_ID_MINOR_MASK 0x3 +#define AR71XX_REV_ID_MINOR_AR7130 0x0 +#define AR71XX_REV_ID_MINOR_AR7141 0x1 +#define AR71XX_REV_ID_MINOR_AR7161 0x2 +#define AR71XX_REV_ID_REVISION_MASK 0x3 +#define AR71XX_REV_ID_REVISION_SHIFT 2 + +#define AR91XX_REV_ID_MINOR_MASK 0x3 +#define AR91XX_REV_ID_MINOR_AR9130 0x0 +#define AR91XX_REV_ID_MINOR_AR9132 0x1 +#define AR91XX_REV_ID_REVISION_MASK 0x3 +#define AR91XX_REV_ID_REVISION_SHIFT 2 + +#define AR724X_REV_ID_REVISION_MASK 0x3 + +// extern void __iomem *ar71xx_reset_base; + +static inline void ar71xx_reset_wr(unsigned reg, u32 val) +{ + __raw_writel(val, KSEG1ADDR(AR71XX_RESET_BASE) + reg); +} + +static inline u32 ar71xx_reset_rr(unsigned reg) +{ + return __raw_readl(KSEG1ADDR(AR71XX_RESET_BASE) + reg); +} + +// void ar71xx_device_stop(u32 mask); +// void ar71xx_device_start(u32 mask); +// int ar71xx_device_stopped(u32 mask); + +/* + * SPI block + */ +#define SPI_REG_FS 0x00 /* Function Select */ +#define SPI_REG_CTRL 0x04 /* SPI Control */ +#define SPI_REG_IOC 0x08 /* SPI I/O Control */ +#define SPI_REG_RDS 0x0c /* Read Data Shift */ + +#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */ + +#define SPI_CTRL_RD BIT(6) /* Remap Disable */ +#define SPI_CTRL_DIV_MASK 0x3f + +#define SPI_IOC_DO BIT(0) /* Data Out pin */ +#define SPI_IOC_CLK BIT(8) /* CLK pin */ +#define SPI_IOC_CS(n) BIT(16 + (n)) +#define SPI_IOC_CS0 SPI_IOC_CS(0) +#define SPI_IOC_CS1 SPI_IOC_CS(1) +#define SPI_IOC_CS2 SPI_IOC_CS(2) +#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2) + +// void ar71xx_flash_acquire(void); +// void ar71xx_flash_release(void); + +/* + * MII_CTRL block + */ +#define MII_REG_MII0_CTRL 0x00 +#define MII_REG_MII1_CTRL 0x04 + +#define MII0_CTRL_IF_GMII 0 +#define MII0_CTRL_IF_MII 1 +#define MII0_CTRL_IF_RGMII 2 +#define MII0_CTRL_IF_RMII 3 + +#define MII1_CTRL_IF_RGMII 0 +#define MII1_CTRL_IF_RMII 1 + +#endif /* __ASSEMBLER__ */ + +#endif /* __ASM_MACH_AR71XX_H */ diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h new file mode 100644 index 0000000..c92364b --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _AR71XX_GPIO_H +#define _AR71XX_GPIO_H + +#include <common.h> +#include <asm/ar71xx.h> + +static inline void ar71xx_setpin(uint8_t pin, uint8_t state) +{ + uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT)); + + if (state != 0) { + reg |= (1 << pin); + } else { + reg &= ~(1 << pin); + } + + writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT)); + readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT)); +} + +static inline uint32_t ar71xx_getpin(uint8_t pin) +{ + uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_IN)); + return (((reg & (1 << pin)) != 0) ? 1 : 0); +} + +static inline void ar71xx_setpindir(uint8_t pin, uint8_t direction) +{ + uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE)); + + if (direction != 0) { + reg |= (1 << pin); + } else { + reg &= ~(1 << pin); + } + + writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE)); + readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE)); +} + + +#endif /* AR71XX_GPIO_H */ diff --git a/package/boot/uboot-ar71xx/files/include/configs/.svn/entries b/package/boot/uboot-ar71xx/files/include/configs/.svn/entries new file mode 100644 index 0000000..240eb56 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/configs/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/files/include/configs +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +nbg460n.h +file + + + + +2013-03-17T12:13:21.000000Z +85e62ebf6a2d7d9a9fb3a787bb7e0ec1 +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +4386 + diff --git a/package/boot/uboot-ar71xx/files/include/configs/.svn/prop-base/nbg460n.h.svn-base b/package/boot/uboot-ar71xx/files/include/configs/.svn/prop-base/nbg460n.h.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/configs/.svn/prop-base/nbg460n.h.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/uboot-ar71xx/files/include/configs/.svn/text-base/nbg460n.h.svn-base b/package/boot/uboot-ar71xx/files/include/configs/.svn/text-base/nbg460n.h.svn-base new file mode 100644 index 0000000..dd9b4c3 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/configs/.svn/text-base/nbg460n.h.svn-base @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* This file contains the configuration parameters for the zyxel nbg460n board. */ + +#ifndef _NBG460N_CONFIG_H +#define _NBG460N_CONFIG_H + +#define CONFIG_MIPS32 1 /* MIPS32 CPU core */ +#define CONFIG_AR71XX 1 +#define CONFIG_AR91XX 1 +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_MIPS_TIMER_FREQ (400000000/2) + +/* Cache Configuration */ +#define CONFIG_SYS_DCACHE_SIZE 32768 +#define CONFIG_SYS_ICACHE_SIZE 65536 +#define CONFIG_SYS_CACHELINE_SIZE 32 +/* Cache lock for stack */ +#define CONFIG_SYS_INIT_SP_OFFSET 0x1000 + +#define CONFIG_SYS_MONITOR_BASE (TEXT_BASE) + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {115200} + +#define CONFIG_MISC_INIT_R + +/* SPI-Flash support */ +#define CONFIG_SPI_FLASH +#define CONFIG_AR71XX_SPI +#define CONFIG_SPI_FLASH_MACRONIX +#define CONFIG_SF_DEFAULT_HZ 25000000 + +#define CONFIG_ENV_SPI_MAX_HZ 25000000 +#define CONFIG_ENV_SPI_BUS 0 +#define CONFIG_ENV_SPI_CS 0 + +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_ADDR 0xbfc20000 +#define CONFIG_ENV_OFFSET 0x20000 +#define CONFIG_ENV_SIZE 0x01000 +#define CONFIG_ENV_SECT_SIZE 0x10000 +#define CONFIG_SYS_MAX_FLASH_BANKS 1 +#define CONFIG_SYS_MAX_FLASH_SECT 64 +#define CONFIG_SYS_FLASH_BASE 0xbfc00000 + +/* Net support */ +#define CONFIG_ETHADDR_ADDR 0xbfc0fff8 +#define CONFIG_SYS_RX_ETH_BUFFER 16 +#define CONFIG_AG71XX +#define CONFIG_AG71XX_PORTS { 1, 1 } +#define CONFIG_AG71XX_MII0_IIF MII0_CTRL_IF_RGMII +#define CONFIG_AG71XX_MII1_IIF MII1_CTRL_IF_RGMII +#define CONFIG_NET_MULTI +#define CONFIG_IPADDR 192.168.1.254 +#define CONFIG_SERVERIP 192.168.1.42 + +/* Switch support */ +#define CONFIG_MII +#define CONFIG_RTL8366_MII +#define RTL8366_PIN_SDA 16 +#define RTL8366_PIN_SCK 18 +#define MII_GPIOINCLUDE <asm/ar71xx_gpio.h> +#define MII_SETSDA(x) ar71xx_setpin(RTL8366_PIN_SDA, x) +#define MII_GETSDA ar71xx_getpin(RTL8366_PIN_SDA) +#define MII_SETSCK(x) ar71xx_setpin(RTL8366_PIN_SCK, x) +#define MII_SDAINPUT ar71xx_setpindir(RTL8366_PIN_SDA, 0) +#define MII_SDAOUTPUT ar71xx_setpindir(RTL8366_PIN_SDA, 1) +#define MII_SCKINPUT ar71xx_setpindir(RTL8366_PIN_SCK, 0) +#define MII_SCKOUTPUT ar71xx_setpindir(RTL8366_PIN_SCK, 1) + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTARGS "console=ttyS0,115200 rootfstype==squashfs,jffs2 noinitrd machtype=NBG460N" +#define CONFIG_BOOTCOMMAND "bootm 0xbfc70000" +#define CONFIG_LZMA + + +/* Commands */ +#define CONFIG_SYS_NO_FLASH +#include <config_cmd_default.h> +#undef CONFIG_CMD_BDI +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_IMI +#undef CONFIG_CMD_IMLS +#undef CONFIG_CMD_LOADS +#define CONFIG_CMD_SF +#define CONFIG_CMD_MII +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_SPI + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_PROMPT "U-Boot> " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_LONGHELP 1 +#define CONFIG_CMDLINE_EDITING 1 +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN ROUND(3 * 0x10000 + 128*1024, 0x1000) +#define CONFIG_SYS_GBL_DATA_SIZE 128 /* 128 bytes for initial data */ + +#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024 + +#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ +#define CONFIG_SYS_LOAD_ADDR 0x80060000 /* default load address */ + +#define CONFIG_SYS_MEMTEST_START 0x80000800 +#define CONFIG_SYS_MEMTEST_END 0x81E00000 + +#endif /* _NBG460N_CONFIG_H */ diff --git a/package/boot/uboot-ar71xx/files/include/configs/nbg460n.h b/package/boot/uboot-ar71xx/files/include/configs/nbg460n.h new file mode 100644 index 0000000..dd9b4c3 --- /dev/null +++ b/package/boot/uboot-ar71xx/files/include/configs/nbg460n.h @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2010 + * Michael Kurz <michi.kurz@googlemail.com>. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* This file contains the configuration parameters for the zyxel nbg460n board. */ + +#ifndef _NBG460N_CONFIG_H +#define _NBG460N_CONFIG_H + +#define CONFIG_MIPS32 1 /* MIPS32 CPU core */ +#define CONFIG_AR71XX 1 +#define CONFIG_AR91XX 1 +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_MIPS_TIMER_FREQ (400000000/2) + +/* Cache Configuration */ +#define CONFIG_SYS_DCACHE_SIZE 32768 +#define CONFIG_SYS_ICACHE_SIZE 65536 +#define CONFIG_SYS_CACHELINE_SIZE 32 +/* Cache lock for stack */ +#define CONFIG_SYS_INIT_SP_OFFSET 0x1000 + +#define CONFIG_SYS_MONITOR_BASE (TEXT_BASE) + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {115200} + +#define CONFIG_MISC_INIT_R + +/* SPI-Flash support */ +#define CONFIG_SPI_FLASH +#define CONFIG_AR71XX_SPI +#define CONFIG_SPI_FLASH_MACRONIX +#define CONFIG_SF_DEFAULT_HZ 25000000 + +#define CONFIG_ENV_SPI_MAX_HZ 25000000 +#define CONFIG_ENV_SPI_BUS 0 +#define CONFIG_ENV_SPI_CS 0 + +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_ADDR 0xbfc20000 +#define CONFIG_ENV_OFFSET 0x20000 +#define CONFIG_ENV_SIZE 0x01000 +#define CONFIG_ENV_SECT_SIZE 0x10000 +#define CONFIG_SYS_MAX_FLASH_BANKS 1 +#define CONFIG_SYS_MAX_FLASH_SECT 64 +#define CONFIG_SYS_FLASH_BASE 0xbfc00000 + +/* Net support */ +#define CONFIG_ETHADDR_ADDR 0xbfc0fff8 +#define CONFIG_SYS_RX_ETH_BUFFER 16 +#define CONFIG_AG71XX +#define CONFIG_AG71XX_PORTS { 1, 1 } +#define CONFIG_AG71XX_MII0_IIF MII0_CTRL_IF_RGMII +#define CONFIG_AG71XX_MII1_IIF MII1_CTRL_IF_RGMII +#define CONFIG_NET_MULTI +#define CONFIG_IPADDR 192.168.1.254 +#define CONFIG_SERVERIP 192.168.1.42 + +/* Switch support */ +#define CONFIG_MII +#define CONFIG_RTL8366_MII +#define RTL8366_PIN_SDA 16 +#define RTL8366_PIN_SCK 18 +#define MII_GPIOINCLUDE <asm/ar71xx_gpio.h> +#define MII_SETSDA(x) ar71xx_setpin(RTL8366_PIN_SDA, x) +#define MII_GETSDA ar71xx_getpin(RTL8366_PIN_SDA) +#define MII_SETSCK(x) ar71xx_setpin(RTL8366_PIN_SCK, x) +#define MII_SDAINPUT ar71xx_setpindir(RTL8366_PIN_SDA, 0) +#define MII_SDAOUTPUT ar71xx_setpindir(RTL8366_PIN_SDA, 1) +#define MII_SCKINPUT ar71xx_setpindir(RTL8366_PIN_SCK, 0) +#define MII_SCKOUTPUT ar71xx_setpindir(RTL8366_PIN_SCK, 1) + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTARGS "console=ttyS0,115200 rootfstype==squashfs,jffs2 noinitrd machtype=NBG460N" +#define CONFIG_BOOTCOMMAND "bootm 0xbfc70000" +#define CONFIG_LZMA + + +/* Commands */ +#define CONFIG_SYS_NO_FLASH +#include <config_cmd_default.h> +#undef CONFIG_CMD_BDI +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_IMI +#undef CONFIG_CMD_IMLS +#undef CONFIG_CMD_LOADS +#define CONFIG_CMD_SF +#define CONFIG_CMD_MII +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_SPI + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_PROMPT "U-Boot> " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_LONGHELP 1 +#define CONFIG_CMDLINE_EDITING 1 +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN ROUND(3 * 0x10000 + 128*1024, 0x1000) +#define CONFIG_SYS_GBL_DATA_SIZE 128 /* 128 bytes for initial data */ + +#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024 + +#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ +#define CONFIG_SYS_LOAD_ADDR 0x80060000 /* default load address */ + +#define CONFIG_SYS_MEMTEST_START 0x80000800 +#define CONFIG_SYS_MEMTEST_END 0x81E00000 + +#endif /* _NBG460N_CONFIG_H */ diff --git a/package/boot/uboot-ar71xx/patches/.svn/entries b/package/boot/uboot-ar71xx/patches/.svn/entries new file mode 100644 index 0000000..f3d8b90 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/.svn/entries @@ -0,0 +1,266 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-ar71xx/patches +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +002-ar71xx-spi.patch +file + + + + +2013-03-17T12:13:21.000000Z +c93e74225de2389588d6c1b4d30fc2d3 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +458 + +010-enet-ag71xx.patch +file + + + + +2013-03-17T12:13:21.000000Z +ca96c86b1b5a1e69d9574118712b38de +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +1055 + +021-darwin_compat.patch +file + + + + +2013-03-17T12:13:21.000000Z +4bd7c68770a42e7fa70cdf0e902d99f8 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +881 + +001-ar71xx.patch +file + + + + +2013-03-17T12:13:21.000000Z +2dc4f04e60b981ffe9ad13993f924f23 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +1243 + +020-freebsd-compat.patch +file + + + + +2013-03-17T12:13:21.000000Z +690ab49ce8bb8ad88ce2a16976f89b5e +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +313 + +011-switch-rtl8366sr.patch +file + + + + +2013-03-17T12:13:21.000000Z +d85aa0315186eeac81cbba96f5c83314 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +1139 + +022-getline_backport.patch +file + + + + +2013-03-17T12:13:21.000000Z +88d64f3c9686f9d3de6a3d4ae2f4cafc +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +436 + diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/001-ar71xx.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/001-ar71xx.patch.svn-base new file mode 100644 index 0000000..409f67a --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/001-ar71xx.patch.svn-base @@ -0,0 +1,28 @@ +diff -ur u-boot-2010.03/cpu/mips/Makefile u-boot-nbg/cpu/mips/Makefile +--- u-boot-2010.03/cpu/mips/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/cpu/mips/Makefile 2010-04-15 18:58:01.000000000 +0200 +@@ -33,6 +33,7 @@ + COBJS-$(CONFIG_INCA_IP) += asc_serial.o incaip_clock.o + COBJS-$(CONFIG_PURPLE) += asc_serial.o + COBJS-$(CONFIG_SOC_AU1X00) += au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o ++COBJS-$(CONFIG_AR71XX) += ar71xx_serial.o + + SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) + OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +diff -ur u-boot-2010.03/Makefile u-boot-nbg/Makefile +--- u-boot-2010.03/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/Makefile 2010-04-11 23:31:29.000000000 +0200 +@@ -3455,6 +3455,13 @@ + @$(MKCONFIG) -a qemu-mips mips mips qemu-mips + + ######################################################################### ++## MIPS32 AR71XX (24K) ++######################################################################### ++ ++nbg460n_550n_550nh_config : unconfig ++ @$(MKCONFIG) -a nbg460n mips mips nbg460n zyxel ++ ++######################################################################### + ## MIPS64 5Kc + ######################################################################### + diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/002-ar71xx-spi.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/002-ar71xx-spi.patch.svn-base new file mode 100644 index 0000000..2bb1ba2 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/002-ar71xx-spi.patch.svn-base @@ -0,0 +1,11 @@ +diff -ur u-boot-2010.03/drivers/spi/Makefile u-boot-nbg/drivers/spi/Makefile +--- u-boot-2010.03/drivers/spi/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/drivers/spi/Makefile 2010-04-15 19:31:27.000000000 +0200 +@@ -25,6 +25,7 @@ + + LIB := $(obj)libspi.a + ++COBJS-$(CONFIG_AR71XX_SPI) += ar71xx_spi.o + COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o + COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o + COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/010-enet-ag71xx.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/010-enet-ag71xx.patch.svn-base new file mode 100644 index 0000000..ee90e32 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/010-enet-ag71xx.patch.svn-base @@ -0,0 +1,22 @@ +diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile +--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200 +@@ -27,6 +27,7 @@ + + COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o + COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o ++COBJS-$(CONFIG_AG71XX) += ag71xx.o + COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o + COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o + COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o +diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h +--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200 +@@ -42,6 +42,7 @@ + + /* Driver initialization prototypes */ + int au1x00_enet_initialize(bd_t*); ++int ag71xx_register(bd_t * bis, char *phyname[], u16 phyid[], u16 phyfixed[]); + int at91emac_register(bd_t *bis, unsigned long iobase); + int bfin_EMAC_initialize(bd_t *bis); + int cs8900_initialize(u8 dev_num, int base_addr); diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/011-switch-rtl8366sr.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/011-switch-rtl8366sr.patch.svn-base new file mode 100644 index 0000000..5d2ba41 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/011-switch-rtl8366sr.patch.svn-base @@ -0,0 +1,28 @@ +diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile +--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200 +@@ -65,6 +65,7 @@ + COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o + COBJS-$(CONFIG_RTL8139) += rtl8139.o + COBJS-$(CONFIG_RTL8169) += rtl8169.o ++COBJS-$(CONFIG_RTL8366_MII) += phy/rtl8366_mii.o + COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o + COBJS-$(CONFIG_SH_ETHER) += sh_eth.o + COBJS-$(CONFIG_SMC91111) += smc91111.o +diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h +--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200 +@@ -175,5 +175,13 @@ + + int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig); + #endif /* CONFIG_MV88E61XX_SWITCH */ ++ ++#if defined(CONFIG_RTL8366_MII) ++#define RTL8366_DEVNAME "rtl8366" ++#define RTL8366_WANPHY_ID 4 ++#define RTL8366_LANPHY_ID -1 ++int rtl8366_mii_register(bd_t *bis); ++int rtl8366s_initialize(void); ++#endif + + #endif /* _NETDEV_H_ */ diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/020-freebsd-compat.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/020-freebsd-compat.patch.svn-base new file mode 100644 index 0000000..fee0669 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/020-freebsd-compat.patch.svn-base @@ -0,0 +1,11 @@ +--- a/include/compiler.h ++++ b/include/compiler.h +@@ -46,7 +46,7 @@ extern int errno; + #ifdef __linux__ + # include <endian.h> + # include <byteswap.h> +-#elif defined(__MACH__) ++#elif defined(__MACH__) || defined(__FreeBSD__) + # include <machine/endian.h> + typedef unsigned long ulong; + typedef unsigned int uint; diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/021-darwin_compat.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/021-darwin_compat.patch.svn-base new file mode 100644 index 0000000..dde83d4 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/021-darwin_compat.patch.svn-base @@ -0,0 +1,23 @@ +--- a/config.mk ++++ b/config.mk +@@ -64,9 +64,17 @@ HOSTSTRIP = strip + # + + ifeq ($(HOSTOS),darwin) +-HOSTCC = cc +-HOSTCFLAGS += -traditional-cpp +-HOSTLDFLAGS += -multiply_defined suppress ++#get the major and minor product version (e.g. '10' and '6' for Snow Leopard) ++DARWIN_MAJOR_VERSION = $(shell sw_vers -productVersion | cut -f 1 -d '.') ++DARWIN_MINOR_VERSION = $(shell sw_vers -productVersion | cut -f 2 -d '.') ++ ++before-snow-leopard = $(shell if [ $(DARWIN_MAJOR_VERSION) -le 10 -a \ ++ $(DARWIN_MINOR_VERSION) -le 5 ] ; then echo "$(1)"; else echo "$(2)"; fi ;) ++ ++# Snow Leopards build environment has no longer restrictions as described above ++HOSTCC = $(call before-snow-leopard, "cc", "gcc") ++HOSTCFLAGS += $(call before-snow-leopard, "-traditional-cpp") ++HOSTLDFLAGS += $(call before-snow-leopard, "-multiply_defined suppress") + else + HOSTCC = gcc + endif diff --git a/package/boot/uboot-ar71xx/patches/.svn/text-base/022-getline_backport.patch.svn-base b/package/boot/uboot-ar71xx/patches/.svn/text-base/022-getline_backport.patch.svn-base new file mode 100644 index 0000000..2ce2b61 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/.svn/text-base/022-getline_backport.patch.svn-base @@ -0,0 +1,21 @@ +--- a/tools/os_support.c ++++ b/tools/os_support.c +@@ -23,6 +23,6 @@ + #ifdef __MINGW32__ + #include "mingw_support.c" + #endif +-#ifdef __APPLE__ ++#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L + #include "getline.c" + #endif +--- a/tools/os_support.h ++++ b/tools/os_support.h +@@ -28,7 +28,7 @@ + #include "mingw_support.h" + #endif + +-#ifdef __APPLE__ ++#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L + #include "getline.h" + #endif + diff --git a/package/boot/uboot-ar71xx/patches/001-ar71xx.patch b/package/boot/uboot-ar71xx/patches/001-ar71xx.patch new file mode 100644 index 0000000..409f67a --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/001-ar71xx.patch @@ -0,0 +1,28 @@ +diff -ur u-boot-2010.03/cpu/mips/Makefile u-boot-nbg/cpu/mips/Makefile +--- u-boot-2010.03/cpu/mips/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/cpu/mips/Makefile 2010-04-15 18:58:01.000000000 +0200 +@@ -33,6 +33,7 @@ + COBJS-$(CONFIG_INCA_IP) += asc_serial.o incaip_clock.o + COBJS-$(CONFIG_PURPLE) += asc_serial.o + COBJS-$(CONFIG_SOC_AU1X00) += au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o ++COBJS-$(CONFIG_AR71XX) += ar71xx_serial.o + + SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) + OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +diff -ur u-boot-2010.03/Makefile u-boot-nbg/Makefile +--- u-boot-2010.03/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/Makefile 2010-04-11 23:31:29.000000000 +0200 +@@ -3455,6 +3455,13 @@ + @$(MKCONFIG) -a qemu-mips mips mips qemu-mips + + ######################################################################### ++## MIPS32 AR71XX (24K) ++######################################################################### ++ ++nbg460n_550n_550nh_config : unconfig ++ @$(MKCONFIG) -a nbg460n mips mips nbg460n zyxel ++ ++######################################################################### + ## MIPS64 5Kc + ######################################################################### + diff --git a/package/boot/uboot-ar71xx/patches/002-ar71xx-spi.patch b/package/boot/uboot-ar71xx/patches/002-ar71xx-spi.patch new file mode 100644 index 0000000..2bb1ba2 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/002-ar71xx-spi.patch @@ -0,0 +1,11 @@ +diff -ur u-boot-2010.03/drivers/spi/Makefile u-boot-nbg/drivers/spi/Makefile +--- u-boot-2010.03/drivers/spi/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/drivers/spi/Makefile 2010-04-15 19:31:27.000000000 +0200 +@@ -25,6 +25,7 @@ + + LIB := $(obj)libspi.a + ++COBJS-$(CONFIG_AR71XX_SPI) += ar71xx_spi.o + COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o + COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o + COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o diff --git a/package/boot/uboot-ar71xx/patches/010-enet-ag71xx.patch b/package/boot/uboot-ar71xx/patches/010-enet-ag71xx.patch new file mode 100644 index 0000000..ee90e32 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/010-enet-ag71xx.patch @@ -0,0 +1,22 @@ +diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile +--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200 +@@ -27,6 +27,7 @@ + + COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o + COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o ++COBJS-$(CONFIG_AG71XX) += ag71xx.o + COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o + COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o + COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o +diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h +--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200 +@@ -42,6 +42,7 @@ + + /* Driver initialization prototypes */ + int au1x00_enet_initialize(bd_t*); ++int ag71xx_register(bd_t * bis, char *phyname[], u16 phyid[], u16 phyfixed[]); + int at91emac_register(bd_t *bis, unsigned long iobase); + int bfin_EMAC_initialize(bd_t *bis); + int cs8900_initialize(u8 dev_num, int base_addr); diff --git a/package/boot/uboot-ar71xx/patches/011-switch-rtl8366sr.patch b/package/boot/uboot-ar71xx/patches/011-switch-rtl8366sr.patch new file mode 100644 index 0000000..5d2ba41 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/011-switch-rtl8366sr.patch @@ -0,0 +1,28 @@ +diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile +--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200 +@@ -65,6 +65,7 @@ + COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o + COBJS-$(CONFIG_RTL8139) += rtl8139.o + COBJS-$(CONFIG_RTL8169) += rtl8169.o ++COBJS-$(CONFIG_RTL8366_MII) += phy/rtl8366_mii.o + COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o + COBJS-$(CONFIG_SH_ETHER) += sh_eth.o + COBJS-$(CONFIG_SMC91111) += smc91111.o +diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h +--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200 ++++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200 +@@ -175,5 +175,13 @@ + + int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig); + #endif /* CONFIG_MV88E61XX_SWITCH */ ++ ++#if defined(CONFIG_RTL8366_MII) ++#define RTL8366_DEVNAME "rtl8366" ++#define RTL8366_WANPHY_ID 4 ++#define RTL8366_LANPHY_ID -1 ++int rtl8366_mii_register(bd_t *bis); ++int rtl8366s_initialize(void); ++#endif + + #endif /* _NETDEV_H_ */ diff --git a/package/boot/uboot-ar71xx/patches/020-freebsd-compat.patch b/package/boot/uboot-ar71xx/patches/020-freebsd-compat.patch new file mode 100644 index 0000000..fee0669 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/020-freebsd-compat.patch @@ -0,0 +1,11 @@ +--- a/include/compiler.h ++++ b/include/compiler.h +@@ -46,7 +46,7 @@ extern int errno; + #ifdef __linux__ + # include <endian.h> + # include <byteswap.h> +-#elif defined(__MACH__) ++#elif defined(__MACH__) || defined(__FreeBSD__) + # include <machine/endian.h> + typedef unsigned long ulong; + typedef unsigned int uint; diff --git a/package/boot/uboot-ar71xx/patches/021-darwin_compat.patch b/package/boot/uboot-ar71xx/patches/021-darwin_compat.patch new file mode 100644 index 0000000..dde83d4 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/021-darwin_compat.patch @@ -0,0 +1,23 @@ +--- a/config.mk ++++ b/config.mk +@@ -64,9 +64,17 @@ HOSTSTRIP = strip + # + + ifeq ($(HOSTOS),darwin) +-HOSTCC = cc +-HOSTCFLAGS += -traditional-cpp +-HOSTLDFLAGS += -multiply_defined suppress ++#get the major and minor product version (e.g. '10' and '6' for Snow Leopard) ++DARWIN_MAJOR_VERSION = $(shell sw_vers -productVersion | cut -f 1 -d '.') ++DARWIN_MINOR_VERSION = $(shell sw_vers -productVersion | cut -f 2 -d '.') ++ ++before-snow-leopard = $(shell if [ $(DARWIN_MAJOR_VERSION) -le 10 -a \ ++ $(DARWIN_MINOR_VERSION) -le 5 ] ; then echo "$(1)"; else echo "$(2)"; fi ;) ++ ++# Snow Leopards build environment has no longer restrictions as described above ++HOSTCC = $(call before-snow-leopard, "cc", "gcc") ++HOSTCFLAGS += $(call before-snow-leopard, "-traditional-cpp") ++HOSTLDFLAGS += $(call before-snow-leopard, "-multiply_defined suppress") + else + HOSTCC = gcc + endif diff --git a/package/boot/uboot-ar71xx/patches/022-getline_backport.patch b/package/boot/uboot-ar71xx/patches/022-getline_backport.patch new file mode 100644 index 0000000..2ce2b61 --- /dev/null +++ b/package/boot/uboot-ar71xx/patches/022-getline_backport.patch @@ -0,0 +1,21 @@ +--- a/tools/os_support.c ++++ b/tools/os_support.c +@@ -23,6 +23,6 @@ + #ifdef __MINGW32__ + #include "mingw_support.c" + #endif +-#ifdef __APPLE__ ++#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L + #include "getline.c" + #endif +--- a/tools/os_support.h ++++ b/tools/os_support.h +@@ -28,7 +28,7 @@ + #include "mingw_support.h" + #endif + +-#ifdef __APPLE__ ++#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L + #include "getline.h" + #endif + diff --git a/package/boot/uboot-envtools/.svn/entries b/package/boot/uboot-envtools/.svn/entries new file mode 100644 index 0000000..dd03750 --- /dev/null +++ b/package/boot/uboot-envtools/.svn/entries @@ -0,0 +1,68 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-envtools +svn://svn.openwrt.org/openwrt + + + +2013-03-15T01:36:53.833391Z +36033 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +c912a9069ac7b571a308a7eb4a9a1dc4 +2013-03-15T01:36:53.833391Z +36033 +luka + + + + + + + + + + + + + + + + + + + + + +2018 + diff --git a/package/boot/uboot-envtools/.svn/text-base/Makefile.svn-base b/package/boot/uboot-envtools/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..55aaf88 --- /dev/null +++ b/package/boot/uboot-envtools/.svn/text-base/Makefile.svn-base @@ -0,0 +1,74 @@ +# +# Copyright (C) 2006-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=uboot-envtools +PKG_DISTNAME:=u-boot +PKG_VERSION:=2013.01.01 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=73939f78606f89a1775c7e9acb2ca617 + +PKG_BUILD_DIR:=$(BUILD_DIR)/u-boot-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/uboot-envtools + SECTION:=utils + CATEGORY:=Utilities + TITLE:=read/modify U-Boot bootloader environment + URL:=http://www.denx.de/wiki/U-Boot +endef + +define Package/uboot-envtools/description + This package includes tools to read and modify U-Boot bootloader environment. +endef + +define Build/Configure +endef + +define Build/Compile + touch $(PKG_BUILD_DIR)/include/config.h + $(MAKE) -C $(PKG_BUILD_DIR) \ + HOSTCC="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)gcc" \ + HOSTSTRIP="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)strip" \ + env +endef + +define Package/uboot-envtools/conffiles +/etc/config/ubootenv +/etc/fw_env.config +endef + +define Package/uboot-envtools/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/env/fw_printenv $(1)/usr/sbin + ln -s fw_printenv $(1)/usr/sbin/fw_setenv + $(INSTALL_DIR) $(1)/lib + $(INSTALL_DATA) ./files/uboot-envtools.sh $(1)/lib +ifneq ($(CONFIG_TARGET_ar71xx),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/ar71xx $(1)/etc/uci-defaults/uboot-envtools +endif +ifneq ($(CONFIG_TARGET_kirkwood),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/kirkwood $(1)/etc/uci-defaults/uboot-envtools +endif +ifneq ($(CONFIG_TARGET_lantiq),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/lantiq $(1)/etc/uci-defaults/uboot-envtools +endif +ifneq ($(CONFIG_TARGET_ramips),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/ramips $(1)/etc/uci-defaults/uboot-envtools +endif +endef + +$(eval $(call BuildPackage,uboot-envtools)) diff --git a/package/boot/uboot-envtools/Makefile b/package/boot/uboot-envtools/Makefile new file mode 100644 index 0000000..55aaf88 --- /dev/null +++ b/package/boot/uboot-envtools/Makefile @@ -0,0 +1,74 @@ +# +# Copyright (C) 2006-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=uboot-envtools +PKG_DISTNAME:=u-boot +PKG_VERSION:=2013.01.01 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=73939f78606f89a1775c7e9acb2ca617 + +PKG_BUILD_DIR:=$(BUILD_DIR)/u-boot-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/uboot-envtools + SECTION:=utils + CATEGORY:=Utilities + TITLE:=read/modify U-Boot bootloader environment + URL:=http://www.denx.de/wiki/U-Boot +endef + +define Package/uboot-envtools/description + This package includes tools to read and modify U-Boot bootloader environment. +endef + +define Build/Configure +endef + +define Build/Compile + touch $(PKG_BUILD_DIR)/include/config.h + $(MAKE) -C $(PKG_BUILD_DIR) \ + HOSTCC="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)gcc" \ + HOSTSTRIP="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)strip" \ + env +endef + +define Package/uboot-envtools/conffiles +/etc/config/ubootenv +/etc/fw_env.config +endef + +define Package/uboot-envtools/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/env/fw_printenv $(1)/usr/sbin + ln -s fw_printenv $(1)/usr/sbin/fw_setenv + $(INSTALL_DIR) $(1)/lib + $(INSTALL_DATA) ./files/uboot-envtools.sh $(1)/lib +ifneq ($(CONFIG_TARGET_ar71xx),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/ar71xx $(1)/etc/uci-defaults/uboot-envtools +endif +ifneq ($(CONFIG_TARGET_kirkwood),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/kirkwood $(1)/etc/uci-defaults/uboot-envtools +endif +ifneq ($(CONFIG_TARGET_lantiq),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/lantiq $(1)/etc/uci-defaults/uboot-envtools +endif +ifneq ($(CONFIG_TARGET_ramips),) + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/ramips $(1)/etc/uci-defaults/uboot-envtools +endif +endef + +$(eval $(call BuildPackage,uboot-envtools)) diff --git a/package/boot/uboot-envtools/files/.svn/entries b/package/boot/uboot-envtools/files/.svn/entries new file mode 100644 index 0000000..b8b2ee3 --- /dev/null +++ b/package/boot/uboot-envtools/files/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-envtools/files +svn://svn.openwrt.org/openwrt + + + +2013-03-03T21:59:35.671819Z +35866 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +lantiq +file + + + + +2013-03-17T12:13:21.000000Z +feaeaee38e5a27cd3fdb620527e84a40 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +388 + +uboot-envtools.sh +file + + + + +2013-03-17T12:13:21.000000Z +4c8999ee23b10578d350fc5a58690e02 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +771 + +kirkwood +file + + + + +2013-03-17T12:13:21.000000Z +be3738327f58fad9f27bd01a23ae277a +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +418 + +ar71xx +file + + + + +2013-03-17T12:13:21.000000Z +10b2cf77277fa90f3966c145ff410c23 +2013-03-03T21:59:35.671819Z +35866 +luka + + + + + + + + + + + + + + + + + + + + + +630 + +ramips +file + + + + +2013-03-17T12:13:21.000000Z +e8cb5e6fbb48539d2d9d74f7e858737d +2013-02-02T17:01:52.502693Z +35464 +juhosg + + + + + + + + + + + + + + + + + + + + + +495 + diff --git a/package/boot/uboot-envtools/files/.svn/text-base/ar71xx.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/ar71xx.svn-base new file mode 100644 index 0000000..1803a9f --- /dev/null +++ b/package/boot/uboot-envtools/files/.svn/text-base/ar71xx.svn-base @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Copyright (C) 2011-2013 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/ar71xx.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(ar71xx_board_name) + +case "$board" in +all0258n | \ +cap4200ag | \ +mr600 | \ +mr600v2) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" + ;; +alfa-ap96 | \ +all0315n | \ +om2p | \ +om2p-hs | \ +om2p-lc) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x40000" "0x40000" + ;; +wzr-hp-ag300h) + ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x10000" "0x10000" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/.svn/text-base/kirkwood.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/kirkwood.svn-base new file mode 100644 index 0000000..cad53aa --- /dev/null +++ b/package/boot/uboot-envtools/files/.svn/text-base/kirkwood.svn-base @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (C) 2012 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/kirkwood.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +hardware=$(kirkwood_hardware_name) + +case "$hardware" in +"RaidSonic ICY BOX IB-NAS6210") + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/.svn/text-base/lantiq.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/lantiq.svn-base new file mode 100644 index 0000000..40befc3 --- /dev/null +++ b/package/boot/uboot-envtools/files/.svn/text-base/lantiq.svn-base @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (C) 2012 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/lantiq.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(lantiq_board_name) + +case "$board" in +GIGASX76X) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" "1" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/.svn/text-base/ramips.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/ramips.svn-base new file mode 100644 index 0000000..3599f68 --- /dev/null +++ b/package/boot/uboot-envtools/files/.svn/text-base/ramips.svn-base @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Copyright (C) 2011-2012 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/ramips.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(ramips_board_name) + +case "$board" in +all0239-3g | \ +all0256n | \ +all5002) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" + ;; +esac + +br6425) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x10000" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/.svn/text-base/uboot-envtools.sh.svn-base b/package/boot/uboot-envtools/files/.svn/text-base/uboot-envtools.sh.svn-base new file mode 100644 index 0000000..e21b283 --- /dev/null +++ b/package/boot/uboot-envtools/files/.svn/text-base/uboot-envtools.sh.svn-base @@ -0,0 +1,36 @@ +#!/bin/sh +# +# Copyright (C) 2011-2012 OpenWrt.org +# + +ubootenv_add_uci_config() { + local dev=$1 + local offset=$2 + local envsize=$3 + local secsize=$4 + local numsec=$5 + uci batch <<EOF +add ubootenv ubootenv +set ubootenv.@ubootenv[-1].dev='$dev' +set ubootenv.@ubootenv[-1].offset='$offset' +set ubootenv.@ubootenv[-1].envsize='$envsize' +set ubootenv.@ubootenv[-1].secsize='$secsize' +set ubootenv.@ubootenv[-1].numsec='$numsec' +EOF + uci commit ubootenv +} + +ubootenv_add_app_config() { + local dev + local offset + local envsize + local secsize + local numsec + config_get dev "$1" dev + config_get offset "$1" offset + config_get envsize "$1" envsize + config_get secsize "$1" secsize + config_get numsec "$1" numsec + echo "$dev $offset $envsize $secsize $numsec" >>/etc/fw_env.config +} + diff --git a/package/boot/uboot-envtools/files/ar71xx b/package/boot/uboot-envtools/files/ar71xx new file mode 100644 index 0000000..1803a9f --- /dev/null +++ b/package/boot/uboot-envtools/files/ar71xx @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Copyright (C) 2011-2013 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/ar71xx.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(ar71xx_board_name) + +case "$board" in +all0258n | \ +cap4200ag | \ +mr600 | \ +mr600v2) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" + ;; +alfa-ap96 | \ +all0315n | \ +om2p | \ +om2p-hs | \ +om2p-lc) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x40000" "0x40000" + ;; +wzr-hp-ag300h) + ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x10000" "0x10000" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/kirkwood b/package/boot/uboot-envtools/files/kirkwood new file mode 100644 index 0000000..cad53aa --- /dev/null +++ b/package/boot/uboot-envtools/files/kirkwood @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (C) 2012 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/kirkwood.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +hardware=$(kirkwood_hardware_name) + +case "$hardware" in +"RaidSonic ICY BOX IB-NAS6210") + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/lantiq b/package/boot/uboot-envtools/files/lantiq new file mode 100644 index 0000000..40befc3 --- /dev/null +++ b/package/boot/uboot-envtools/files/lantiq @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (C) 2012 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/lantiq.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(lantiq_board_name) + +case "$board" in +GIGASX76X) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" "1" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/ramips b/package/boot/uboot-envtools/files/ramips new file mode 100644 index 0000000..3599f68 --- /dev/null +++ b/package/boot/uboot-envtools/files/ramips @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Copyright (C) 2011-2012 OpenWrt.org +# + +[ -e /etc/config/ubootenv ] && exit 0 + +touch /etc/config/ubootenv + +. /lib/ramips.sh +. /lib/uboot-envtools.sh +. /lib/functions.sh + +board=$(ramips_board_name) + +case "$board" in +all0239-3g | \ +all0256n | \ +all5002) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" + ;; +esac + +br6425) + ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x10000" + ;; +esac + +config_load ubootenv +config_foreach ubootenv_add_app_config ubootenv + +exit 0 diff --git a/package/boot/uboot-envtools/files/uboot-envtools.sh b/package/boot/uboot-envtools/files/uboot-envtools.sh new file mode 100644 index 0000000..e21b283 --- /dev/null +++ b/package/boot/uboot-envtools/files/uboot-envtools.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# +# Copyright (C) 2011-2012 OpenWrt.org +# + +ubootenv_add_uci_config() { + local dev=$1 + local offset=$2 + local envsize=$3 + local secsize=$4 + local numsec=$5 + uci batch <<EOF +add ubootenv ubootenv +set ubootenv.@ubootenv[-1].dev='$dev' +set ubootenv.@ubootenv[-1].offset='$offset' +set ubootenv.@ubootenv[-1].envsize='$envsize' +set ubootenv.@ubootenv[-1].secsize='$secsize' +set ubootenv.@ubootenv[-1].numsec='$numsec' +EOF + uci commit ubootenv +} + +ubootenv_add_app_config() { + local dev + local offset + local envsize + local secsize + local numsec + config_get dev "$1" dev + config_get offset "$1" offset + config_get envsize "$1" envsize + config_get secsize "$1" secsize + config_get numsec "$1" numsec + echo "$dev $offset $envsize $secsize $numsec" >>/etc/fw_env.config +} + diff --git a/package/boot/uboot-envtools/patches/.svn/entries b/package/boot/uboot-envtools/patches/.svn/entries new file mode 100644 index 0000000..d5b8a2a --- /dev/null +++ b/package/boot/uboot-envtools/patches/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-envtools/patches +svn://svn.openwrt.org/openwrt + + + +2013-03-15T01:36:53.833391Z +36033 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-kirkwood/.svn/entries b/package/boot/uboot-kirkwood/.svn/entries new file mode 100644 index 0000000..3077356 --- /dev/null +++ b/package/boot/uboot-kirkwood/.svn/entries @@ -0,0 +1,68 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood +svn://svn.openwrt.org/openwrt + + + +2012-11-29T01:04:37.686581Z +34401 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +b1a0c2e2c531d535f679f4ef6296f475 +2012-11-29T01:04:37.686581Z +34401 +luka + + + + + + + + + + + + + + + + + + + + + +2412 + diff --git a/package/boot/uboot-kirkwood/.svn/text-base/Makefile.svn-base b/package/boot/uboot-kirkwood/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..dc66450 --- /dev/null +++ b/package/boot/uboot-kirkwood/.svn/text-base/Makefile.svn-base @@ -0,0 +1,104 @@ +# +# Copyright (C) 2010-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2012.10 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=8655f63b1e5c4647295ac9ce44660be3 +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/sheevaplug + TITLE:=U-Boot for the SheevaPlug +endef + +define uboot/dockstar + TITLE:=U-Boot for the Seagate DockStar +endef + +define uboot/iconnect + TITLE:=U-Boot for the Iomega iConnect Wireless +endef + +define uboot/ib62x0 + TITLE:=U-Boot for the RaidSonic ICY BOX NAS6210 and NAS6220 +endef + +UBOOTS:=sheevaplug dockstar iconnect ib62x0 + +define Package/uboot/template +define Package/uboot-kirkwood-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_kirkwood + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) +endef +endef + +define BuildUBootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + u-boot.kwb \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/default + $(INSTALL_DIR) $(BIN_DIR)/uboot-$(BOARD)-$(1) + $(CP) $(PKG_BUILD_DIR)/u-boot.bin \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.bin + $(CP) $(PKG_BUILD_DIR)/u-boot.kwb \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.kwb + $(INSTALL_DIR) $(BIN_DIR)/u-boot-kwboot/ + $(CP) $(PKG_BUILD_DIR)/tools/kwboot \ + $(BIN_DIR)/u-boot-kwboot/ +endef + +define Package/uboot/install/template +define Package/uboot-kirkwood-$(1)/install + $(call Package/uboot/install/default,$(2)) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),$(u))) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUBootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-kirkwood-$(u))) \ +) diff --git a/package/boot/uboot-kirkwood/Makefile b/package/boot/uboot-kirkwood/Makefile new file mode 100644 index 0000000..dc66450 --- /dev/null +++ b/package/boot/uboot-kirkwood/Makefile @@ -0,0 +1,104 @@ +# +# Copyright (C) 2010-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2012.10 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=8655f63b1e5c4647295ac9ce44660be3 +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/sheevaplug + TITLE:=U-Boot for the SheevaPlug +endef + +define uboot/dockstar + TITLE:=U-Boot for the Seagate DockStar +endef + +define uboot/iconnect + TITLE:=U-Boot for the Iomega iConnect Wireless +endef + +define uboot/ib62x0 + TITLE:=U-Boot for the RaidSonic ICY BOX NAS6210 and NAS6220 +endef + +UBOOTS:=sheevaplug dockstar iconnect ib62x0 + +define Package/uboot/template +define Package/uboot-kirkwood-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_kirkwood + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) +endef +endef + +define BuildUBootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + u-boot.kwb \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/default + $(INSTALL_DIR) $(BIN_DIR)/uboot-$(BOARD)-$(1) + $(CP) $(PKG_BUILD_DIR)/u-boot.bin \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.bin + $(CP) $(PKG_BUILD_DIR)/u-boot.kwb \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.kwb + $(INSTALL_DIR) $(BIN_DIR)/u-boot-kwboot/ + $(CP) $(PKG_BUILD_DIR)/tools/kwboot \ + $(BIN_DIR)/u-boot-kwboot/ +endef + +define Package/uboot/install/template +define Package/uboot-kirkwood-$(1)/install + $(call Package/uboot/install/default,$(2)) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),$(u))) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUBootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-kirkwood-$(u))) \ +) diff --git a/package/boot/uboot-kirkwood/files/.svn/entries b/package/boot/uboot-kirkwood/files/.svn/entries new file mode 100644 index 0000000..beb8916 --- /dev/null +++ b/package/boot/uboot-kirkwood/files/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files +svn://svn.openwrt.org/openwrt + + + +2012-11-22T21:16:04.130323Z +34303 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +include +dir + +board +dir + diff --git a/package/boot/uboot-kirkwood/files/board/.svn/entries b/package/boot/uboot-kirkwood/files/board/.svn/entries new file mode 100644 index 0000000..87dc985 --- /dev/null +++ b/package/boot/uboot-kirkwood/files/board/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/board +svn://svn.openwrt.org/openwrt + + + +2012-11-22T21:16:04.130323Z +34303 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +iomega +dir + diff --git a/package/boot/uboot-kirkwood/files/board/iomega/.svn/entries b/package/boot/uboot-kirkwood/files/board/iomega/.svn/entries new file mode 100644 index 0000000..4656309 --- /dev/null +++ b/package/boot/uboot-kirkwood/files/board/iomega/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/board/iomega +svn://svn.openwrt.org/openwrt + + + +2012-11-22T21:16:04.130323Z +34303 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +iconnect +dir + diff --git a/package/boot/uboot-kirkwood/files/board/iomega/iconnect/.svn/entries b/package/boot/uboot-kirkwood/files/board/iomega/iconnect/.svn/entries new file mode 100644 index 0000000..9056757 --- /dev/null +++ b/package/boot/uboot-kirkwood/files/board/iomega/iconnect/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/board/iomega/iconnect +svn://svn.openwrt.org/openwrt + + + +2012-11-22T21:16:04.130323Z +34303 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-kirkwood/files/include/.svn/entries b/package/boot/uboot-kirkwood/files/include/.svn/entries new file mode 100644 index 0000000..ee6253a --- /dev/null +++ b/package/boot/uboot-kirkwood/files/include/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/include +svn://svn.openwrt.org/openwrt + + + +2012-11-22T21:16:04.130323Z +34303 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +configs +dir + diff --git a/package/boot/uboot-kirkwood/files/include/configs/.svn/entries b/package/boot/uboot-kirkwood/files/include/configs/.svn/entries new file mode 100644 index 0000000..84be5da --- /dev/null +++ b/package/boot/uboot-kirkwood/files/include/configs/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/files/include/configs +svn://svn.openwrt.org/openwrt + + + +2012-11-22T21:16:04.130323Z +34303 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-kirkwood/patches/.svn/entries b/package/boot/uboot-kirkwood/patches/.svn/entries new file mode 100644 index 0000000..38b5197 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-kirkwood/patches +svn://svn.openwrt.org/openwrt + + + +2012-11-22T21:16:04.130323Z +34303 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +110-dockstar.patch +file + + + + +2013-03-17T12:13:21.000000Z +11b1822c2274e5ec31c4552b382fe2f2 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +1224 + diff --git a/package/boot/uboot-kirkwood/patches/.svn/text-base/110-dockstar.patch.svn-base b/package/boot/uboot-kirkwood/patches/.svn/text-base/110-dockstar.patch.svn-base new file mode 100644 index 0000000..4ff7e57 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/.svn/text-base/110-dockstar.patch.svn-base @@ -0,0 +1,35 @@ +--- a/include/configs/dockstar.h ++++ b/include/configs/dockstar.h +@@ -83,22 +83,19 @@ + * Default environment variables + */ + #define CONFIG_BOOTCOMMAND \ +- "setenv bootargs ${console} ${mtdparts} ${bootargs_root}; " \ +- "ubi part root; " \ +- "ubifsmount root; " \ +- "ubifsload 0x800000 ${kernel}; " \ +- "ubifsload 0x1100000 ${initrd}; " \ +- "bootm 0x800000 0x1100000" ++ "${x_bootcmd_kernel}; " \ ++ "setenv bootargs ${x_bootargs} ${x_bootargs_root}; " \ ++ "${x_bootcmd_usb}; bootm 0x6400000;" + +-#define CONFIG_MTDPARTS "mtdparts=orion_nand:1m(uboot),-(root)\0" ++#define CONFIG_MTDPARTS \ ++ "orion_nand:1M(u-boot),1M@1M(second_stage_u-boot)," \ ++ "3M@2M(kernel),32M@5M(rootfs),219M@37M(data) rw\0" + + #define CONFIG_EXTRA_ENV_SETTINGS \ +- "console=console=ttyS0,115200\0" \ +- "mtdids=nand0=orion_nand\0" \ +- "mtdparts="CONFIG_MTDPARTS \ +- "kernel=/boot/uImage\0" \ +- "initrd=/boot/uInitrd\0" \ +- "bootargs_root=ubi.mtd=1 root=ubi0:root rootfstype=ubifs ro\0" ++ "x_bootargs=console=ttyS0,115200 mtdparts="CONFIG_MTDPARTS \ ++ "x_bootcmd_kernel=nand read 0x6400000 0x200000 0x300000\0" \ ++ "x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0" \ ++ "x_bootcmd_usb=usb start\0" + + /* + * Ethernet Driver configuration diff --git a/package/boot/uboot-kirkwood/patches/110-dockstar.patch b/package/boot/uboot-kirkwood/patches/110-dockstar.patch new file mode 100644 index 0000000..4ff7e57 --- /dev/null +++ b/package/boot/uboot-kirkwood/patches/110-dockstar.patch @@ -0,0 +1,35 @@ +--- a/include/configs/dockstar.h ++++ b/include/configs/dockstar.h +@@ -83,22 +83,19 @@ + * Default environment variables + */ + #define CONFIG_BOOTCOMMAND \ +- "setenv bootargs ${console} ${mtdparts} ${bootargs_root}; " \ +- "ubi part root; " \ +- "ubifsmount root; " \ +- "ubifsload 0x800000 ${kernel}; " \ +- "ubifsload 0x1100000 ${initrd}; " \ +- "bootm 0x800000 0x1100000" ++ "${x_bootcmd_kernel}; " \ ++ "setenv bootargs ${x_bootargs} ${x_bootargs_root}; " \ ++ "${x_bootcmd_usb}; bootm 0x6400000;" + +-#define CONFIG_MTDPARTS "mtdparts=orion_nand:1m(uboot),-(root)\0" ++#define CONFIG_MTDPARTS \ ++ "orion_nand:1M(u-boot),1M@1M(second_stage_u-boot)," \ ++ "3M@2M(kernel),32M@5M(rootfs),219M@37M(data) rw\0" + + #define CONFIG_EXTRA_ENV_SETTINGS \ +- "console=console=ttyS0,115200\0" \ +- "mtdids=nand0=orion_nand\0" \ +- "mtdparts="CONFIG_MTDPARTS \ +- "kernel=/boot/uImage\0" \ +- "initrd=/boot/uInitrd\0" \ +- "bootargs_root=ubi.mtd=1 root=ubi0:root rootfstype=ubifs ro\0" ++ "x_bootargs=console=ttyS0,115200 mtdparts="CONFIG_MTDPARTS \ ++ "x_bootcmd_kernel=nand read 0x6400000 0x200000 0x300000\0" \ ++ "x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0" \ ++ "x_bootcmd_usb=usb start\0" + + /* + * Ethernet Driver configuration diff --git a/package/boot/uboot-lantiq/.svn/entries b/package/boot/uboot-lantiq/.svn/entries new file mode 100644 index 0000000..b679bd3 --- /dev/null +++ b/package/boot/uboot-lantiq/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-lantiq +svn://svn.openwrt.org/openwrt + + + +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +bb017dc208140158e17d27f258ff37f8 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +2983 + diff --git a/package/boot/uboot-lantiq/.svn/text-base/Makefile.svn-base b/package/boot/uboot-lantiq/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..b3d9173 --- /dev/null +++ b/package/boot/uboot-lantiq/.svn/text-base/Makefile.svn-base @@ -0,0 +1,123 @@ +# +# Copyright (C) 2012-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2013.01 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=e58a8a7f78972248190d83de0dc362ce +PKG_TARGETS:=bin + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + SOC:= + DDR_SETTINGS:= + IMAGE:= +endef + +define uboot/arv4519pw_ram + TITLE:=U-Boot for Arcadyan arv4519pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv4519pw/ddr_settings.h +endef + +define uboot/arv4519pw_nor + TITLE:=U-Boot for Arcadyan arv4519pw (NOR) + SOC:=danube +endef + +define uboot/arv7518pw_ram + TITLE:=U-Boot for Arcadyan arv7518pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv7518pw/ddr_settings.h +endef + +define uboot/arv7518pw_nor + TITLE:=U-Boot for Arcadyan arv7518pw (NOR) + SOC:=danube +endef + +define uboot/gigasx76x_ram + TITLE:=U-Boot for Siemens Gigaset sx76x (RAM) + SOC:=danube + DDR_SETTINGS:=board/gigaset/sx76x/ddr_settings.h +endef + +define uboot/gigasx76x_nor + TITLE:=U-Boot for Siemens Gigaset sx76x (NOR) + SOC:=danube +endef + +UBOOTS:= \ + arv4519pw_ram arv4519pw_nor \ + arv7518pw_ram arv7518pw_nor \ + gigasx76x_ram gigasx76x_nor + +define Package/uboot/template +define Package/uboot-lantiq-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_lantiq_xway + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Luka Perkov <luka@openwrt.org> +endef +endef + +define BuildUBootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) $(BUILD_VARIANT)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/default + $(CP) \ + $(PKG_BUILD_DIR)/$(2) \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.img +endef + +define Package/uboot/install/uart + awk -f $(PKG_BUILD_DIR)/tools/lantiq_ram_init_uart.awk \ + -v soc=$(2) $(PKG_BUILD_DIR)/$(3) \ + > $(PKG_BUILD_DIR)/ddr_settings + perl $(PKG_BUILD_DIR)/tools/gct.pl \ + $(PKG_BUILD_DIR)/ddr_settings $(PKG_BUILD_DIR)/u-boot.srec \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.asc + endef + +define Package/uboot/install/template +define Package/uboot-lantiq-$(1)/install + $(call Package/uboot/install/default,$(1),$(if $(IMAGE),$(IMAGE),u-boot.bin)) + $(if $(DDR_SETTINGS), \ + $(call Package/uboot/install/uart,$(1),$(SOC),$(DDR_SETTINGS)) \ + ) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUBootPackage,$(u))) \ + $(eval $(call Package/uboot/install/template,$(u))) \ + $(eval $(call BuildPackage,uboot-lantiq-$(u))) \ +) diff --git a/package/boot/uboot-lantiq/Makefile b/package/boot/uboot-lantiq/Makefile new file mode 100644 index 0000000..b3d9173 --- /dev/null +++ b/package/boot/uboot-lantiq/Makefile @@ -0,0 +1,123 @@ +# +# Copyright (C) 2012-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2013.01 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=e58a8a7f78972248190d83de0dc362ce +PKG_TARGETS:=bin + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + SOC:= + DDR_SETTINGS:= + IMAGE:= +endef + +define uboot/arv4519pw_ram + TITLE:=U-Boot for Arcadyan arv4519pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv4519pw/ddr_settings.h +endef + +define uboot/arv4519pw_nor + TITLE:=U-Boot for Arcadyan arv4519pw (NOR) + SOC:=danube +endef + +define uboot/arv7518pw_ram + TITLE:=U-Boot for Arcadyan arv7518pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv7518pw/ddr_settings.h +endef + +define uboot/arv7518pw_nor + TITLE:=U-Boot for Arcadyan arv7518pw (NOR) + SOC:=danube +endef + +define uboot/gigasx76x_ram + TITLE:=U-Boot for Siemens Gigaset sx76x (RAM) + SOC:=danube + DDR_SETTINGS:=board/gigaset/sx76x/ddr_settings.h +endef + +define uboot/gigasx76x_nor + TITLE:=U-Boot for Siemens Gigaset sx76x (NOR) + SOC:=danube +endef + +UBOOTS:= \ + arv4519pw_ram arv4519pw_nor \ + arv7518pw_ram arv7518pw_nor \ + gigasx76x_ram gigasx76x_nor + +define Package/uboot/template +define Package/uboot-lantiq-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_lantiq_xway + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Luka Perkov <luka@openwrt.org> +endef +endef + +define BuildUBootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) $(BUILD_VARIANT)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/default + $(CP) \ + $(PKG_BUILD_DIR)/$(2) \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.img +endef + +define Package/uboot/install/uart + awk -f $(PKG_BUILD_DIR)/tools/lantiq_ram_init_uart.awk \ + -v soc=$(2) $(PKG_BUILD_DIR)/$(3) \ + > $(PKG_BUILD_DIR)/ddr_settings + perl $(PKG_BUILD_DIR)/tools/gct.pl \ + $(PKG_BUILD_DIR)/ddr_settings $(PKG_BUILD_DIR)/u-boot.srec \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.asc + endef + +define Package/uboot/install/template +define Package/uboot-lantiq-$(1)/install + $(call Package/uboot/install/default,$(1),$(if $(IMAGE),$(IMAGE),u-boot.bin)) + $(if $(DDR_SETTINGS), \ + $(call Package/uboot/install/uart,$(1),$(SOC),$(DDR_SETTINGS)) \ + ) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUBootPackage,$(u))) \ + $(eval $(call Package/uboot/install/template,$(u))) \ + $(eval $(call BuildPackage,uboot-lantiq-$(u))) \ +) diff --git a/package/boot/uboot-lantiq/patches/.svn/entries b/package/boot/uboot-lantiq/patches/.svn/entries new file mode 100644 index 0000000..0113087 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/entries @@ -0,0 +1,980 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-lantiq/patches +svn://svn.openwrt.org/openwrt + + + +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +0015-sf-macronix-add-support-for-MX66L51235L.patch +file + + + + +2013-03-17T12:13:21.000000Z +602fb08450d9ee680150b4b6378ed147 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +620 + +0022-net-switchlib-add-driver-for-Atheros-AR8216.patch +file + + + + +2013-03-17T12:13:21.000000Z +578fbe6f2d625581bdab30ad15aceacb +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +3946 + +0026-MIPS-add-board-support-for-Gigaset-SX76X.patch +file + + + + +2013-03-17T12:13:21.000000Z +c557b83b9f972af2fe018d7e8bceb2d9 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +7688 + +0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch +file + + + + +2013-03-17T12:13:21.000000Z +4f4c2ba4ecb1006a500ea6693062c0a8 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +5685 + +0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch +file + + + + +2013-03-17T12:13:21.000000Z +d6df3ee4d0d1bb634d515eaf3c1d0bf1 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +10840 + +0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch +file + + + + +2013-03-17T12:13:21.000000Z +49e21898d73d7e2914bbc83bdd486086 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +4439 + +0007-sf-eon-use-16-bit-ID-for-comparison.patch +file + + + + +2013-03-17T12:13:21.000000Z +f5c77287a92ace9da6ab48ac0c8307b9 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +1098 + +0009-sf-eon-add-support-for-EN25QH256.patch +file + + + + +2013-03-17T12:13:21.000000Z +0a18abd1ee5dda839e36b9ea148a7766 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +596 + +0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch +file + + + + +2013-03-17T12:13:21.000000Z +be788cc7364980b8d4b8a3840c8324fa +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +3471 + +0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch +file + + + + +2013-03-17T12:13:21.000000Z +d9e3240b34b482e402e2cd8993fad402 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +248589 + +0006-sf-add-generic-support-for-4-byte-address-mode.patch +file + + + + +2013-03-17T12:13:21.000000Z +bb9f6b4f62ba46f9a635360abaaa0039 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +4669 + +0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch +file + + + + +2013-03-17T12:13:21.000000Z +cf814d35e34cb938873ec8ae40bea6c7 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +7484 + +0013-sf-macronix-add-support-for-4-byte-address-mode.patch +file + + + + +2013-03-17T12:13:21.000000Z +f85f2f23cede590205ce320e42968c10 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +1269 + +0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch +file + + + + +2013-03-17T12:13:21.000000Z +82e2ab95e1eee1895db8cf3a457863a2 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +3369 + +0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch +file + + + + +2013-03-17T12:13:21.000000Z +ca4ecb71ceab421e44e9305c09e7e0d1 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +7474 + +0005-sf-factor-out-the-flash-address-calculation.patch +file + + + + +2013-03-17T12:13:21.000000Z +b75411af756e141f6998390ec2700c88 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +3263 + +0002-sf-handle-CONFIG_MANUAL_RELOC.patch +file + + + + +2013-03-17T12:13:21.000000Z +e3f49d1615edf5a441a17fe1af0901c0 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +1309 + +0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch +file + + + + +2013-03-17T12:13:21.000000Z +0dda929b094582fe39387a9923b77e90 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +1044 + +0008-sf-eon-add-support-for-4-byte-address-mode.patch +file + + + + +2013-03-17T12:13:21.000000Z +40bc8aa4f9847b3c858cd2c3748a4dc2 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +1117 + +0018-MIPS-add-SPI-flash-init-hook.patch +file + + + + +2013-03-17T12:13:21.000000Z +6b48b2e832bb1185a77cdd6c6bbbfd2b +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +1183 + +0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch +file + + + + +2013-03-17T12:13:21.000000Z +fd730dc30a31d6c47027115a403069dc +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +4602 + +0017-sf-add-init-function.patch +file + + + + +2013-03-17T12:13:21.000000Z +9aa02a17e92e047ec05be9695b1056fe +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +1257 + +0012-sf-spansion-add-support-for-S25FL512S.patch +file + + + + +2013-03-17T12:13:21.000000Z +7cc84fd8eca16c98369a40613da48f24 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +679 + +0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch +file + + + + +2013-03-17T12:13:21.000000Z +a21e1f8f3ca4336f6b8bef85efa6e2b2 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +8788 + +0011-sf-spansion-add-support-for-4-byte-address-mode.patch +file + + + + +2013-03-17T12:13:21.000000Z +6856262a607d534b2cfe33e8859409d3 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +1517 + +0014-sf-macronix-add-support-for-MX25L25635E.patch +file + + + + +2013-03-17T12:13:21.000000Z +0ec732bb910a790afe321d1aaee9df87 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +619 + +0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch +file + + + + +2013-03-17T12:13:21.000000Z +bc39484ed9eea8e820f295f582343406 +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +783 + +0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch +file + + + + +2013-03-17T12:13:21.000000Z +35f88c1039b8799350ce6eee51270d2f +2013-01-22T12:55:01.537267Z +35292 +luka + + + + + + + + + + + + + + + + + + + + + +21472 + diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0002-sf-handle-CONFIG_MANUAL_RELOC.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0002-sf-handle-CONFIG_MANUAL_RELOC.patch.svn-base new file mode 100644 index 0000000..63a21af --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0002-sf-handle-CONFIG_MANUAL_RELOC.patch.svn-base @@ -0,0 +1,46 @@ +From 60e8a35f0efa5a7e5d797a3f239971c84061ef11 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 21:39:47 +0100 +Subject: sf: handle CONFIG_MANUAL_RELOC + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -293,7 +293,7 @@ int spi_flash_cmd_write_status(struct sp + */ + #define IDCODE_CONT_LEN 0 + #define IDCODE_PART_LEN 5 +-static const struct { ++static struct { + const u8 shift; + const u8 idcode; + struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode); +@@ -335,6 +335,10 @@ static const struct { + }; + #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN) + ++#ifdef CONFIG_NEEDS_MANUAL_RELOC ++DECLARE_GLOBAL_DATA_PTR; ++#endif ++ + struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int spi_mode) + { +@@ -342,6 +346,16 @@ struct spi_flash *spi_flash_probe(unsign + struct spi_flash *flash = NULL; + int ret, i, shift; + u8 idcode[IDCODE_LEN], *idp; ++#ifdef CONFIG_NEEDS_MANUAL_RELOC ++ static int relocated; ++ ++ if (!relocated) { ++ for (i = 0; i < ARRAY_SIZE(flashes); i++) ++ flashes[i].probe += gd->reloc_off; ++ ++ relocated = 1; ++ } ++#endif + + spi = spi_setup_slave(bus, cs, max_hz, spi_mode); + if (!spi) { diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch.svn-base new file mode 100644 index 0000000..7f44675 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch.svn-base @@ -0,0 +1,719 @@ +From 73d127565b5a4b19bcaacabc505689ee039f16fd Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Sun, 11 Nov 2012 03:11:38 +0100 +Subject: sf: factor out malloc from SPI flash drivers + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/atmel.c ++++ b/drivers/mtd/spi/atmel.c +@@ -40,18 +40,6 @@ struct atmel_spi_flash_params { + const char *name; + }; + +-/* spi_flash needs to be first so upper layers can free() it */ +-struct atmel_spi_flash { +- struct spi_flash flash; +- const struct atmel_spi_flash_params *params; +-}; +- +-static inline struct atmel_spi_flash * +-to_atmel_spi_flash(struct spi_flash *flash) +-{ +- return container_of(flash, struct atmel_spi_flash, flash); +-} +- + static const struct atmel_spi_flash_params atmel_spi_flash_table[] = { + { + .idcode1 = 0x22, +@@ -156,7 +144,8 @@ static int at45_wait_ready(struct spi_fl + * Assemble the address part of a command for AT45 devices in + * non-power-of-two page size mode. + */ +-static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset) ++static void at45_build_address(const struct atmel_spi_flash_params *params, ++ u8 *cmd, u32 offset) + { + unsigned long page_addr; + unsigned long byte_addr; +@@ -167,7 +156,7 @@ static void at45_build_address(struct at + * The "extra" space per page is the power-of-two page size + * divided by 32. + */ +- page_shift = asf->params->l2_page_size; ++ page_shift = params->l2_page_size; + page_size = (1 << page_shift) + (1 << (page_shift - 5)); + page_shift++; + page_addr = offset / page_size; +@@ -181,11 +170,11 @@ static void at45_build_address(struct at + static int dataflash_read_fast_at45(struct spi_flash *flash, + u32 offset, size_t len, void *buf) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + u8 cmd[5]; + + cmd[0] = CMD_READ_ARRAY_FAST; +- at45_build_address(asf, cmd + 1, offset); ++ at45_build_address(params, cmd + 1, offset); + cmd[4] = 0x00; + + return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len); +@@ -197,7 +186,7 @@ static int dataflash_read_fast_at45(stru + static int dataflash_write_p2(struct spi_flash *flash, + u32 offset, size_t len, const void *buf) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + unsigned long page_size; + u32 addr = offset; + size_t chunk_len; +@@ -211,7 +200,7 @@ static int dataflash_write_p2(struct spi + * the other is being programmed into main memory. + */ + +- page_size = (1 << asf->params->l2_page_size); ++ page_size = (1 << params->l2_page_size); + + ret = spi_claim_bus(flash->spi); + if (ret) { +@@ -263,7 +252,7 @@ out: + static int dataflash_write_at45(struct spi_flash *flash, + u32 offset, size_t len, const void *buf) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + unsigned long page_addr; + unsigned long byte_addr; + unsigned long page_size; +@@ -279,7 +268,7 @@ static int dataflash_write_at45(struct s + * the other is being programmed into main memory. + */ + +- page_shift = asf->params->l2_page_size; ++ page_shift = params->l2_page_size; + page_size = (1 << page_shift) + (1 << (page_shift - 5)); + page_shift++; + page_addr = offset / page_size; +@@ -338,7 +327,7 @@ out: + */ + static int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + unsigned long page_size; + + size_t actual; +@@ -351,7 +340,7 @@ static int dataflash_erase_p2(struct spi + * when possible. + */ + +- page_size = (1 << asf->params->l2_page_size); ++ page_size = (1 << params->l2_page_size); + + if (offset % page_size || len % page_size) { + debug("SF: Erase offset/length not multiple of page size\n"); +@@ -397,7 +386,7 @@ out: + + static int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + unsigned long page_addr; + unsigned long page_size; + unsigned int page_shift; +@@ -411,7 +400,7 @@ static int dataflash_erase_at45(struct s + * when possible. + */ + +- page_shift = asf->params->l2_page_size; ++ page_shift = params->l2_page_size; + page_size = (1 << page_shift) + (1 << (page_shift - 5)); + page_shift++; + page_addr = offset / page_size; +@@ -458,12 +447,12 @@ out: + return ret; + } + +-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode) + { + const struct atmel_spi_flash_params *params; ++ struct spi_slave *spi = flash->spi; + unsigned page_size; + unsigned int family; +- struct atmel_spi_flash *asf; + unsigned int i; + int ret; + u8 status; +@@ -477,18 +466,11 @@ struct spi_flash *spi_flash_probe_atmel( + if (i == ARRAY_SIZE(atmel_spi_flash_table)) { + debug("SF: Unsupported DataFlash ID %02x\n", + idcode[1]); +- return NULL; +- } +- +- asf = malloc(sizeof(struct atmel_spi_flash)); +- if (!asf) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; ++ return 0; + } + +- asf->params = params; +- asf->flash.spi = spi; +- asf->flash.name = params->name; ++ flash->priv = (void *)params; ++ flash->name = params->name; + + /* Assuming power-of-two page size initially. */ + page_size = 1 << params->l2_page_size; +@@ -503,48 +485,44 @@ struct spi_flash *spi_flash_probe_atmel( + */ + ret = spi_flash_cmd(spi, CMD_AT45_READ_STATUS, &status, 1); + if (ret) +- goto err; ++ return -1; + + debug("SF: AT45 status register: %02x\n", status); + + if (!(status & AT45_STATUS_P2_PAGE_SIZE)) { +- asf->flash.read = dataflash_read_fast_at45; +- asf->flash.write = dataflash_write_at45; +- asf->flash.erase = dataflash_erase_at45; ++ flash->read = dataflash_read_fast_at45; ++ flash->write = dataflash_write_at45; ++ flash->erase = dataflash_erase_at45; + page_size += 1 << (params->l2_page_size - 5); + } else { +- asf->flash.read = spi_flash_cmd_read_fast; +- asf->flash.write = dataflash_write_p2; +- asf->flash.erase = dataflash_erase_p2; ++ flash->read = spi_flash_cmd_read_fast; ++ flash->write = dataflash_write_p2; ++ flash->erase = dataflash_erase_p2; + } + +- asf->flash.page_size = page_size; +- asf->flash.sector_size = page_size; ++ flash->page_size = page_size; ++ flash->sector_size = page_size; + break; + + case DF_FAMILY_AT26F: + case DF_FAMILY_AT26DF: +- asf->flash.read = spi_flash_cmd_read_fast; +- asf->flash.write = spi_flash_cmd_write_multi; +- asf->flash.erase = spi_flash_cmd_erase; +- asf->flash.page_size = page_size; +- asf->flash.sector_size = 4096; ++ flash->read = spi_flash_cmd_read_fast; ++ flash->write = spi_flash_cmd_write_multi; ++ flash->erase = spi_flash_cmd_erase; ++ flash->page_size = page_size; ++ flash->sector_size = 4096; + /* clear SPRL# bit for locked flash */ +- spi_flash_cmd_write_status(&asf->flash, 0); ++ spi_flash_cmd_write_status(flash, 0); + break; + + default: + debug("SF: Unsupported DataFlash family %u\n", family); +- goto err; ++ return -1; + } + +- asf->flash.size = page_size * params->pages_per_block ++ flash->size = page_size * params->pages_per_block + * params->blocks_per_sector + * params->nr_sectors; + +- return &asf->flash; +- +-err: +- free(asf); +- return NULL; ++ return 1; + } +--- a/drivers/mtd/spi/eon.c ++++ b/drivers/mtd/spi/eon.c +@@ -29,10 +29,9 @@ static const struct eon_spi_flash_params + }, + }; + +-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode) + { + const struct eon_spi_flash_params *params; +- struct spi_flash *flash; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) { +@@ -43,16 +42,10 @@ struct spi_flash *spi_flash_probe_eon(st + + if (i == ARRAY_SIZE(eon_spi_flash_table)) { + debug("SF: Unsupported EON ID %02x\n", idcode[1]); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -63,5 +56,5 @@ struct spi_flash *spi_flash_probe_eon(st + flash->size = 256 * 16 + * params->nr_sectors; + +- return flash; ++ return 1; + } +--- a/drivers/mtd/spi/macronix.c ++++ b/drivers/mtd/spi/macronix.c +@@ -79,10 +79,9 @@ static const struct macronix_spi_flash_p + }, + }; + +-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode) + { + const struct macronix_spi_flash_params *params; +- struct spi_flash *flash; + unsigned int i; + u16 id = idcode[2] | idcode[1] << 8; + +@@ -94,16 +93,10 @@ struct spi_flash *spi_flash_probe_macron + + if (i == ARRAY_SIZE(macronix_spi_flash_table)) { + debug("SF: Unsupported Macronix ID %04x\n", id); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -116,5 +109,5 @@ struct spi_flash *spi_flash_probe_macron + /* Clear BP# bits for read-only flash */ + spi_flash_cmd_write_status(flash, 0); + +- return flash; ++ return 1; + } +--- a/drivers/mtd/spi/ramtron.c ++++ b/drivers/mtd/spi/ramtron.c +@@ -69,17 +69,6 @@ struct ramtron_spi_fram_params { + const char *name; /* name for display and/or matching */ + }; + +-struct ramtron_spi_fram { +- struct spi_flash flash; +- const struct ramtron_spi_fram_params *params; +-}; +- +-static inline struct ramtron_spi_fram *to_ramtron_spi_fram(struct spi_flash +- *flash) +-{ +- return container_of(flash, struct ramtron_spi_fram, flash); +-} +- + /* + * table describing supported FRAM chips: + * chips without RDID command must have the values 0xff for id1 and id2 +@@ -155,18 +144,18 @@ static const struct ramtron_spi_fram_par + static int ramtron_common(struct spi_flash *flash, + u32 offset, size_t len, void *buf, u8 command) + { +- struct ramtron_spi_fram *sn = to_ramtron_spi_fram(flash); ++ const struct ramtron_spi_fram_params *params = flash->priv; + u8 cmd[4]; + int cmd_len; + int ret; + +- if (sn->params->addr_len == 3 && sn->params->merge_cmd == 0) { ++ if (params->addr_len == 3 && params->merge_cmd == 0) { + cmd[0] = command; + cmd[1] = offset >> 16; + cmd[2] = offset >> 8; + cmd[3] = offset; + cmd_len = 4; +- } else if (sn->params->addr_len == 2 && sn->params->merge_cmd == 0) { ++ } else if (params->addr_len == 2 && params->merge_cmd == 0) { + cmd[0] = command; + cmd[1] = offset >> 8; + cmd[2] = offset; +@@ -230,10 +219,9 @@ static int ramtron_erase(struct spi_flas + * nore: we are called here with idcode pointing to the first non-0x7f byte + * already! + */ +-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode) ++int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode) + { + const struct ramtron_spi_fram_params *params; +- struct ramtron_spi_fram *sn; + unsigned int i; + #ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC + int ret; +@@ -259,11 +247,11 @@ struct spi_flash *spi_fram_probe_ramtron + */ + ret = spi_flash_cmd(spi, CMD_READ_STATUS, &sr, 1); + if (ret) +- return NULL; ++ return 0; + + /* Bits 5,4,0 are fixed 0 for all devices */ + if ((sr & 0x31) != 0x00) +- return NULL; ++ return 0; + /* now find the device */ + for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) { + params = &ramtron_spi_fram_table[i]; +@@ -281,23 +269,16 @@ struct spi_flash *spi_fram_probe_ramtron + /* arriving here means no method has found a device we can handle */ + debug("SF/ramtron: unsupported device id0=%02x id1=%02x id2=%02x\n", + idcode[0], idcode[1], idcode[2]); +- return NULL; ++ return 0; + + found: +- sn = malloc(sizeof(*sn)); +- if (!sn) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } ++ flash->priv = (void *)params; ++ flash->name = params->name; + +- sn->params = params; +- sn->flash.spi = spi; +- sn->flash.name = params->name; +- +- sn->flash.write = ramtron_write; +- sn->flash.read = ramtron_read; +- sn->flash.erase = ramtron_erase; +- sn->flash.size = params->size; ++ flash->write = ramtron_write; ++ flash->read = ramtron_read; ++ flash->erase = ramtron_erase; ++ flash->size = params->size; + +- return &sn->flash; ++ return 1; + } +--- a/drivers/mtd/spi/spansion.c ++++ b/drivers/mtd/spi/spansion.c +@@ -105,10 +105,9 @@ static const struct spansion_spi_flash_p + }, + }; + +-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode) + { + const struct spansion_spi_flash_params *params; +- struct spi_flash *flash; + unsigned int i; + unsigned short jedec, ext_jedec; + +@@ -125,16 +124,10 @@ struct spi_flash *spi_flash_probe_spansi + + if (i == ARRAY_SIZE(spansion_spi_flash_table)) { + debug("SF: Unsupported SPANSION ID %04x %04x\n", jedec, ext_jedec); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -144,5 +137,5 @@ struct spi_flash *spi_flash_probe_spansi + flash->sector_size = 256 * params->pages_per_sector; + flash->size = flash->sector_size * params->nr_sectors; + +- return flash; ++ return 1; + } +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -296,7 +296,7 @@ int spi_flash_cmd_write_status(struct sp + static struct { + const u8 shift; + const u8 idcode; +- struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode); ++ int (*probe) (struct spi_flash *flash, u8 *idcode); + } flashes[] = { + /* Keep it sorted by define name */ + #ifdef CONFIG_SPI_FLASH_ATMEL +@@ -343,7 +343,7 @@ struct spi_flash *spi_flash_probe(unsign + unsigned int max_hz, unsigned int spi_mode) + { + struct spi_slave *spi; +- struct spi_flash *flash = NULL; ++ struct spi_flash *flash; + int ret, i, shift; + u8 idcode[IDCODE_LEN], *idp; + #ifdef CONFIG_NEEDS_MANUAL_RELOC +@@ -379,6 +379,15 @@ struct spi_flash *spi_flash_probe(unsign + print_buffer(0, idcode, 1, sizeof(idcode), 0); + #endif + ++ flash = malloc(sizeof(*flash)); ++ if (!flash) { ++ debug("SF: failed to alloc memory\n"); ++ goto err_malloc; ++ } ++ ++ memset(flash, 0, sizeof(*flash)); ++ flash->spi = spi; ++ + /* count the number of continuation bytes */ + for (shift = 0, idp = idcode; + shift < IDCODE_CONT_LEN && *idp == 0x7f; +@@ -389,12 +398,12 @@ struct spi_flash *spi_flash_probe(unsign + for (i = 0; i < ARRAY_SIZE(flashes); ++i) + if (flashes[i].shift == shift && flashes[i].idcode == *idp) { + /* we have a match, call probe */ +- flash = flashes[i].probe(spi, idp); +- if (flash) ++ ret = flashes[i].probe(flash, idp); ++ if (ret) + break; + } + +- if (!flash) { ++ if (ret <= 0) { + printf("SF: Unsupported manufacturer %02x\n", *idp); + goto err_manufacturer_probe; + } +@@ -408,6 +417,8 @@ struct spi_flash *spi_flash_probe(unsign + return flash; + + err_manufacturer_probe: ++ free(flash); ++err_malloc: + err_read_id: + spi_release_bus(spi); + err_claim_bus: +--- a/drivers/mtd/spi/spi_flash_internal.h ++++ b/drivers/mtd/spi/spi_flash_internal.h +@@ -98,11 +98,11 @@ int spi_flash_cmd_wait_ready(struct spi_ + int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len); + + /* Manufacturer-specific probe functions */ +-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode); ++int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_stmicro(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode); ++int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode); +--- a/drivers/mtd/spi/sst.c ++++ b/drivers/mtd/spi/sst.c +@@ -39,11 +39,6 @@ struct sst_spi_flash_params { + const char *name; + }; + +-struct sst_spi_flash { +- struct spi_flash flash; +- const struct sst_spi_flash_params *params; +-}; +- + static const struct sst_spi_flash_params sst_spi_flash_table[] = { + { + .idcode1 = 0x8d, +@@ -185,11 +180,9 @@ sst_write_wp(struct spi_flash *flash, u3 + return ret; + } + +-struct spi_flash * +-spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode) + { + const struct sst_spi_flash_params *params; +- struct sst_spi_flash *stm; + size_t i; + + for (i = 0; i < ARRAY_SIZE(sst_spi_flash_table); ++i) { +@@ -200,31 +193,24 @@ spi_flash_probe_sst(struct spi_slave *sp + + if (i == ARRAY_SIZE(sst_spi_flash_table)) { + debug("SF: Unsupported SST ID %02x\n", idcode[1]); +- return NULL; +- } +- +- stm = malloc(sizeof(*stm)); +- if (!stm) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; ++ return 0; + } + +- stm->params = params; +- stm->flash.spi = spi; +- stm->flash.name = params->name; ++ flash->priv = (void *)params; ++ flash->name = params->name; + +- if (stm->params->flags & SST_FEAT_WP) +- stm->flash.write = sst_write_wp; ++ if (params->flags & SST_FEAT_WP) ++ flash->write = sst_write_wp; + else +- stm->flash.write = spi_flash_cmd_write_multi; +- stm->flash.erase = spi_flash_cmd_erase; +- stm->flash.read = spi_flash_cmd_read_fast; +- stm->flash.page_size = 256; +- stm->flash.sector_size = 4096; +- stm->flash.size = stm->flash.sector_size * params->nr_sectors; ++ flash->write = spi_flash_cmd_write_multi; ++ flash->erase = spi_flash_cmd_erase; ++ flash->read = spi_flash_cmd_read_fast; ++ flash->page_size = 256; ++ flash->sector_size = 4096; ++ flash->size = flash->sector_size * params->nr_sectors; + + /* Flash powers up read-only, so clear BP# bits */ +- spi_flash_cmd_write_status(&stm->flash, 0); ++ spi_flash_cmd_write_status(flash, 0); + +- return &stm->flash; ++ return 1; + } +--- a/drivers/mtd/spi/stmicro.c ++++ b/drivers/mtd/spi/stmicro.c +@@ -112,10 +112,10 @@ static const struct stmicro_spi_flash_pa + }, + }; + +-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) ++int spi_flash_probe_stmicro(struct spi_flash *flash, u8 * idcode) + { + const struct stmicro_spi_flash_params *params; +- struct spi_flash *flash; ++ struct spi_slave *spi = flash->spi; + unsigned int i; + u16 id; + +@@ -123,13 +123,13 @@ struct spi_flash *spi_flash_probe_stmicr + i = spi_flash_cmd(spi, CMD_M25PXX_RES, + idcode, 4); + if (i) +- return NULL; ++ return 0; + if ((idcode[3] & 0xf0) == 0x10) { + idcode[0] = 0x20; + idcode[1] = 0x20; + idcode[2] = idcode[3] + 1; + } else +- return NULL; ++ return 0; + } + + id = ((idcode[1] << 8) | idcode[2]); +@@ -143,16 +143,10 @@ struct spi_flash *spi_flash_probe_stmicr + + if (i == ARRAY_SIZE(stmicro_spi_flash_table)) { + debug("SF: Unsupported STMicro ID %04x\n", id); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -162,5 +156,5 @@ struct spi_flash *spi_flash_probe_stmicr + flash->sector_size = 256 * params->pages_per_sector; + flash->size = flash->sector_size * params->nr_sectors; + +- return flash; ++ return 1; + } +--- a/drivers/mtd/spi/winbond.c ++++ b/drivers/mtd/spi/winbond.c +@@ -69,10 +69,9 @@ static const struct winbond_spi_flash_pa + }, + }; + +-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode) + { + const struct winbond_spi_flash_params *params; +- struct spi_flash *flash; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) { +@@ -84,16 +83,10 @@ struct spi_flash *spi_flash_probe_winbon + if (i == ARRAY_SIZE(winbond_spi_flash_table)) { + debug("SF: Unsupported Winbond ID %02x%02x\n", + idcode[1], idcode[2]); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -103,5 +96,5 @@ struct spi_flash *spi_flash_probe_winbon + flash->sector_size = 4096; + flash->size = 4096 * 16 * params->nr_blocks; + +- return flash; ++ return 1; + } +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -31,6 +31,7 @@ struct spi_flash { + struct spi_slave *spi; + + const char *name; ++ void *priv; + + /* Total flash size */ + u32 size; diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch.svn-base new file mode 100644 index 0000000..7a1ef3b --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch.svn-base @@ -0,0 +1,131 @@ +From f9ab44c271fbd82a5702b6ba067fa90e33a30089 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:29:27 +0100 +Subject: sf: add malloc-free probe functions dedicated for SPL + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -339,11 +339,11 @@ static struct { + DECLARE_GLOBAL_DATA_PTR; + #endif + +-struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, +- unsigned int max_hz, unsigned int spi_mode) ++int spi_flash_probe_spl(struct spi_flash *flash, unsigned int bus, ++ unsigned int cs, unsigned int max_hz, ++ unsigned int spi_mode) + { + struct spi_slave *spi; +- struct spi_flash *flash; + int ret, i, shift; + u8 idcode[IDCODE_LEN], *idp; + #ifdef CONFIG_NEEDS_MANUAL_RELOC +@@ -359,8 +359,8 @@ struct spi_flash *spi_flash_probe(unsign + + spi = spi_setup_slave(bus, cs, max_hz, spi_mode); + if (!spi) { +- printf("SF: Failed to set up slave\n"); +- return NULL; ++ debug("SF: Failed to set up slave\n"); ++ return -1; + } + + ret = spi_claim_bus(spi); +@@ -379,13 +379,6 @@ struct spi_flash *spi_flash_probe(unsign + print_buffer(0, idcode, 1, sizeof(idcode), 0); + #endif + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: failed to alloc memory\n"); +- goto err_malloc; +- } +- +- memset(flash, 0, sizeof(*flash)); + flash->spi = spi; + + /* count the number of continuation bytes */ +@@ -404,30 +397,58 @@ struct spi_flash *spi_flash_probe(unsign + } + + if (ret <= 0) { +- printf("SF: Unsupported manufacturer %02x\n", *idp); ++ debug("SF: Unsupported manufacturer %02x\n", *idp); + goto err_manufacturer_probe; + } + +- printf("SF: Detected %s with page size ", flash->name); +- print_size(flash->sector_size, ", total "); +- print_size(flash->size, "\n"); +- + spi_release_bus(spi); + +- return flash; ++ return 0; + + err_manufacturer_probe: +- free(flash); +-err_malloc: + err_read_id: + spi_release_bus(spi); + err_claim_bus: + spi_free_slave(spi); ++ ++ return ret; ++} ++ ++struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, ++ unsigned int max_hz, unsigned int spi_mode) ++{ ++ struct spi_flash *flash; ++ int ret; ++ ++ flash = malloc(sizeof(*flash)); ++ if (!flash) { ++ debug("SF: Failed to malloc spi_flash\n"); ++ return NULL; ++ } ++ memset(flash, 0, sizeof(*flash)); ++ ++ ret = spi_flash_probe_spl(flash, bus, cs, max_hz, spi_mode); ++ if (ret) ++ goto err_probe; ++ ++ printf("SF: %s, page size ", flash->name); ++ print_size(flash->sector_size, ", total "); ++ print_size(flash->size, "\n"); ++ ++ return flash; ++ ++err_probe: ++ free(flash); + return NULL; + } + +-void spi_flash_free(struct spi_flash *flash) ++void spi_flash_free_spl(struct spi_flash *flash) + { + spi_free_slave(flash->spi); ++} ++ ++void spi_flash_free(struct spi_flash *flash) ++{ ++ spi_flash_free_spl(flash); + free(flash); + } +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -52,6 +52,11 @@ struct spi_flash *spi_flash_probe(unsign + unsigned int max_hz, unsigned int spi_mode); + void spi_flash_free(struct spi_flash *flash); + ++int spi_flash_probe_spl(struct spi_flash *flash, unsigned int bus, ++ unsigned int cs, unsigned int max_hz, ++ unsigned int spi_mode); ++void spi_flash_free_spl(struct spi_flash *flash); ++ + static inline int spi_flash_read(struct spi_flash *flash, u32 offset, + size_t len, void *buf) + { diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0005-sf-factor-out-the-flash-address-calculation.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0005-sf-factor-out-the-flash-address-calculation.patch.svn-base new file mode 100644 index 0000000..356db59 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0005-sf-factor-out-the-flash-address-calculation.patch.svn-base @@ -0,0 +1,107 @@ +From acb2721e1cd2e7488a7b08a4ed590177369a1689 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 19:10:40 +0100 +Subject: sf: factor out the flash address calculation + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -15,12 +15,22 @@ + + #include "spi_flash_internal.h" + +-static void spi_flash_addr(u32 addr, u8 *cmd) ++static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd, u8 *cmd_len) + { + /* cmd[0] is actual command */ + cmd[1] = addr >> 16; + cmd[2] = addr >> 8; + cmd[3] = addr >> 0; ++ *cmd_len = 4; ++} ++ ++static void spi_flash_page_addr(struct spi_flash *flash, u32 page_addr, u32 byte_addr, u8 *cmd, u8 *cmd_len) ++{ ++ /* cmd[0] is actual command */ ++ cmd[1] = page_addr >> 8; ++ cmd[2] = page_addr >> 0; ++ cmd[3] = byte_addr; ++ *cmd_len = 4; + } + + static int spi_flash_read_write(struct spi_slave *spi, +@@ -71,7 +81,7 @@ int spi_flash_cmd_write_multi(struct spi + unsigned long page_addr, byte_addr, page_size; + size_t chunk_len, actual; + int ret; +- u8 cmd[4]; ++ u8 cmd[4], cmd_len; + + page_size = flash->page_size; + page_addr = offset / page_size; +@@ -87,9 +97,7 @@ int spi_flash_cmd_write_multi(struct spi + for (actual = 0; actual < len; actual += chunk_len) { + chunk_len = min(len - actual, page_size - byte_addr); + +- cmd[1] = page_addr >> 8; +- cmd[2] = page_addr; +- cmd[3] = byte_addr; ++ spi_flash_page_addr(flash, page_addr, byte_addr, cmd, &cmd_len); + + debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", + buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); +@@ -100,7 +108,7 @@ int spi_flash_cmd_write_multi(struct spi + break; + } + +- ret = spi_flash_cmd_write(flash->spi, cmd, 4, ++ ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, + buf + actual, chunk_len); + if (ret < 0) { + debug("SF: write failed\n"); +@@ -138,13 +146,13 @@ int spi_flash_read_common(struct spi_fla + int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, + size_t len, void *data) + { +- u8 cmd[5]; ++ u8 cmd[5], cmd_len; + + cmd[0] = CMD_READ_ARRAY_FAST; +- spi_flash_addr(offset, cmd); +- cmd[4] = 0x00; ++ spi_flash_addr(flash, offset, cmd, &cmd_len); ++ cmd[cmd_len] = 0x00; + +- return spi_flash_read_common(flash, cmd, sizeof(cmd), data, len); ++ return spi_flash_read_common(flash, cmd, cmd_len + 1, data, len); + } + + int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout, +@@ -194,7 +202,7 @@ int spi_flash_cmd_erase(struct spi_flash + { + u32 start, end, erase_size; + int ret; +- u8 cmd[4]; ++ u8 cmd[4], cmd_len; + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { +@@ -216,7 +224,7 @@ int spi_flash_cmd_erase(struct spi_flash + end = start + len; + + while (offset < end) { +- spi_flash_addr(offset, cmd); ++ spi_flash_addr(flash, offset, cmd, &cmd_len); + offset += erase_size; + + debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], +@@ -226,7 +234,7 @@ int spi_flash_cmd_erase(struct spi_flash + if (ret) + goto out; + +- ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0); ++ ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, NULL, 0); + if (ret) + goto out; + diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0006-sf-add-generic-support-for-4-byte-address-mode.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0006-sf-add-generic-support-for-4-byte-address-mode.patch.svn-base new file mode 100644 index 0000000..1623b15 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0006-sf-add-generic-support-for-4-byte-address-mode.patch.svn-base @@ -0,0 +1,161 @@ +From fb9ed0ef6f0ba6b6535c64dcfcf45c161723e56f Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 19:31:38 +0100 +Subject: sf: add generic support for 4-byte address mode + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -18,19 +18,35 @@ + static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd, u8 *cmd_len) + { + /* cmd[0] is actual command */ +- cmd[1] = addr >> 16; +- cmd[2] = addr >> 8; +- cmd[3] = addr >> 0; +- *cmd_len = 4; ++ if (spi_flash_use_4byte_mode(flash)) { ++ cmd[1] = addr >> 24; ++ cmd[2] = addr >> 16; ++ cmd[3] = addr >> 8; ++ cmd[4] = addr >> 0; ++ *cmd_len = 5; ++ } else { ++ cmd[1] = addr >> 16; ++ cmd[2] = addr >> 8; ++ cmd[3] = addr >> 0; ++ *cmd_len = 4; ++ } + } + + static void spi_flash_page_addr(struct spi_flash *flash, u32 page_addr, u32 byte_addr, u8 *cmd, u8 *cmd_len) + { + /* cmd[0] is actual command */ +- cmd[1] = page_addr >> 8; +- cmd[2] = page_addr >> 0; +- cmd[3] = byte_addr; +- *cmd_len = 4; ++ if (spi_flash_use_4byte_mode(flash)) { ++ cmd[1] = page_addr >> 16; ++ cmd[2] = page_addr >> 8; ++ cmd[3] = page_addr >> 0; ++ cmd[4] = byte_addr; ++ *cmd_len = 5; ++ } else { ++ cmd[1] = page_addr >> 8; ++ cmd[2] = page_addr >> 0; ++ cmd[3] = byte_addr; ++ *cmd_len = 4; ++ } + } + + static int spi_flash_read_write(struct spi_slave *spi, +@@ -81,7 +97,7 @@ int spi_flash_cmd_write_multi(struct spi + unsigned long page_addr, byte_addr, page_size; + size_t chunk_len, actual; + int ret; +- u8 cmd[4], cmd_len; ++ u8 cmd[5], cmd_len; + + page_size = flash->page_size; + page_addr = offset / page_size; +@@ -99,8 +115,8 @@ int spi_flash_cmd_write_multi(struct spi + + spi_flash_page_addr(flash, page_addr, byte_addr, cmd, &cmd_len); + +- debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", +- buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); ++ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x%02x } chunk_len = %zu\n", ++ buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], chunk_len); + + ret = spi_flash_cmd_write_enable(flash); + if (ret < 0) { +@@ -146,7 +162,7 @@ int spi_flash_read_common(struct spi_fla + int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, + size_t len, void *data) + { +- u8 cmd[5], cmd_len; ++ u8 cmd[6], cmd_len; + + cmd[0] = CMD_READ_ARRAY_FAST; + spi_flash_addr(flash, offset, cmd, &cmd_len); +@@ -202,7 +218,7 @@ int spi_flash_cmd_erase(struct spi_flash + { + u32 start, end, erase_size; + int ret; +- u8 cmd[4], cmd_len; ++ u8 cmd[5], cmd_len; + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { +@@ -227,8 +243,8 @@ int spi_flash_cmd_erase(struct spi_flash + spi_flash_addr(flash, offset, cmd, &cmd_len); + offset += erase_size; + +- debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], +- cmd[2], cmd[3], offset); ++ debug("SF: erase %2x %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], ++ cmd[2], cmd[3], cmd[4], offset); + + ret = spi_flash_cmd_write_enable(flash); + if (ret) +@@ -409,6 +425,12 @@ int spi_flash_probe_spl(struct spi_flash + goto err_manufacturer_probe; + } + ++ ret = spi_flash_set_4byte_mode(flash); ++ if (ret) { ++ debug("SF: Failed to enable 4 byte mode: %d\n", ret); ++ goto err_manufacturer_probe; ++ } ++ + spi_release_bus(spi); + + return 0; +--- a/drivers/mtd/spi/spi_flash_internal.h ++++ b/drivers/mtd/spi/spi_flash_internal.h +@@ -97,6 +97,31 @@ int spi_flash_cmd_wait_ready(struct spi_ + /* Erase sectors. */ + int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len); + ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++static inline int spi_flash_use_4byte_mode(struct spi_flash *flash) ++{ ++ return NULL != flash->set_4byte_mode; ++} ++ ++static inline int spi_flash_set_4byte_mode(struct spi_flash *flash) ++{ ++ if (spi_flash_use_4byte_mode(flash)) ++ return flash->set_4byte_mode(flash); ++ ++ return 0; ++} ++#else ++static inline int spi_flash_use_4byte_mode(struct spi_flash *flash) ++{ ++ return 0; ++} ++ ++static inline int spi_flash_set_4byte_mode(struct spi_flash *flash) ++{ ++ return 0; ++} ++#endif ++ + /* Manufacturer-specific probe functions */ + int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode); + int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode); +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -46,6 +46,9 @@ struct spi_flash { + size_t len, const void *buf); + int (*erase)(struct spi_flash *flash, u32 offset, + size_t len); ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++ int (*set_4byte_mode)(struct spi_flash *flash); ++#endif + }; + + struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0007-sf-eon-use-16-bit-ID-for-comparison.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0007-sf-eon-use-16-bit-ID-for-comparison.patch.svn-base new file mode 100644 index 0000000..6836674 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0007-sf-eon-use-16-bit-ID-for-comparison.patch.svn-base @@ -0,0 +1,45 @@ +From d32f45357f0475a2f810752eeb9412fe692e1c0a Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:09:21 +0100 +Subject: sf: eon: use 16 bit ID for comparison + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/eon.c ++++ b/drivers/mtd/spi/eon.c +@@ -11,19 +11,19 @@ + #include "spi_flash_internal.h" + + struct eon_spi_flash_params { +- u8 idcode1; ++ u16 idcode; + u16 nr_sectors; + const char *name; + }; + + static const struct eon_spi_flash_params eon_spi_flash_table[] = { + { +- .idcode1 = 0x16, ++ .idcode = 0x3016, + .nr_sectors = 1024, + .name = "EN25Q32B", + }, + { +- .idcode1 = 0x18, ++ .idcode = 0x3018, + .nr_sectors = 4096, + .name = "EN25Q128", + }, +@@ -33,10 +33,11 @@ int spi_flash_probe_eon(struct spi_flash + { + const struct eon_spi_flash_params *params; + unsigned int i; ++ u16 id = idcode[2] | idcode[1] << 8; + + for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) { + params = &eon_spi_flash_table[i]; +- if (params->idcode1 == idcode[2]) ++ if (params->idcode == id) + break; + } + diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0008-sf-eon-add-support-for-4-byte-address-mode.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0008-sf-eon-add-support-for-4-byte-address-mode.patch.svn-base new file mode 100644 index 0000000..c037a86 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0008-sf-eon-add-support-for-4-byte-address-mode.patch.svn-base @@ -0,0 +1,43 @@ +From 37254e3284f61ea495f73a78b7c8efae983781e2 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:10:07 +0100 +Subject: sf: eon: add support for 4-byte address mode + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/eon.c ++++ b/drivers/mtd/spi/eon.c +@@ -10,6 +10,8 @@ + + #include "spi_flash_internal.h" + ++#define EN25XX_EN4B 0xb7 /* Enter 4-byte mode */ ++ + struct eon_spi_flash_params { + u16 idcode; + u16 nr_sectors; +@@ -29,6 +31,13 @@ static const struct eon_spi_flash_params + }, + }; + ++static __maybe_unused int eon_set_4byte_mode(struct spi_flash *flash) ++{ ++ struct spi_slave *spi = flash->spi; ++ ++ return spi_flash_cmd(spi, EN25XX_EN4B, NULL, 0); ++} ++ + int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode) + { + const struct eon_spi_flash_params *params; +@@ -57,5 +66,10 @@ int spi_flash_probe_eon(struct spi_flash + flash->size = 256 * 16 + * params->nr_sectors; + ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++ if (flash->size > (1 << 24)) ++ flash->set_4byte_mode = eon_set_4byte_mode; ++#endif ++ + return 1; + } diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0009-sf-eon-add-support-for-EN25QH256.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0009-sf-eon-add-support-for-EN25QH256.patch.svn-base new file mode 100644 index 0000000..18f5823 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0009-sf-eon-add-support-for-EN25QH256.patch.svn-base @@ -0,0 +1,21 @@ +From e510be1145796cd44cf5800e187a94ad7c19e764 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:10:34 +0100 +Subject: sf: eon: add support for EN25QH256 + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/eon.c ++++ b/drivers/mtd/spi/eon.c +@@ -29,6 +29,11 @@ static const struct eon_spi_flash_params + .nr_sectors = 4096, + .name = "EN25Q128", + }, ++ { ++ .idcode = 0x7019, ++ .nr_sectors = 8192, ++ .name = "EN25QH256", ++ }, + }; + + static __maybe_unused int eon_set_4byte_mode(struct spi_flash *flash) diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch.svn-base new file mode 100644 index 0000000..af8c7a1 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch.svn-base @@ -0,0 +1,30 @@ +From 81a8e9e192d53ce8b5cafd47190d6c6826519d09 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:58:59 +0100 +Subject: sf: spansion: fix device IDs and sector architecture for S25FL256S + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spansion.c ++++ b/drivers/mtd/spi/spansion.c +@@ -97,11 +97,18 @@ static const struct spansion_spi_flash_p + .name = "S25FL129P_64K", + }, + { +- .idcode1 = 0x2019, ++ .idcode1 = 0x0219, + .idcode2 = 0x4d01, + .pages_per_sector = 256, + .nr_sectors = 512, +- .name = "S25FL256S", ++ .name = "S25FL256S_64K", ++ }, ++ { ++ .idcode1 = 0x0219, ++ .idcode2 = 0x4d00, ++ .pages_per_sector = 1024, ++ .nr_sectors = 128, ++ .name = "S25FL256S_256K", + }, + }; + diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0011-sf-spansion-add-support-for-4-byte-address-mode.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0011-sf-spansion-add-support-for-4-byte-address-mode.patch.svn-base new file mode 100644 index 0000000..9471d47 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0011-sf-spansion-add-support-for-4-byte-address-mode.patch.svn-base @@ -0,0 +1,55 @@ +From 0add8e5c60961d2b99174610df8d3d9d6d192b74 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:16:11 +0100 +Subject: sf: spansion: add support for 4-byte address mode + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spansion.c ++++ b/drivers/mtd/spi/spansion.c +@@ -31,6 +31,10 @@ + + #include "spi_flash_internal.h" + ++#define S25FLXX_BRRD 0x16 /* Read Bank Register */ ++#define S25FLXX_BRWR 0x17 /* Write Bank Register */ ++#define S25FLXX_BAR_EXTADD (1 << 7) /* Extended address enable */ ++ + struct spansion_spi_flash_params { + u16 idcode1; + u16 idcode2; +@@ -112,6 +116,23 @@ static const struct spansion_spi_flash_p + }, + }; + ++static __maybe_unused int spansion_set_4byte_mode(struct spi_flash *flash) ++{ ++ struct spi_slave *spi = flash->spi; ++ u8 bar, cmd; ++ int err; ++ ++ cmd = S25FLXX_BRRD; ++ err = spi_flash_cmd(spi, cmd, &bar, 1); ++ if (err) ++ return err; ++ ++ bar |= S25FLXX_BAR_EXTADD; ++ cmd = S25FLXX_BRWR; ++ ++ return spi_flash_cmd_write(spi, &cmd, 1, &bar, 1); ++} ++ + int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode) + { + const struct spansion_spi_flash_params *params; +@@ -144,5 +165,10 @@ int spi_flash_probe_spansion(struct spi_ + flash->sector_size = 256 * params->pages_per_sector; + flash->size = flash->sector_size * params->nr_sectors; + ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++ if (flash->size > (1 << 24)) ++ flash->set_4byte_mode = spansion_set_4byte_mode; ++#endif ++ + return 1; + } diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0012-sf-spansion-add-support-for-S25FL512S.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0012-sf-spansion-add-support-for-S25FL512S.patch.svn-base new file mode 100644 index 0000000..5f415a9 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0012-sf-spansion-add-support-for-S25FL512S.patch.svn-base @@ -0,0 +1,23 @@ +From bff335ac524843bc90163c3b231091a5016f8670 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:07:54 +0100 +Subject: sf: spansion: add support for S25FL512S + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spansion.c ++++ b/drivers/mtd/spi/spansion.c +@@ -114,6 +114,13 @@ static const struct spansion_spi_flash_p + .nr_sectors = 128, + .name = "S25FL256S_256K", + }, ++ { ++ .idcode1 = 0x0220, ++ .idcode2 = 0x4d00, ++ .pages_per_sector = 1024, ++ .nr_sectors = 256, ++ .name = "S25FL512S_256K", ++ }, + }; + + static __maybe_unused int spansion_set_4byte_mode(struct spi_flash *flash) diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0013-sf-macronix-add-support-for-4-byte-address-mode.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0013-sf-macronix-add-support-for-4-byte-address-mode.patch.svn-base new file mode 100644 index 0000000..70015c9 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0013-sf-macronix-add-support-for-4-byte-address-mode.patch.svn-base @@ -0,0 +1,44 @@ +From 207662a9270cc542709fbab0d25fbc361b39748c Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:13:49 +0100 +Subject: sf: macronix: add support for 4-byte address mode + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/macronix.c ++++ b/drivers/mtd/spi/macronix.c +@@ -35,6 +35,8 @@ + + #include "spi_flash_internal.h" + ++#define MX25XX_EN4B 0xb7 /* Enter 4-byte mode */ ++ + struct macronix_spi_flash_params { + u16 idcode; + u16 nr_blocks; +@@ -79,6 +81,13 @@ static const struct macronix_spi_flash_p + }, + }; + ++static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash) ++{ ++ struct spi_slave *spi = flash->spi; ++ ++ return spi_flash_cmd(spi, MX25XX_EN4B, NULL, 0); ++} ++ + int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode) + { + const struct macronix_spi_flash_params *params; +@@ -106,6 +115,11 @@ int spi_flash_probe_macronix(struct spi_ + flash->sector_size = 256 * 16 * 16; + flash->size = flash->sector_size * params->nr_blocks; + ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++ if (flash->size > (1 << 24)) ++ flash->set_4byte_mode = macronix_set_4byte_mode; ++#endif ++ + /* Clear BP# bits for read-only flash */ + spi_flash_cmd_write_status(flash, 0); + diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0014-sf-macronix-add-support-for-MX25L25635E.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0014-sf-macronix-add-support-for-MX25L25635E.patch.svn-base new file mode 100644 index 0000000..8e33836 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0014-sf-macronix-add-support-for-MX25L25635E.patch.svn-base @@ -0,0 +1,21 @@ +From 0f31fef3d6a5110684ea31c5064c45fc448013d6 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:14:24 +0100 +Subject: sf: macronix: add support for MX25L25635E + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/macronix.c ++++ b/drivers/mtd/spi/macronix.c +@@ -79,6 +79,11 @@ static const struct macronix_spi_flash_p + .nr_blocks = 256, + .name = "MX25L12855E", + }, ++ { ++ .idcode = 0x2019, ++ .nr_blocks = 512, ++ .name = "MX25L25635E", ++ }, + }; + + static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash) diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0015-sf-macronix-add-support-for-MX66L51235L.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0015-sf-macronix-add-support-for-MX66L51235L.patch.svn-base new file mode 100644 index 0000000..fbc22e4 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0015-sf-macronix-add-support-for-MX66L51235L.patch.svn-base @@ -0,0 +1,21 @@ +From a2d80b6b91ac63beea31455ce8d136230c030500 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:14:40 +0100 +Subject: sf: macronix: add support for MX66L51235L + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/macronix.c ++++ b/drivers/mtd/spi/macronix.c +@@ -84,6 +84,11 @@ static const struct macronix_spi_flash_p + .nr_blocks = 512, + .name = "MX25L25635E", + }, ++ { ++ .idcode = 0x201A, ++ .nr_blocks = 1024, ++ .name = "MX66L51235L", ++ }, + }; + + static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash) diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch.svn-base new file mode 100644 index 0000000..a9ee560 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch.svn-base @@ -0,0 +1,133 @@ +From 7f6ded11965b09daf6da44d4fa98da17b9fba36c Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 19:41:26 +0100 +Subject: sf: add MTD layer driver for SPI flash devices + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/Makefile ++++ b/drivers/mtd/spi/Makefile +@@ -30,6 +30,7 @@ COBJS-$(CONFIG_SPL_SPI_LOAD) += spi_spl_ + endif + + COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o ++COBJS-$(CONFIG_SPI_FLASH_MTD) += spi_flash_mtd.o + COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o + COBJS-$(CONFIG_SPI_FLASH_EON) += eon.o + COBJS-$(CONFIG_SPI_FLASH_MACRONIX) += macronix.o +--- a/drivers/mtd/spi/spi_flash_internal.h ++++ b/drivers/mtd/spi/spi_flash_internal.h +@@ -122,6 +122,9 @@ static inline int spi_flash_set_4byte_mo + } + #endif + ++/* SPI flash MTD adapter init */ ++int spi_flash_mtd_init(struct spi_flash *flash); ++ + /* Manufacturer-specific probe functions */ + int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode); + int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode); +--- /dev/null ++++ b/drivers/mtd/spi/spi_flash_mtd.c +@@ -0,0 +1,101 @@ ++/* ++ * (C) Copyright 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * MTD layer driver for SPI flash devices ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <asm/errno.h> ++#include <linux/mtd/mtd.h> ++#include <spi_flash.h> ++ ++static struct mtd_info sf_mtd_info; ++static char sf_mtd_name[8]; ++ ++static int spi_flash_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ struct spi_flash *flash = mtd->priv; ++ int err; ++ ++ instr->state = MTD_ERASING; ++ ++ err = spi_flash_erase(flash, instr->addr, instr->len); ++ if (err) { ++ instr->state = MTD_ERASE_FAILED; ++ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; ++ return -EIO; ++ } ++ ++ instr->state = MTD_ERASE_DONE; ++ mtd_erase_callback(instr); ++ ++ return 0; ++} ++ ++static int spi_flash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ struct spi_flash *flash = mtd->priv; ++ int err; ++ ++ err = spi_flash_read(flash, from, len, buf); ++ if (!err) ++ *retlen = len; ++ ++ return err; ++} ++ ++static int spi_flash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ struct spi_flash *flash = mtd->priv; ++ int err; ++ ++ err = spi_flash_write(flash, to, len, buf); ++ if (!err) ++ *retlen = len; ++ ++ return err; ++} ++ ++static void spi_flash_mtd_sync(struct mtd_info *mtd) ++{ ++} ++ ++static int spi_flash_mtd_number(void) ++{ ++#ifdef CONFIG_SYS_MAX_FLASH_BANKS ++ return CONFIG_SYS_MAX_FLASH_BANKS; ++#else ++ return 0; ++#endif ++} ++ ++int spi_flash_mtd_init(struct spi_flash *flash) ++{ ++ memset(&sf_mtd_info, 0, sizeof(sf_mtd_info)); ++ sprintf(sf_mtd_name, "nor%d", spi_flash_mtd_number()); ++ ++ sf_mtd_info.name = sf_mtd_name; ++ sf_mtd_info.type = MTD_NORFLASH; ++ sf_mtd_info.flags = MTD_CAP_NORFLASH; ++ sf_mtd_info.writesize = 1; ++ ++ sf_mtd_info.erase = spi_flash_mtd_erase; ++ sf_mtd_info.read = spi_flash_mtd_read; ++ sf_mtd_info.write = spi_flash_mtd_write; ++ sf_mtd_info.sync = spi_flash_mtd_sync; ++ ++ sf_mtd_info.size = flash->size; ++ sf_mtd_info.priv = flash; ++ ++ /* Only uniform flash devices for now */ ++ sf_mtd_info.numeraseregions = 0; ++ sf_mtd_info.erasesize = flash->sector_size; ++ ++ return add_mtd_device(&sf_mtd_info); ++} diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0017-sf-add-init-function.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0017-sf-add-init-function.patch.svn-base new file mode 100644 index 0000000..2d29051 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0017-sf-add-init-function.patch.svn-base @@ -0,0 +1,57 @@ +From aa9d5d64ca6441cb24e22dc3c1f707da62da2887 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 19:35:17 +0100 +Subject: sf: add init function + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -482,3 +482,36 @@ void spi_flash_free(struct spi_flash *fl + spi_flash_free_spl(flash); + free(flash); + } ++ ++#ifdef CONFIG_SPI_FLASH_MTD ++static int spi_flash_mtd_register(void) ++{ ++ struct spi_flash *flash; ++ int err; ++ ++ flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, ++ CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); ++ if (!flash) ++ return -1; ++ ++ err = spi_flash_mtd_init(flash); ++ if (err) ++ spi_flash_free(flash); ++ ++ return err; ++} ++#else ++static int spi_flash_mtd_register(void) ++{ ++ return 0; ++} ++#endif ++ ++int spi_flash_init(void) ++{ ++ int err; ++ ++ err = spi_flash_mtd_register(); ++ ++ return err; ++} +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -51,6 +51,8 @@ struct spi_flash { + #endif + }; + ++int spi_flash_init(void); ++ + struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int spi_mode); + void spi_flash_free(struct spi_flash *flash); diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0018-MIPS-add-SPI-flash-init-hook.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0018-MIPS-add-SPI-flash-init-hook.patch.svn-base new file mode 100644 index 0000000..71f094b --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0018-MIPS-add-SPI-flash-init-hook.patch.svn-base @@ -0,0 +1,47 @@ +From 888b33e84082fe72d60d528c05c885c0c9d70bc4 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 21:19:43 +0100 +Subject: MIPS: add SPI flash init hook + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/arch/mips/lib/board.c ++++ b/arch/mips/lib/board.c +@@ -32,6 +32,7 @@ + #include <nand.h> + #include <onenand_uboot.h> + #include <spi.h> ++#include <spi_flash.h> + + #ifdef CONFIG_BITBANGMII + #include <miiphy.h> +@@ -312,6 +313,16 @@ void board_init_r(gd_t *id, ulong dest_a + onenand_init(); + #endif + ++#ifdef CONFIG_CMD_SPI ++ puts("SPI: "); ++ spi_init(); /* go init the SPI */ ++ puts("ready\n"); ++#endif ++ ++#if defined(CONFIG_SPI_FLASH) ++ spi_flash_init(); ++#endif ++ + /* relocate environment function pointers etc. */ + env_relocate(); + +@@ -335,12 +346,6 @@ void board_init_r(gd_t *id, ulong dest_a + /* Initialize from environment */ + load_addr = getenv_ulong("loadaddr", 16, load_addr); + +-#ifdef CONFIG_CMD_SPI +- puts("SPI: "); +- spi_init(); /* go init the SPI */ +- puts("ready\n"); +-#endif +- + #if defined(CONFIG_MISC_INIT_R) + /* miscellaneous platform dependent initialisations */ + misc_init_r(); diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch.svn-base new file mode 100644 index 0000000..a215d1a --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch.svn-base @@ -0,0 +1,239 @@ +From d8b1597130d228bc7e2bafd0c8d097529018c833 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 29 Aug 2012 22:08:15 +0200 +Subject: net: switchlib: add framework for ethernet switch drivers + +Add a generic framework similar to phylib for ethernet switch +drivers and devices. This is useful to share the init and +setup code for switch devices across different boards. + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Cc: Joe Hershberger <joe.hershberger@gmail.com> + +--- a/Makefile ++++ b/Makefile +@@ -291,6 +291,7 @@ LIBS-y += drivers/mtd/ubi/libubi.o + LIBS-y += drivers/mtd/spi/libspi_flash.o + LIBS-y += drivers/net/libnet.o + LIBS-y += drivers/net/phy/libphy.o ++LIBS-y += drivers/net/switch/libswitch.o + LIBS-y += drivers/pci/libpci.o + LIBS-y += drivers/pcmcia/libpcmcia.o + LIBS-y += drivers/power/libpower.o \ +--- /dev/null ++++ b/drivers/net/switch/Makefile +@@ -0,0 +1,31 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB := $(obj)libswitch.o ++ ++COBJS-$(CONFIG_SWITCH_MULTI) += switch.o ++ ++COBJS := $(COBJS-y) ++SRCS := $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++ ++all: $(LIB) ++ ++$(LIB): $(obj).depend $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/drivers/net/switch/switch.c +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <switch.h> ++ ++static struct list_head switch_drivers; ++static struct list_head switch_devices; ++ ++void switch_init(void) ++{ ++ INIT_LIST_HEAD(&switch_drivers); ++ INIT_LIST_HEAD(&switch_devices); ++ ++ board_switch_init(); ++} ++ ++void switch_driver_register(struct switch_driver *drv) ++{ ++ INIT_LIST_HEAD(&drv->list); ++ list_add_tail(&drv->list, &switch_drivers); ++} ++ ++int switch_device_register(struct switch_device *dev) ++{ ++ struct switch_driver *drv; ++ ++ /* Add switch device only, if an adequate driver is registered */ ++ list_for_each_entry(drv, &switch_drivers, list) { ++ if (!strcmp(drv->name, dev->name)) { ++ dev->drv = drv; ++ ++ INIT_LIST_HEAD(&dev->list); ++ list_add_tail(&dev->list, &switch_devices); ++ ++ return 0; ++ } ++ } ++ ++ return -1; ++} ++ ++struct switch_device *switch_connect(struct mii_dev *bus) ++{ ++ struct switch_device *sw; ++ int err; ++ ++ list_for_each_entry(sw, &switch_devices, list) { ++ sw->bus = bus; ++ ++ err = sw->drv->probe(sw); ++ if (!err) ++ return sw; ++ } ++ ++ return NULL; ++} +--- /dev/null ++++ b/include/switch.h +@@ -0,0 +1,95 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __SWITCH_H ++#define __SWITCH_H ++ ++#include <linux/list.h> ++ ++#define SWITCH_NAME_SIZE 32 ++ ++struct switch_device; ++struct mii_dev; ++ ++struct switch_driver { ++ struct list_head list; ++ ++ /* Switch device name */ ++ const char name[SWITCH_NAME_SIZE]; ++ ++ /* ++ * Called to probe the switch chip. Must return 0 if the switch ++ * chip matches the given switch device/driver combination. Otherwise ++ * 1 must be returned. ++ */ ++ int (*probe) (struct switch_device *dev); ++ ++ /* ++ * Called to initialize the switch chip. ++ */ ++ void (*setup) (struct switch_device *dev); ++}; ++ ++struct switch_device { ++ struct list_head list; ++ struct switch_driver *drv; ++ ++ /* MII bus the switch chip is connected to */ ++ struct mii_dev *bus; ++ ++ /* Switch device name */ ++ const char name[SWITCH_NAME_SIZE]; ++ ++ /* Bitmask for board specific setup of used switch ports */ ++ u16 port_mask; ++ ++ /* Number of switch port that is connected to host CPU */ ++ u16 cpu_port; ++}; ++ ++/* ++ * Board specific switch initialization. ++ * ++ * Called from switch_init to register the board specific switch_device ++ * structure. ++ */ ++extern int board_switch_init(void); ++ ++/* Initialize switch subsystem */ ++#ifdef CONFIG_SWITCH_MULTI ++extern void switch_init(void); ++#else ++static inline void switch_init(void) ++{ ++} ++#endif ++ ++/* Register a switch driver */ ++extern void switch_driver_register(struct switch_driver *drv); ++ ++/* Register a switch device */ ++extern int switch_device_register(struct switch_device *dev); ++ ++/* ++ * Probe the available switch chips and connect the found one ++ * with the given MII bus ++ */ ++extern struct switch_device *switch_connect(struct mii_dev *bus); ++ ++/* ++ * Setup the given switch device ++ */ ++static inline void switch_setup(struct switch_device *dev) ++{ ++ if (dev->drv->setup) ++ dev->drv->setup(dev); ++} ++ ++/* Init functions for supported Switch drivers */ ++ ++#endif /* __SWITCH_H */ ++ +--- a/net/eth.c ++++ b/net/eth.c +@@ -26,6 +26,7 @@ + #include <net.h> + #include <miiphy.h> + #include <phy.h> ++#include <switch.h> + + void eth_parse_enetaddr(const char *addr, uchar *enetaddr) + { +@@ -303,6 +304,8 @@ int eth_initialize(bd_t *bis) + phy_init(); + #endif + ++ switch_init(); ++ + eth_env_init(bis); + + /* diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch.svn-base new file mode 100644 index 0000000..c017e0f --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch.svn-base @@ -0,0 +1,162 @@ +From b8c666eda693906488637c414db9db35b6760e4a Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 29 Aug 2012 22:08:15 +0200 +Subject: net: switchlib: add driver for Lantiq PSB697X switch family + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/net/switch/Makefile ++++ b/drivers/net/switch/Makefile +@@ -11,6 +11,7 @@ include $(TOPDIR)/config.mk + LIB := $(obj)libswitch.o + + COBJS-$(CONFIG_SWITCH_MULTI) += switch.o ++COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +--- /dev/null ++++ b/drivers/net/switch/psb697x.c +@@ -0,0 +1,119 @@ ++/* ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <switch.h> ++#include <miiphy.h> ++ ++#define PSB697X_CHIPID1 0x2599 ++#define PSB697X_PORT_COUNT 7 ++ ++#define PSB697X_PORT_BASE(p) (p * 0x20) ++#define PSB697X_REG_PS(p) (PSB697X_PORT_BASE(p) + 0x00) ++#define PSB697X_REG_PBC(p) (PSB697X_PORT_BASE(p) + 0x01) ++#define PSB697X_REG_PEC(p) (PSB697X_PORT_BASE(p) + 0x02) ++ ++#define PSB697X_REG_SGC1 0x0E0 /* Switch Global Control Register 1 */ ++#define PSB697X_REG_SGC2 0x0E1 /* Switch Global Control Register 2 */ ++#define PSB697X_REG_CMH 0x0E2 /* CPU Port & Mirror Control */ ++#define PSB697X_REG_MIICR 0x0F5 /* MII Port Control */ ++#define PSB697X_REG_CI0 0x100 /* Chip Identifier 0 */ ++#define PSB697X_REG_CI1 0x101 /* Chip Identifier 1 */ ++#define PSB697X_REG_MIIAC 0x120 /* MII Indirect Access Control */ ++#define PSB697X_REG_MIIWD 0x121 /* MII Indirect Write Data */ ++#define PSB697X_REG_MIIRD 0x122 /* MII Indirect Read Data */ ++ ++#define PSB697X_REG_PORT_FLP (1 << 2) /* Force link up */ ++#define PSB697X_REG_PORT_FLD (1 << 1) /* Force link down */ ++ ++#define PSB697X_REG_SGC2_SE (1 << 15) /* Switch enable */ ++ ++#define PSB697X_REG_CMH_CPN_MASK 0x7 ++#define PSB697X_REG_CMH_CPN_SHIFT 5 ++ ++ ++static inline int psb697x_mii_read(struct mii_dev *bus, u16 reg) ++{ ++ int ret; ++ ++ ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f); ++ ++ return ret; ++} ++ ++static inline int psb697x_mii_write(struct mii_dev *bus, u16 reg, u16 val) ++{ ++ int ret; ++ ++ ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, ++ reg & 0x1f, val); ++ ++ return ret; ++} ++ ++static int psb697x_probe(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ int ci1; ++ ++ ci1 = psb697x_mii_read(bus, PSB697X_REG_CI1); ++ ++ if (ci1 == PSB697X_CHIPID1) ++ return 0; ++ ++ return 1; ++} ++ ++static void psb697x_setup(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ int i, state; ++ ++ /* Enable switch */ ++ psb697x_mii_write(bus, PSB697X_REG_SGC2, PSB697X_REG_SGC2_SE); ++ ++ /* ++ * Force 100 Mbps as default value for CPU ports 5 and 6 to get ++ * full speed. ++ */ ++ psb697x_mii_write(bus, PSB697X_REG_MIICR, 0x0773); ++ ++ for (i = 0; i < PSB697X_PORT_COUNT; i++) { ++ state = dev->port_mask & (1 << i); ++ ++ /* ++ * Software workaround from Errata Sheet: ++ * Force link down and reset internal PHY, keep that state ++ * for all unconnected ports and disable force link down ++ * for all connected ports ++ */ ++ psb697x_mii_write(bus, PSB697X_REG_PBC(i), ++ PSB697X_REG_PORT_FLD); ++ ++ if (i == dev->cpu_port) ++ /* Force link up for CPU port */ ++ psb697x_mii_write(bus, PSB697X_REG_PBC(i), ++ PSB697X_REG_PORT_FLP); ++ else if (state) ++ /* Disable force link down for active LAN ports */ ++ psb697x_mii_write(bus, PSB697X_REG_PBC(i), 0); ++ } ++} ++ ++static struct switch_driver psb697x_drv = { ++ .name = "psb697x", ++}; ++ ++void switch_psb697x_init(void) ++{ ++ /* For archs with manual relocation */ ++ psb697x_drv.probe = psb697x_probe; ++ psb697x_drv.setup = psb697x_setup; ++ ++ switch_driver_register(&psb697x_drv); ++} +--- a/drivers/net/switch/switch.c ++++ b/drivers/net/switch/switch.c +@@ -18,6 +18,10 @@ void switch_init(void) + INIT_LIST_HEAD(&switch_drivers); + INIT_LIST_HEAD(&switch_devices); + ++#if defined(CONFIG_SWITCH_PSB697X) ++ switch_psb697x_init(); ++#endif ++ + board_switch_init(); + } + +--- a/include/switch.h ++++ b/include/switch.h +@@ -90,6 +90,7 @@ static inline void switch_setup(struct s + } + + /* Init functions for supported Switch drivers */ ++extern void switch_psb697x_init(void); + + #endif /* __SWITCH_H */ + diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch.svn-base new file mode 100644 index 0000000..342fa46 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch.svn-base @@ -0,0 +1,158 @@ +From fcbbb1beb2ae862f5c703c5719ed0e155cbbf82f Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 29 Aug 2012 22:08:16 +0200 +Subject: net: switchlib: add driver for Lantiq ADM6996I switch family + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/net/switch/Makefile ++++ b/drivers/net/switch/Makefile +@@ -12,6 +12,7 @@ LIB := $(obj)libswitch.o + + COBJS-$(CONFIG_SWITCH_MULTI) += switch.o + COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o ++COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +--- /dev/null ++++ b/drivers/net/switch/adm6996i.c +@@ -0,0 +1,116 @@ ++/* ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <switch.h> ++#include <miiphy.h> ++ ++#define ADM6996I_CHIPID0 0x1020 ++#define ADM6996I_CHIPID1 0x0007 ++#define ADM6996I_PORT_COUNT 6 ++ ++#define ADM6996I_REG_P0BC 0x001 /* P0 Basic Control */ ++#define ADM6996I_REG_P1BC 0x003 /* P1 Basic Control */ ++#define ADM6996I_REG_P2BC 0x005 /* P2 Basic Control */ ++#define ADM6996I_REG_P3BC 0x007 /* P3 Basic Control */ ++#define ADM6996I_REG_P4BC 0x008 /* P4 Basic Control */ ++#define ADM6996I_REG_P5BC 0x009 /* P5 Basic Control */ ++ ++#define ADM6996I_REG_P0EC 0x002 /* P0 Extended Control */ ++#define ADM6996I_REG_P1EC 0x002 /* P1 Extended Control */ ++#define ADM6996I_REG_P2EC 0x004 /* P2 Extended Control */ ++#define ADM6996I_REG_P3EC 0x004 /* P3 Extended Control */ ++#define ADM6996I_REG_P4EC 0x006 /* P4 Extended Control */ ++#define ADM6996I_REG_P5EC 0x006 /* P5 Extended Control */ ++ ++#define ADM6996I_REG_SC4 0x012 /* System Control 4 */ ++ ++#define ADM6996I_REG_CI0 0xA0 /* Chip Identifier 0 */ ++#define ADM6996I_REG_CI1 0xA1 /* Chip Identifier 1 */ ++ ++#define ADM6996I_REG_PXBC_DEFAULT 0x040F ++#define ADM6996I_REG_PXBC_CROSS_EE (1 << 15) ++#define ADM6996I_REG_PXBC_PD (1 << 5) ++ ++#define ADM6996I_REG_SC4_DEFAULT 0x3600 ++#define ADM6996I_REG_SC4_LED_ENABLE (1 << 1) ++ ++#define ADM6996I_REG_CI0_PC_MASK 0xFFF0 ++#define ADM6996I_REG_CI0_VN_MASK 0xF ++#define ADM6996I_REG_CI1_PC_MASK 0xF ++ ++ ++static inline int adm6996i_mii_read(struct mii_dev *bus, u16 reg) ++{ ++ int ret; ++ ++ ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f); ++ ++ return ret; ++} ++ ++static inline int adm6996i_mii_write(struct mii_dev *bus, u16 reg, u16 val) ++{ ++ int ret; ++ ++ ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, ++ reg & 0x1f, val); ++ ++ return ret; ++} ++ ++static int adm6996i_probe(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ u16 ci0, ci1; ++ ++ ci0 = adm6996i_mii_read(bus, ADM6996I_REG_CI0); ++ ci1 = adm6996i_mii_read(bus, ADM6996I_REG_CI1); ++ ++ ci0 &= ADM6996I_REG_CI0_PC_MASK; ++ ci1 &= ADM6996I_REG_CI1_PC_MASK; ++ ++ if (ci0 == ADM6996I_CHIPID0 && ci1 == ADM6996I_CHIPID1) ++ return 0; ++ ++ return 1; ++} ++ ++static void adm6996i_setup(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ u16 val; ++ ++ /* ++ * Write default values (Port enable, 100 Mbps, Full Duplex, ++ * Auto negotiation, Flow control) and enable crossover auto-detect ++ */ ++ val = ADM6996I_REG_PXBC_DEFAULT | ADM6996I_REG_PXBC_CROSS_EE; ++ adm6996i_mii_write(bus, ADM6996I_REG_P0BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P1BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P2BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P3BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P4BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P5BC, val); ++ ++ val = ADM6996I_REG_SC4_DEFAULT | ADM6996I_REG_SC4_LED_ENABLE; ++ adm6996i_mii_write(bus, ADM6996I_REG_SC4, val); ++} ++ ++static struct switch_driver adm6996i_drv = { ++ .name = "adm6996i", ++}; ++ ++void switch_adm6996i_init(void) ++{ ++ /* For archs with manual relocation */ ++ adm6996i_drv.probe = adm6996i_probe; ++ adm6996i_drv.setup = adm6996i_setup; ++ ++ switch_driver_register(&adm6996i_drv); ++} +--- a/drivers/net/switch/switch.c ++++ b/drivers/net/switch/switch.c +@@ -21,6 +21,9 @@ void switch_init(void) + #if defined(CONFIG_SWITCH_PSB697X) + switch_psb697x_init(); + #endif ++#if defined(CONFIG_SWITCH_ADM6996I) ++ switch_adm6996i_init(); ++#endif + + board_switch_init(); + } +--- a/include/switch.h ++++ b/include/switch.h +@@ -91,6 +91,7 @@ static inline void switch_setup(struct s + + /* Init functions for supported Switch drivers */ + extern void switch_psb697x_init(void); ++extern void switch_adm6996i_init(void); + + #endif /* __SWITCH_H */ + diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch.svn-base new file mode 100644 index 0000000..127c0d8 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch.svn-base @@ -0,0 +1,158 @@ +From 16b8c52f80f20e07866e397ff52ff9658766437b Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Wed, 29 Aug 2012 22:08:16 +0200 +Subject: net: switchlib: add driver for Atheros AR8216 + +Signed-off-by: Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/net/switch/Makefile ++++ b/drivers/net/switch/Makefile +@@ -13,6 +13,7 @@ LIB := $(obj)libswitch.o + COBJS-$(CONFIG_SWITCH_MULTI) += switch.o + COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o + COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o ++COBJS-$(CONFIG_SWITCH_AR8216) += ar8216.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +--- /dev/null ++++ b/drivers/net/switch/ar8216.c +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <miiphy.h> ++#include <switch.h> ++#include <netdev.h> ++ ++#define BITS(_s, _n) (((1UL << (_n)) - 1) << _s) ++ ++#define AR8216_REG_CTRL 0x0000 ++#define AR8216_CTRL_REVISION BITS(0, 8) ++#define AR8216_CTRL_VERSION BITS(8, 8) ++ ++#define AR8216_PROBE_RETRIES 10 ++ ++static void split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) ++{ ++ regaddr >>= 1; ++ *r1 = regaddr & 0x1e; ++ ++ regaddr >>= 5; ++ *r2 = regaddr & 0x7; ++ ++ regaddr >>= 3; ++ *page = regaddr & 0x1ff; ++} ++ ++static int ar8216_mii_read(struct mii_dev *bus, u32 reg) ++{ ++ u16 r1, r2, page; ++ u16 lo, hi; ++ ++ split_addr(reg, &r1, &r2, &page); ++ ++ bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, page); ++ __udelay(1000); ++ ++ lo = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1); ++ hi = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1); ++ ++ return (hi << 16) | lo; ++} ++ ++static void ar8216_mii_write(struct mii_dev *bus, u16 reg, u32 val) ++{ ++ u16 r1, r2, r3; ++ u16 lo, hi; ++ ++ split_addr((u32) reg, &r1, &r2, &r3); ++ ++ bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, r3); ++ __udelay(1000); ++ ++ lo = val & 0xffff; ++ hi = (u16) (val >> 16); ++ bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1, hi); ++ bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1, lo); ++} ++ ++static int ar8216_probe(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ u32 val; ++ u16 id; ++ ++ val = ar8216_mii_read(bus, AR8216_REG_CTRL); ++ if (val == ~0) ++ return 1; ++ ++ id = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION); ++ ++ switch (id) { ++ case 0x0101: ++ return 0; ++ default: ++ return 1; ++ } ++} ++ ++static void ar8216_setup(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ ++ ar8216_mii_write(bus, 0x200, 0x200); ++ ar8216_mii_write(bus, 0x300, 0x200); ++ ar8216_mii_write(bus, 0x400, 0x200); ++ ar8216_mii_write(bus, 0x500, 0x200); ++ ar8216_mii_write(bus, 0x600, 0x7d); ++ ar8216_mii_write(bus, 0x38, 0xc000050e); ++ ar8216_mii_write(bus, 0x104, 0x4004); ++ ar8216_mii_write(bus, 0x60, 0xffffffff); ++ ar8216_mii_write(bus, 0x64, 0xaaaaaaaa); ++ ar8216_mii_write(bus, 0x68, 0x55555555); ++ ar8216_mii_write(bus, 0x6c, 0x0); ++ ar8216_mii_write(bus, 0x70, 0x41af); ++} ++ ++static struct switch_driver ar8216_drv = { ++ .name = "ar8216", ++}; ++ ++void switch_ar8216_init(void) ++{ ++ /* for archs with manual relocation */ ++ ar8216_drv.probe = ar8216_probe; ++ ar8216_drv.setup = ar8216_setup; ++ ++ switch_driver_register(&ar8216_drv); ++} +--- a/drivers/net/switch/switch.c ++++ b/drivers/net/switch/switch.c +@@ -24,6 +24,9 @@ void switch_init(void) + #if defined(CONFIG_SWITCH_ADM6996I) + switch_adm6996i_init(); + #endif ++#if defined(CONFIG_SWITCH_AR8216) ++ switch_ar8216_init(); ++#endif + + board_switch_init(); + } +--- a/include/switch.h ++++ b/include/switch.h +@@ -92,6 +92,7 @@ static inline void switch_setup(struct s + /* Init functions for supported Switch drivers */ + extern void switch_psb697x_init(void); + extern void switch_adm6996i_init(void); ++extern void switch_ar8216_init(void); + + #endif /* __SWITCH_H */ + diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch.svn-base new file mode 100644 index 0000000..2582c16 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch.svn-base @@ -0,0 +1,9496 @@ +From ed2effe0839929d00f05ec0e1e16fb467f324e1b Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Thu, 20 Dec 2012 19:05:54 +0100 +Subject: MIPS: add support for Lantiq XWAY SoCs + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/.gitignore ++++ b/.gitignore +@@ -44,6 +44,13 @@ + /u-boot.sb + /u-boot.geany + /include/u-boot.lst ++/u-boot.bin.lzma ++/u-boot.bin.lzo ++/u-boot.ltq.lzma.norspl ++/u-boot.ltq.lzo.norspl ++/u-boot.ltq.norspl ++/u-boot.lzma.img ++/u-boot.lzo.img + + # + # Generated files +--- a/Makefile ++++ b/Makefile +@@ -441,6 +441,12 @@ $(obj)u-boot.bin: $(obj)u-boot + $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ + $(BOARD_SIZE_CHECK) + ++$(obj)u-boot.bin.lzma: $(obj)u-boot.bin ++ cat $< | lzma -9 -f - > $@ ++ ++$(obj)u-boot.bin.lzo: $(obj)u-boot.bin ++ cat $< | lzop -9 -f - > $@ ++ + $(obj)u-boot.ldr: $(obj)u-boot + $(CREATE_LDR_ENV) + $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS) +@@ -460,13 +466,23 @@ ifndef CONFIG_SYS_UBOOT_START + CONFIG_SYS_UBOOT_START := 0 + endif + +-$(obj)u-boot.img: $(obj)u-boot.bin +- $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \ ++define GEN_UBOOT_IMAGE ++ $(obj)tools/mkimage -A $(ARCH) -T firmware -C $(1) \ + -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \ + -e $(CONFIG_SYS_UBOOT_START) \ + -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \ + sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \ + -d $< $@ ++endef ++ ++$(obj)u-boot.img: $(obj)u-boot.bin ++ $(call GEN_UBOOT_IMAGE,none) ++ ++$(obj)u-boot.lzma.img: $(obj)u-boot.bin.lzma ++ $(call GEN_UBOOT_IMAGE,lzma) ++ ++$(obj)u-boot.lzo.img: $(obj)u-boot.bin.lzo ++ $(call GEN_UBOOT_IMAGE,lzo) + + $(obj)u-boot.imx: $(obj)u-boot.bin + $(obj)tools/mkimage -n $(CONFIG_IMX_CONFIG) -T imximage \ +@@ -549,6 +565,27 @@ endif + $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img + cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@ + ++$(obj)u-boot.ltq.sfspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin ++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \ ++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@ ++ ++$(obj)u-boot.ltq.lzo.sfspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin ++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \ ++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@ ++ ++$(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin ++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \ ++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@ ++ ++$(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin ++ cat $(obj)spl/u-boot-spl.bin $< > $@ ++ ++$(obj)u-boot.ltq.lzo.norspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin ++ cat $(obj)spl/u-boot-spl.bin $< > $@ ++ ++$(obj)u-boot.ltq.lzma.norspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin ++ cat $(obj)spl/u-boot-spl.bin $< > $@ ++ + ifeq ($(CONFIG_SANDBOX),y) + GEN_UBOOT = \ + cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \ +--- a/README ++++ b/README +@@ -460,6 +460,11 @@ The following options need to be configu + CONF_CM_CACHABLE_CUW + CONF_CM_CACHABLE_ACCELERATED + ++ CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ ++ Enable this to use extended cache initialization for recent ++ MIPS CPU cores. ++ + CONFIG_SYS_XWAY_EBU_BOOTCFG + + Special option for Lantiq XWAY SoCs for booting from NOR flash. +--- a/arch/mips/config.mk ++++ b/arch/mips/config.mk +@@ -61,7 +61,10 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__M + # On the other hand, we want PIC in the U-Boot code to relocate it from ROM + # to RAM. $28 is always used as gp. + # +-PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS) ++PF_ABICALLS ?= -mabicalls ++PF_PIC ?= -fpic ++ ++PLATFORM_CPPFLAGS += -G 0 $(PF_ABICALLS) $(PF_PIC) $(ENDIANNESS) + PLATFORM_CPPFLAGS += -msoft-float + PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS) + PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections +--- a/arch/mips/cpu/mips32/cache.S ++++ b/arch/mips/cpu/mips32/cache.S +@@ -45,7 +45,11 @@ + */ + #define MIPS_MAX_CACHE_SIZE 0x10000 + ++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT ++#define INDEX_BASE 0x9fc00000 ++#else + #define INDEX_BASE CKSEG0 ++#endif + + .macro cache_op op addr + .set push +@@ -81,7 +85,11 @@ + */ + LEAF(mips_init_icache) + blez a1, 9f ++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ mtc0 zero, CP0_ITAGLO ++#else + mtc0 zero, CP0_TAGLO ++#endif + /* clear tag to invalidate */ + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, a1 +@@ -106,7 +114,11 @@ LEAF(mips_init_icache) + */ + LEAF(mips_init_dcache) + blez a1, 9f ++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ mtc0 zero, CP0_DTAGLO ++#else + mtc0 zero, CP0_TAGLO ++#endif + /* clear all tags */ + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, a1 +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/Makefile +@@ -0,0 +1,33 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(SOC).o ++ ++COBJS-y += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o ++SOBJS-y += cgu_init.o mem_init.o ++ ++COBJS := $(COBJS-y) ++SOBJS := $(SOBJS-y) ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) ++ ++all: $(LIB) ++ ++$(LIB): $(obj).depend $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/cgu.c +@@ -0,0 +1,118 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_CGU_SYS_DDR_MASK 0x0003 ++#define LTQ_CGU_SYS_DDR_SHIFT 0 ++#define LTQ_CGU_SYS_CPU0_MASK 0x000C ++#define LTQ_CGU_SYS_CPU0_SHIFT 2 ++#define LTQ_CGU_SYS_FPI_MASK 0x0040 ++#define LTQ_CGU_SYS_FPI_SHIFT 6 ++ ++struct ltq_cgu_regs { ++ u32 rsvd0; ++ u32 pll0_cfg; /* PLL0 config */ ++ u32 pll1_cfg; /* PLL1 config */ ++ u32 pll2_cfg; /* PLL2 config */ ++ u32 sys; /* System clock */ ++ u32 update; /* CGU update control */ ++ u32 if_clk; /* Interface clock */ ++ u32 osc_con; /* Update OSC Control */ ++ u32 smd; /* SDRAM Memory Control */ ++ u32 rsvd1[3]; ++ u32 pcm_cr; /* PCM control */ ++ u32 pci_cr; /* PCI clock control */ ++}; ++ ++static struct ltq_cgu_regs *ltq_cgu_regs = ++ (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE); ++ ++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift) ++{ ++ return (ltq_readl(<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,143 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/asm.h> ++#include <asm/regdef.h> ++#include <asm/addrspace.h> ++#include <asm/arch/soc.h> ++ ++/* RCU module register */ ++#define LTQ_RCU_RST_REQ 0x0010 ++#define LTQ_RCU_RST_STAT 0x0014 ++#define LTQ_RCU_RST_REQ_VALUE 0x40000008 ++#define LTQ_RCU_RST_STAT_XTAL_F 0x20000 ++ ++/* CGU module register */ ++#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */ ++#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */ ++#define LTQ_CGU_PLL2_CFG 0x000C /* PLL2 config */ ++#define LTQ_CGU_SYS 0x0010 /* System clock */ ++ ++/* Valid SYS.CPU0/1 values */ ++#define LTQ_CGU_SYS_CPU0_SHIFT 2 ++#define LTQ_CGU_SYS_CPU1_SHIFT 4 ++#define LTQ_CGU_SYS_CPU_PLL0 0x0 ++#define LTQ_CGU_SYS_CPU_DDR_EQUAL 0x1 ++#define LTQ_CGU_SYS_CPU_DDR_TWICE 0x2 ++ ++/* Valid SYS.DDR values */ ++#define LTQ_CGU_SYS_DDR_SHIFT 0 ++#define LTQ_CGU_SYS_DDR_167_MHZ 0x0 ++#define LTQ_CGU_SYS_DDR_133_MHZ 0x1 ++#define LTQ_CGU_SYS_DDR_111_MHZ 0x2 ++#define LTQ_CGU_SYS_DDR_83_MHZ 0x3 ++ ++/* Valid SYS.FPI values */ ++#define LTQ_CGU_SYS_FPI_SHIFT 6 ++#define LTQ_CGU_SYS_FPI_DDR_EQUAL 0x0 ++#define LTQ_CGU_SYS_FPI_DDR_HALF 0x1 ++ ++/* Valid SYS.PPE values */ ++#define LTQ_CGU_SYS_PPE_SHIFT 7 ++#define LTQ_CGU_SYS_PPE_266_MHZ 0x0 ++#define LTQ_CGU_SYS_PPE_240_MHZ 0x1 ++#define LTQ_CGU_SYS_PPE_222_MHZ 0x2 ++#define LTQ_CGU_SYS_PPE_133_MHZ 0x3 ++ ++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167) ++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_TWICE ++#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_167_MHZ ++#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF ++#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_266_MHZ ++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111) ++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_EQUAL ++#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_111_MHZ ++#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF ++#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_133_MHZ ++#else ++#error "Invalid system clock configuration!" ++#endif ++ ++/* Build register values */ ++#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_PPE_CONFIG << \ ++ LTQ_CGU_SYS_PPE_SHIFT) | \ ++ (LTQ_CGU_SYS_FPI_CONFIG << \ ++ LTQ_CGU_SYS_FPI_SHIFT) | \ ++ (LTQ_CGU_SYS_CPU_CONFIG << \ ++ LTQ_CGU_SYS_CPU1_SHIFT) | \ ++ (LTQ_CGU_SYS_CPU_CONFIG << \ ++ LTQ_CGU_SYS_CPU0_SHIFT) | \ ++ LTQ_CGU_SYS_DDR_CONFIG) ++ ++/* Reset values for PLL registers for usage with 35.328 MHz crystal */ ++#define PLL0_35MHZ_CONFIG 0x9D861059 ++#define PLL1_35MHZ_CONFIG 0x1A260CD9 ++#define PLL2_35MHZ_CONFIG 0x8000f1e5 ++ ++/* Reset values for PLL registers for usage with 36 MHz crystal */ ++#define PLL0_36MHZ_CONFIG 0x1000125D ++#define PLL1_36MHZ_CONFIG 0x1B1E0C99 ++#define PLL2_36MHZ_CONFIG 0x8002f2a1 ++ ++LEAF(ltq_cgu_init) ++ /* Load current CGU register value */ ++ li t0, (LTQ_CGU_BASE | KSEG1) ++ lw t1, LTQ_CGU_SYS(t0) ++ ++ /* Load target CGU register values */ ++ li t3, LTQ_CGU_SYS_VALUE ++ ++ /* Only update registers if values differ */ ++ beq t1, t3, finished ++ ++ /* ++ * Check whether the XTAL_F bit in RST_STAT register is set or not. ++ * This bit is latched in via pin strapping. If bit is set then ++ * clock source is a 36 MHz crystal. Otherwise a 35.328 MHz crystal. ++ */ ++ li t1, (LTQ_RCU_BASE | KSEG1) ++ lw t2, LTQ_RCU_RST_STAT(t1) ++ and t2, t2, LTQ_RCU_RST_STAT_XTAL_F ++ beq t2, LTQ_RCU_RST_STAT_XTAL_F, boot_36mhz ++ ++boot_35mhz: ++ /* Configure PLL for 35.328 MHz */ ++ li t2, PLL0_35MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL0_CFG(t0) ++ li t2, PLL1_35MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL1_CFG(t0) ++ li t2, PLL2_35MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL2_CFG(t0) ++ ++ b do_reset ++ ++boot_36mhz: ++ /* Configure PLL for 36 MHz */ ++ li t2, PLL0_36MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL0_CFG(t0) ++ li t2, PLL1_36MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL1_CFG(t0) ++ li t2, PLL2_36MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL2_CFG(t0) ++ ++do_reset: ++ /* Store new clock config */ ++ sw t3, LTQ_CGU_SYS(t0) ++ ++ /* Perform software reset to activate new clock config */ ++ li t2, LTQ_RCU_RST_REQ_VALUE ++ sw t2, LTQ_RCU_RST_REQ(t1) ++ ++wait_reset: ++ b wait_reset ++ ++finished: ++ jr ra ++ ++ END(ltq_cgu_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/chipid.c +@@ -0,0 +1,60 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_CHIPID_VERSION_SHIFT 28 ++#define LTQ_CHIPID_VERSION_MASK (0xF << LTQ_CHIPID_VERSION_SHIFT) ++#define LTQ_CHIPID_PNUM_SHIFT 12 ++#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT) ++ ++struct ltq_chipid_regs { ++ u32 manid; /* Manufacturer identification */ ++ u32 chipid; /* Chip identification */ ++}; ++ ++static struct ltq_chipid_regs *ltq_chipid_regs = ++ (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE); ++ ++unsigned int ltq_chip_version_get(void) ++{ ++ u32 chipid; ++ ++ chipid = ltq_readl(<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,27 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,) ++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE) ++ ++ifdef CONFIG_SPL_BUILD ++PF_ABICALLS := -mno-abicalls ++PF_PIC := -fno-pic ++USE_PRIVATE_LIBGCC := yes ++endif ++ ++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o ++ ++ifndef CONFIG_SPL_BUILD ++ifdef CONFIG_SYS_BOOT_NORSPL ++ALL-y += $(obj)u-boot.ltq.norspl ++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl ++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl ++endif ++endif ++ ++LDSCRIPT := $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot.lds +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/ebu.c +@@ -0,0 +1,51 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_EBU_CON_0_RST_VAL 0x8001F7FF ++ ++#define LTQ_EBU_CON_WRDIS (1 << 31) ++ ++struct ltq_ebu_regs { ++ u32 clc; ++ u32 rsvd0[3]; ++ u32 con; ++ u32 rsvd1[3]; ++ u32 addr_sel_0; ++ u32 addr_sel_1; ++ u32 rsvd2[14]; ++ u32 con_0; ++ u32 con_1; ++}; ++ ++static struct ltq_ebu_regs *ltq_ebu_regs = ++ (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE); ++ ++void ltq_ebu_init(void) ++{ ++ /* ++ * Map EBU region 0 to range 0x10000000-0x13ffffff and enable ++ * region control. This supports up to 32 MiB NOR flash in ++ * bank 0. ++ */ ++ ltq_writel(<q_ebu_regs->addr_sel_0, 0x10000011); ++ ++ /* ++ * Restore reset value to fix modifications by internal BootROM. ++ * Also disable write protection. ++ */ ++ ltq_writel(<q_ebu_regs->con_0, ++ LTQ_EBU_CON_0_RST_VAL & ~LTQ_EBU_CON_WRDIS); ++} ++ ++void *flash_swap_addr(unsigned long addr) ++{ ++ return (void *)(addr ^ 2); ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/mem.c +@@ -0,0 +1,31 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE); ++ ++static inline u32 ltq_mc_dc_read(u32 index) ++{ ++ return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index)); ++} ++ ++phys_size_t initdram(int board_type) ++{ ++ u32 col, row, dc04, dc19, dc20; ++ ++ dc04 = ltq_mc_dc_read(4); ++ dc19 = ltq_mc_dc_read(19); ++ dc20 = ltq_mc_dc_read(20); ++ ++ row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8); ++ col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7); ++ ++ return (1 << (row + col)) * 4 * 2; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/mem_init.S +@@ -0,0 +1,115 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/asm.h> ++#include <asm/regdef.h> ++#include <asm/addrspace.h> ++#include <asm/arch/soc.h> ++ ++/* Must be configured in BOARDDIR */ ++#include <ddr_settings.h> ++ ++#define LTQ_MC_GEN_ERRCAUSE 0x0010 ++#define LTQ_MC_GEN_ERRADDR 0x0020 ++#define LTQ_MC_GEN_CON 0x0060 ++#define LTQ_MC_GEN_STAT 0x0070 ++#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE 0x5 ++#define LTQ_MC_GEN_STAT_DLCK_PWRON 0xC ++ ++#define LTQ_MC_DDR_DC03_MC_START 0x100 ++ ++ /* Store given value in MC DDR CCRx register */ ++ .macro dc_sw num, val ++ li t2, \val ++ sw t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1) ++ .endm ++ ++LEAF(ltq_mem_init) ++ /* Load MC General and MC DDR module base */ ++ li t0, (LTQ_MC_GEN_BASE | KSEG1) ++ li t1, (LTQ_MC_DDR_BASE | KSEG1) ++ ++ /* Clear access error log registers */ ++ sw zero, LTQ_MC_GEN_ERRCAUSE(t0) ++ sw zero, LTQ_MC_GEN_ERRADDR(t0) ++ ++ /* Enable DDR and SRAM module in memory controller */ ++ li t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE ++ sw t2, LTQ_MC_GEN_CON(t0) ++ ++ /* Clear start bit of DDR memory controller */ ++ sw zero, LTQ_MC_DDR_DC_OFFSET(3)(t1) ++ ++ /* Init memory controller registers with values ddr_settings.h */ ++ dc_sw 0, MC_DC00_VALUE ++ dc_sw 1, MC_DC01_VALUE ++ dc_sw 2, MC_DC02_VALUE ++ dc_sw 4, MC_DC04_VALUE ++ dc_sw 5, MC_DC05_VALUE ++ dc_sw 6, MC_DC06_VALUE ++ dc_sw 7, MC_DC07_VALUE ++ dc_sw 8, MC_DC08_VALUE ++ dc_sw 9, MC_DC09_VALUE ++ ++ dc_sw 10, MC_DC10_VALUE ++ dc_sw 11, MC_DC11_VALUE ++ dc_sw 12, MC_DC12_VALUE ++ dc_sw 13, MC_DC13_VALUE ++ dc_sw 14, MC_DC14_VALUE ++ dc_sw 15, MC_DC15_VALUE ++ dc_sw 16, MC_DC16_VALUE ++ dc_sw 17, MC_DC17_VALUE ++ dc_sw 18, MC_DC18_VALUE ++ dc_sw 19, MC_DC19_VALUE ++ ++ dc_sw 20, MC_DC20_VALUE ++ dc_sw 21, MC_DC21_VALUE ++ dc_sw 22, MC_DC22_VALUE ++ dc_sw 23, MC_DC23_VALUE ++ dc_sw 24, MC_DC24_VALUE ++ dc_sw 25, MC_DC25_VALUE ++ dc_sw 26, MC_DC26_VALUE ++ dc_sw 27, MC_DC27_VALUE ++ dc_sw 28, MC_DC28_VALUE ++ dc_sw 29, MC_DC29_VALUE ++ ++ dc_sw 30, MC_DC30_VALUE ++ dc_sw 31, MC_DC31_VALUE ++ dc_sw 32, MC_DC32_VALUE ++ dc_sw 33, MC_DC33_VALUE ++ dc_sw 34, MC_DC34_VALUE ++ dc_sw 35, MC_DC35_VALUE ++ dc_sw 36, MC_DC36_VALUE ++ dc_sw 37, MC_DC37_VALUE ++ dc_sw 38, MC_DC38_VALUE ++ dc_sw 39, MC_DC39_VALUE ++ ++ dc_sw 40, MC_DC40_VALUE ++ dc_sw 41, MC_DC41_VALUE ++ dc_sw 42, MC_DC42_VALUE ++ dc_sw 43, MC_DC43_VALUE ++ dc_sw 44, MC_DC44_VALUE ++ dc_sw 45, MC_DC45_VALUE ++ dc_sw 46, MC_DC46_VALUE ++ ++ /* Set start bit of DDR memory controller */ ++ li t2, LTQ_MC_DDR_DC03_MC_START ++ sw t2, LTQ_MC_DDR_DC_OFFSET(3)(t1) ++ ++ /* Wait until DLL has locked and core is ready for data transfers */ ++wait_ready: ++ lw t2, LTQ_MC_GEN_STAT(t0) ++ li t3, LTQ_MC_GEN_STAT_DLCK_PWRON ++ and t2, t3 ++ bne t2, t3, wait_ready ++ ++finished: ++ jr ra ++ ++ END(ltq_mem_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/pmu.c +@@ -0,0 +1,118 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/pm.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_PMU_PWDCR_RESERVED 0xFD0C001C ++ ++#define LTQ_PMU_PWDCR_TDM (1 << 25) ++#define LTQ_PMU_PWDCR_PPE_ENET0 (1 << 23) ++#define LTQ_PMU_PWDCR_PPE_ENET1 (1 << 22) ++#define LTQ_PMU_PWDCR_PPE_TC (1 << 21) ++#define LTQ_PMU_PWDCR_DEU (1 << 20) ++#define LTQ_PMU_PWDCR_UART1 (1 << 17) ++#define LTQ_PMU_PWDCR_SDIO (1 << 16) ++#define LTQ_PMU_PWDCR_AHB (1 << 15) ++#define LTQ_PMU_PWDCR_FPI0 (1 << 14) ++#define LTQ_PMU_PWDCR_PPE (1 << 13) ++#define LTQ_PMU_PWDCR_GPTC (1 << 12) ++#define LTQ_PMU_PWDCR_LEDC (1 << 11) ++#define LTQ_PMU_PWDCR_EBU (1 << 10) ++#define LTQ_PMU_PWDCR_DSL (1 << 9) ++#define LTQ_PMU_PWDCR_SPI (1 << 8) ++#define LTQ_PMU_PWDCR_UART0 (1 << 7) ++#define LTQ_PMU_PWDCR_USB (1 << 6) ++#define LTQ_PMU_PWDCR_DMA (1 << 5) ++#define LTQ_PMU_PWDCR_FPI1 (1 << 1) ++#define LTQ_PMU_PWDCR_USB_PHY (1 << 0) ++ ++struct ltq_pmu_regs { ++ u32 rsvd0[7]; ++ u32 pwdcr; ++ u32 sr; ++ u32 pwdcr1; ++ u32 sr1; ++}; ++ ++static struct ltq_pmu_regs *ltq_pmu_regs = ++ (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE); ++ ++u32 ltq_pm_map(enum ltq_pm_modules module) ++{ ++ u32 val; ++ ++ switch (module) { ++ case LTQ_PM_CORE: ++ val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 | ++ LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU; ++ break; ++ case LTQ_PM_DMA: ++ val = LTQ_PMU_PWDCR_DMA; ++ break; ++ case LTQ_PM_ETH: ++ val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC | ++ LTQ_PMU_PWDCR_PPE; ++ break; ++ case LTQ_PM_SPI: ++ val = LTQ_PMU_PWDCR_SPI; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ ++ return val; ++} ++ ++int ltq_pm_enable(enum ltq_pm_modules module) ++{ ++ const unsigned long timeout = 1000; ++ unsigned long timebase; ++ u32 sr, val; ++ ++ val = ltq_pm_map(module); ++ if (unlikely(!val)) ++ return 1; ++ ++ ltq_clrbits(<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,126 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/cpu.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */ ++#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */ ++#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */ ++#define LTQ_RCU_RD_DFE_AFE (1 << 12) /* Voice DFE/AFE */ ++#define LTQ_RCU_RD_DSL_AFE (1 << 11) /* DSL AFE */ ++#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */ ++#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */ ++#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */ ++#define LTQ_RCU_RD_ARC_DFE (1 << 7) /* ARC/DFE core */ ++#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */ ++#define LTQ_RCU_RD_ENET_MAC1 (1 << 5) /* Ethernet MAC1 */ ++#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */ ++#define LTQ_RCU_RD_CPU1 (1 << 3) /* CPU1 subsystem */ ++#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */ ++#define LTQ_RCU_RD_CPU0 (1 << 1) /* CPU0 subsystem */ ++#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */ ++ ++#define LTQ_RCU_STAT_BOOT_SHIFT 18 ++#define LTQ_RCU_STAT_BOOT_MASK (0x7 << LTQ_RCU_STAT_BOOT_SHIFT) ++ ++struct ltq_rcu_regs { ++ u32 rsvd0[4]; ++ u32 req; /* Reset request */ ++ u32 stat; /* Reset status */ ++ u32 usb_cfg; /* USB configure */ ++ u32 rsvd1[2]; ++ u32 pci_rdy; /* PCI boot ready */ ++}; ++ ++static struct ltq_rcu_regs *ltq_rcu_regs = ++ (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE); ++ ++u32 ltq_reset_map(enum ltq_reset_modules module) ++{ ++ u32 val; ++ ++ switch (module) { ++ case LTQ_RESET_CORE: ++ case LTQ_RESET_SOFT: ++ val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1; ++ break; ++ case LTQ_RESET_DMA: ++ val = LTQ_RCU_RD_DMA; ++ break; ++ case LTQ_RESET_ETH: ++ val = LTQ_RCU_RD_PPE; ++ break; ++ case LTQ_RESET_HARD: ++ val = LTQ_RCU_RD_HRST; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ ++ return val; ++} ++ ++int ltq_reset_activate(enum ltq_reset_modules module) ++{ ++ u32 val; ++ ++ val = ltq_reset_map(module); ++ if (unlikely(!val)) ++ return 1; ++ ++ ltq_setbits(<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/danube/u-boot.lds +@@ -0,0 +1,69 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") ++OUTPUT_ARCH(mips) ++ENTRY(_start) ++SECTIONS ++{ ++ . = 0x00000000; ++ ++ . = ALIGN(4); ++ .text : { ++ *(.text*) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { ++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) ++ } ++ ++ . = ALIGN(4); ++ .data : { ++ *(.data*) ++ } ++ ++ . = ALIGN(4); ++ .sdata : { ++ *(.sdata*) ++ } ++ ++ . = .; ++ _gp = ALIGN(16) + 0x7ff0; ++ ++ .got : { ++ __got_start = .; ++ *(.got) ++ __got_end = .; ++ } ++ ++ num_got_entries = (__got_end - __got_start) >> 2; ++ ++#ifndef CONFIG_SPL_BUILD ++ . = ALIGN(4); ++ .u_boot_list : { ++ #include <u-boot.lst> ++ } ++#endif ++ ++ . = ALIGN(4); ++ __image_copy_end = .; ++ uboot_end_data = .; ++ ++ .bss (NOLOAD) : { ++ __bss_start = .; ++ *(.bss*) ++ *(.sbss*) ++ . = ALIGN(4); ++ __bss_end = .; ++ } ++ ++ . = ALIGN(4); ++ __end = .; ++ uboot_end = .; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/Makefile +@@ -0,0 +1,36 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)liblantiq-common.o ++ ++START = start.o ++COBJS-y = cpu.o pmu.o ++COBJS-$(CONFIG_SPL_BUILD) += spl.o ++SOBJS-y = lowlevel_init.o ++ ++COBJS := $(COBJS-y) ++SOBJS := $(SOBJS-y) ++SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) ++START := $(addprefix $(obj),$(START)) ++ ++all: $(LIB) ++ ++$(LIB): $(obj).depend $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c +@@ -0,0 +1,60 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/cpu.h> ++ ++static const char ltq_bootsel_strings[][16] = { ++ "NOR", ++ "NOR w/o BootROM", ++ "UART", ++ "UART w/o EEPROM", ++ "SPI", ++ "NAND", ++ "PCI", ++ "MII0", ++ "RMII0", ++ "RGMII1", ++ "unknown", ++}; ++ ++const char *ltq_boot_select_str(void) ++{ enum ltq_boot_select bootsel = ltq_boot_select(); ++ ++ if (bootsel > BOOT_UNKNOWN) ++ bootsel = BOOT_UNKNOWN; ++ ++ return ltq_bootsel_strings[bootsel]; ++} ++ ++void ltq_chip_print_info(void) ++{ ++ char buf[32]; ++ ++ printf("SoC: Lantiq %s v1.%u\n", ltq_chip_partnum_str(), ++ ltq_chip_version_get()); ++ printf("CPU: %s MHz\n", strmhz(buf, ltq_get_cpu_clock())); ++ printf("IO: %s MHz\n", strmhz(buf, ltq_get_io_region_clock())); ++ printf("BUS: %s MHz\n", strmhz(buf, ltq_get_bus_clock())); ++ printf("BOOT: %s\n", ltq_boot_select_str()); ++} ++ ++int arch_cpu_init(void) ++{ ++ ltq_pmu_init(); ++ ltq_ebu_init(); ++ ++ return 0; ++} ++ ++void _machine_restart(void) ++{ ++ ltq_reset_activate(LTQ_RESET_CORE); ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S +@@ -0,0 +1,21 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <asm/asm.h> ++#include <asm/regdef.h> ++ ++NESTED(lowlevel_init, 0, ra) ++ move t8, ra ++ ++ la t7, ltq_cgu_init ++ jalr t7 ++ ++ la t7, ltq_mem_init ++ jalr t7 ++ ++ jr t8 ++ END(lowlevel_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c +@@ -0,0 +1,10 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/pm.h> ++ +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/spl.c +@@ -0,0 +1,385 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <image.h> ++#include <version.h> ++#include <spi_flash.h> ++#include <linux/compiler.h> ++#include <lzma/LzmaDec.h> ++#include <linux/lzo.h> ++#include <asm/mipsregs.h> ++ ++#if defined(CONFIG_LTQ_SPL_CONSOLE) ++#define spl_has_console 1 ++ ++#if defined(CONFIG_LTQ_SPL_DEBUG) ++#define spl_has_debug 1 ++#else ++#define spl_has_debug 0 ++#endif ++ ++#else ++#define spl_has_console 0 ++#endif ++ ++#define spl_debug(fmt, args...) \ ++ do { \ ++ if (spl_has_debug) \ ++ printf(fmt, ##args); \ ++ } while (0) ++ ++#define spl_puts(msg) \ ++ do { \ ++ if (spl_has_console) \ ++ puts(msg); \ ++ } while (0) ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL) ++#define spl_boot_spi_flash 1 ++#else ++#define spl_boot_spi_flash 0 ++#ifndef CONFIG_SPL_SPI_BUS ++#define CONFIG_SPL_SPI_BUS 0 ++#endif ++#ifndef CONFIG_SPL_SPI_CS ++#define CONFIG_SPL_SPI_CS 0 ++#endif ++#ifndef CONFIG_SPL_SPI_MAX_HZ ++#define CONFIG_SPL_SPI_MAX_HZ 0 ++#endif ++#ifndef CONFIG_SPL_SPI_MODE ++#define CONFIG_SPL_SPI_MODE 0 ++#endif ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL) ++#define spl_boot_nor_flash 1 ++#else ++#define spl_boot_nor_flash 0 ++#endif ++ ++#define spl_sync() __asm__ __volatile__("sync"); ++ ++struct spl_image { ++ ulong data_addr; ++ ulong entry_addr; ++ size_t data_size; ++ size_t entry_size; ++ u8 comp; ++}; ++ ++extern ulong __image_copy_end; ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* Emulated malloc area needed for LZMA allocator in BSS */ ++static u8 *spl_mem_ptr __maybe_unused; ++static size_t spl_mem_size __maybe_unused; ++ ++static int spl_is_comp_lzma(const struct spl_image *spl) ++{ ++#if defined(CONFIG_LTQ_SPL_COMP_LZMA) ++ return spl->comp == IH_COMP_LZMA; ++#else ++ return 0; ++#endif ++} ++ ++static int spl_is_comp_lzo(const struct spl_image *spl) ++{ ++#if defined(CONFIG_LTQ_SPL_COMP_LZO) ++ return spl->comp == IH_COMP_LZO; ++#else ++ return 0; ++#endif ++} ++ ++static int spl_is_compressed(const struct spl_image *spl) ++{ ++ if (spl_is_comp_lzma(spl)) ++ return 1; ++ ++ if (spl_is_comp_lzo(spl)) ++ return 1; ++ ++ return 0; ++} ++ ++static void spl_console_init(void) ++{ ++ if (!spl_has_console) ++ return; ++ ++ gd->flags |= GD_FLG_RELOC; ++ gd->baudrate = CONFIG_BAUDRATE; ++ ++ serial_init(); ++ ++ gd->have_console = 1; ++ ++ spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ ++ U_BOOT_TIME ")\n"); ++} ++ ++static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl) ++{ ++ u32 magic; ++ ++ spl_puts("SPL: checking U-Boot image\n"); ++ ++ magic = image_get_magic(hdr); ++ if (magic != IH_MAGIC) ++ return -1; ++ ++ spl->data_addr += image_get_header_size(); ++ spl->entry_addr = image_get_load(hdr); ++ spl->data_size = image_get_data_size(hdr); ++ spl->comp = image_get_comp(hdr); ++ ++ spl_debug("SPL: data %08lx, size %zu, entry %08lx, comp %u\n", ++ spl->data_addr, spl->data_size, spl->entry_addr, spl->comp); ++ ++ return 0; ++} ++ ++static void *spl_lzma_alloc(void *p, size_t size) ++{ ++ u8 *ret; ++ ++ if (size > spl_mem_size) ++ return NULL; ++ ++ ret = spl_mem_ptr; ++ spl_mem_ptr += size; ++ spl_mem_size -= size; ++ ++ return ret; ++} ++ ++static void spl_lzma_free(void *p, void *addr) ++{ ++} ++ ++static int spl_copy_image(struct spl_image *spl) ++{ ++ spl_puts("SPL: copying U-Boot to RAM\n"); ++ ++ memcpy((void *) spl->entry_addr, (const void *) spl->data_addr, ++ spl->data_size); ++ ++ spl->entry_size = spl->data_size; ++ ++ return 0; ++} ++ ++static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr) ++{ ++ SRes res; ++ const Byte *prop = (const Byte *) loadaddr; ++ const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE + ++ sizeof(uint64_t); ++ Byte *dest = (Byte *) spl->entry_addr; ++ SizeT dest_len = 0xFFFFFFFF; ++ SizeT src_len = spl->data_size - LZMA_PROPS_SIZE; ++ ELzmaStatus status = 0; ++ ISzAlloc alloc; ++ ++ spl_puts("SPL: decompressing U-Boot with LZMA\n"); ++ ++ alloc.Alloc = spl_lzma_alloc; ++ alloc.Free = spl_lzma_free; ++ spl_mem_ptr = (u8 *) CONFIG_SPL_MALLOC_BASE; ++ spl_mem_size = CONFIG_SPL_MALLOC_MAX_SIZE; ++ ++ res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE, ++ LZMA_FINISH_ANY, &status, &alloc); ++ if (res != SZ_OK) ++ return 1; ++ ++ spl->entry_size = dest_len; ++ ++ return 0; ++} ++ ++static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr) ++{ ++ size_t len; ++ int ret; ++ ++ spl_puts("SPL: decompressing U-Boot with LZO\n"); ++ ++ ret = lzop_decompress( ++ (const unsigned char*) loadaddr, spl->data_size, ++ (unsigned char *) spl->entry_addr, &len); ++ ++ spl->entry_size = len; ++ ++ return ret; ++} ++ ++static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr) ++{ ++ int ret; ++ ++ if (spl_is_comp_lzma(spl)) ++ ret = spl_uncompress_lzma(spl, loadaddr); ++ else if (spl_is_comp_lzo(spl)) ++ ret = spl_uncompress_lzo(spl, loadaddr); ++ else ++ ret = 1; ++ ++ return ret; ++} ++ ++static int spl_load_spi_flash(struct spl_image *spl) ++{ ++ struct spi_flash sf; ++ image_header_t hdr; ++ int ret; ++ unsigned long loadaddr; ++ ++ /* ++ * Image format: ++ * ++ * - 12 byte non-volatile bootstrap header ++ * - SPL binary ++ * - 12 byte non-volatile bootstrap header ++ * - 64 byte U-Boot mkimage header ++ * - U-Boot binary ++ */ ++ spl->data_addr = (ulong) &__image_copy_end - CONFIG_SPL_TEXT_BASE + 24; ++ ++ spl_puts("SPL: probing SPI flash\n"); ++ ++ spi_init(); ++ ret = spi_flash_probe_spl(&sf, CONFIG_SPL_SPI_BUS, CONFIG_SPL_SPI_CS, ++ CONFIG_SPL_SPI_MAX_HZ, CONFIG_SPL_SPI_MODE); ++ if (ret) ++ return ret; ++ ++ spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr); ++ ++ ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr); ++ if (ret) ++ return ret; ++ ++ spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr); ++ ++ ret = spl_parse_image(&hdr, spl); ++ if (ret) ++ return ret; ++ ++ if (spl_is_compressed(spl)) ++ loadaddr = CONFIG_LOADADDR; ++ else ++ loadaddr = spl->entry_addr; ++ ++ spl_puts("SPL: loading U-Boot to RAM\n"); ++ ++ ret = spi_flash_read(&sf, spl->data_addr, spl->data_size, ++ (void *) loadaddr); ++ ++ if (spl_is_compressed(spl)) ++ ret = spl_uncompress(spl, loadaddr); ++ ++ return ret; ++} ++ ++static int spl_load_nor_flash(struct spl_image *spl) ++{ ++ const image_header_t *hdr; ++ int ret; ++ ++ /* ++ * Image format: ++ * ++ * - SPL binary ++ * - 64 byte U-Boot mkimage header ++ * - U-Boot binary ++ */ ++ spl->data_addr = (ulong) &__image_copy_end; ++ hdr = (const image_header_t *) &__image_copy_end; ++ ++ spl_debug("SPL: checking image header at address %p\n", hdr); ++ ++ ret = spl_parse_image(hdr, spl); ++ if (ret) ++ return ret; ++ ++ if (spl_is_compressed(spl)) ++ ret = spl_uncompress(spl, spl->data_addr); ++ else ++ ret = spl_copy_image(spl); ++ ++ return ret; ++} ++ ++static int spl_load(struct spl_image *spl) ++{ ++ int ret; ++ ++ if (spl_boot_spi_flash) ++ ret = spl_load_spi_flash(spl); ++ else if (spl_boot_nor_flash) ++ ret = spl_load_nor_flash(spl); ++ else ++ ret = 1; ++ ++ return ret; ++} ++ ++void __noreturn spl_lantiq_init(void) ++{ ++ void (*uboot)(void) __noreturn; ++ struct spl_image spl; ++ gd_t gd_data; ++ int ret; ++ ++ gd = &gd_data; ++ barrier(); ++ memset((void *)gd, 0, sizeof(gd_t)); ++ ++ spl_console_init(); ++ ++ spl_debug("SPL: initializing\n"); ++ ++#if 0 ++ spl_debug("CP0_CONFIG: %08x\n", read_c0_config()); ++ spl_debug("CP0_CONFIG1: %08x\n", read_c0_config1()); ++ spl_debug("CP0_CONFIG2: %08x\n", read_c0_config2()); ++ spl_debug("CP0_CONFIG3: %08x\n", read_c0_config3()); ++ spl_debug("CP0_CONFIG6: %08x\n", read_c0_config6()); ++ spl_debug("CP0_CONFIG7: %08x\n", read_c0_config7()); ++ spl_debug("CP0_STATUS: %08x\n", read_c0_status()); ++ spl_debug("CP0_PRID: %08x\n", read_c0_prid()); ++#endif ++ ++ board_early_init_f(); ++ timer_init(); ++ ++ memset(&spl, 0, sizeof(spl)); ++ ++ ret = spl_load(&spl); ++ if (ret) ++ goto hang; ++ ++ spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr); ++ spl_puts("SPL: jumping to U-Boot\n"); ++ ++ flush_cache(spl.entry_addr, spl.entry_size); ++ spl_sync(); ++ ++ uboot = (void *) spl.entry_addr; ++ uboot(); ++ ++hang: ++ spl_puts("SPL: cannot start U-Boot\n"); ++ ++ for (;;) ++ ; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/start.S +@@ -0,0 +1,144 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2003 Wolfgang Denk, wd@denx.de ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/regdef.h> ++#include <asm/mipsregs.h> ++ ++#define S_PRIdCoID 16 /* Company ID (R) */ ++#define M_PRIdCoID (0xff << S_PRIdCoID) ++#define S_PRIdImp 8 /* Implementation ID (R) */ ++#define M_PRIdImp (0xff << S_PRIdImp) ++ ++#define K_CacheAttrCWTnWA 0 /* Cacheable, write-thru, no write allocate */ ++#define K_CacheAttrCWTWA 1 /* Cacheable, write-thru, write allocate */ ++#define K_CacheAttrU 2 /* Uncached */ ++#define K_CacheAttrC 3 /* Cacheable */ ++#define K_CacheAttrCN 3 /* Cacheable, non-coherent */ ++#define K_CacheAttrCCE 4 /* Cacheable, coherent, exclusive */ ++#define K_CacheAttrCCS 5 /* Cacheable, coherent, shared */ ++#define K_CacheAttrCCU 6 /* Cacheable, coherent, update */ ++#define K_CacheAttrUA 7 /* Uncached accelerated */ ++ ++#define S_ConfigK23 28 /* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */ ++#define M_ConfigK23 (0x7 << S_ConfigK23) ++#define W_ConfigK23 3 ++#define S_ConfigKU 25 /* Kuseg coherency algorithm (FM MMU only) (R/W) */ ++#define M_ConfigKU (0x7 << S_ConfigKU) ++#define W_ConfigKU 3 ++ ++#define S_ConfigMM 18 /* Merge mode (implementation specific) */ ++#define M_ConfigMM (0x1 << S_ConfigMM) ++ ++#define S_StatusBEV 22 /* Enable Boot Exception Vectors (R/W) */ ++#define M_StatusBEV (0x1 << S_StatusBEV) ++ ++#define S_StatusFR 26 /* Enable 64-bit FPRs (R/W) */ ++#define M_StatusFR (0x1 << S_StatusFR) ++ ++#define S_ConfigK0 0 /* Kseg0 coherency algorithm (R/W) */ ++#define M_ConfigK0 (0x7 << S_ConfigK0) ++ ++#define CONFIG0_MIPS32_64_MSK 0x8000ffff ++#define STATUS_MIPS32_64_MSK 0xfffcffff ++ ++#define STATUS_MIPS24K 0 ++#define CONFIG0_MIPS24K ((K_CacheAttrCN << S_ConfigK23) |\ ++ (K_CacheAttrCN << S_ConfigKU) |\ ++ (M_ConfigMM)) ++ ++#define STATUS_MIPS34K 0 ++#define CONFIG0_MIPS34K ((K_CacheAttrCN << S_ConfigK23) |\ ++ (K_CacheAttrCN << S_ConfigKU) |\ ++ (M_ConfigMM)) ++ ++#define STATUS_MIPS32_64 (M_StatusBEV | M_StatusFR) ++#define CONFIG0_MIPS32_64 (K_CacheAttrCN << S_ConfigK0) ++ ++#ifdef CONFIG_SOC_XWAY_DANUBE ++#define CONFIG0_LANTIQ (CONFIG0_MIPS24K | CONFIG0_MIPS32_64) ++#define STATUS_LANTIQ (STATUS_MIPS24K | STATUS_MIPS32_64) ++#endif ++ ++#ifdef CONFIG_SOC_XWAY_VRX200 ++#define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64) ++#define STATUS_LANTIQ (STATUS_MIPS34K | STATUS_MIPS32_64) ++#endif ++ ++ ++ .set noreorder ++ ++ .globl _start ++ .text ++_start: ++ /* Entry point */ ++ b main ++ nop ++ ++ /* Lantiq SoC Boot config word */ ++ .org 0x10 ++#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG ++ .word CONFIG_SYS_XWAY_EBU_BOOTCFG ++#else ++ .word 0 ++#endif ++ .word 0 ++ ++ .align 4 ++main: ++ ++ /* Init Timer */ ++ mtc0 zero, CP0_COUNT ++ mtc0 zero, CP0_COMPARE ++ ++ /* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */ ++ mfc0 t0, CP0_CONFIG ++ li t1, CONFIG0_MIPS32_64_MSK ++ and t0, t1 ++ li t1, CONFIG0_LANTIQ ++ or t0, t1 ++ mtc0 t0, CP0_CONFIG ++ ++ mfc0 t0, CP0_STATUS ++ li t1, STATUS_MIPS32_64_MSK ++ and t0, t1 ++ li t1, STATUS_LANTIQ ++ or t0, t1 ++ mtc0 t0, CP0_STATUS ++ ++ /* Initialize CGU */ ++ la t9, ltq_cgu_init ++ jalr t9 ++ nop ++ ++ /* Initialize memory controller */ ++ la t9, ltq_mem_init ++ jalr t9 ++ nop ++ ++ /* Initialize caches... */ ++ la t9, mips_cache_reset ++ jalr t9 ++ nop ++ ++ /* Clear BSS */ ++ la t1, __bss_start ++ la t2, __bss_end ++ sub t1, 4 ++1: ++ addi t1, 4 ++ bltl t1, t2, 1b ++ sw zero, 0(t1) ++ ++ /* Setup stack pointer and force alignment on a 16 byte boundary */ ++ li t0, (CONFIG_SPL_STACK_BASE & ~0xF) ++ la sp, 0(t0) ++ ++ la t9, spl_lantiq_init ++ jr t9 ++ nop +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds +@@ -0,0 +1,49 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \ ++ LENGTH = CONFIG_SPL_MAX_SIZE } ++MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_BASE, \ ++ LENGTH = CONFIG_SPL_BSS_MAX_SIZE } ++ ++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") ++OUTPUT_ARCH(mips) ++ENTRY(_start) ++SECTIONS ++{ ++ . = ALIGN(4); ++ .text : { ++ *(.text*) ++ } > .spl_mem ++ ++ . = ALIGN(4); ++ .rodata : { ++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) ++ } > .spl_mem ++ ++ . = ALIGN(4); ++ .data : { ++ *(SORT_BY_ALIGNMENT(.data*)) ++ *(SORT_BY_ALIGNMENT(.sdata*)) ++ } > .spl_mem ++ ++ . = ALIGN(4); ++ __image_copy_end = .; ++ uboot_end_data = .; ++ ++ .bss : { ++ __bss_start = .; ++ *(.bss*) ++ *(.sbss*) ++ . = ALIGN(4); ++ __bss_end = .; ++ } > .bss_mem ++ ++ . = ALIGN(4); ++ __end = .; ++ uboot_end = .; ++} +--- a/arch/mips/cpu/mips32/start.S ++++ b/arch/mips/cpu/mips32/start.S +@@ -55,166 +55,63 @@ + #endif + .endm + +-#define RVECENT(f,n) \ +- b f; nop +-#define XVECENT(f,bev) \ +- b f ; \ +- li k0,bev +- +- .set noreorder +- +- .globl _start +- .text +-_start: +- RVECENT(reset,0) # U-boot entry point +- RVECENT(reset,1) # software reboot +-#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG + /* + * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to + * access external NOR flashes. If the board boots from NOR flash the + * internal BootROM does a blind read at address 0xB0000010 to read the + * initial configuration for that EBU in order to access the flash + * device with correct parameters. This config option is board-specific. ++ * Default to 0 if this option is not set. + */ +- .word CONFIG_SYS_XWAY_EBU_BOOTCFG +- .word 0x00000000 ++ .macro lantiq_soc_bootcfg ++ .set push ++ .set noreorder ++ .org 0x10 ++#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG ++ .word CONFIG_SYS_XWAY_EBU_BOOTCFG + #else +- RVECENT(romReserved,2) ++ .word 0 + #endif +- RVECENT(romReserved,3) +- RVECENT(romReserved,4) +- RVECENT(romReserved,5) +- RVECENT(romReserved,6) +- RVECENT(romReserved,7) +- RVECENT(romReserved,8) +- RVECENT(romReserved,9) +- RVECENT(romReserved,10) +- RVECENT(romReserved,11) +- RVECENT(romReserved,12) +- RVECENT(romReserved,13) +- RVECENT(romReserved,14) +- RVECENT(romReserved,15) +- RVECENT(romReserved,16) +- RVECENT(romReserved,17) +- RVECENT(romReserved,18) +- RVECENT(romReserved,19) +- RVECENT(romReserved,20) +- RVECENT(romReserved,21) +- RVECENT(romReserved,22) +- RVECENT(romReserved,23) +- RVECENT(romReserved,24) +- RVECENT(romReserved,25) +- RVECENT(romReserved,26) +- RVECENT(romReserved,27) +- RVECENT(romReserved,28) +- RVECENT(romReserved,29) +- RVECENT(romReserved,30) +- RVECENT(romReserved,31) +- RVECENT(romReserved,32) +- RVECENT(romReserved,33) +- RVECENT(romReserved,34) +- RVECENT(romReserved,35) +- RVECENT(romReserved,36) +- RVECENT(romReserved,37) +- RVECENT(romReserved,38) +- RVECENT(romReserved,39) +- RVECENT(romReserved,40) +- RVECENT(romReserved,41) +- RVECENT(romReserved,42) +- RVECENT(romReserved,43) +- RVECENT(romReserved,44) +- RVECENT(romReserved,45) +- RVECENT(romReserved,46) +- RVECENT(romReserved,47) +- RVECENT(romReserved,48) +- RVECENT(romReserved,49) +- RVECENT(romReserved,50) +- RVECENT(romReserved,51) +- RVECENT(romReserved,52) +- RVECENT(romReserved,53) +- RVECENT(romReserved,54) +- RVECENT(romReserved,55) +- RVECENT(romReserved,56) +- RVECENT(romReserved,57) +- RVECENT(romReserved,58) +- RVECENT(romReserved,59) +- RVECENT(romReserved,60) +- RVECENT(romReserved,61) +- RVECENT(romReserved,62) +- RVECENT(romReserved,63) +- XVECENT(romExcHandle,0x200) # bfc00200: R4000 tlbmiss vector +- RVECENT(romReserved,65) +- RVECENT(romReserved,66) +- RVECENT(romReserved,67) +- RVECENT(romReserved,68) +- RVECENT(romReserved,69) +- RVECENT(romReserved,70) +- RVECENT(romReserved,71) +- RVECENT(romReserved,72) +- RVECENT(romReserved,73) +- RVECENT(romReserved,74) +- RVECENT(romReserved,75) +- RVECENT(romReserved,76) +- RVECENT(romReserved,77) +- RVECENT(romReserved,78) +- RVECENT(romReserved,79) +- XVECENT(romExcHandle,0x280) # bfc00280: R4000 xtlbmiss vector +- RVECENT(romReserved,81) +- RVECENT(romReserved,82) +- RVECENT(romReserved,83) +- RVECENT(romReserved,84) +- RVECENT(romReserved,85) +- RVECENT(romReserved,86) +- RVECENT(romReserved,87) +- RVECENT(romReserved,88) +- RVECENT(romReserved,89) +- RVECENT(romReserved,90) +- RVECENT(romReserved,91) +- RVECENT(romReserved,92) +- RVECENT(romReserved,93) +- RVECENT(romReserved,94) +- RVECENT(romReserved,95) +- XVECENT(romExcHandle,0x300) # bfc00300: R4000 cache vector +- RVECENT(romReserved,97) +- RVECENT(romReserved,98) +- RVECENT(romReserved,99) +- RVECENT(romReserved,100) +- RVECENT(romReserved,101) +- RVECENT(romReserved,102) +- RVECENT(romReserved,103) +- RVECENT(romReserved,104) +- RVECENT(romReserved,105) +- RVECENT(romReserved,106) +- RVECENT(romReserved,107) +- RVECENT(romReserved,108) +- RVECENT(romReserved,109) +- RVECENT(romReserved,110) +- RVECENT(romReserved,111) +- XVECENT(romExcHandle,0x380) # bfc00380: R4000 general vector +- RVECENT(romReserved,113) +- RVECENT(romReserved,114) +- RVECENT(romReserved,115) +- RVECENT(romReserved,116) +- RVECENT(romReserved,116) +- RVECENT(romReserved,118) +- RVECENT(romReserved,119) +- RVECENT(romReserved,120) +- RVECENT(romReserved,121) +- RVECENT(romReserved,122) +- RVECENT(romReserved,123) +- RVECENT(romReserved,124) +- RVECENT(romReserved,125) +- RVECENT(romReserved,126) +- RVECENT(romReserved,127) ++ .word 0 ++ .set pop ++ .endm ++ ++ .macro reset_vector branch ++ .set push ++ .set noreorder ++ b \branch ++ nop ++ .set pop ++ .endm ++ ++ .macro exception_vector offset branch ++ .set push ++ .set noreorder ++ .org \offset ++ b \branch ++ li k0, \offset ++ .set pop ++ .endm ++ ++ .set noreorder ++ ++ .globl _start ++ .text ++_start: ++ reset_vector reset # U-boot entry point ++ reset_vector reset # software reboot ++ ++ lantiq_soc_bootcfg # Lantiq SoC Boot config word ++ ++ exception_vector 0x200, halt # TLB miss ++ exception_vector 0x280, halt # XTLB miss ++ exception_vector 0x300, halt # Cache error ++ exception_vector 0x380, halt # General ++ exception_vector 0x400, halt # Interrupt, CauseIV ++ exception_vector 0x480, ejtag_exception # EJTAG debug + +- /* +- * We hope there are no more reserved vectors! +- * 128 * 8 == 1024 == 0x400 +- * so this is address R_VEC+0x400 == 0xbfc00400 +- */ + .align 4 + reset: +- + /* Clear watch registers */ + mtc0 zero, CP0_WATCHLO + mtc0 zero, CP0_WATCHHI +@@ -222,13 +119,15 @@ reset: + /* WP(Watch Pending), SW0/1 should be cleared */ + mtc0 zero, CP0_CAUSE + ++#if 0 + setup_c0_status_reset ++#endif + + /* Init Timer */ + mtc0 zero, CP0_COUNT + mtc0 zero, CP0_COMPARE + +-#ifndef CONFIG_SKIP_LOWLEVEL_INIT ++#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_SYS_DISABLE_CACHE) + /* CONFIG0 register */ + li t0, CONF_CM_UNCACHED + mtc0 t0, CP0_CONFIG +@@ -323,6 +222,8 @@ relocate_code: + jalr t9 + nop + ++ sync ++ + /* Jump to where we've relocated ourselves */ + addi t0, s2, in_ram - _start + jr t0 +@@ -378,8 +279,12 @@ in_ram: + .end relocate_code + + /* Exception handlers */ +-romReserved: +- b romReserved ++ejtag_exception: ++ /* Set DEPC to halt and exit debug mode */ ++ la k1, halt ++ mtc0 k1, CP0_DEPC ++ deret ++ nop + +-romExcHandle: +- b romExcHandle ++halt: ++ b halt +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/Makefile +@@ -0,0 +1,34 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(SOC).o ++ ++COBJS-y += cgu.o chipid.o dcdc.o ebu.o gphy.o mem.o pmu.o rcu.o ++SOBJS-y += cgu_init.o mem_init.o ++SOBJS-y += gphy_fw.o ++ ++COBJS := $(COBJS-y) ++SOBJS := $(SOBJS-y) ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) ++ ++all: $(LIB) ++ ++$(LIB): $(obj).depend $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/cgu.c +@@ -0,0 +1,209 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/gphy.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_CGU_PLL1_PLLN_SHIFT 6 ++#define LTQ_CGU_PLL1_PLLN_MASK (0x3F << LTQ_CGU_PLL1_PLLN_SHIFT) ++#define LTQ_CGU_PLL1_PLLM_SHIFT 2 ++#define LTQ_CGU_PLL1_PLLM_MASK (0xF << LTQ_CGU_PLL1_PLLM_SHIFT) ++#define LTQ_CGU_PLL1_PLLL (1 << 1) ++#define LTQ_CGU_PLL1_PLL_EN 1 ++ ++#define LTQ_CGU_SYS_OCP_SHIFT 0 ++#define LTQ_CGU_SYS_OCP_MASK (0x3 << LTQ_CGU_SYS_OCP_SHIFT) ++#define LTQ_CGU_SYS_CPU_SHIFT 4 ++#define LTQ_CGU_SYS_CPU_MASK (0xF << LTQ_CGU_SYS_CPU_SHIFT) ++ ++#define LTQ_CGU_UPDATE 1 ++ ++#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT 2 ++#define LTQ_CGU_IFCLK_GPHY_SEL_MASK (0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT) ++ ++struct ltq_cgu_regs { ++ u32 rsvd0; ++ u32 pll0_cfg; /* PLL0 config */ ++ u32 pll1_cfg; /* PLL1 config */ ++ u32 sys; /* System clock */ ++ u32 clk_fsr; /* Clock frequency select */ ++ u32 clk_gsr; /* Clock gating status */ ++ u32 clk_gcr0; /* Clock gating control 0 */ ++ u32 clk_gcr1; /* Clock gating control 1 */ ++ u32 update; /* CGU update control */ ++ u32 if_clk; /* Interface clock */ ++ u32 ddr; /* DDR memory control */ ++ u32 ct1_sr; /* CT status 1 */ ++ u32 ct_kval; /* CT K value */ ++ u32 pcm_cr; /* PCM control */ ++ u32 pci_cr; /* PCI clock control */ ++ u32 rsvd1; ++ u32 gphy1_cfg; /* GPHY1 config */ ++ u32 gphy0_cfg; /* GPHY0 config */ ++ u32 rsvd2[6]; ++ u32 pll2_cfg; /* PLL2 config */ ++}; ++ ++static struct ltq_cgu_regs *ltq_cgu_regs = ++ (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE); ++ ++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift) ++{ ++ return (ltq_readl(<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,120 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/asm.h> ++#include <asm/regdef.h> ++#include <asm/addrspace.h> ++#include <asm/arch/soc.h> ++ ++/* RCU module register */ ++#define LTQ_RCU_RST_REQ 0x0010 /* Reset request */ ++#define LTQ_RCU_RST_REQ_VALUE ((1 << 14) | (1 << 1)) ++ ++/* CGU module register */ ++#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */ ++#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */ ++#define LTQ_CGU_PLL2_CFG 0x0060 /* PLL2 config */ ++#define LTQ_CGU_SYS 0x000C /* System clock */ ++#define LTQ_CGU_CLK_FSR 0x0010 /* Clock frequency select */ ++#define LTQ_CGU_UPDATE 0x0020 /* Clock update control */ ++ ++/* Valid SYS.CPU values */ ++#define LTQ_CGU_SYS_CPU_SHIFT 4 ++#define LTQ_CGU_SYS_CPU_600_MHZ 0x0 ++#define LTQ_CGU_SYS_CPU_500_MHZ 0x1 ++#define LTQ_CGU_SYS_CPU_393_MHZ 0x2 ++#define LTQ_CGU_SYS_CPU_333_MHZ 0x3 ++#define LTQ_CGU_SYS_CPU_197_MHZ 0x5 ++#define LTQ_CGU_SYS_CPU_166_MHZ 0x7 ++#define LTQ_CGU_SYS_CPU_125_MHZ 0x9 ++ ++/* Valid SYS.OCP values */ ++#define LTQ_CGU_SYS_OCP_SHIFT 0 ++#define LTQ_CGU_SYS_OCP_1 0x0 ++#define LTQ_CGU_SYS_OCP_2 0x2 ++#define LTQ_CGU_SYS_OCP_2_5 0x3 ++#define LTQ_CGU_SYS_OCP_3 0x4 ++ ++/* Valid CLK_FSR.ETH values */ ++#define LTQ_CGU_CLK_FSR_ETH_SHIFT 24 ++#define LTQ_CGU_CLK_FSR_ETH_50_MHZ 0x0 ++#define LTQ_CGU_CLK_FSR_ETH_25_MHZ 0x1 ++#define LTQ_CGU_CLK_FSR_ETH_2_5_MHZ 0x2 ++#define LTQ_CGU_CLK_FSR_ETH_125_MHZ 0x3 ++ ++/* Valid CLK_FSR.PPE values */ ++#define LTQ_CGU_CLK_FSR_PPE_SHIFT 16 ++#define LTQ_CGU_CLK_FSR_PPE_500_MHZ 0x0 /* Overclock frequency */ ++#define LTQ_CGU_CLK_FSR_PPE_450_MHZ 0x1 /* High frequency */ ++#define LTQ_CGU_CLK_FSR_PPE_400_MHZ 0x2 /* Low frequency */ ++ ++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_500_DDR_250) ++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_500_MHZ ++#define LTQ_CGU_SYS_OCP_CONFIG LTQ_CGU_SYS_OCP_2 ++#define LTQ_CGU_CLK_FSR_ETH_CONFIG LTQ_CGU_CLK_FSR_ETH_125_MHZ ++#define LTQ_CGU_CLK_FSR_PPE_CONFIG LTQ_CGU_CLK_FSR_PPE_450_MHZ ++#else ++#error "Invalid system clock configuration!" ++#endif ++ ++/* Build register values */ ++#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_CPU_CONFIG << \ ++ LTQ_CGU_SYS_CPU_SHIFT) | \ ++ LTQ_CGU_SYS_OCP_CONFIG) ++ ++#define LTQ_CGU_CLK_FSR_VALUE ((LTQ_CGU_CLK_FSR_ETH_CONFIG << \ ++ LTQ_CGU_CLK_FSR_ETH_SHIFT) | \ ++ (LTQ_CGU_CLK_FSR_PPE_CONFIG << \ ++ LTQ_CGU_CLK_FSR_PPE_SHIFT)) ++ ++ .set noreorder ++ ++LEAF(ltq_cgu_init) ++ /* Load current CGU register values */ ++ li t0, (LTQ_CGU_BASE | KSEG1) ++ lw t1, LTQ_CGU_SYS(t0) ++ lw t2, LTQ_CGU_CLK_FSR(t0) ++ ++ /* Load target CGU register values */ ++ li t3, LTQ_CGU_SYS_VALUE ++ li t4, LTQ_CGU_CLK_FSR_VALUE ++ ++ /* Only update registers if values differ */ ++ bne t1, t3, update ++ nop ++ beq t2, t4, finished ++ nop ++ ++update: ++ /* Store target register values */ ++ sw t3, LTQ_CGU_SYS(t0) ++ sw t4, LTQ_CGU_CLK_FSR(t0) ++ ++ /* Perform software reset to activate new clock config */ ++#if 0 ++ li t0, (LTQ_RCU_BASE | KSEG1) ++ lw t1, LTQ_RCU_RST_REQ(t0) ++ or t1, LTQ_RCU_RST_REQ_VALUE ++ sw t1, LTQ_RCU_RST_REQ(t0) ++#else ++ li t1, 1 ++ sw t1, LTQ_CGU_UPDATE(t0) ++#endif ++ ++#if 0 ++wait_reset: ++ b wait_reset ++ nop ++#endif ++ ++finished: ++ jr ra ++ nop ++ ++ END(ltq_cgu_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/chipid.c +@@ -0,0 +1,63 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_CHIPID_VERSION_SHIFT 28 ++#define LTQ_CHIPID_VERSION_MASK (0x7 << LTQ_CHIPID_VERSION_SHIFT) ++#define LTQ_CHIPID_PNUM_SHIFT 12 ++#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT) ++ ++struct ltq_chipid_regs { ++ u32 manid; /* Manufacturer identification */ ++ u32 chipid; /* Chip identification */ ++}; ++ ++static struct ltq_chipid_regs *ltq_chipid_regs = ++ (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE); ++ ++unsigned int ltq_chip_version_get(void) ++{ ++ u32 chipid; ++ ++ chipid = ltq_readl(<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,32 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,) ++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX) ++ ++ifdef CONFIG_SPL_BUILD ++PF_ABICALLS := -mno-abicalls ++PF_PIC := -fno-pic ++USE_PRIVATE_LIBGCC := yes ++endif ++ ++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o ++ ++ifndef CONFIG_SPL_BUILD ++ifdef CONFIG_SYS_BOOT_SFSPL ++ALL-y += $(obj)u-boot.ltq.sfspl ++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl ++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl ++endif ++ifdef CONFIG_SYS_BOOT_NORSPL ++ALL-y += $(obj)u-boot.ltq.norspl ++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl ++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl ++endif ++endif ++ ++LDSCRIPT := $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot.lds +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/dcdc.c +@@ -0,0 +1,107 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_DCDC_CLK_SET0_CLK_SEL_P (1 << 6) ++#define LTQ_DCDC_CLK_SET1_SEL_DIV25 (1 << 5) ++#define LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE (1 << 5) ++ ++struct ltq_dcdc_regs { ++ u8 b0_coeh; /* Coefficient b0 */ ++ u8 b0_coel; /* Coefficient b0 */ ++ u8 b1_coeh; /* Coefficient b1 */ ++ u8 b1_coel; /* Coefficient b1 */ ++ u8 b2_coeh; /* Coefficient b2 */ ++ u8 b2_coel; /* Coefficient b2 */ ++ u8 clk_set0; /* Clock setup */ ++ u8 clk_set1; /* Clock setup */ ++ u8 pwm_confh; /* Configure PWM */ ++ u8 pwm_confl; /* Configure PWM */ ++ u8 bias_vreg0; /* Bias and regulator setup */ ++ u8 bias_vreg1; /* Bias and regulator setup */ ++ u8 adc_gen0; /* ADC and general control */ ++ u8 adc_gen1; /* ADC and general control */ ++ u8 adc_con0; /* ADC and general config */ ++ u8 adc_con1; /* ADC and general config */ ++ u8 conf_test_ana; /* not documented */ ++ u8 conf_test_dig; /* not documented */ ++ u8 dcdc_status; /* not documented */ ++ u8 pid_status; /* not documented */ ++ u8 duty_cycle; /* not documented */ ++ u8 non_ov_delay; /* not documented */ ++ u8 analog_gain; /* not documented */ ++ u8 duty_cycle_max_sat; /* not documented */ ++ u8 duty_cycle_min_sat; /* not documented */ ++ u8 duty_cycle_max; /* not documented */ ++ u8 duty_cycle_min; /* not documented */ ++ u8 error_max; /* not documented */ ++ u8 error_read; /* not documented */ ++ u8 delay_deglitch; /* not documented */ ++ u8 latch_control; /* not documented */ ++ u8 rsvd[240]; ++ u8 osc_conf; /* OSC general config */ ++ u8 osc_stat; /* OSC general status */ ++}; ++ ++static struct ltq_dcdc_regs *ltq_dcdc_regs = ++ (struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE); ++ ++void ltq_dcdc_init(unsigned int dig_ref) ++{ ++ u8 dig_ref_cur, val; ++ ++ /* Set duty cycle max sat. to 70/90, enable PID freeze */ ++ ltq_writeb(<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,112 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4) ++#define EBU_ADDRSEL_REGEN (1 << 0) ++ ++#define EBU_CON_WRDIS (1 << 31) ++#define EBU_CON_AGEN_DEMUX (0x0 << 24) ++#define EBU_CON_AGEN_MUX (0x2 << 24) ++#define EBU_CON_SETUP (1 << 22) ++#define EBU_CON_WAIT_DIS (0x0 << 20) ++#define EBU_CON_WAIT_ASYNC (0x1 << 20) ++#define EBU_CON_WAIT_SYNC (0x2 << 20) ++#define EBU_CON_WINV (1 << 19) ++#define EBU_CON_PW_8BIT (0x0 << 16) ++#define EBU_CON_PW_16BIT (0x1 << 16) ++#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14) ++#define EBU_CON_BCGEN_CS (0x0 << 12) ++#define EBU_CON_BCGEN_INTEL (0x1 << 12) ++#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12) ++#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8) ++#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6) ++#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4) ++#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2) ++#define EBU_CON_CMULT_1 0x0 ++#define EBU_CON_CMULT_4 0x1 ++#define EBU_CON_CMULT_8 0x2 ++#define EBU_CON_CMULT_16 0x3 ++ ++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) ++#define ebu_region0_enable 1 ++#else ++#define ebu_region0_enable 0 ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH) ++#define ebu_region1_enable 1 ++#else ++#define ebu_region1_enable 0 ++#endif ++ ++struct ltq_ebu_regs { ++ u32 clc; ++ u32 rsvd0; ++ u32 id; ++ u32 rsvd1; ++ u32 con; ++ u32 rsvd2[3]; ++ u32 addr_sel_0; ++ u32 addr_sel_1; ++ u32 addr_sel_2; ++ u32 addr_sel_3; ++ u32 rsvd3[12]; ++ u32 con_0; ++ u32 con_1; ++ u32 con_2; ++ u32 con_3; ++}; ++ ++static struct ltq_ebu_regs *ltq_ebu_regs = ++ (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE); ++ ++void ltq_ebu_init(void) ++{ ++ if (ebu_region0_enable) { ++ /* ++ * Map EBU region 0 to range 0x10000000-0x13ffffff and enable ++ * region control. This supports up to 32 MiB NOR flash in ++ * bank 0. ++ */ ++ ltq_writel(<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,59 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/gphy.h> ++ ++static inline void ltq_gphy_copy(const void *fw_start, const void *fw_end, ++ ulong dst_addr) ++{ ++ const ulong fw_len = (ulong) fw_end - (ulong) fw_start; ++ const ulong addr = CKSEG1ADDR(dst_addr); ++ ++ debug("ltq_gphy_copy: addr %08lx, fw_start %p, fw_end %p\n", ++ addr, fw_start, fw_end); ++ ++ memcpy((void *) addr, fw_start, fw_len); ++} ++ ++void ltq_gphy_phy11g_a1x_load(ulong addr) ++{ ++ extern ulong __ltq_fw_phy11g_a1x_start; ++ extern ulong __ltq_fw_phy11g_a1x_end; ++ ++ ltq_gphy_copy(&__ltq_fw_phy11g_a1x_start, &__ltq_fw_phy11g_a1x_end, ++ addr); ++} ++ ++void ltq_gphy_phy11g_a2x_load(ulong addr) ++{ ++ extern ulong __ltq_fw_phy11g_a2x_start; ++ extern ulong __ltq_fw_phy11g_a2x_end; ++ ++ ltq_gphy_copy(&__ltq_fw_phy11g_a2x_start, &__ltq_fw_phy11g_a2x_end, ++ addr); ++} ++ ++void ltq_gphy_phy22f_a1x_load(ulong addr) ++{ ++ extern ulong __ltq_fw_phy22f_a1x_start; ++ extern ulong __ltq_fw_phy22f_a1x_end; ++ ++ ltq_gphy_copy(&__ltq_fw_phy22f_a1x_start, &__ltq_fw_phy22f_a1x_end, ++ addr); ++} ++ ++void ltq_gphy_phy22f_a2x_load(ulong addr) ++{ ++ extern ulong __ltq_fw_phy22f_a2x_start; ++ extern ulong __ltq_fw_phy22f_a2x_end; ++ ++ ltq_gphy_copy(&__ltq_fw_phy22f_a2x_start, &__ltq_fw_phy22f_a2x_end, ++ addr); ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S +@@ -0,0 +1,28 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <asm/asm.h> ++ ++ .section .rodata.__ltq_fw_phy11g_a1x ++EXPORT(__ltq_fw_phy11g_a1x_start) ++ .incbin "fw_phy11g_a1x.bin" ++EXPORT(__ltq_fw_phy11g_a1x_end) ++ ++ .section .rodata.__ltq_fw_phy11g_a2x ++EXPORT(__ltq_fw_phy11g_a2x_start) ++ .incbin "fw_phy11g_a2x.bin" ++EXPORT(__ltq_fw_phy11g_a2x_end) ++ ++ .section .rodata.__ltq_fw_phy22f_a1x ++EXPORT(__ltq_fw_phy22f_a1x_start) ++ .incbin "fw_phy22f_a1x.bin" ++EXPORT(__ltq_fw_phy22f_a1x_end) ++ ++ .section .rodata.__ltq_fw_phy22f_a2x ++EXPORT(__ltq_fw_phy22f_a2x_start) ++ .incbin "fw_phy22f_a2x.bin" ++EXPORT(__ltq_fw_phy22f_a2x_end) +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/mem.c +@@ -0,0 +1,58 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_CCR03_EIGHT_BANK_MODE (1 << 0) ++#define LTQ_CCR08_CS_MAP_SHIFT 24 ++#define LTQ_CCR08_CS_MAP_MASK (0x3 << LTQ_CCR08_CS_MAP_SHIFT) ++#define LTQ_CCR11_COLUMN_SIZE_SHIFT 24 ++#define LTQ_CCR11_COLUMN_SIZE_MASK (0x7 << LTQ_CCR11_COLUMN_SIZE_SHIFT) ++#define LTQ_CCR11_ADDR_PINS_MASK 0x7 ++#define LTQ_CCR15_MAX_COL_REG_SHIFT 24 ++#define LTQ_CCR15_MAX_COL_REG_MASK (0xF << LTQ_CCR15_MAX_COL_REG_SHIFT) ++#define LTQ_CCR16_MAX_ROW_REG_MASK 0xF ++ ++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE); ++ ++static inline u32 ltq_mc_ccr_read(u32 index) ++{ ++ return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index)); ++} ++ ++phys_size_t initdram(int board_type) ++{ ++ u32 max_col_reg, max_row_reg, column_size, addr_pins; ++ u32 banks, cs_map; ++ phys_size_t size; ++ ++ banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4; ++ ++ cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >> ++ LTQ_CCR08_CS_MAP_SHIFT; ++ ++ column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >> ++ LTQ_CCR11_COLUMN_SIZE_SHIFT; ++ ++ addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK; ++ ++ max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >> ++ LTQ_CCR15_MAX_COL_REG_SHIFT; ++ ++ max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK; ++ ++ /* ++ * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects ++ * * datawidth (bytes) ++ */ ++ size = (2 << (max_col_reg - column_size - 1)) * ++ (2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2; ++ ++ return size; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/mem_init.S +@@ -0,0 +1,234 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/asm.h> ++#include <asm/regdef.h> ++#include <asm/addrspace.h> ++#include <asm/arch/soc.h> ++ ++/* Must be configured in BOARDDIR */ ++#include <ddr_settings.h> ++ ++#define LTQ_MC_DDR_START (1 << 8) ++#define LTQ_MC_DDR_DLL_LOCK_IND 1 ++ ++#define CCS_ALWAYS_LAST 0x0430 ++#define CCS_AHBM_CR_BURST_EN (1 << 2) ++#define CCS_FPIM_CR_BURST_EN (1 << 1) ++ ++#define CCR03_EIGHT_BANK_MODE (1 << 0) ++ ++ /* Store given value in MC DDR CCRx register */ ++ .macro ccr_sw num, val ++ li t1, \val ++ sw t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0) ++ .endm ++ ++LEAF(ltq_mem_init) ++ /* Load MC DDR module base */ ++ li t0, (LTQ_MC_DDR_BASE | KSEG1) ++ ++ /* Put memory controller in inactive mode */ ++ sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0) ++ ++ /* Init MC DDR CCR registers with values from ddr_settings.h */ ++ ccr_sw 0, MC_CCR00_VALUE ++ ccr_sw 1, MC_CCR01_VALUE ++ ccr_sw 2, MC_CCR02_VALUE ++ ccr_sw 3, MC_CCR03_VALUE ++ ccr_sw 4, MC_CCR04_VALUE ++ ccr_sw 5, MC_CCR05_VALUE ++ ccr_sw 6, MC_CCR06_VALUE ++ ccr_sw 7, MC_CCR07_VALUE ++ ccr_sw 8, MC_CCR08_VALUE ++ ccr_sw 9, MC_CCR09_VALUE ++ ++ ccr_sw 10, MC_CCR10_VALUE ++ ccr_sw 11, MC_CCR11_VALUE ++ ccr_sw 12, MC_CCR12_VALUE ++ ccr_sw 13, MC_CCR13_VALUE ++ ccr_sw 14, MC_CCR14_VALUE ++ ccr_sw 15, MC_CCR15_VALUE ++ ccr_sw 16, MC_CCR16_VALUE ++ ccr_sw 17, MC_CCR17_VALUE ++ ccr_sw 18, MC_CCR18_VALUE ++ ccr_sw 19, MC_CCR19_VALUE ++ ++ ccr_sw 20, MC_CCR20_VALUE ++ ccr_sw 21, MC_CCR21_VALUE ++ ccr_sw 22, MC_CCR22_VALUE ++ ccr_sw 23, MC_CCR23_VALUE ++ ccr_sw 24, MC_CCR24_VALUE ++ ccr_sw 25, MC_CCR25_VALUE ++ ccr_sw 26, MC_CCR26_VALUE ++ ccr_sw 27, MC_CCR27_VALUE ++ ccr_sw 28, MC_CCR28_VALUE ++ ccr_sw 29, MC_CCR29_VALUE ++ ++ ccr_sw 30, MC_CCR30_VALUE ++ ccr_sw 31, MC_CCR31_VALUE ++ ccr_sw 32, MC_CCR32_VALUE ++ ccr_sw 33, MC_CCR33_VALUE ++ ccr_sw 34, MC_CCR34_VALUE ++ ccr_sw 35, MC_CCR35_VALUE ++ ccr_sw 36, MC_CCR36_VALUE ++ ccr_sw 37, MC_CCR37_VALUE ++ ccr_sw 38, MC_CCR38_VALUE ++ ccr_sw 39, MC_CCR39_VALUE ++ ++ ccr_sw 40, MC_CCR40_VALUE ++ ccr_sw 41, MC_CCR41_VALUE ++ ccr_sw 42, MC_CCR42_VALUE ++ ccr_sw 43, MC_CCR43_VALUE ++ ccr_sw 44, MC_CCR44_VALUE ++ ccr_sw 45, MC_CCR45_VALUE ++ ccr_sw 46, MC_CCR46_VALUE ++ ++ ccr_sw 52, MC_CCR52_VALUE ++ ccr_sw 53, MC_CCR53_VALUE ++ ccr_sw 54, MC_CCR54_VALUE ++ ccr_sw 55, MC_CCR55_VALUE ++ ccr_sw 56, MC_CCR56_VALUE ++ ccr_sw 57, MC_CCR57_VALUE ++ ccr_sw 58, MC_CCR58_VALUE ++ ccr_sw 59, MC_CCR59_VALUE ++ ++ ccr_sw 60, MC_CCR60_VALUE ++ ccr_sw 61, MC_CCR61_VALUE ++ ++ /* Disable bursts between FPI Master bus and XBAR bus */ ++ li t4, (LTQ_MC_GLOBAL_BASE | KSEG1) ++ li t5, CCS_AHBM_CR_BURST_EN ++ sw t5, CCS_ALWAYS_LAST(t4) ++ ++ /* Init abort condition for DRAM probe */ ++ move t4, zero ++ ++ /* ++ * Put memory controller in active mode and start initialitation ++ * sequence for connected DDR-SDRAM device ++ */ ++mc_start: ++ lw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0) ++ li t2, LTQ_MC_DDR_START ++ or t1, t1, t2 ++ sw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0) ++ ++ /* ++ * Wait until DLL has locked and core is ready for data transfers. ++ * DLL lock indication is in register CCR47 and CCR48 ++ */ ++wait_ready: ++ li t1, LTQ_MC_DDR_DLL_LOCK_IND ++ lw t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0) ++ and t2, t2, t1 ++ bne t1, t2, wait_ready ++ ++ lw t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0) ++ and t2, t2, t1 ++ bne t1, t2, wait_ready ++ ++#ifdef CONFIG_SYS_DRAM_PROBE ++dram_probe: ++ /* Initialization is finished after the second MC start */ ++ bnez t4, mc_finished ++ ++ /* ++ * Preload register values for CCR03 and CCR11. Initial settings ++ * are 8-bank mode enabled, 14 use address row bits, 10 used ++ * column address bits. ++ */ ++ li t1, CONFIG_SYS_SDRAM_BASE_UC ++ li t5, MC_CCR03_VALUE ++ li t6, MC_CCR11_VALUE ++ addi t4, t4, 1 ++ ++ /* ++ * Store test values to DRAM at offsets 0 and 2^13 (bit 2 in bank select ++ * address BA[3]) and read back the value at offset 0. If the resulting ++ * value is equal to 1 we can skip to the next test. Otherwise ++ * the 8-bank mode does not work with the current DRAM device, ++ * thus we need to clear the according bit in register CCR03. ++ */ ++ li t2, 1 ++ sw t2, 0x0(t1) ++ li t3, (1 << 13) ++ add t3, t3, t1 ++ sw zero, 0(t3) ++ lw t3, 0(t1) ++ bnez t3, row_col_test ++ ++ /* Clear CCR03.EIGHT_BANK_MODE */ ++ li t3, ~CCR03_EIGHT_BANK_MODE ++ and t5, t5, t3 ++ ++row_col_test: ++ /* ++ * Store test values to DRAM at offsets 0, 2^27 (bit 13 of row address ++ * RA[14]) and 2^26 (bit 12 of RA[14]). The chosen test values ++ * represent the difference between max. row address bits (14) and used ++ * row address bits. Then the read back value at offset 0 indicates ++ * the useable row address bits with the current DRAM device. This ++ * value must be set in the CCR11 register. ++ */ ++ sw zero, 0(t1) ++ ++ li t2, 1 ++ li t3, (1 << 27) ++ add t3, t3, t1 ++ sw t2, 0(t3) ++ ++ li t2, 2 ++ li t3, (1 << 26) ++ add t3, t3, t1 ++ sw t2, 0(t3) ++ ++ /* Update CCR11.ADDR_PINS */ ++ lw t3, 0(t1) ++ add t6, t6, t3 ++ ++ /* ++ * Store test values to DRAM at offsets 0, 2^10 (bit 9 of column address ++ * CA[10]) and 2^9 (bit 8 of CA[10]). The chosen test values represent ++ * the difference between max. column address bits (12) and used ++ * column address bits. Then the read back value at offset 0 indicates ++ * the useable column address bits with the current DRAM device. This ++ * value must be set in the CCR11 register. ++ */ ++ sw zero, 0(t1) ++ ++ li t2, 1 ++ li t3, (1 << 10) ++ add t3, t3, t1 ++ sw t2, 0(t3) ++ ++ li t2, 2 ++ li t3, (1 << 9) ++ add t3, t3, t1 ++ sw t2, 0(t3) ++ ++ /* Update CCR11.COLUMN_SIZE */ ++ lw t3, 0(t1) ++ sll t3, t3, 24 ++ add t6, t6, t3 ++ ++ /* Put memory controller in inactive mode */ ++ sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0) ++ ++ /* Update CCR03 and CCR11 and restart memory controller initialiation */ ++ sw t5, LTQ_MC_DDR_CCR_OFFSET(3)(t0) ++ sw t6, LTQ_MC_DDR_CCR_OFFSET(11)(t0) ++ b mc_start ++ ++mc_finished: ++#endif /* CONFIG_SYS_DRAM_PROBE */ ++ ++ jr ra ++ ++ END(ltq_mem_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/pmu.c +@@ -0,0 +1,131 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/pm.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_PMU_PWDCR_RESERVED ((1 << 13) | (1 << 4)) ++ ++#define LTQ_PMU_PWDCR_PCIELOC_EN (1 << 31) ++#define LTQ_PMU_PWDCR_GPHY (1 << 30) ++#define LTQ_PMU_PWDCR_PPE_TOP (1 << 29) ++#define LTQ_PMU_PWDCR_SWITCH (1 << 28) ++#define LTQ_PMU_PWDCR_USB1 (1 << 27) ++#define LTQ_PMU_PWDCR_USB1_PHY (1 << 26) ++#define LTQ_PMU_PWDCR_TDM (1 << 25) ++#define LTQ_PMU_PWDCR_PPE_DPLUS (1 << 24) ++#define LTQ_PMU_PWDCR_PPE_DPLUM (1 << 23) ++#define LTQ_PMU_PWDCR_PPE_EMA (1 << 22) ++#define LTQ_PMU_PWDCR_PPE_TC (1 << 21) ++#define LTQ_PMU_PWDCR_DEU (1 << 20) ++#define LTQ_PMU_PWDCR_PPE_SLL01 (1 << 19) ++#define LTQ_PMU_PWDCR_PPE_QSB (1 << 18) ++#define LTQ_PMU_PWDCR_UART1 (1 << 17) ++#define LTQ_PMU_PWDCR_SDIO (1 << 16) ++#define LTQ_PMU_PWDCR_AHBM (1 << 15) ++#define LTQ_PMU_PWDCR_FPIM (1 << 14) ++#define LTQ_PMU_PWDCR_GPTC (1 << 12) ++#define LTQ_PMU_PWDCR_LEDC (1 << 11) ++#define LTQ_PMU_PWDCR_EBU (1 << 10) ++#define LTQ_PMU_PWDCR_DSL (1 << 9) ++#define LTQ_PMU_PWDCR_SPI (1 << 8) ++#define LTQ_PMU_PWDCR_USIF (1 << 7) ++#define LTQ_PMU_PWDCR_USB0 (1 << 6) ++#define LTQ_PMU_PWDCR_DMA (1 << 5) ++#define LTQ_PMU_PWDCR_DFEV1 (1 << 3) ++#define LTQ_PMU_PWDCR_DFEV0 (1 << 2) ++#define LTQ_PMU_PWDCR_FPIS (1 << 1) ++#define LTQ_PMU_PWDCR_USB0_PHY (1 << 0) ++ ++struct ltq_pmu_regs { ++ u32 rsvd0[7]; ++ u32 pwdcr; /* Power down control */ ++ u32 sr; /* Power down status */ ++ u32 pwdcr1; /* Power down control 1 */ ++ u32 sr1; /* Power down status 1 */ ++}; ++ ++static struct ltq_pmu_regs *ltq_pmu_regs = ++ (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE); ++ ++u32 ltq_pm_map(enum ltq_pm_modules module) ++{ ++ u32 val; ++ ++ switch (module) { ++ case LTQ_PM_CORE: ++ val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM | ++ LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU; ++ break; ++ case LTQ_PM_DMA: ++ val = LTQ_PMU_PWDCR_DMA; ++ break; ++ case LTQ_PM_ETH: ++ val = LTQ_PMU_PWDCR_GPHY | LTQ_PMU_PWDCR_PPE_TOP | ++ LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DPLUS | ++ LTQ_PMU_PWDCR_PPE_DPLUM | LTQ_PMU_PWDCR_PPE_EMA | ++ LTQ_PMU_PWDCR_PPE_TC | LTQ_PMU_PWDCR_PPE_SLL01 | ++ LTQ_PMU_PWDCR_PPE_QSB; ++ break; ++ case LTQ_PM_SPI: ++ val = LTQ_PMU_PWDCR_SPI; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ ++ return val; ++} ++ ++int ltq_pm_enable(enum ltq_pm_modules module) ++{ ++ const unsigned long timeout = 1000; ++ unsigned long timebase; ++ u32 sr, val; ++ ++ val = ltq_pm_map(module); ++ if (unlikely(!val)) ++ return 1; ++ ++ ltq_clrbits(<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,195 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/cpu.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_RCU_RD_GPHY0 (1 << 31) /* GPHY0 */ ++#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */ ++#define LTQ_RCU_RD_GPHY1 (1 << 29) /* GPHY1 */ ++#define LTQ_RCU_RD_ENMIP2 (1 << 28) /* Enable NMI of PLL2 */ ++#define LTQ_RCU_RD_REG25_PD (1 << 26) /* Power down 2.5V regulator */ ++#define LTQ_RCU_RD_ENDINIT (1 << 25) /* FPI slave bus access */ ++#define LTQ_RCU_RD_PPE_ATM_TC (1 << 23) /* PPE ATM TC */ ++#define LTQ_RCU_RD_PCIE (1 << 22) /* PCI-E core */ ++#define LTQ_RCU_RD_ETHSW (1 << 21) /* Ethernet switch */ ++#define LTQ_RCU_RD_DSP_DEN (1 << 20) /* Enable DSP JTAG */ ++#define LTQ_RCU_RD_TDM (1 << 19) /* TDM module interface */ ++#define LTQ_RCU_RD_ENMIP1 (1 << 18) /* Enable NMI of PLL1 */ ++#define LTQ_RCU_RD_SWBCK (1 << 17) /* Switch backward compat */ ++#define LTQ_RCU_RD_HSNAND (1 << 16) /* HSNAND controller */ ++#define LTQ_RCU_RD_ENMIP0 (1 << 15) /* Enable NMI of PLL0 */ ++#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */ ++#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */ ++#define LTQ_RCU_RD_PCIE_PHY (1 << 12) /* PCI-E Phy */ ++#define LTQ_RCU_RD_DFE_CORE (1 << 11) /* DFE core */ ++#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */ ++#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */ ++#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */ ++#define LTQ_RCU_RD_DFE (1 << 7) /* DFE core */ ++#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */ ++#define LTQ_RCU_RD_HRST_CFG (1 << 5) /* HW reset configuration */ ++#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */ ++#define LTQ_RCU_RD_PPE_DSP (1 << 3) /* PPE DSP interface */ ++#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */ ++#define LTQ_RCU_RD_CPU (1 << 1) /* CPU subsystem */ ++#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */ ++ ++#define LTQ_RCU_STAT_BOOT_SHIFT 17 ++#define LTQ_RCU_STAT_BOOT_MASK (0xF << LTQ_RCU_STAT_BOOT_SHIFT) ++#define LTQ_RCU_STAT_BOOT_H (1 << 12) ++ ++#define LTQ_RCU_GP_STRAP_CLOCKSOURCE (1 << 15) ++ ++struct ltq_rcu_regs { ++ u32 rsvd0[4]; ++ u32 req; /* Reset request */ ++ u32 stat; /* Reset status */ ++ u32 usb0_cfg; /* USB0 configure */ ++ u32 gp_strap; /* GPIO strapping */ ++ u32 gfs_add0; /* GPHY0 firmware base addr */ ++ u32 stat2; /* SLIC and USB reset status */ ++ u32 pci_rdy; /* PCI boot ready */ ++ u32 ppe_conf; /* PPE ethernet config */ ++ u32 pcie_phy_con; /* PCIE PHY config/status */ ++ u32 usb1_cfg; /* USB1 configure */ ++ u32 usb_ana_cfg1a; /* USB analog config 1a */ ++ u32 usb_ana_cfg1b; /* USB analog config 1b */ ++ u32 rsvd1; ++ u32 gf_mdio_add; /* GPHY0/1 MDIO address */ ++ u32 req2; /* SLIC and USB reset request */ ++ u32 ahb_endian; /* AHB bus endianess */ ++ u32 rsvd2[4]; ++ u32 gcc; /* General CPU config */ ++ u32 rsvd3; ++ u32 gfs_add1; /* GPHY1 firmware base addr */ ++}; ++ ++static struct ltq_rcu_regs *ltq_rcu_regs = ++ (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE); ++ ++u32 ltq_reset_map(enum ltq_reset_modules module) ++{ ++ u32 val; ++ ++ switch (module) { ++ case LTQ_RESET_CORE: ++ case LTQ_RESET_SOFT: ++ val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU | LTQ_RCU_RD_ENMIP2 | ++ LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0; ++ break; ++ case LTQ_RESET_DMA: ++ val = LTQ_RCU_RD_DMA; ++ break; ++ case LTQ_RESET_ETH: ++ val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW; ++ break; ++ case LTQ_RESET_PHY: ++ val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0; ++ break; ++ case LTQ_RESET_HARD: ++ val = LTQ_RCU_RD_HRST; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ ++ return val; ++} ++ ++int ltq_reset_activate(enum ltq_reset_modules module) ++{ ++ u32 val; ++ ++ val = ltq_reset_map(module); ++ if (unlikely(!val)) ++ return 1; ++ ++ ltq_setbits(<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/cpu/mips32/vrx200/u-boot.lds +@@ -0,0 +1,69 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") ++OUTPUT_ARCH(mips) ++ENTRY(_start) ++SECTIONS ++{ ++ . = 0x00000000; ++ ++ . = ALIGN(4); ++ .text : { ++ *(.text*) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { ++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) ++ } ++ ++ . = ALIGN(4); ++ .data : { ++ *(.data*) ++ } ++ ++ . = ALIGN(4); ++ .sdata : { ++ *(.sdata*) ++ } ++ ++ . = .; ++ _gp = ALIGN(16) + 0x7ff0; ++ ++ .got : { ++ __got_start = .; ++ *(.got) ++ __got_end = .; ++ } ++ ++ num_got_entries = (__got_end - __got_start) >> 2; ++ ++#ifndef CONFIG_SPL_BUILD ++ . = ALIGN(4); ++ .u_boot_list : { ++ #include <u-boot.lst> ++ } ++#endif ++ ++ . = ALIGN(4); ++ __image_copy_end = .; ++ uboot_end_data = .; ++ ++ .bss (NOLOAD) : { ++ __bss_start = .; ++ *(.bss*) ++ *(.sbss*) ++ . = ALIGN(4); ++ __bss_end = .; ++ } ++ ++ . = ALIGN(4); ++ __end = .; ++ uboot_end = .; ++} +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/config.h +@@ -0,0 +1,156 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * Common board configuration for Lantiq XWAY Danube family ++ * ++ * Use following defines in your board config to enable specific features ++ * and drivers for this SoC: ++ * ++ * CONFIG_LTQ_SUPPORT_UART ++ * - support the Danube ASC/UART interface and console ++ * ++ * CONFIG_LTQ_SUPPORT_NOR_FLASH ++ * - support a parallel NOR flash via the CFI interface in flash bank 0 ++ * ++ * CONFIG_LTQ_SUPPORT_ETHERNET ++ * - support the Danube ETOP and MAC interface ++ * ++ * CONFIG_LTQ_SUPPORT_SPI_FLASH ++ * - support the Danube SPI interface and serial flash drivers ++ * - specific SPI flash drivers must be configured separately ++ */ ++ ++#ifndef __DANUBE_CONFIG_H__ ++#define __DANUBE_CONFIG_H__ ++ ++/* CPU and SoC type */ ++#define CONFIG_SOC_LANTIQ ++#define CONFIG_SOC_XWAY_DANUBE ++ ++/* Cache configuration */ ++#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT ++#define CONFIG_SYS_DCACHE_SIZE (16 * 1024) ++#define CONFIG_SYS_ICACHE_SIZE (16 * 1024) ++#define CONFIG_SYS_CACHELINE_SIZE 32 ++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ ++/* ++ * Supported clock modes ++ * PLL0 clock output is 333 MHz ++ * PLL1 clock output is 262.144 MHz ++ */ ++#define LTQ_CLK_CPU_333_DDR_167 0 /* Base PLL0, OCP 2 */ ++#define LTQ_CLK_CPU_111_DDR_111 1 /* Base PLL0, OCP 1 */ ++ ++/* CPU speed */ ++#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_333_DDR_167 ++#define CONFIG_SYS_MIPS_TIMER_FREQ 166666667 ++#define CONFIG_SYS_HZ 1000 ++ ++/* RAM */ ++#define CONFIG_NR_DRAM_BANKS 1 ++#define CONFIG_SYS_SDRAM_BASE 0x80000000 ++#define CONFIG_SYS_MEMTEST_START 0x81000000 ++#define CONFIG_SYS_MEMTEST_END 0x82000000 ++#define CONFIG_SYS_LOAD_ADDR 0x81000000 ++#define CONFIG_SYS_INIT_SP_OFFSET 0x4000 ++ ++/* SRAM */ ++#define CONFIG_SYS_SRAM_BASE 0xBE180000 ++#define CONFIG_SYS_SRAM_SIZE 0x10000 ++ ++/* ASC/UART driver and console */ ++#define CONFIG_LANTIQ_SERIAL ++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } ++ ++/* GPIO */ ++#define CONFIG_LANTIQ_GPIO ++#define CONFIG_LTQ_GPIO_MAX_BANKS 2 ++ ++/* FLASH driver */ ++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) ++#define CONFIG_SYS_MAX_FLASH_BANKS 1 ++#define CONFIG_SYS_MAX_FLASH_SECT 256 ++#define CONFIG_SYS_FLASH_BASE 0xB0000000 ++#define CONFIG_FLASH_16BIT ++#define CONFIG_SYS_FLASH_CFI ++#define CONFIG_FLASH_CFI_DRIVER ++#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT ++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE ++#define CONFIG_FLASH_SHOW_PROGRESS 50 ++#define CONFIG_SYS_FLASH_PROTECTION ++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP ++ ++#define CONFIG_CMD_FLASH ++#else ++#define CONFIG_SYS_NO_FLASH ++#endif /* CONFIG_NOR_FLASH */ ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH) ++#define CONFIG_LANTIQ_SPI ++#define CONFIG_SPI_FLASH ++ ++#define CONFIG_CMD_SF ++#define CONFIG_CMD_SPI ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET) ++#define CONFIG_LANTIQ_DMA ++#define CONFIG_LANTIQ_DANUBE_ETOP ++ ++#define CONFIG_PHYLIB ++#define CONFIG_MII ++ ++#define CONFIG_CMD_MII ++#define CONFIG_CMD_NET ++#endif ++ ++#define CONFIG_SPL_MAX_SIZE (32 * 1024) ++#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024) ++#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024) ++#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024) ++/*#define CONFIG_SPL_STACK_BSS_IN_SRAM*/ ++ ++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM) ++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \ ++ CONFIG_SPL_MAX_SIZE + \ ++ CONFIG_SPL_STACK_MAX_SIZE - 1) ++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1) ++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \ ++ CONFIG_SYS_INIT_SP_OFFSET) ++#else ++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \ ++ CONFIG_SYS_INIT_SP_OFFSET + \ ++ CONFIG_SPL_STACK_MAX_SIZE - 1) ++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1) ++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \ ++ CONFIG_SPL_BSS_MAX_SIZE) ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_RAM) ++#define CONFIG_SYS_TEXT_BASE 0xa0100000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_SYS_TEXT_BASE 0xB0000000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SPL_TEXT_BASE 0xB0000000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C ++#define CONFIG_XWAY_SWAP_BYTES ++#endif ++ ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE ++ ++#endif /* __DANUBE_CONFIG_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/gpio.h +@@ -0,0 +1,13 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __DANUBE_GPIO_H__ ++#define __DANUBE_GPIO_H__ ++ ++#include <asm/lantiq/gpio.h> ++ ++#endif /* __DANUBE_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/soc.h +@@ -0,0 +1,40 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __DANUBE_SOC_H__ ++#define __DANUBE_SOC_H__ ++ ++#define LTQ_ASC0_BASE 0x1E100400 ++#define LTQ_SPI_BASE 0x1E100800 ++#define LTQ_GPIO_BASE 0x1E100B00 ++#define LTQ_SSIO_BASE 0x1E100BB0 ++#define LTQ_ASC1_BASE 0x1E100C00 ++#define LTQ_DMA_BASE 0x1E104100 ++ ++#define LTQ_EBU_BASE 0x1E105300 ++#define LTQ_EBU_REGION0_BASE 0x10000000 ++#define LTQ_EBU_REGION0_SIZE (64 * 1024 * 1024) ++#define LTQ_EBU_REGION1_BASE 0x14000000 ++#define LTQ_EBU_REGION1_SIZE (32 * 1024 * 1024) ++ ++#define LTQ_PPE_BASE 0x1E180000 ++#define LTQ_PPE_ETOP_BASE (LTQ_PPE_BASE + 0x11800) ++#define LTQ_PPE_ENET0_BASE (LTQ_PPE_BASE + 0x11840) ++ ++#define LTQ_PMU_BASE 0x1F102000 ++#define LTQ_CGU_BASE 0x1F103000 ++#define LTQ_MPS_BASE 0x1F107000 ++#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340) ++#define LTQ_RCU_BASE 0x1F203000 ++ ++#define LTQ_MC_GEN_BASE 0x1F800000 ++#define LTQ_MC_SDR_BASE 0x1F800200 ++#define LTQ_MC_DDR_BASE 0x1F801000 ++#define LTQ_MC_DDR_DC_OFFSET(x) (x * 0x10) ++ ++#endif /* __DANUBE_SOC_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/config.h +@@ -0,0 +1,185 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * Common board configuration for Lantiq XWAY VRX200 family ++ * ++ * Use following defines in your board config to enable specific features ++ * and drivers for this SoC: ++ * ++ * CONFIG_LTQ_SUPPORT_UART ++ * - support the VRX200 ASC/UART interface and console ++ * ++ * CONFIG_LTQ_SUPPORT_NOR_FLASH ++ * - support a parallel NOR flash via the CFI interface in flash bank 0 ++ * ++ * CONFIG_LTQ_SUPPORT_SPI_FLASH ++ * - support the VRX200 SPI interface and serial flash drivers ++ * - specific SPI flash drivers must be configured separately ++ * ++ * CONFIG_LTQ_SUPPORT_ETHERNET ++ * - support the VRX200 internal switch ++ * ++ * CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH ++ * - build a preloader that runs in the internal SRAM and loads ++ * the U-Boot from SPI flash into RAM ++ */ ++ ++#ifndef __VRX200_CONFIG_H__ ++#define __VRX200_CONFIG_H__ ++ ++/* CPU and SoC type */ ++#define CONFIG_SOC_LANTIQ ++#define CONFIG_SOC_XWAY_VRX200 ++ ++/* Cache configuration */ ++#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT ++#define CONFIG_SYS_DCACHE_SIZE (32 * 1024) ++#define CONFIG_SYS_ICACHE_SIZE (32 * 1024) ++#define CONFIG_SYS_CACHELINE_SIZE 32 ++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ ++/* ++ * Supported clock modes ++ * PLL0 clock output is 1000 MHz ++ * PLL1 clock output is 393.219 MHz ++ */ ++#define LTQ_CLK_CPU_600_DDR_300 0 /* Base PLL0, OCP 2 */ ++#define LTQ_CLK_CPU_600_DDR_200 1 /* Base PLL0, OCP 3 */ ++#define LTQ_CLK_CPU_500_DDR_250 2 /* Base PLL0, OCP 2 */ ++#define LTQ_CLK_CPU_500_DDR_200 3 /* Base PLL0, OCP 2.5 */ ++#define LTQ_CLK_CPU_333_DDR_167 4 /* Base PLL0, OCP 2 */ ++#define LTQ_CLK_CPU_167_DDR_167 5 /* Base PLL0, OCP 1 */ ++#define LTQ_CLK_CPU_125_DDR_125 6 /* Base PLL0, OCP 1 */ ++#define LTQ_CLK_CPU_393_DDR_197 7 /* Base PLL1, OCP 2 */ ++#define LTQ_CLK_CPU_197_DDR_197 8 /* Base PLL1, OCP 1 */ ++ ++/* CPU speed */ ++#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_500_DDR_250 ++#define CONFIG_SYS_MIPS_TIMER_FREQ 250000000 ++#define CONFIG_SYS_HZ 1000 ++ ++/* RAM */ ++#define CONFIG_NR_DRAM_BANKS 1 ++#define CONFIG_SYS_SDRAM_BASE 0x80000000 ++#define CONFIG_SYS_SDRAM_BASE_UC 0xa0000000 ++#define CONFIG_SYS_MEMTEST_START 0x81000000 ++#define CONFIG_SYS_MEMTEST_END 0x82000000 ++#define CONFIG_SYS_LOAD_ADDR 0x81000000 ++#define CONFIG_SYS_INIT_SP_OFFSET (32 * 1024) ++ ++/* SRAM */ ++#define CONFIG_SYS_SRAM_BASE 0xBE220000 ++#define CONFIG_SYS_SRAM_SIZE 0x10000 ++ ++/* ASC/UART driver and console */ ++#define CONFIG_LANTIQ_SERIAL ++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } ++ ++/* GPIO */ ++#define CONFIG_LANTIQ_GPIO ++#define CONFIG_LTQ_GPIO_MAX_BANKS 3 ++#define CONFIG_LTQ_HAS_GPIO_BANK3 ++ ++/* FLASH driver */ ++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) ++#define CONFIG_SYS_MAX_FLASH_BANKS 1 ++#define CONFIG_SYS_MAX_FLASH_SECT 256 ++#define CONFIG_SYS_FLASH_BASE 0xB0000000 ++#define CONFIG_FLASH_16BIT ++#define CONFIG_SYS_FLASH_CFI ++#define CONFIG_FLASH_CFI_DRIVER ++#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT ++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE ++#define CONFIG_FLASH_SHOW_PROGRESS 50 ++#define CONFIG_SYS_FLASH_PROTECTION ++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP ++ ++#define CONFIG_CMD_FLASH ++#else ++#define CONFIG_SYS_NO_FLASH ++#endif /* CONFIG_NOR_FLASH */ ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH) ++#define CONFIG_LANTIQ_SPI ++#define CONFIG_SPI_FLASH ++ ++#define CONFIG_CMD_SF ++#define CONFIG_CMD_SPI ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH) ++#define CONFIG_NAND_LANTIQ ++#define CONFIG_SYS_MAX_NAND_DEVICE 1 ++#define CONFIG_SYS_NAND_BASE 0xB4000000 ++ ++#define CONFIG_CMD_NAND ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET) ++#define CONFIG_LANTIQ_DMA ++#define CONFIG_LANTIQ_VRX200_SWITCH ++#define CONFIG_PHY_LANTIQ ++ ++#define CONFIG_SYS_RX_ETH_BUFFER 8 ++#define CONFIG_PHYLIB ++#define CONFIG_MII ++#define CONFIG_UDP_CHECKSUM ++ ++#define CONFIG_CMD_MII ++#define CONFIG_CMD_NET ++#endif ++ ++#define CONFIG_SPL_MAX_SIZE (32 * 1024) ++#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024) ++#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024) ++#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024) ++#define CONFIG_SPL_STACK_BSS_IN_SRAM ++ ++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM) ++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \ ++ CONFIG_SPL_MAX_SIZE + \ ++ CONFIG_SPL_STACK_MAX_SIZE - 1) ++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1) ++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \ ++ CONFIG_SYS_INIT_SP_OFFSET) ++#else ++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \ ++ CONFIG_SYS_INIT_SP_OFFSET + \ ++ CONFIG_SPL_STACK_MAX_SIZE - 1) ++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1) ++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \ ++ CONFIG_SPL_BSS_MAX_SIZE) ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_RAM) ++#define CONFIG_SYS_TEXT_BASE 0xA0100000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_SYS_TEXT_BASE 0xB0000000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_SFSPL) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SPL_TEXT_BASE 0xBE220000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SPL_TEXT_BASE 0xB0000000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C ++#define CONFIG_XWAY_SWAP_BYTES ++#endif ++ ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE ++ ++#endif /* __VRX200_CONFIG_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/gphy.h +@@ -0,0 +1,66 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __VRX200_GPHY_H__ ++#define __VRX200_GPHY_H__ ++ ++enum ltq_gphy_clk { ++ /* XTAL 36 MHz input */ ++ LTQ_GPHY_CLK_36MHZ_XTAL = 1, ++ /* 25 MHz from PLL0 with divider */ ++ LTQ_GPHY_CLK_25MHZ_PLL0 = 2, ++ /* derived from PLL2 output (XTAL is 36 MHz) */ ++ LTQ_GPHY_CLK_24MHZ_PLL2 = 3, ++ /* 25 MHz Clock from Pin GPIO3 */ ++ LTQ_GPHY_CLK_25MHZ_GPIO3 = 4, ++}; ++ ++/* ++ * Load PHY11G firmware for VRX200 v1.1 to given RAM address ++ * ++ * Address must be 16k aligned! ++ */ ++extern void ltq_gphy_phy11g_a1x_load(ulong addr); ++ ++/* ++ * Load PHY11G firmware for VRX200 v1.2 to given RAM address ++ * ++ * Address must be 16k aligned! ++ */ ++extern void ltq_gphy_phy11g_a2x_load(ulong addr); ++ ++/* ++ * Load PHY22F firmware for VRX200 v1.1 to given RAM address ++ * ++ * Address must be 16k aligned! ++ */ ++extern void ltq_gphy_phy22f_a1x_load(ulong addr); ++ ++/* ++ * Load PHY22F firmware for VRX200 v1.2 to given RAM address ++ * ++ * Address must be 16k aligned! ++ */ ++extern void ltq_gphy_phy22f_a2x_load(ulong addr); ++ ++/* ++ * Set clock source of internal GPHYs ++ * ++ * According registers resides in CGU address space. Thus this function ++ * is implemented by the CGU driver. ++ */ ++extern void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk); ++ ++/* ++ * Boot internal GPHY with id from given RAM address ++ * ++ * According registers resides in RCU address space. Thus this function ++ * is implemented by the RCU driver. ++ */ ++extern void ltq_rcu_gphy_boot(unsigned int id, ulong addr); ++ ++#endif /* __VRX200_GPHY_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/gpio.h +@@ -0,0 +1,13 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __VRX200_GPIO_H__ ++#define __VRX200_GPIO_H__ ++ ++#include <asm/lantiq/gpio.h> ++ ++#endif /* __VRX200_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/nand.h +@@ -0,0 +1,14 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#ifndef __VRX200_NAND_H__ ++#define __VRX200_NAND_H__ ++ ++struct nand_chip; ++int ltq_nand_init(struct nand_chip *nand); ++ ++#endif /* __VRX200_NAND_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/soc.h +@@ -0,0 +1,46 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __VRX200_SOC_H__ ++#define __VRX200_SOC_H__ ++ ++#define LTQ_ASC0_BASE 0x1E100400 ++#define LTQ_SPI_BASE 0x1E100800 ++#define LTQ_GPIO_BASE 0x1E100B00 ++#define LTQ_SSIO_BASE 0x1E100BB0 ++#define LTQ_ASC1_BASE 0x1E100C00 ++#define LTQ_DMA_BASE 0x1E104100 ++ ++#define LTQ_EBU_BASE 0x1E105300 ++#define LTQ_EBU_REGION0_BASE 0x10000000 ++#define LTQ_EBU_REGION1_BASE 0x14000000 ++#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0) ++ ++#define LTQ_SWITCH_BASE 0x1E108000 ++#define LTQ_SWITCH_CORE_BASE LTQ_SWITCH_BASE ++#define LTQ_SWITCH_TOP_PDI_BASE LTQ_SWITCH_CORE_BASE ++#define LTQ_SWITCH_BM_PDI_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x40) ++#define LTQ_SWITCH_MAC_PDI_0_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x900) ++#define LTQ_SWITCH_MAC_PDI_X_BASE(x) (LTQ_SWITCH_MAC_PDI_0_BASE + x * 0x30) ++#define LTQ_SWITCH_TOPLEVEL_BASE (LTQ_SWITCH_BASE + 4 * 0xC40) ++#define LTQ_SWITCH_MDIO_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE) ++#define LTQ_SWITCH_MII_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x36) ++#define LTQ_SWITCH_PMAC_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x82) ++ ++#define LTQ_PMU_BASE 0x1F102000 ++#define LTQ_CGU_BASE 0x1F103000 ++#define LTQ_DCDC_BASE 0x1F106A00 ++#define LTQ_MPS_BASE 0x1F107000 ++#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340) ++#define LTQ_RCU_BASE 0x1F203000 ++ ++#define LTQ_MC_GLOBAL_BASE 0x1F400000 ++#define LTQ_MC_DDR_BASE 0x1F401000 ++#define LTQ_MC_DDR_CCR_OFFSET(x) (x * 0x10) ++ ++#endif /* __VRX200_SOC_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/switch.h +@@ -0,0 +1,514 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com> ++ */ ++ ++#ifndef __VR9_SWITCH_H__ ++#define __VR9_SWITCH_H__ ++ ++/* Switch core registers */ ++struct vr9_switch_core_regs { ++ __be32 swres; ++ /* TODO: implement registers */ ++ __be32 rsvd0[0x3f]; ++}; ++ ++/* Switch buffer management registers */ ++struct vr9_switch_bm_regs { ++ struct bm_core { ++ __be32 ram_val3; /* RAM value 3 */ ++ __be32 ram_val2; /* RAM value 2 */ ++ __be32 ram_val1; /* RAM value 1 */ ++ __be32 ram_val0; /* RAM value 0 */ ++ __be32 ram_addr; /* RAM address */ ++ __be32 ram_ctrl; /* RAM access control */ ++ __be32 fsqm_gctrl; /* Free segment queue global control */ ++ __be32 cons_sel; /* Number of consumed segments */ ++ __be32 cons_pkt; /* Number of consumed packet pointers */ ++ __be32 gctrl; /* Global control */ ++ __be32 queue_gctrl; /* Queue manager global control */ ++ /* TODO: implement registers */ ++ __be32 rsvd0[0x35]; ++ } core; ++ ++ struct bm_port { ++ __be32 pcfg; /* Port config */ ++ __be32 rmon_ctrl; /* RMON control */ ++ } port[13]; ++ ++ __be32 rsvd0[0x66]; ++ ++ struct bm_queue { ++ __be32 rsvd0; ++ __be32 pqm_rs; /* Packet queue manager rate shape assignment */ ++ } queue[32]; ++ ++ struct bm_shaper { ++ __be32 ctrl; /* Rate shaper control */ ++ __be32 cbs; /* Rate shaper committed burst size */ ++ __be32 ibs; /* Rate shaper instantaneous burst size */ ++ __be32 cir_ext; /* Rate shaper rate exponent */ ++ __be32 cir_mant; /* Rate shaper rate mantissa */ ++ } shaper[16]; ++ ++ __be32 rsvd1[0x2a8]; ++}; ++ ++/* Switch parser and classification engine registers */ ++struct vr9_switch_pce_regs { ++ struct pce_core { ++ __be32 tbl_key[16]; /* Table key data */ ++ __be32 tbl_mask; /* Table mask */ ++ __be32 tbl_val[5]; /* Table value */ ++ __be32 tbl_addr; /* Table entry address */ ++ __be32 tbl_ctrl; /* Table access control */ ++ __be32 tbl_stat; /* Table general status */ ++ __be32 age_0; /* Aging counter config 0 */ ++ __be32 age_1; /* Aging counter config 1 */ ++ __be32 pmap_1; /* Port map (monitoring) */ ++ __be32 pmap_2; /* Port map (multicast) */ ++ __be32 pmap_3; /* Port map (unknown unicast) */ ++ __be32 gctrl_0; /* Global control 0 */ ++ __be32 gctrl_1; /* Global control 1 */ ++ __be32 tcm_gctrl; /* Three-color marker global control */ ++ __be32 igmp_ctrl; /* IGMP control */ ++ __be32 igmp_drpm; /* IGMP default router port map */ ++ __be32 igmp_age_0; /* IGMP aging 0 */ ++ __be32 igmp_age_1; /* IGMP aging 1 */ ++ __be32 igmp_stat; /* IGMP status */ ++ __be32 wol_gctrl; /* Wake-on-LAN control */ ++ __be32 wol_da_0; /* Wake-on-LAN destination address 0 */ ++ __be32 wol_da_1; /* Wake-on-LAN destination address 1 */ ++ __be32 wol_da_2; /* Wake-on-LAN destination address 2 */ ++ __be32 wol_pw_0; /* Wake-on-LAN password 0 */ ++ __be32 wol_pw_1; /* Wake-on-LAN password 1 */ ++ __be32 wol_pw_2; /* Wake-on-LAN password 2 */ ++ __be32 ier_0; /* PCE global interrupt enable 0 */ ++ __be32 ier_1; /* PCE global interrupt enable 1 */ ++ __be32 isr_0; /* PCE global interrupt status 0 */ ++ __be32 isr_1; /* PCE global interrupt status 1 */ ++ __be32 parser_stat; /* Parser status */ ++ __be32 rsvd0[0x6]; ++ } core; ++ ++ __be32 rsvd0[0x10]; ++ ++ struct pce_port { ++ __be32 pctrl_0; /* Port control 0 */ ++ __be32 pctrl_1; /* Port control 1 */ ++ __be32 pctrl_2; /* Port control 2 */ ++ __be32 pctrl_3; /* Port control 3 */ ++ __be32 wol_ctrl; /* Wake-on-LAN control */ ++ __be32 vlan_ctrl; /* VLAN control */ ++ __be32 def_pvid; /* Default port VID */ ++ __be32 pstat; /* Port status */ ++ __be32 pier; /* Interrupt enable */ ++ __be32 pisr; /* Interrupt status */ ++ } port[13]; ++ ++ __be32 rsvd1[0x7e]; ++ ++ struct pce_meter { ++ /* TODO: implement registers */ ++ __be32 rsvd0[0x7]; ++ } meter[8]; ++ ++ __be32 rsvd2[0x308]; ++}; ++ ++static inline unsigned int to_pce_tbl_key_id(unsigned int id) ++{ ++ BUG_ON(id > 15); ++ ++ return 15 - id; ++} ++ ++static inline unsigned int to_pce_tbl_value_id(unsigned int id) ++{ ++ BUG_ON(id > 4); ++ ++ return 4 - id; ++} ++ ++/* Switch ethernet MAC registers */ ++struct vr9_switch_mac_regs { ++ struct mac_core { ++ __be32 test; /* MAC test */ ++ __be32 pfad_cfg; /* Pause frame source address config */ ++ __be32 pfsa_0; /* Pause frame source address 0 */ ++ __be32 pfsa_1; /* Pause frame source address 1 */ ++ __be32 pfsa_2; /* Pause frame source address 2 */ ++ __be32 flen; /* Frame length */ ++ __be32 vlan_etype_0; /* VLAN ethertype 0 */ ++ __be32 vlan_etype_1; /* VLAN ethertype 1 */ ++ __be32 ier; /* Interrupt enable */ ++ __be32 isr; /* Interrupt status */ ++ __be32 rsvd0[0x36]; ++ } core; ++ ++ struct mac_port { ++ __be32 pstat; /* Port status */ ++ __be32 pisr; /* Interrupt status */ ++ __be32 pier; /* Interrupt enable */ ++ __be32 ctrl_0; /* Control 0 */ ++ __be32 ctrl_1; /* Control 1 */ ++ __be32 ctrl_2; /* Control 2 */ ++ __be32 ctrl_3; /* Control 3 */ ++ __be32 ctrl_4; /* Control 4 */ ++ __be32 ctrl_5; /* Control 5 */ ++ __be32 rsvd0[0x2]; ++ __be32 testen; /* Test enable */ ++ } port[13]; ++ ++ __be32 rsvd0[0xa4]; ++}; ++ ++/* Switch Fetch DMA registers */ ++struct vr9_switch_fdma_regs { ++ struct fdma_core { ++ __be32 ctrl; /* FDMA control */ ++ __be32 stetype; /* Special tag ethertype control */ ++ __be32 vtetype; /* VLAN tag ethertype control */ ++ __be32 stat; /* FDMA status */ ++ __be32 ier; /* FDMA interrupt enable */ ++ __be32 isr; /* FDMA interrupt status */ ++ } core; ++ ++ __be32 rsvd0[0x3a]; ++ ++ struct fdma_port { ++ __be32 pctrl; /* Port control */ ++ __be32 prio; /* Port priority */ ++ __be32 pstat_0; /* Port status 0 */ ++ __be32 pstat_1; /* Port status 1 */ ++ __be32 tstamp_0; /* Egress time stamp 0 */ ++ __be32 tstamp_1; /* Egress time stamp 1 */ ++ } port[13]; ++ ++ __be32 rsvd1[0x72]; ++}; ++ ++/* Switch Store DMA registers */ ++struct vr9_switch_sdma_regs { ++ struct sdma_core { ++ __be32 ctrl; /* SDMA Control */ ++ __be32 fcthr_1; /* Flow control threshold 1 */ ++ __be32 rsvd0; ++ __be32 fcthr_3; /* Flow control threshold 3 */ ++ __be32 fcthr_4; /* Flow control threshold 4 */ ++ __be32 fcthr_5; /* Flow control threshold 5 */ ++ __be32 fcthr_6; /* Flow control threshold 6 */ ++ __be32 fcthr_7; /* Flow control threshold 7 */ ++ __be32 stat_0; /* SDMA status 0 */ ++ __be32 stat_1; /* SDMA status 1 */ ++ __be32 stat_2; /* SDMA status 2 */ ++ __be32 ier; /* SDMA interrupt enable */ ++ __be32 isr; /* SDMA interrupt status */ ++ } core; ++ ++ __be32 rsvd0[0x73]; ++ ++ struct sdma_port { ++ __be32 pctrl; /* Port control */ ++ __be32 prio; /* Port priority */ ++ __be32 pstat_0; /* Port status 0 */ ++ __be32 pstat_1; /* Port status 1 */ ++ __be32 tstamp_0; /* Ingress time stamp 0 */ ++ __be32 tstamp_1; /* Ingress time stamp 1 */ ++ } port[13]; ++ ++ __be32 rsvd1[0x32]; ++}; ++ ++/* Switch MDIO control and status registers */ ++struct vr9_switch_mdio_regs { ++ __be32 glob_ctrl; /* Global control 0 */ ++ __be32 rsvd0[7]; ++ __be32 mdio_ctrl; /* MDIO control */ ++ __be32 mdio_read; /* MDIO read data */ ++ __be32 mdio_write; /* MDIO write data */ ++ __be32 mdc_cfg_0; /* MDC clock configuration 0 */ ++ __be32 mdc_cfg_1; /* MDC clock configuration 1 */ ++ __be32 rsvd1[0x3]; ++ __be32 phy_addr[6]; /* PHY address port 5..0 */ ++ __be32 mdio_stat[6]; /* MDIO PHY polling status port 0..5 */ ++ __be32 aneg_eee[6]; /* EEE auto-neg overrides port 0..5 */ ++ __be32 rsvd2[0x14]; ++}; ++ ++static inline unsigned int to_mdio_phyaddr_id(unsigned int id) ++{ ++ BUG_ON(id > 5); ++ ++ return 5 - id; ++} ++ ++/* Switch xMII control registers */ ++struct vr9_switch_mii_regs { ++ __be32 mii_cfg0; /* xMII port 0 configuration */ ++ __be32 pcdu0; /* Port 0 clock delay configuration */ ++ __be32 mii_cfg1; /* xMII port 1 configuration */ ++ __be32 pcdu1; /* Port 1 clock delay configuration */ ++ __be32 rsvd0[0x6]; ++ __be32 mii_cfg5; /* xMII port 5 configuration */ ++ __be32 pcdu5; /* Port 5 clock delay configuration */ ++ __be32 rsvd1[0x14]; ++ __be32 rxb_ctl_0; /* Port 0 receive buffer control */ ++ __be32 rxb_ctl_1; /* Port 1 receive buffer control */ ++ __be32 rxb_ctl_5; /* Port 5 receive buffer control */ ++ __be32 rsvd2[0x28]; ++ __be32 dbg_ctl; /* Debug control */ ++}; ++ ++/* Switch Pseudo-MAC registers */ ++struct vr9_switch_pmac_regs { ++ __be32 hd_ctl; /* PMAC header control */ ++ __be32 tl; /* PMAC type/length */ ++ __be32 sa1; /* PMAC source address 1 */ ++ __be32 sa2; /* PMAC source address 2 */ ++ __be32 sa3; /* PMAC source address 3 */ ++ __be32 da1; /* PMAC destination address 1 */ ++ __be32 da2; /* PMAC destination address 2 */ ++ __be32 da3; /* PMAC destination address 3 */ ++ __be32 vlan; /* PMAC VLAN */ ++ __be32 rx_ipg; /* PMAC interpacket gap in RX direction */ ++ __be32 st_etype; /* PMAC special tag ethertype */ ++ __be32 ewan; /* PMAC ethernet WAN group */ ++ __be32 ctl; /* PMAC control */ ++ __be32 rsvd0[0x2]; ++}; ++ ++struct vr9_switch_regs { ++ struct vr9_switch_core_regs core; ++ struct vr9_switch_bm_regs bm; ++ struct vr9_switch_pce_regs pce; ++ struct vr9_switch_mac_regs mac; ++ struct vr9_switch_fdma_regs fdma; ++ struct vr9_switch_sdma_regs sdma; ++ struct vr9_switch_mdio_regs mdio; ++ struct vr9_switch_mii_regs mii; ++ struct vr9_switch_pmac_regs pmac; ++}; ++ ++static inline void *to_pce_tbl_key(struct vr9_switch_regs *regs, ++ unsigned int id) ++{ ++ return ®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 +--- a/arch/mips/include/asm/asm.h ++++ b/arch/mips/include/asm/asm.h +@@ -53,6 +53,7 @@ + .align 2; \ + .type symbol, @function; \ + .ent symbol, 0; \ ++ .section .text.symbol,"x"; \ + symbol: .frame sp, 0, ra + + /* +@@ -62,7 +63,8 @@ symbol: .frame sp, 0, ra + .globl symbol; \ + .align 2; \ + .type symbol, @function; \ +- .ent symbol, 0; \ ++ .ent symbol, 0; \ ++ .section .text.symbol,"x"; \ + symbol: .frame sp, framesize, rpc + + /* +--- /dev/null ++++ b/arch/mips/include/asm/gpio.h +@@ -0,0 +1,7 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <asm/arch/gpio.h> ++#include <asm-generic/gpio.h> +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/chipid.h +@@ -0,0 +1,74 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_CHIPID_H__ ++#define __LANTIQ_CHIPID_H__ ++ ++enum ltq_chip_partnum { ++ LTQ_SOC_UNKNOWN = 0, ++ LTQ_SOC_VRX288_2 = 0x000B, /* VRX288 v1.2 */ ++ LTQ_SOC_VRX268_2 = 0x000C, /* VRX268 v1.2 */ ++ LTQ_SOC_GRX288_2 = 0x000D, /* GRX288 v1.2 */ ++ LTQ_SOC_DANUBE = 0x0129, ++ LTQ_SOC_DANUBE_S = 0x012B, ++ LTQ_SOC_TWINPASS = 0x012D, ++ LTQ_SOC_VRX288 = 0x01C0, /* VRX288 v1.1 */ ++ LTQ_SOC_VRX268 = 0x01C2, /* VRX268 v1.1 */ ++ LTQ_SOC_GRX288 = 0x01C9, /* GRX288 v1.1 */ ++}; ++ ++extern unsigned int ltq_chip_version_get(void); ++extern unsigned int ltq_chip_partnum_get(void); ++extern const char *ltq_chip_partnum_str(void); ++ ++extern void ltq_chip_print_info(void); ++ ++#ifdef CONFIG_SOC_XWAY_DANUBE ++static inline int ltq_soc_is_danube(void) ++{ ++ return 1; ++} ++#else ++static inline int ltq_soc_is_danube(void) ++{ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_SOC_XWAY_VRX200 ++static inline int ltq_soc_is_vrx200(void) ++{ ++ return 1; ++} ++ ++static inline int ltq_soc_is_vrx200_v1(void) ++{ ++ return ltq_chip_version_get() == 1; ++} ++ ++static inline int ltq_soc_is_vrx200_v2(void) ++{ ++ return ltq_chip_version_get() == 2; ++} ++#else ++static inline int ltq_soc_is_vrx200(void) ++{ ++ return 0; ++} ++ ++static inline int ltq_soc_is_vrx200_v1(void) ++{ ++ return 0; ++} ++ ++static inline int ltq_soc_is_vrx200_v2(void) ++{ ++ return 0; ++} ++#endif ++ ++#endif /* __LANTIQ_CHIPID_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/clk.h +@@ -0,0 +1,33 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * Based on Lantiq port in Linux kernel ++ */ ++ ++#ifndef __LANTIQ_CLK_H__ ++#define __LANTIQ_CLK_H__ ++ ++/* Symbolic clock speeds */ ++enum ltq_clk { ++ CLOCK_83_MHZ = 83333333, ++ CLOCK_111_MHZ = 111111111, ++ CLOCK_125_MHZ = 125000000, ++ CLOCK_133_MHZ = 133333333, ++ CLOCK_166_MHZ = 166666667, ++ CLOCK_197_MHZ = 197000000, ++ CLOCK_333_MHZ = 333333333, ++ CLOCK_393_MHZ = 393219000, ++ CLOCK_500_MHZ = 500000000, ++ CLOCK_600_MHZ = 600000000, ++ CLOCK_1000_MHZ = 1000000000, ++}; ++ ++extern unsigned long ltq_get_cpu_clock(void); ++extern unsigned long ltq_get_bus_clock(void); ++extern unsigned long ltq_get_io_region_clock(void); ++ ++#endif /* __LANTIQ_CLK_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/config.h +@@ -0,0 +1,166 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_CONFIG_H__ ++#define __LANTIQ_CONFIG_H__ ++ ++/* Memory usage */ ++#define CONFIG_SYS_MAXARGS 24 ++#define CONFIG_SYS_MALLOC_LEN 1024*1024 ++#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024 ++ ++/* Command line */ ++#define CONFIG_SYS_PROMPT CONFIG_MACH_TYPE " # " ++#define CONFIG_SYS_CBSIZE 512 ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ ++ sizeof(CONFIG_SYS_PROMPT)+16) ++ ++#define CONFIG_SYS_HUSH_PARSER ++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " ++ ++/* ++ * Enable advanced console features on demand to reduce ++ * flash and RAM footprint ++ */ ++#if defined(CONFIG_LTQ_ADVANCED_CONSOLE) ++#define CONFIG_SYS_LONGHELP ++#define CONFIG_AUTO_COMPLETE ++#define CONFIG_CMDLINE_EDITING ++#endif ++ ++/* SPI flash SPL */ ++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL) ++#define CONFIG_SPL ++#define CONFIG_SPL_SPI_SUPPORT ++#define CONFIG_SPL_SPI_FLASH_SUPPORT ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SPL ++#endif ++ ++/* Common SPL */ ++#if defined(CONFIG_SPL) ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SPL_LIBGENERIC_SUPPORT ++#define CONFIG_SPL_GPIO_SUPPORT ++#define CONFIG_SPL_START_S_PATH \ ++ "arch/mips/cpu/mips32/lantiq-common" ++#define CONFIG_SPL_LDSCRIPT \ ++ "arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds" ++#endif ++ ++#if defined(CONFIG_LTQ_SPL_CONSOLE) ++#define CONFIG_SPL_SERIAL_SUPPORT ++#define CONFIG_SPL_LIBCOMMON_SUPPORT ++#endif ++ ++#if defined(CONFIG_LTQ_SPL_COMP_LZMA) ++#define CONFIG_LZMA ++#define CONFIG_SPL_LZMA_SUPPORT ++#endif ++ ++#if defined(CONFIG_LTQ_SPL_COMP_LZO) ++#define CONFIG_LZO ++#define CONFIG_SPL_LZO_SUPPORT ++#endif ++ ++/* Basic commands */ ++#define CONFIG_CMD_BDI ++#define CONFIG_CMD_EDITENV ++#define CONFIG_CMD_IMI ++#define CONFIG_CMD_MEMORY ++#define CONFIG_CMD_RUN ++#define CONFIG_CMD_SAVEENV ++#define CONFIG_CMD_LOADS ++#define CONFIG_CMD_LOADB ++ ++/* Other U-Boot settings */ ++#define CONFIG_UBOOT_VERSION ++#define CONFIG_TIMESTAMP ++ ++/* Default environment */ ++#define CONFIG_ENV_CONSOLEDEV \ ++ "consoledev=" CONFIG_CONSOLE_DEV "\0" ++ ++#define CONFIG_ENV_ADDCONSOLE \ ++ "addconsole=setenv bootargs $bootargs" \ ++ " console=$consoledev,$baudrate\0" ++ ++#if defined(CONFIG_NET_DEV) ++#define CONFIG_ENV_NETDEV \ ++ "netdev=" CONFIG_NET_DEV "\0" ++#else ++#define CONFIG_ENV_NETDEV \ ++ "netdev=eth0\0" ++#endif ++ ++#define CONFIG_ENV_ADDIP \ ++ "addip=setenv bootargs $bootargs" \ ++ " ip=$ipaddr:$serverip::::$netdev:off\0" ++ ++#define CONFIG_ENV_ADDETH \ ++ "addeth=setenv bootargs $bootargs" \ ++ " ethaddr=$ethaddr\0" ++ ++#define CONFIG_ENV_ADDMACHTYPE \ ++ "addmachtype=setenv bootargs $bootargs" \ ++ " machtype=" CONFIG_MACH_TYPE "\0" ++ ++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) ++#define CONFIG_ENV_WRITE_UBOOT_NOR \ ++ "write-uboot-nor=" \ ++ "protect off " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \ ++ "erase " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \ ++ "cp.b $fileaddr " __stringify(CONFIG_SYS_FLASH_BASE) " $filesize\0" ++ ++#define CONFIG_ENV_LOAD_UBOOT_NOR \ ++ "load-uboot-nor=tftpboot u-boot.bin\0" \ ++ "load-uboot-norspl=tftpboot u-boot.ltq.norspl\0" \ ++ "load-uboot-norspl-lzo=tftpboot u-boot.ltq.lzo.norspl\0" \ ++ "load-uboot-norspl-lzma=tftpboot u-boot.ltq.lzma.norspl\0" ++#else ++#define CONFIG_ENV_WRITE_UBOOT_NOR ++#define CONFIG_ENV_LOAD_UBOOT_NOR ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH) ++#define CONFIG_ENV_SF_PROBE \ ++ "sf-probe=sf probe " __stringify(CONFIG_ENV_SPI_CS) " " \ ++ __stringify(CONFIG_ENV_SPI_MAX_HZ) " " \ ++ __stringify(CONFIG_ENV_SPI_MODE) " \0" ++ ++#define CONFIG_ENV_WRITE_UBOOT_SF \ ++ "write-uboot-sf=" \ ++ "run sf-probe && sf erase 0 +$filesize && " \ ++ "sf write $fileaddr 0 $filesize\0" ++ ++#define CONFIG_ENV_LOAD_UBOOT_SF \ ++ "load-uboot-sfspl=tftpboot u-boot.ltq.sfspl\0" \ ++ "load-uboot-sfspl-lzo=tftpboot u-boot.ltq.lzo.sfspl\0" \ ++ "load-uboot-sfspl-lzma=tftpboot u-boot.ltq.lzma.sfspl\0" ++#else ++#define CONFIG_ENV_SF_PROBE ++#define CONFIG_ENV_WRITE_UBOOT_SF ++#define CONFIG_ENV_LOAD_UBOOT_SF ++#endif ++ ++#define CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_CONSOLEDEV \ ++ CONFIG_ENV_ADDCONSOLE \ ++ CONFIG_ENV_NETDEV \ ++ CONFIG_ENV_ADDIP \ ++ CONFIG_ENV_ADDETH \ ++ CONFIG_ENV_ADDMACHTYPE \ ++ CONFIG_ENV_WRITE_UBOOT_NOR \ ++ CONFIG_ENV_LOAD_UBOOT_NOR \ ++ CONFIG_ENV_SF_PROBE \ ++ CONFIG_ENV_WRITE_UBOOT_SF \ ++ CONFIG_ENV_LOAD_UBOOT_SF ++ ++#endif /* __LANTIQ_CONFIG_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/cpu.h +@@ -0,0 +1,35 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#ifndef __LANTIQ_CPU_H__ ++#define __LANTIQ_CPU_H__ ++ ++enum ltq_boot_select { ++ BOOT_NOR, ++ BOOT_NOR_NO_BOOTROM, ++ BOOT_UART, ++ BOOT_UART_NO_EEPROM, ++ BOOT_SPI, ++ BOOT_NAND, ++ BOOT_PCI, ++ BOOT_MII0, ++ BOOT_RMII0, ++ BOOT_RGMII1, ++ BOOT_UNKNOWN, ++}; ++ ++enum ltq_boot_select ltq_boot_select(void); ++const char *ltq_boot_select_str(void); ++ ++void ltq_pmu_init(void); ++void ltq_ebu_init(void); ++void ltq_gpio_init(void); ++ ++void ltq_pll_init(void); ++void ltq_dcdc_init(unsigned int dig_ref); ++ ++#endif /* __LANTIQ_CPU_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/dma.h +@@ -0,0 +1,95 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_DMA_H__ ++#define __LANTIQ_DMA_H__ ++ ++enum ltq_dma_endianess { ++ LTQ_DMA_ENDIANESS_B0_B1_B2_B3, /* No byte swapping */ ++ LTQ_DMA_ENDIANESS_B1_B0_B3_B2, /* B0B1B2B3 => B1B0B3B2 */ ++ LTQ_DMA_ENDIANESS_B2_B3_B0_B1, /* B0B1B2B3 => B2B3B0B1 */ ++ LTQ_DMA_ENDIANESS_B3_B2_B1_B0, /* B0B1B2B3 => B3B2B1B0 */ ++}; ++ ++enum ltq_dma_burst_len { ++ LTQ_DMA_BURST_2WORDS = 1, ++ LTQ_DMA_BURST_4WORDS = 2, ++ LTQ_DMA_BURST_8WORDS = 3, ++}; ++ ++struct ltq_dma_desc { ++ u32 ctl; ++ u32 addr; ++}; ++ ++struct ltq_dma_channel { ++ struct ltq_dma_device *dev; ++ u8 chan_no; ++ u8 class; ++ u16 num_desc; ++ struct ltq_dma_desc *desc_base; ++ void *mem_base; ++ u32 dma_addr; ++}; ++ ++struct ltq_dma_device { ++ enum ltq_dma_endianess rx_endian_swap; ++ enum ltq_dma_endianess tx_endian_swap; ++ enum ltq_dma_burst_len rx_burst_len; ++ enum ltq_dma_burst_len tx_burst_len; ++ struct ltq_dma_channel rx_chan; ++ struct ltq_dma_channel tx_chan; ++ u8 port; ++}; ++ ++/** ++ * Initialize DMA hardware and driver ++ */ ++void ltq_dma_init(void); ++ ++/** ++ * Register given DMA client context ++ * ++ * @returns 0 on success, negative value otherwise ++ */ ++int ltq_dma_register(struct ltq_dma_device *dev); ++ ++/** ++ * Reset and halt all channels related to given DMA client ++ */ ++void ltq_dma_reset(struct ltq_dma_device *dev); ++void ltq_dma_enable(struct ltq_dma_device *dev); ++void ltq_dma_disable(struct ltq_dma_device *dev); ++ ++/** ++ * Map RX DMA descriptor to memory region ++ * ++ * @returns 0 on success, negative value otherwise ++ */ ++int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len); ++ ++/** ++ * Check if new data is available. ++ * ++ * @returns length of received data, 0 otherwise ++ */ ++int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index); ++ ++int ltq_dma_rx_length(struct ltq_dma_device *dev, int index); ++ ++/** ++ * Map TX DMA descriptor to memory region ++ * ++ * @returns 0 on success, negative value otherwise ++ */ ++int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len, ++ unsigned long timeout); ++ ++int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index, ++ unsigned long timeout); ++ ++#endif /* __LANTIQ_DMA_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/eth.h +@@ -0,0 +1,36 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_ETH_H__ ++#define __LANTIQ_ETH_H__ ++ ++#include <phy.h> ++ ++enum LTQ_ETH_PORT_FLAGS { ++ LTQ_ETH_PORT_NONE = 0, ++ LTQ_ETH_PORT_PHY = 1, ++ LTQ_ETH_PORT_SWITCH = (1 << 1), ++ LTQ_ETH_PORT_MAC = (1 << 2), ++}; ++ ++struct ltq_eth_port_config { ++ u8 num; ++ u8 phy_addr; ++ u16 flags; ++ phy_interface_t phy_if; ++ u8 rgmii_rx_delay; ++ u8 rgmii_tx_delay; ++}; ++ ++struct ltq_eth_board_config { ++ const struct ltq_eth_port_config *ports; ++ int num_ports; ++}; ++ ++extern int ltq_eth_initialize(const struct ltq_eth_board_config *board_config); ++ ++#endif /* __LANTIQ_ETH_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/gpio.h +@@ -0,0 +1,51 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_GPIO_H__ ++#define __LANTIQ_GPIO_H__ ++ ++enum ltq_gpio_dir { ++ GPIO_DIR_IN = 0, ++ GPIO_DIR_OUT ++}; ++ ++enum ltq_gpio_od { ++ GPIO_OD_ACTIVE = 0, ++ GPIO_OD_NORMAL ++}; ++ ++enum ltq_gpio_altsel { ++ GPIO_ALTSEL_CLR = 0, ++ GPIO_ALTSEL_SET ++}; ++ ++extern int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir); ++extern int gpio_set_opendrain(unsigned gpio, int od); ++ ++static inline int gpio_to_port(unsigned gpio) ++{ ++ return gpio >> 4; ++} ++ ++static inline int gpio_to_pin(unsigned gpio) ++{ ++ return gpio & 0xF; ++} ++ ++static inline int gpio_to_bit(unsigned gpio) ++{ ++ return 1 << gpio_to_pin(gpio); ++} ++ ++static inline int gpio_to_gpio(unsigned port, unsigned pin) ++{ ++ return (port << 4) | (pin & 0xF); ++} ++ ++#include <asm-generic/gpio.h> ++ ++#endif /* __LANTIQ_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/io.h +@@ -0,0 +1,38 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 John Crispin <blogic@openwrt.org> ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_IO_H__ ++#define __LANTIQ_IO_H__ ++ ++#include <asm/io.h> ++ ++#define ltq_readb(a) __raw_readb(a) ++#define ltq_writeb(a, v) __raw_writeb(v, a) ++ ++#define ltq_readl(a) __raw_readl(a) ++#define ltq_writel(a, v) __raw_writel(v, a) ++ ++#define ltq_clrbits(a, clear) \ ++ ltq_writel(a, ltq_readl(a) & ~(clear)) ++ ++#define ltq_setbits(a, set) \ ++ ltq_writel(a, ltq_readl(a) | (set)) ++ ++#define ltq_clrsetbits(a, clear, set) \ ++ ltq_writel(a, (ltq_readl(a) & ~(clear)) | (set)) ++ ++static inline void ltq_reg_dump(const void *addr, const char *desc) ++{ ++ u32 data; ++ ++ data = ltq_readl(addr); ++ printf("ltq_reg_dump: %s 0x%p = 0x%08x\n", ++ desc, addr, data); ++} ++ ++#endif /* __LANTIQ_IO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/pm.h +@@ -0,0 +1,22 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_PM_H__ ++#define __LANTIQ_PM_H__ ++ ++enum ltq_pm_modules { ++ LTQ_PM_CORE, ++ LTQ_PM_DMA, ++ LTQ_PM_ETH, ++ LTQ_PM_SPI, ++}; ++ ++u32 ltq_pm_map(enum ltq_pm_modules module); ++int ltq_pm_enable(enum ltq_pm_modules module); ++int ltq_pm_disable(enum ltq_pm_modules module); ++ ++#endif /* __LANTIQ_PM_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/reset.h +@@ -0,0 +1,38 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_RESET_H__ ++#define __LANTIQ_RESET_H__ ++ ++enum ltq_reset_modules { ++ LTQ_RESET_CORE, ++ LTQ_RESET_DMA, ++ LTQ_RESET_ETH, ++ LTQ_RESET_PHY, ++ LTQ_RESET_HARD, ++ LTQ_RESET_SOFT, ++}; ++ ++extern u32 ltq_reset_map(enum ltq_reset_modules module); ++extern int ltq_reset_activate(enum ltq_reset_modules module); ++extern int ltq_reset_deactivate(enum ltq_reset_modules module); ++ ++static inline int ltq_reset_once(enum ltq_reset_modules module, ulong usec) ++{ ++ int ret; ++ ++ ret = ltq_reset_activate(module); ++ if (ret) ++ return ret; ++ ++ __udelay(usec); ++ ret = ltq_reset_deactivate(module); ++ ++ return ret; ++} ++ ++#endif /* __LANTIQ_RESET_H__ */ +--- a/arch/mips/include/asm/mipsregs.h ++++ b/arch/mips/include/asm/mipsregs.h +@@ -46,7 +46,10 @@ + #define CP0_ENTRYLO1 $3 + #define CP0_CONF $3 + #define CP0_CONTEXT $4 ++#define CP0_CONTEXTCONFIG $4,1 ++#define CP0_USERLOCAL $4,1 + #define CP0_PAGEMASK $5 ++#define CP0_PAGEGRAIN $5,1 + #define CP0_WIRED $6 + #define CP0_INFO $7 + #define CP0_BADVADDR $8 +@@ -54,10 +57,19 @@ + #define CP0_ENTRYHI $10 + #define CP0_COMPARE $11 + #define CP0_STATUS $12 ++#define CP0_INTCTL $12,1 ++#define CP0_SRSCTL $12,2 ++#define CP0_SRSMAP $12,3 ++#define CP0_SRSHIGH $12,4 + #define CP0_CAUSE $13 + #define CP0_EPC $14 + #define CP0_PRID $15 ++#define CP0_EBASE $15,1 + #define CP0_CONFIG $16 ++#define CP0_CONFIG1 $16,1 ++#define CP0_CONFIG2 $16,2 ++#define CP0_CONFIG3 $16,3 ++#define CP0_CONFIG7 $16,7 + #define CP0_LLADDR $17 + #define CP0_WATCHLO $18 + #define CP0_WATCHHI $19 +@@ -70,7 +82,17 @@ + #define CP0_ECC $26 + #define CP0_CACHEERR $27 + #define CP0_TAGLO $28 ++#define CP0_ITAGLO $28 ++#define CP0_IDATALO $28,1 ++#define CP0_DTAGLO $28,2 ++#define CP0_DDATALO $28,3 ++#define CP0_L23TAGLO $28,4 ++#define CP0_L23DATALO $28,5 + #define CP0_TAGHI $29 ++#define CP0_IDATAHI $29,1 ++#define CP0_DTAGHI $29,2 ++#define CP0_L23TAGHI $29,4 ++#define CP0_L23DATAHI $29,5 + #define CP0_ERROREPC $30 + #define CP0_DESAVE $31 + +@@ -395,6 +417,12 @@ + #define CAUSEF_BD (_ULCAST_(1) << 31) + + /* ++ * Bits in the coprocessor 0 EBase register. ++ */ ++#define EBASEB_CPUNUM 0 ++#define EBASEF_CPUNUM (_ULCAST_(1023)) ++ ++/* + * Bits in the coprocessor 0 config register. + */ + /* Generic bits. */ +--- a/arch/mips/include/asm/u-boot-mips.h ++++ b/arch/mips/include/asm/u-boot-mips.h +@@ -9,3 +9,4 @@ extern ulong uboot_end_data; + extern ulong uboot_end; + + extern int incaip_set_cpuclk(void); ++extern int arch_cpu_init(void); +--- a/arch/mips/lib/board.c ++++ b/arch/mips/lib/board.c +@@ -50,6 +50,16 @@ static char *failed = "*** failed ***\n" + */ + const unsigned long mips_io_port_base = -1; + ++int __arch_cpu_init(void) ++{ ++ /* ++ * Nothing to do in this dummy implementation ++ */ ++ return 0; ++} ++int arch_cpu_init(void) ++ __attribute__((weak, alias("__arch_cpu_init"))); ++ + int __board_early_init_f(void) + { + /* +@@ -123,6 +133,7 @@ static int init_baudrate(void) + typedef int (init_fnc_t)(void); + + init_fnc_t *init_sequence[] = { ++ arch_cpu_init, + board_early_init_f, + timer_init, + env_init, /* initialize environment */ +--- /dev/null ++++ b/board/lantiq/easy50712/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/lantiq/easy50712/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/lantiq/easy50712/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define MC_DC00_VALUE 0x1B1B ++#define MC_DC01_VALUE 0x0 ++#define MC_DC02_VALUE 0x0 ++#define MC_DC03_VALUE 0x0 ++#define MC_DC04_VALUE 0x0 ++#define MC_DC05_VALUE 0x200 ++#define MC_DC06_VALUE 0x605 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x102 ++#define MC_DC09_VALUE 0x70a ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xc02 ++#define MC_DC12_VALUE 0x1C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x13c ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xd ++#define MC_DC18_VALUE 0x300 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0xd00 ++#define MC_DC22_VALUE 0xd0d ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x62 ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x510 ++#define MC_DC29_VALUE 0x2d89 ++#define MC_DC30_VALUE 0x8300 ++#define MC_DC31_VALUE 0x0 ++#define MC_DC32_VALUE 0x0 ++#define MC_DC33_VALUE 0x0 ++#define MC_DC34_VALUE 0x0 ++#define MC_DC35_VALUE 0x0 ++#define MC_DC36_VALUE 0x0 ++#define MC_DC37_VALUE 0x0 ++#define MC_DC38_VALUE 0x0 ++#define MC_DC39_VALUE 0x0 ++#define MC_DC40_VALUE 0x0 ++#define MC_DC41_VALUE 0x0 ++#define MC_DC42_VALUE 0x0 ++#define MC_DC43_VALUE 0x0 ++#define MC_DC44_VALUE 0x0 ++#define MC_DC45_VALUE 0x500 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/lantiq/easy50712/easy50712.c +@@ -0,0 +1,106 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <switch.h> ++#include <spi.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/chipid.h> ++ ++static void gpio_init(void) ++{ ++ /* SPI/CS output (low-active) for serial flash */ ++ gpio_direction_output(22, 1); ++ ++ /* enable CLK_OUT2 for external switch */ ++ gpio_set_altfunc(3, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++} ++ ++int board_early_init_f(void) ++{ ++ gpio_init(); ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* MAC0: Lantiq ADM6996I switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t *bis) ++{ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++static struct switch_device adm6996i_dev = { ++ .name = "adm6996i", ++ .cpu_port = 5, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ /* Deactivate HRST line to release reset of ADM6996I switch */ ++ ltq_reset_once(LTQ_RESET_HARD, 200000); ++ ++ /* ADM6996I needs some time to come out of reset */ ++ __udelay(50000); ++ ++ return switch_device_register(&adm6996i_dev); ++} ++ ++int spi_cs_is_valid(unsigned int bus, unsigned int cs) ++{ ++ if (bus) ++ return 0; ++ ++ switch (cs) { ++ case 2: ++ return 1; ++ default: ++ return 0; ++ } ++} ++ ++void spi_cs_activate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 2: ++ gpio_set_value(22, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++void spi_cs_deactivate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 2: ++ gpio_set_value(22, 1); ++ break; ++ default: ++ break; ++ } ++} +--- /dev/null ++++ b/board/lantiq/easy80920/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/lantiq/easy80920/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/lantiq/easy80920/ddr_settings.h +@@ -0,0 +1,70 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define MC_CCR00_VALUE 0x101 ++#define MC_CCR01_VALUE 0x1000100 ++#define MC_CCR02_VALUE 0x1010000 ++#define MC_CCR03_VALUE 0x101 ++#define MC_CCR04_VALUE 0x1000000 ++#define MC_CCR05_VALUE 0x1000101 ++#define MC_CCR06_VALUE 0x1000100 ++#define MC_CCR07_VALUE 0x1010000 ++#define MC_CCR08_VALUE 0x1000101 ++#define MC_CCR09_VALUE 0x0 ++#define MC_CCR10_VALUE 0x2000100 ++#define MC_CCR11_VALUE 0x2000300 ++#define MC_CCR12_VALUE 0x30000 ++#define MC_CCR13_VALUE 0x202 ++#define MC_CCR14_VALUE 0x7080A0F ++#define MC_CCR15_VALUE 0x2040F ++#define MC_CCR16_VALUE 0x40000 ++#define MC_CCR17_VALUE 0x70102 ++#define MC_CCR18_VALUE 0x4020002 ++#define MC_CCR19_VALUE 0x30302 ++#define MC_CCR20_VALUE 0x8000700 ++#define MC_CCR21_VALUE 0x40F020A ++#define MC_CCR22_VALUE 0x0 ++#define MC_CCR23_VALUE 0xC020000 ++#define MC_CCR24_VALUE 0x4401B04 ++#define MC_CCR25_VALUE 0x0 ++#define MC_CCR26_VALUE 0x0 ++#define MC_CCR27_VALUE 0x6420000 ++#define MC_CCR28_VALUE 0x0 ++#define MC_CCR29_VALUE 0x0 ++#define MC_CCR30_VALUE 0x798 ++#define MC_CCR31_VALUE 0x0 ++#define MC_CCR32_VALUE 0x0 ++#define MC_CCR33_VALUE 0x650000 ++#define MC_CCR34_VALUE 0x200C8 ++#define MC_CCR35_VALUE 0x1D445D ++#define MC_CCR36_VALUE 0xC8 ++#define MC_CCR37_VALUE 0xC351 ++#define MC_CCR38_VALUE 0x0 ++#define MC_CCR39_VALUE 0x141F04 ++#define MC_CCR40_VALUE 0x142704 ++#define MC_CCR41_VALUE 0x141b42 ++#define MC_CCR42_VALUE 0x141b42 ++#define MC_CCR43_VALUE 0x566504 ++#define MC_CCR44_VALUE 0x566504 ++#define MC_CCR45_VALUE 0x565F17 ++#define MC_CCR46_VALUE 0x565F17 ++#define MC_CCR47_VALUE 0x0 ++#define MC_CCR48_VALUE 0x0 ++#define MC_CCR49_VALUE 0x0 ++#define MC_CCR50_VALUE 0x0 ++#define MC_CCR51_VALUE 0x0 ++#define MC_CCR52_VALUE 0x133 ++#define MC_CCR53_VALUE 0xF3014B27 ++#define MC_CCR54_VALUE 0xF3014B27 ++#define MC_CCR55_VALUE 0xF3014B27 ++#define MC_CCR56_VALUE 0xF3014B27 ++#define MC_CCR57_VALUE 0x7800301 ++#define MC_CCR58_VALUE 0x7800301 ++#define MC_CCR59_VALUE 0x7800301 ++#define MC_CCR60_VALUE 0x7800301 ++#define MC_CCR61_VALUE 0x4 +--- /dev/null ++++ b/board/lantiq/easy80920/easy80920.c +@@ -0,0 +1,139 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <spi.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/lantiq/cpu.h> ++#include <asm/arch/gphy.h> ++ ++#if defined(CONFIG_SPL_BUILD) ++#define do_gpio_init 1 ++#define do_pll_init 1 ++#define do_dcdc_init 0 ++#elif defined(CONFIG_SYS_BOOT_RAM) ++#define do_gpio_init 1 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#elif defined(CONFIG_SYS_BOOT_NOR) ++#define do_gpio_init 1 ++#define do_pll_init 1 ++#define do_dcdc_init 1 ++#else ++#define do_gpio_init 0 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#endif ++ ++static void gpio_init(void) ++{ ++ /* SPI CS 0.4 to serial flash */ ++ gpio_direction_output(10, 1); ++ ++ /* EBU.FL_CS1 as output for NAND CE */ ++ gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* EBU.FL_A23 as output for NAND CLE */ ++ gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* EBU.FL_A24 as output for NAND ALE */ ++ gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* GPIO 3.0 as input for NAND Ready Busy */ ++ gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN); ++ /* GPIO 3.1 as output for NAND Read */ ++ gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++} ++ ++int board_early_init_f(void) ++{ ++ if (do_gpio_init) ++ gpio_init(); ++ ++ if (do_pll_init) ++ ltq_pll_init(); ++ ++ if (do_dcdc_init) ++ ltq_dcdc_init(0x7F); ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */ ++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */ ++ { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */ ++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC3: unused */ ++ { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE }, ++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */ ++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */ ++ { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t * bis) ++{ ++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0; ++ const ulong fw_addr = 0x80FF0000; ++ ++ ltq_gphy_phy11g_a1x_load(fw_addr); ++ ++ ltq_cgu_gphy_clk_src(clk); ++ ++ ltq_rcu_gphy_boot(0, fw_addr); ++ ltq_rcu_gphy_boot(1, fw_addr); ++ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++int spi_cs_is_valid(unsigned int bus, unsigned int cs) ++{ ++ if (bus) ++ return 0; ++ ++ if (cs == 4) ++ return 1; ++ ++ return 0; ++} ++ ++void spi_cs_activate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 4: ++ gpio_set_value(10, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++void spi_cs_deactivate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 4: ++ gpio_set_value(10, 1); ++ break; ++ default: ++ break; ++ } ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -444,10 +444,17 @@ dbau1500 mips + dbau1550 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550 + dbau1550_el mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN + pb1000 mips mips32 pb1x00 - au1x00 pb1x00:PB1000 ++easy50712_nor mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NOR ++easy50712_norspl mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NORSPL ++easy50712_ram mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_RAM + incaip mips mips32 incaip - incaip + incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000 + incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000 + incaip_150MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=150000000 ++easy80920_nor mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NOR ++easy80920_norspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NORSPL ++easy80920_ram mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_RAM ++easy80920_sfspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_SFSPL + qi_lb60 mips xburst qi_lb60 qi + adp-ag101 nds32 n1213 adp-ag101 AndesTech ag101 + adp-ag101p nds32 n1213 adp-ag101p AndesTech ag101 +--- a/drivers/dma/Makefile ++++ b/drivers/dma/Makefile +@@ -28,6 +28,7 @@ LIB := $(obj)libdma.o + COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o + COBJS-$(CONFIG_APBH_DMA) += apbh_dma.o + COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o ++COBJS-$(CONFIG_LANTIQ_DMA) += lantiq_dma.o + COBJS-$(CONFIG_OMAP3_DMA) += omap3_dma.o + + COBJS := $(COBJS-y) +--- /dev/null ++++ b/drivers/dma/lantiq_dma.c +@@ -0,0 +1,388 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <watchdog.h> ++#include <linux/compiler.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/dma.h> ++#include <asm/lantiq/pm.h> ++#include <asm/lantiq/reset.h> ++#include <asm/arch/soc.h> ++#include <asm/processor.h> ++ ++#define DMA_CTRL_PKTARB (1 << 31) ++#define DMA_CTRL_MBRSTARB (1 << 30) ++#define DMA_CTRL_MBRSTCNT_SHIFT 16 ++#define DMA_CTRL_MBRSTCNT_MASK (0x3ff << DMA_CTRL_MBRSTCNT_SHIFT) ++#define DMA_CTRL_DRB (1 << 8) ++#define DMA_CTRL_RESET (1 << 0) ++ ++#define DMA_CPOLL_EN (1 << 31) ++#define DMA_CPOLL_CNT_SHIFT 4 ++#define DMA_CPOLL_CNT_MASK (0xFFF << DMA_CPOLL_CNT_SHIFT) ++ ++#define DMA_CCTRL_TXWGT_SHIFT 16 ++#define DMA_CCTRL_TXWGT_MASK (0x3 << DMA_CCTRL_TXWGT_SHIFT) ++#define DMA_CCTRL_CLASS_SHIFT 9 ++#define DMA_CCTRL_CLASS_MASK (0x3 << DMA_CCTRL_CLASS_SHIFT) ++#define DMA_CCTRL_RST (1 << 1) ++#define DMA_CCTRL_ONOFF (1 << 0) ++ ++#define DMA_PCTRL_TXBL_SHIFT 4 ++#define DMA_PCTRL_TXBL_2WORDS (1 << DMA_PCTRL_TXBL_SHIFT) ++#define DMA_PCTRL_TXBL_4WORDS (2 << DMA_PCTRL_TXBL_SHIFT) ++#define DMA_PCTRL_TXBL_8WORDS (3 << DMA_PCTRL_TXBL_SHIFT) ++#define DMA_PCTRL_RXBL_SHIFT 2 ++#define DMA_PCTRL_RXBL_2WORDS (1 << DMA_PCTRL_RXBL_SHIFT) ++#define DMA_PCTRL_RXBL_4WORDS (2 << DMA_PCTRL_RXBL_SHIFT) ++#define DMA_PCTRL_RXBL_8WORDS (3 << DMA_PCTRL_RXBL_SHIFT) ++#define DMA_PCTRL_TXENDI_SHIFT 10 ++#define DMA_PCTRL_TXENDI_MASK (0x3 << DMA_PCTRL_TXENDI_SHIFT) ++#define DMA_PCTRL_RXENDI_SHIFT 8 ++#define DMA_PCTRL_RXENDI_MASK (0x3 << DMA_PCTRL_RXENDI_SHIFT) ++ ++#define DMA_DESC_OWN (1 << 31) ++#define DMA_DESC_C (1 << 30) ++#define DMA_DESC_SOP (1 << 29) ++#define DMA_DESC_EOP (1 << 28) ++#define DMA_DESC_TX_OFFSET(x) ((x & 0x1f) << 23) ++#define DMA_DESC_RX_OFFSET(x) ((x & 0x3) << 23) ++#define DMA_DESC_LENGTH(x) (x & 0xffff) ++ ++#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) ++ ++struct ltq_dma_regs { ++ u32 clc; /* Clock control */ ++ u32 rsvd0; ++ u32 id; /* Identification */ ++ u32 rsvd1; ++ u32 ctrl; /* Control */ ++ u32 cpoll; /* Channel polling */ ++ u32 cs; /* Channel select */ ++ u32 cctrl; /* Channel control */ ++ u32 cdba; /* Channel descriptor base address */ ++ u32 cdlen; /* Channel descriptor length */ ++ u32 cis; /* Channel interrupt status */ ++ u32 cie; /* Channel interrupt enable */ ++ u32 cgbl; /* Channel global buffer length */ ++ u32 cdptnrd; /* Current descriptor pointer */ ++ u32 rsvd2[2]; ++ u32 ps; /* Port select */ ++ u32 pctrl; /* Port control */ ++ u32 rsvd3[43]; ++ u32 irnen; /* Interrupt node enable */ ++ u32 irncr; /* Interrupt node control */ ++ u32 irnicr; /* Interrupt capture */ ++}; ++ ++static struct ltq_dma_regs *ltq_dma_regs = ++ (struct ltq_dma_regs *) CKSEG1ADDR(LTQ_DMA_BASE); ++ ++static inline unsigned long ltq_dma_addr_to_virt(u32 dma_addr) ++{ ++ return KSEG0ADDR(dma_addr); ++} ++ ++static inline u32 ltq_virt_to_dma_addr(void *addr) ++{ ++ return CPHYSADDR(addr); ++} ++ ++static inline int ltq_dma_burst_align(enum ltq_dma_burst_len burst_len) ++{ ++ switch (burst_len) { ++ case LTQ_DMA_BURST_2WORDS: ++ return 2 * 4; ++ case LTQ_DMA_BURST_4WORDS: ++ return 4 * 4; ++ case LTQ_DMA_BURST_8WORDS: ++ return 8 * 4; ++ } ++ ++ return 0; ++} ++ ++static inline void ltq_dma_sync(void) ++{ ++ __asm__ __volatile__("sync"); ++} ++ ++static inline void ltq_dma_dcache_wb_inv(const void *ptr, size_t size) ++{ ++ unsigned long addr = (unsigned long) ptr; ++ ++ flush_dcache_range(addr, addr + size); ++ ltq_dma_sync(); ++} ++ ++static inline void ltq_dma_dcache_inv(const void *ptr, size_t size) ++{ ++ unsigned long addr = (unsigned long) ptr; ++ ++ invalidate_dcache_range(addr, addr + size); ++} ++ ++void ltq_dma_init(void) ++{ ++ /* Power up DMA */ ++ ltq_pm_enable(LTQ_PM_DMA); ++ ++ /* Reset DMA */ ++ ltq_setbits(<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 +@@ -28,6 +28,7 @@ LIB := $(obj)libgpio.o + COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o + COBJS-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o + COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o ++COBJS-$(CONFIG_LANTIQ_GPIO) += lantiq_gpio.o + COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o + COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o + COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o +--- /dev/null ++++ b/drivers/gpio/lantiq_gpio.c +@@ -0,0 +1,330 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/gpio.h> ++#include <asm/lantiq/io.h> ++ ++#define SSIO_GPIO_BASE 64 ++ ++#define SSIO_CON0_SWU (1 << 31) ++#define SSIO_CON0_RZFL (1 << 26) ++#define SSIO_CON0_GPHY1_SHIFT 27 ++#define SSIO_CON0_GPHY1_CONFIG ((CONFIG_LTQ_SSIO_GPHY1_MODE & 0x7) << 27) ++ ++#define SSIO_CON1_US_FPI (2 << 30) ++#define SSIO_CON1_FPID_2HZ (0 << 23) ++#define SSIO_CON1_FPID_4HZ (1 << 23) ++#define SSIO_CON1_FPID_8HZ (2 << 23) ++#define SSIO_CON1_FPID_10HZ (3 << 23) ++#define SSIO_CON1_FPIS_1_2 (1 << 20) ++#define SSIO_CON1_FPIS_1_32 (2 << 20) ++#define SSIO_CON1_FPIS_1_64 (3 << 20) ++ ++#define SSIO_CON1_GPHY2_SHIFT 15 ++#define SSIO_CON1_GPHY2_CONFIG ((CONFIG_LTQ_SSIO_GPHY2_MODE & 0x7) << 15) ++ ++#define SSIO_CON1_GROUP2 (1 << 2) ++#define SSIO_CON1_GROUP1 (1 << 1) ++#define SSIO_CON1_GROUP0 (1 << 0) ++#define SSIO_CON1_GROUP_CONFIG (0x3) ++ ++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS ++#define enable_ssio 1 ++#else ++#define enable_ssio 0 ++ ++#define CONFIG_LTQ_SSIO_GPHY1_MODE 0 ++#define CONFIG_LTQ_SSIO_GPHY2_MODE 0 ++#define CONFIG_LTQ_SSIO_INIT_VALUE 0 ++#endif ++ ++#ifdef CONFIG_LTQ_SSIO_EDGE_FALLING ++#define SSIO_RZFL_CONFIG SSIO_CON0_RZFL ++#else ++#define SSIO_RZFL_CONFIG 0 ++#endif ++ ++struct ltq_gpio_port_regs { ++ __be32 out; ++ __be32 in; ++ __be32 dir; ++ __be32 altsel0; ++ __be32 altsel1; ++ __be32 od; ++ __be32 stoff; ++ __be32 pudsel; ++ __be32 puden; ++ __be32 rsvd1[3]; ++}; ++ ++struct ltq_gpio_regs { ++ u32 rsvd[4]; ++ struct ltq_gpio_port_regs ports[CONFIG_LTQ_GPIO_MAX_BANKS]; ++}; ++ ++struct ltq_gpio3_regs { ++ u32 rsvd0[13]; ++ __be32 od; ++ __be32 pudsel; ++ __be32 puden; ++ u32 rsvd1[9]; ++ __be32 altsel1; ++ u32 rsvd2[14]; ++ __be32 out; ++ __be32 in; ++ __be32 dir; ++ __be32 altsel0; ++}; ++ ++struct ltq_ssio_regs { ++ __be32 con0; ++ __be32 con1; ++ __be32 cpu0; ++ __be32 cpu1; ++ __be32 ar; ++}; ++ ++static struct ltq_gpio_regs *ltq_gpio_regs = ++ (struct ltq_gpio_regs *) CKSEG1ADDR(LTQ_GPIO_BASE); ++ ++static struct ltq_gpio3_regs *ltq_gpio3_regs = ++ (struct ltq_gpio3_regs *) CKSEG1ADDR(LTQ_GPIO_BASE); ++ ++static struct ltq_ssio_regs *ltq_ssio_regs = ++ (struct ltq_ssio_regs *) CKSEG1ADDR(LTQ_SSIO_BASE); ++ ++static int is_gpio_bank3(unsigned int port) ++{ ++#ifdef CONFIG_LTQ_HAS_GPIO_BANK3 ++ return port == 3; ++#else ++ return 0; ++#endif ++} ++ ++static int is_gpio_ssio(unsigned int gpio) ++{ ++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS ++ return gpio >= SSIO_GPIO_BASE; ++#else ++ return 0; ++#endif ++} ++ ++static inline int ssio_gpio_to_bit(unsigned gpio) ++{ ++ return 1 << (gpio - SSIO_GPIO_BASE); ++} ++ ++int ltq_gpio_init(void) ++{ ++ ltq_writel(<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 +@@ -177,6 +177,18 @@ u64 flash_read64(void *addr)__attribute_ + #define flash_read64 __flash_read64 + #endif + ++static inline void *__flash_swap_addr(unsigned long addr) ++{ ++ return (void *) addr; ++} ++ ++#ifdef CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP ++void *flash_swap_addr(unsigned long addr) ++ __attribute__((weak, alias("__flash_swap_addr"))); ++#else ++#define flash_swap_addr __flash_swap_addr ++#endif ++ + /*----------------------------------------------------------------------- + */ + #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) +@@ -212,7 +224,7 @@ flash_map (flash_info_t * info, flash_se + { + unsigned int byte_offset = offset * info->portwidth; + +- return (void *)(info->start[sect] + byte_offset); ++ return flash_swap_addr(info->start[sect] + byte_offset); + } + + static inline void flash_unmap(flash_info_t *info, flash_sect_t sect, +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -67,6 +67,7 @@ COBJS-$(CONFIG_NAND_JZ4740) += jz4740_na + COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o + COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o + COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o ++COBJS-$(CONFIG_NAND_LANTIQ) += lantiq_nand.o + COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o + COBJS-$(CONFIG_NAND_MXC) += mxc_nand.o + COBJS-$(CONFIG_NAND_MXS) += mxs_nand.o +--- /dev/null ++++ b/drivers/mtd/nand/lantiq_nand.c +@@ -0,0 +1,127 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#include <common.h> ++#include <linux/mtd/nand.h> ++#include <linux/compiler.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/nand.h> ++#include <asm/lantiq/io.h> ++ ++#define NAND_CON_ECC_ON (1 << 31) ++#define NAND_CON_LATCH_PRE (1 << 23) ++#define NAND_CON_LATCH_WP (1 << 22) ++#define NAND_CON_LATCH_SE (1 << 21) ++#define NAND_CON_LATCH_CS (1 << 20) ++#define NAND_CON_LATCH_CLE (1 << 19) ++#define NAND_CON_LATCH_ALE (1 << 18) ++#define NAND_CON_OUT_CS1 (1 << 10) ++#define NAND_CON_IN_CS1 (1 << 8) ++#define NAND_CON_PRE_P (1 << 7) ++#define NAND_CON_WP_P (1 << 6) ++#define NAND_CON_SE_P (1 << 5) ++#define NAND_CON_CS_P (1 << 4) ++#define NAND_CON_CLE_P (1 << 3) ++#define NAND_CON_ALE_P (1 << 2) ++#define NAND_CON_CSMUX (1 << 1) ++#define NAND_CON_NANDM (1 << 0) ++ ++#define NAND_WAIT_WR_C (1 << 3) ++#define NAND_WAIT_RDBY (1 << 0) ++ ++#define NAND_CMD_ALE (1 << 2) ++#define NAND_CMD_CLE (1 << 3) ++#define NAND_CMD_CS (1 << 4) ++#define NAND_CMD_SE (1 << 5) ++#define NAND_CMD_WP (1 << 6) ++#define NAND_CMD_PRE (1 << 7) ++ ++struct ltq_nand_regs { ++ __be32 con; /* NAND controller control */ ++ __be32 wait; /* NAND Flash Device RD/BY State */ ++ __be32 ecc0; /* NAND Flash ECC Register 0 */ ++ __be32 ecc_ac; /* NAND Flash ECC Register address counter */ ++ __be32 ecc_cr; /* NAND Flash ECC Comparison */ ++}; ++ ++static struct ltq_nand_regs *ltq_nand_regs = ++ (struct ltq_nand_regs *) CKSEG1ADDR(LTQ_EBU_NAND_BASE); ++ ++static void ltq_nand_wait_ready(void) ++{ ++ while ((ltq_readl(<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 +@@ -51,6 +51,8 @@ COBJS-$(CONFIG_GRETH) += greth.o + COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o + COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o + COBJS-$(CONFIG_LAN91C96) += lan91c96.o ++COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o ++COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o + COBJS-$(CONFIG_MACB) += macb.o + COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o + COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o +--- /dev/null ++++ b/drivers/net/lantiq_danube_etop.c +@@ -0,0 +1,411 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <switch.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/pm.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/dma.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_PPE_ETOP_MDIO_ACC_RA (1 << 31) ++#define LTQ_PPE_ETOP_MDIO_CFG_UMM1 (1 << 2) ++#define LTQ_PPE_ETOP_MDIO_CFG_UMM0 (1 << 1) ++ ++#define LTQ_PPE_ETOP_CFG_TCKINV1 (1 << 11) ++#define LTQ_PPE_ETOP_CFG_TCKINV0 (1 << 10) ++#define LTQ_PPE_ETOP_CFG_FEN1 (1 << 9) ++#define LTQ_PPE_ETOP_CFG_FEN0 (1 << 8) ++#define LTQ_PPE_ETOP_CFG_SEN1 (1 << 7) ++#define LTQ_PPE_ETOP_CFG_SEN0 (1 << 6) ++#define LTQ_PPE_ETOP_CFG_TURBO1 (1 << 5) ++#define LTQ_PPE_ETOP_CFG_REMII1 (1 << 4) ++#define LTQ_PPE_ETOP_CFG_OFF1 (1 << 3) ++#define LTQ_PPE_ETOP_CFG_TURBO0 (1 << 2) ++#define LTQ_PPE_ETOP_CFG_REMII0 (1 << 1) ++#define LTQ_PPE_ETOP_CFG_OFF0 (1 << 0) ++ ++#define LTQ_PPE_ENET0_MAC_CFG_CGEN (1 << 11) ++#define LTQ_PPE_ENET0_MAC_CFG_DUPLEX (1 << 2) ++#define LTQ_PPE_ENET0_MAC_CFG_SPEED (1 << 1) ++#define LTQ_PPE_ENET0_MAC_CFG_LINK (1 << 0) ++ ++#define LTQ_PPE_ENETS0_CFG_FTUC (1 << 28) ++ ++#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX ++#define LTQ_ETH_TX_BUFFER_CNT 8 ++#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN ++#define LTQ_ETH_IP_ALIGN 2 ++ ++#define LTQ_MDIO_DRV_NAME "ltq-mdio" ++#define LTQ_ETH_DRV_NAME "ltq-eth" ++ ++struct ltq_ppe_etop_regs { ++ u32 mdio_cfg; /* MDIO configuration */ ++ u32 mdio_acc; /* MDIO access */ ++ u32 cfg; /* ETOP configuration */ ++ u32 ig_vlan_cos; /* IG VLAN priority CoS mapping */ ++ u32 ig_dscp_cos3; /* IG DSCP CoS mapping 3 */ ++ u32 ig_dscp_cos2; /* IG DSCP CoS mapping 2 */ ++ u32 ig_dscp_cos1; /* IG DSCP CoS mapping 1 */ ++ u32 ig_dscp_cos0; /* IG DSCP CoS mapping 0 */ ++ u32 ig_plen_ctrl; /* IG frame length control */ ++ u32 rsvd0[3]; ++ u32 vpid; /* VLAN protocol ID */ ++}; ++ ++struct ltq_ppe_enet_regs { ++ u32 mac_cfg; /* MAC configuration */ ++ u32 rsvd0[3]; ++ u32 ig_cfg; /* Ingress configuration */ ++ u32 ig_pgcnt; /* Ingress buffer used page count */ ++ u32 rsvd1; ++ u32 ig_buf_ctrl; /* Ingress buffer backpressure ctrl */ ++ u32 cos_cfg; /* Classification configuration */ ++ u32 ig_drop; /* Total ingress drop frames */ ++ u32 ig_err; /* Total ingress error frames */ ++ u32 mac_da0; /* Ingress MAC address 0 */ ++ u32 mac_da1; /* Ingress MAC address 1 */ ++ u32 rsvd2[22]; ++ u32 pgcnt; /* Page counter */ ++ u32 rsvd3; ++ u32 hf_ctrl; /* Half duplex control */ ++ u32 tx_ctrl; /* Transmit control */ ++ u32 rsvd4; ++ u32 vlcos0; /* VLAN insertion config CoS 0 */ ++ u32 vlcos1; /* VLAN insertion config CoS 1 */ ++ u32 vlcos2; /* VLAN insertion config CoS 2 */ ++ u32 vlcos3; /* VLAN insertion config CoS 3 */ ++ u32 eg_col; /* Total egress collision frames */ ++ u32 eg_drop; /* Total egress drop frames */ ++}; ++ ++struct ltq_eth_priv { ++ struct ltq_dma_device dma_dev; ++ struct mii_dev *bus; ++ struct eth_device *dev; ++ int rx_num; ++ int tx_num; ++}; ++ ++struct ltq_mdio_access { ++ union { ++ struct { ++ unsigned ra:1; ++ unsigned rw:1; ++ unsigned rsvd:4; ++ unsigned phya:5; ++ unsigned rega:5; ++ unsigned phyd:16; ++ } reg; ++ u32 val; ++ }; ++}; ++ ++static struct ltq_ppe_etop_regs *ltq_ppe_etop_regs = ++ (struct ltq_ppe_etop_regs *) CKSEG1ADDR(LTQ_PPE_ETOP_BASE); ++ ++static struct ltq_ppe_enet_regs *ltq_ppe_enet0_regs = ++ (struct ltq_ppe_enet_regs *) CKSEG1ADDR(LTQ_PPE_ENET0_BASE); ++ ++static inline int ltq_mdio_poll(void) ++{ ++ struct ltq_mdio_access acc; ++ unsigned cnt = 10000; ++ ++ while (likely(cnt--)) { ++ acc.val = ltq_readl(<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,676 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010-2011 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define DEBUG ++ ++#include <common.h> ++#include <malloc.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <linux/compiler.h> ++#include <asm/gpio.h> ++#include <asm/processor.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/pm.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/dma.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/switch.h> ++ ++#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX ++#define LTQ_ETH_TX_BUFFER_CNT 8 ++#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN ++#define LTQ_ETH_IP_ALIGN 2 ++ ++#define LTQ_MDIO_DRV_NAME "ltq-mdio" ++#define LTQ_ETH_DRV_NAME "ltq-eth" ++ ++#define LTQ_ETHSW_MAX_GMAC 6 ++#define LTQ_ETHSW_PMAC 6 ++ ++struct ltq_mdio_phy_addr_reg { ++ union { ++ struct { ++ unsigned rsvd:1; ++ unsigned lnkst:2; /* Link status control */ ++ unsigned speed:2; /* Speed control */ ++ unsigned fdup:2; /* Full duplex control */ ++ unsigned fcontx:2; /* Flow control mode TX */ ++ unsigned fconrx:2; /* Flow control mode RX */ ++ unsigned addr:5; /* PHY address */ ++ } bits; ++ u16 val; ++ }; ++}; ++ ++enum ltq_mdio_phy_addr_lnkst { ++ LTQ_MDIO_PHY_ADDR_LNKST_AUTO = 0, ++ LTQ_MDIO_PHY_ADDR_LNKST_UP = 1, ++ LTQ_MDIO_PHY_ADDR_LNKST_DOWN = 2, ++}; ++ ++enum ltq_mdio_phy_addr_speed { ++ LTQ_MDIO_PHY_ADDR_SPEED_M10 = 0, ++ LTQ_MDIO_PHY_ADDR_SPEED_M100 = 1, ++ LTQ_MDIO_PHY_ADDR_SPEED_G1 = 2, ++ LTQ_MDIO_PHY_ADDR_SPEED_AUTO = 3, ++}; ++ ++enum ltq_mdio_phy_addr_fdup { ++ LTQ_MDIO_PHY_ADDR_FDUP_AUTO = 0, ++ LTQ_MDIO_PHY_ADDR_FDUP_ENABLE = 1, ++ LTQ_MDIO_PHY_ADDR_FDUP_DISABLE = 3, ++}; ++ ++enum ltq_mdio_phy_addr_fcon { ++ LTQ_MDIO_PHY_ADDR_FCON_AUTO = 0, ++ LTQ_MDIO_PHY_ADDR_FCON_ENABLE = 1, ++ LTQ_MDIO_PHY_ADDR_FCON_DISABLE = 3, ++}; ++ ++struct ltq_mii_mii_cfg_reg { ++ union { ++ struct { ++ unsigned res:1; /* Hardware reset */ ++ unsigned en:1; /* xMII interface enable */ ++ unsigned isol:1; /* xMII interface isolate */ ++ unsigned ldclkdis:1; /* Link down clock disable */ ++ unsigned rsvd:1; ++ unsigned crs:2; /* CRS sensitivity config */ ++ unsigned rgmii_ibs:1; /* RGMII In Band status */ ++ unsigned rmii:1; /* RMII ref clock direction */ ++ unsigned miirate:3; /* xMII interface clock rate */ ++ unsigned miimode:4; /* xMII interface mode */ ++ } bits; ++ u16 val; ++ }; ++}; ++ ++enum ltq_mii_mii_cfg_miirate { ++ LTQ_MII_MII_CFG_MIIRATE_M2P5 = 0, ++ LTQ_MII_MII_CFG_MIIRATE_M25 = 1, ++ LTQ_MII_MII_CFG_MIIRATE_M125 = 2, ++ LTQ_MII_MII_CFG_MIIRATE_M50 = 3, ++ LTQ_MII_MII_CFG_MIIRATE_AUTO = 4, ++}; ++ ++enum ltq_mii_mii_cfg_miimode { ++ LTQ_MII_MII_CFG_MIIMODE_MIIP = 0, ++ LTQ_MII_MII_CFG_MIIMODE_MIIM = 1, ++ LTQ_MII_MII_CFG_MIIMODE_RMIIP = 2, ++ LTQ_MII_MII_CFG_MIIMODE_RMIIM = 3, ++ LTQ_MII_MII_CFG_MIIMODE_RGMII = 4, ++}; ++ ++struct ltq_eth_priv { ++ struct ltq_dma_device dma_dev; ++ struct mii_dev *bus; ++ struct eth_device *dev; ++ struct phy_device *phymap[LTQ_ETHSW_MAX_GMAC]; ++ int rx_num; ++ int tx_num; ++}; ++ ++static struct vr9_switch_regs *switch_regs = ++ (struct vr9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE); ++ ++static inline void vr9_switch_sync(void) ++{ ++ __asm__("sync"); ++} ++ ++static inline int vr9_switch_mdio_is_busy(void) ++{ ++ u32 mdio_ctrl = ltq_readl(&switch_regs->mdio.mdio_ctrl); ++ ++ return mdio_ctrl & MDIO_CTRL_MBUSY; ++} ++ ++static inline void vr9_switch_mdio_poll(void) ++{ ++ while (vr9_switch_mdio_is_busy()) ++ cpu_relax(); ++} ++ ++static int vr9_switch_mdio_read(struct mii_dev *bus, int phyad, int devad, ++ int regad) ++{ ++ u32 mdio_ctrl; ++ int retval; ++ ++ mdio_ctrl = MDIO_CTRL_OP_READ | ++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) | ++ (regad & MDIO_CTRL_REGAD_MASK); ++ ++ vr9_switch_mdio_poll(); ++ ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl); ++ vr9_switch_mdio_poll(); ++ retval = ltq_readl(&switch_regs->mdio.mdio_read); ++ ++ return retval; ++} ++ ++static int vr9_switch_mdio_write(struct mii_dev *bus, int phyad, int devad, ++ int regad, u16 val) ++{ ++ u32 mdio_ctrl; ++ ++ mdio_ctrl = MDIO_CTRL_OP_WRITE | ++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) | ++ (regad & MDIO_CTRL_REGAD_MASK); ++ ++ vr9_switch_mdio_poll(); ++ ltq_writel(&switch_regs->mdio.mdio_write, val); ++ ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl); ++ ++ return 0; ++} ++ ++static void ltq_eth_gmac_update(struct phy_device *phydev, int num) ++{ ++ struct ltq_mdio_phy_addr_reg phy_addr_reg; ++ struct ltq_mii_mii_cfg_reg mii_cfg_reg; ++ ++ phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num)); ++ ++ switch (num) { ++ case 0: ++ case 1: ++ case 5: ++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num)); ++ break; ++ default: ++ mii_cfg_reg.val = 0; ++ break; ++ } ++ ++ phy_addr_reg.bits.addr = phydev->addr; ++ ++ if (phydev->link) ++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_UP; ++ else ++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN; ++ ++ switch (phydev->speed) { ++ case SPEED_1000: ++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_G1; ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M125; ++ break; ++ case SPEED_100: ++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M100; ++ switch (mii_cfg_reg.bits.miimode) { ++ case LTQ_MII_MII_CFG_MIIMODE_RMIIM: ++ case LTQ_MII_MII_CFG_MIIMODE_RMIIP: ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M50; ++ break; ++ default: ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M25; ++ break; ++ } ++ break; ++ default: ++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10; ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5; ++ break; ++ } ++ ++ if (phydev->duplex == DUPLEX_FULL) ++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_ENABLE; ++ else ++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE; ++ ++ ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val); ++ ++ switch (num) { ++ case 0: ++ case 1: ++ case 5: ++ ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val); ++ break; ++ default: ++ break; ++ } ++} ++ ++static inline u8 *ltq_eth_rx_packet_align(int rx_num) ++{ ++ u8 *packet = (u8 *) NetRxPackets[rx_num]; ++ ++ /* ++ * IP header needs ++ */ ++ return packet + LTQ_ETH_IP_ALIGN; ++} ++ ++static int ltq_eth_init(struct eth_device *dev, bd_t * bis) ++{ ++ struct ltq_eth_priv *priv = dev->priv; ++ struct ltq_dma_device *dma_dev = &priv->dma_dev; ++ struct phy_device *phydev; ++ int i; ++ ++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) { ++ phydev = priv->phymap[i]; ++ if (!phydev) ++ continue; ++ ++ phy_startup(phydev); ++ ltq_eth_gmac_update(phydev, i); ++ } ++ ++ for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++) ++ ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i), ++ LTQ_ETH_RX_DATA_SIZE); ++ ++ ltq_dma_enable(dma_dev); ++ ++ priv->rx_num = 0; ++ priv->tx_num = 0; ++ ++ return 0; ++} ++ ++static void ltq_eth_halt(struct eth_device *dev) ++{ ++ struct ltq_eth_priv *priv = dev->priv; ++ struct ltq_dma_device *dma_dev = &priv->dma_dev; ++ struct phy_device *phydev; ++ int i; ++ ++ ltq_dma_reset(dma_dev); ++ ++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) { ++ phydev = priv->phymap[i]; ++ if (!phydev) ++ continue; ++ ++ phy_shutdown(phydev); ++ phydev->link = 0; ++ ltq_eth_gmac_update(phydev, i); ++ } ++} ++ ++static int ltq_eth_send(struct eth_device *dev, void *packet, int length) ++{ ++ struct ltq_eth_priv *priv = dev->priv; ++ struct ltq_dma_device *dma_dev = &priv->dma_dev; ++ ++#if 0 ++ printf("%s: packet %p, len %d\n", __func__, packet, length); ++#endif ++ ++ ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10); ++ priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT; ++ ++ return 0; ++} ++ ++static int ltq_eth_recv(struct eth_device *dev) ++{ ++ struct ltq_eth_priv *priv = dev->priv; ++ struct ltq_dma_device *dma_dev = &priv->dma_dev; ++ u8 *packet; ++ int len; ++ ++ if (!ltq_dma_rx_poll(dma_dev, priv->rx_num)) ++ return 0; ++ ++#if 0 ++ printf("%s: rx_num %d\n", __func__, priv->rx_num); ++#endif ++ ++ len = ltq_dma_rx_length(dma_dev, priv->rx_num); ++ packet = ltq_eth_rx_packet_align(priv->rx_num); ++ ++#if 0 ++ printf("%s: received: packet %p, len %u, rx_num %d\n", ++ __func__, packet, len, priv->rx_num); ++#endif ++ ++ if (len) ++ NetReceive(packet, len); ++ ++ ltq_dma_rx_map(dma_dev, priv->rx_num, packet, ++ LTQ_ETH_RX_DATA_SIZE); ++ ++ priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT; ++ ++ return 0; ++} ++ ++static void ltq_eth_gmac_init(int num) ++{ ++ struct ltq_mdio_phy_addr_reg phy_addr_reg; ++ struct ltq_mii_mii_cfg_reg mii_cfg_reg; ++ ++ /* Reset PHY status to link down */ ++ phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num)); ++ phy_addr_reg.bits.addr = num; ++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN; ++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10; ++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE; ++ ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val); ++ ++ /* Reset and disable MII interface */ ++ switch (num) { ++ case 0: ++ case 1: ++ case 5: ++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num)); ++ mii_cfg_reg.bits.en = 0; ++ mii_cfg_reg.bits.res = 1; ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5; ++ ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val); ++ break; ++ default: ++ break; ++ } ++ ++ /* ++ * - enable frame checksum generation ++ * - enable padding of short frames ++ * - disable flow control ++ */ ++ ltq_writel(to_mac_ctrl(switch_regs, num, 0), ++ MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE); ++ ++ vr9_switch_sync(); ++} ++ ++static void ltq_eth_pmac_init(void) ++{ ++ /* ++ * WAR: buffer congestion: ++ * - shorten preambel to 1 byte ++ * - set TX IPG to 7 bytes ++ */ ++#if 1 ++ ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 1), ++ MAC_CTRL1_SHORTPRE | 7); ++#endif ++ ++ /* ++ * WAR: systematical concept weakness ACM bug ++ * - set maximum number of used buffer segments to 254 ++ * - soft-reset BM FSQM ++ */ ++#if 1 ++ ltq_writel(&switch_regs->bm.core.fsqm_gctrl, 253); ++ ltq_setbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES); ++ ltq_clrbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES); ++#endif ++ ++ /* ++ * WAR: switch MAC drop bug ++ */ ++#if 1 ++ ltq_writel(to_pce_tbl_key(switch_regs, 0), 0xf); ++ ltq_writel(to_pce_tbl_value(switch_regs, 0), 0x40); ++ ltq_writel(&switch_regs->pce.core.tbl_addr, 0x3); ++ ltq_writel(&switch_regs->pce.core.tbl_ctrl, 0x902f); ++#endif ++ ++ /* ++ * Configure frame header control: ++ * - enable flow control ++ * - enable CRC check for packets from DMA to PMAC ++ * - remove special tag from packets from PMAC to DMA ++ * - add CRC for packets from DMA to PMAC ++ */ ++ ltq_writel(&switch_regs->pmac.hd_ctl, /*PMAC_HD_CTL_FC |*/ ++ PMAC_HD_CTL_CCRC | PMAC_HD_CTL_RST | PMAC_HD_CTL_AC | ++ PMAC_HD_CTL_RC); ++ ++#if 1 ++ ltq_writel(&switch_regs->pmac.rx_ipg, 0x8b); ++#endif ++ ++ /* ++ * - enable frame checksum generation ++ * - enable padding of short frames ++ * - disable flow control ++ */ ++ ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 0), ++ MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE); ++ ++ vr9_switch_sync(); ++} ++ ++static void ltq_eth_hw_init(void) ++{ ++ int i; ++ ++ /* Power up ethernet and switch subsystems */ ++ ltq_pm_enable(LTQ_PM_ETH); ++ ++ /* Reset ethernet and switch subsystems */ ++#if 0 ++ ltq_reset_once(LTQ_RESET_ETH, 10); ++#endif ++ ++ /* Enable switch macro */ ++ ltq_setbits(&switch_regs->mdio.glob_ctrl, MDIO_GLOB_CTRL_SE); ++ ++ /* Disable MDIO auto-polling for all ports */ ++ ltq_writel(&switch_regs->mdio.mdc_cfg_0, 0); ++ ++ /* ++ * Enable and set MDIO management clock to 2.5 MHz. This is the ++ * maximum clock for FE PHYs. ++ * Formula for clock is: ++ * ++ * 50 MHz ++ * x = ----------- - 1 ++ * 2 * f_MDC ++ */ ++ ltq_writel(&switch_regs->mdio.mdc_cfg_1, MDIO_MDC_CFG1_RES | ++ MDIO_MDC_CFG1_MCEN | 5); ++ ++ vr9_switch_sync(); ++ ++ /* Init MAC connected to CPU */ ++ ltq_eth_pmac_init(); ++ ++ /* Init MACs connected to external MII interfaces */ ++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) ++ ltq_eth_gmac_init(i); ++} ++ ++static void ltq_eth_port_config(struct ltq_eth_priv *priv, ++ const struct ltq_eth_port_config *port) ++{ ++ struct ltq_mii_mii_cfg_reg mii_cfg_reg; ++ struct phy_device *phydev; ++ int setup_gpio = 0; ++ ++ switch (port->num) { ++ case 0: /* xMII0 */ ++ case 1: /* xMII1 */ ++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, ++ port->num)); ++ mii_cfg_reg.bits.en = port->flags ? 1 : 0; ++ ++ switch (port->phy_if) { ++ case PHY_INTERFACE_MODE_MII: ++ if (port->flags & LTQ_ETH_PORT_PHY) ++ /* MII MAC mode, connected to external PHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_MIIM; ++ else ++ /* MII PHY mode, connected to external MAC */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_MIIP; ++ setup_gpio = 1; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ if (port->flags & LTQ_ETH_PORT_PHY) ++ /* RMII MAC mode, connected to external PHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_RMIIM; ++ else ++ /* RMII PHY mode, connected to external MAC */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_RMIIP; ++ setup_gpio = 1; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ /* RGMII MAC mode, connected to external PHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_RGMII; ++ setup_gpio = 1; ++ ++ /* RGMII clock delays */ ++ ltq_writel(to_mii_pcdu(switch_regs, port->num), ++ port->rgmii_rx_delay << PCDU_RXDLY_SHIFT | ++ port->rgmii_tx_delay); ++ break; ++ default: ++ break; ++ } ++ ++ ltq_writel(to_mii_miicfg(switch_regs, port->num), ++ mii_cfg_reg.val); ++ break; ++ case 2: /* internal GPHY0 */ ++ case 3: /* internal GPHY0 */ ++ case 4: /* internal GPHY1 */ ++ switch (port->phy_if) { ++ case PHY_INTERFACE_MODE_MII: ++ case PHY_INTERFACE_MODE_GMII: ++ setup_gpio = 1; ++ break; ++ default: ++ break; ++ } ++ break; ++ case 5: /* internal GPHY1 or xMII2 */ ++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, ++ port->num)); ++ mii_cfg_reg.bits.en = port->flags ? 1 : 0; ++ ++ switch (port->phy_if) { ++ case PHY_INTERFACE_MODE_MII: ++ /* MII MAC mode, connected to internal GPHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_MIIM; ++ setup_gpio = 1; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ /* RGMII MAC mode, connected to external PHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_RGMII; ++ setup_gpio = 1; ++ ++ /* RGMII clock delays */ ++ ltq_writel(to_mii_pcdu(switch_regs, port->num), ++ port->rgmii_rx_delay << PCDU_RXDLY_SHIFT | ++ port->rgmii_tx_delay); ++ break; ++ default: ++ break; ++ } ++ ++ ltq_writel(to_mii_miicfg(switch_regs, port->num), ++ mii_cfg_reg.val); ++ break; ++ default: ++ break; ++ } ++ ++ /* Setup GPIOs for MII with external PHYs/MACs */ ++ if (setup_gpio) { ++ /* MII/MDIO */ ++ gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, ++ GPIO_DIR_OUT); ++ /* MII/MDC */ ++ gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, ++ GPIO_DIR_OUT); ++ } ++ ++ /* Connect to internal/external PHYs */ ++ if (port->flags & LTQ_ETH_PORT_PHY) { ++ phydev = phy_connect(priv->bus, port->phy_addr, priv->dev, ++ port->phy_if); ++ if (phydev) ++ phy_config(phydev); ++ ++ priv->phymap[port->num] = phydev; ++ } ++} ++ ++int ltq_eth_initialize(const struct ltq_eth_board_config *board_config) ++{ ++ struct eth_device *dev; ++ struct mii_dev *bus; ++ struct ltq_eth_priv *priv; ++ struct ltq_dma_device *dma_dev; ++ int i, ret; ++ ++ build_check_vr9_registers(); ++ ++ ltq_dma_init(); ++ ltq_eth_hw_init(); ++ ++ dev = calloc(1, sizeof(struct eth_device)); ++ if (!dev) ++ return -1; ++ ++ priv = calloc(1, sizeof(struct ltq_eth_priv)); ++ if (!priv) ++ return -1; ++ ++ bus = mdio_alloc(); ++ if (!bus) ++ return -1; ++ ++ sprintf(dev->name, LTQ_ETH_DRV_NAME); ++ dev->priv = priv; ++ dev->init = ltq_eth_init; ++ dev->halt = ltq_eth_halt; ++ dev->recv = ltq_eth_recv; ++ dev->send = ltq_eth_send; ++ ++ sprintf(bus->name, LTQ_MDIO_DRV_NAME); ++ bus->read = vr9_switch_mdio_read; ++ bus->write = vr9_switch_mdio_write; ++ bus->priv = priv; ++ ++ dma_dev = &priv->dma_dev; ++ dma_dev->port = 0; ++ dma_dev->rx_chan.chan_no = 0; ++ dma_dev->rx_chan.class = 0; ++ dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT; ++ dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0; ++ dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS; ++ dma_dev->tx_chan.chan_no = 1; ++ dma_dev->tx_chan.class = 0; ++ dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT; ++ dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0; ++ dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS; ++ ++ priv->bus = bus; ++ priv->dev = dev; ++ ++ ret = ltq_dma_register(dma_dev); ++ if (ret) ++ return -1; ++ ++ ret = mdio_register(bus); ++ if (ret) ++ return -1; ++ ++ ret = eth_register(dev); ++ if (ret) ++ return -1; ++ ++ for (i = 0; i < board_config->num_ports; i++) ++ ltq_eth_port_config(priv, &board_config->ports[i]); ++ ++ return 0; ++} +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -34,6 +34,7 @@ COBJS-$(CONFIG_PHYLIB_10G) += generic_10 + COBJS-$(CONFIG_PHY_ATHEROS) += atheros.o + COBJS-$(CONFIG_PHY_BROADCOM) += broadcom.o + COBJS-$(CONFIG_PHY_DAVICOM) += davicom.o ++COBJS-$(CONFIG_PHY_LANTIQ) += lantiq.o + COBJS-$(CONFIG_PHY_LXT) += lxt.o + COBJS-$(CONFIG_PHY_MARVELL) += marvell.o + COBJS-$(CONFIG_PHY_MICREL) += micrel.o +--- /dev/null ++++ b/drivers/net/phy/lantiq.c +@@ -0,0 +1,239 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define DEBUG ++ ++#include <common.h> ++#include <miiphy.h> ++ ++#define ADVERTIZE_MPD (1 << 10) ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* ++ * Update link status. ++ * ++ * Based on genphy_update_link in phylib.c ++ */ ++static int ltq_phy_update_link(struct phy_device *phydev) ++{ ++ unsigned int mii_reg; ++ ++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); ++ ++ /* ++ * If we already saw the link up, and it hasn't gone down, then ++ * we don't need to wait for autoneg again ++ */ ++ if (phydev->link && mii_reg & BMSR_LSTATUS) ++ return 0; ++ ++ if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) { ++ phydev->link = 0; ++ return 0; ++ } else { ++ /* Read the link a second time to clear the latched state */ ++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); ++ ++ if (mii_reg & BMSR_LSTATUS) ++ phydev->link = 1; ++ else ++ phydev->link = 0; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Update speed and duplex. ++ * ++ * Based on genphy_parse_link in phylib.c ++ */ ++static int ltq_phy_parse_link(struct phy_device *phydev) ++{ ++ unsigned int mii_reg; ++ ++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); ++ ++ /* We're using autonegotiation */ ++ if (mii_reg & BMSR_ANEGCAPABLE) { ++ u32 lpa = 0; ++ u32 gblpa = 0; ++ ++ /* Check for gigabit capability */ ++ if (mii_reg & BMSR_ERCAP) { ++ /* We want a list of states supported by ++ * both PHYs in the link ++ */ ++ gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000); ++ gblpa &= phy_read(phydev, ++ MDIO_DEVAD_NONE, MII_CTRL1000) << 2; ++ } ++ ++ /* Set the baseline so we only have to set them ++ * if they're different ++ */ ++ phydev->speed = SPEED_10; ++ phydev->duplex = DUPLEX_HALF; ++ ++ /* Check the gigabit fields */ ++ if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) { ++ phydev->speed = SPEED_1000; ++ ++ if (gblpa & PHY_1000BTSR_1000FD) ++ phydev->duplex = DUPLEX_FULL; ++ ++ /* We're done! */ ++ return 0; ++ } ++ ++ lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE); ++ lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA); ++ ++ if (lpa & (LPA_100FULL | LPA_100HALF)) { ++ phydev->speed = SPEED_100; ++ ++ if (lpa & LPA_100FULL) ++ phydev->duplex = DUPLEX_FULL; ++ ++ } else if (lpa & LPA_10FULL) ++ phydev->duplex = DUPLEX_FULL; ++ } else { ++ u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); ++ ++ phydev->speed = SPEED_10; ++ phydev->duplex = DUPLEX_HALF; ++ ++ if (bmcr & BMCR_FULLDPLX) ++ phydev->duplex = DUPLEX_FULL; ++ ++ if (bmcr & BMCR_SPEED1000) ++ phydev->speed = SPEED_1000; ++ else if (bmcr & BMCR_SPEED100) ++ phydev->speed = SPEED_100; ++ } ++ ++ return 0; ++} ++ ++static int ltq_phy_config(struct phy_device *phydev) ++{ ++ u16 val; ++ ++ /* Advertise as Multi-port device */ ++ val = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); ++ val |= ADVERTIZE_MPD; ++ phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, val); ++ ++ genphy_config_aneg(phydev); ++ ++ return 0; ++} ++ ++static int ltq_phy_startup(struct phy_device *phydev) ++{ ++ /* ++ * Update PHY status immediately without any delays as genphy_startup ++ * does because VRX200 switch needs to be configured dependent ++ * on this information. ++ */ ++ ltq_phy_update_link(phydev); ++ ltq_phy_parse_link(phydev); ++ ++ debug("ltq_phy: addr %d, link %d, speed %d, duplex %d\n", ++ phydev->addr, phydev->link, phydev->speed, phydev->duplex); ++ ++ return 0; ++} ++ ++static struct phy_driver xrx_11g_13_driver = { ++ .name = "Lantiq XWAY XRX PHY11G v1.3 and earlier", ++ .uid = 0x030260D0, ++ .mask = 0xFFFFFFF0, ++ .features = PHY_GBIT_FEATURES, ++ .config = ltq_phy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++static struct phy_driver xrx_11g_14_driver = { ++ .name = "Lantiq XWAY XRX PHY11G v1.4 and later", ++ .uid = 0xd565a408, ++ .mask = 0xFFFFFFF8, ++ .features = PHY_GBIT_FEATURES, ++ .config = ltq_phy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++static struct phy_driver xrx_22f_14_driver = { ++ .name = "Lantiq XWAY XRX PHY22F v1.4 and later", ++ .uid = 0xd565a418, ++ .mask = 0xFFFFFFF8, ++ .features = PHY_BASIC_FEATURES, ++ .config = ltq_phy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++static struct phy_driver pef7071_driver = { ++ .name = "Lantiq XWAY PEF7071", ++ .uid = 0xd565a400, ++ .mask = 0xFFFFFFFF, ++ .features = PHY_GBIT_FEATURES, ++ .config = ltq_phy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++static struct phy_driver xrx_genphy_driver = { ++ .name = "Generic PHY at Lantiq XWAY XRX switch", ++ .uid = 0, ++ .mask = 0, ++ .features = 0, ++ .config = genphy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++int phy_lantiq_init(void) ++{ ++#ifdef CONFIG_NEEDS_MANUAL_RELOC ++ xrx_11g_13_driver.config = ltq_phy_config; ++ xrx_11g_13_driver.startup = ltq_phy_startup; ++ xrx_11g_13_driver.shutdown = genphy_shutdown; ++ xrx_11g_13_driver.name += gd->reloc_off; ++ ++ xrx_11g_14_driver.config = ltq_phy_config; ++ xrx_11g_14_driver.startup = ltq_phy_startup; ++ xrx_11g_14_driver.shutdown = genphy_shutdown; ++ xrx_11g_14_driver.name += gd->reloc_off; ++ ++ xrx_22f_14_driver.config = ltq_phy_config; ++ xrx_22f_14_driver.startup = ltq_phy_startup; ++ xrx_22f_14_driver.shutdown = genphy_shutdown; ++ xrx_22f_14_driver.name += gd->reloc_off; ++ ++ pef7071_driver.config = ltq_phy_config; ++ pef7071_driver.startup = ltq_phy_startup; ++ pef7071_driver.shutdown = genphy_shutdown; ++ pef7071_driver.name += gd->reloc_off; ++ ++ xrx_genphy_driver.config = genphy_config; ++ xrx_genphy_driver.startup = ltq_phy_startup; ++ xrx_genphy_driver.shutdown = genphy_shutdown; ++ xrx_genphy_driver.name += gd->reloc_off; ++#endif ++ ++ phy_register(&xrx_11g_13_driver); ++ phy_register(&xrx_11g_14_driver); ++ phy_register(&xrx_22f_14_driver); ++ phy_register(&pef7071_driver); ++ phy_register(&xrx_genphy_driver); ++ ++ return 0; ++} +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -32,6 +32,8 @@ + #include <phy.h> + #include <errno.h> + ++DECLARE_GLOBAL_DATA_PTR; ++ + /* Generic PHY support and helper functions */ + + /** +@@ -420,6 +422,16 @@ static LIST_HEAD(phy_drivers); + + int phy_init(void) + { ++#ifdef CONFIG_NEEDS_MANUAL_RELOC ++ INIT_LIST_HEAD(&phy_drivers); ++ ++ genphy_driver.config = genphy_config; ++ genphy_driver.startup = genphy_startup; ++ genphy_driver.shutdown = genphy_shutdown; ++ ++ genphy_driver.name += gd->reloc_off; ++#endif ++ + #ifdef CONFIG_PHY_ATHEROS + phy_atheros_init(); + #endif +@@ -429,6 +441,9 @@ int phy_init(void) + #ifdef CONFIG_PHY_DAVICOM + phy_davicom_init(); + #endif ++#ifdef CONFIG_PHY_LANTIQ ++ phy_lantiq_init(); ++#endif + #ifdef CONFIG_PHY_LXT + phy_lxt_init(); + #endif +--- a/drivers/serial/Makefile ++++ b/drivers/serial/Makefile +@@ -42,6 +42,7 @@ COBJS-$(CONFIG_SYS_NS16550_SERIAL) += se + COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o + COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o + COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o ++COBJS-$(CONFIG_LANTIQ_SERIAL) += serial_lantiq.o + COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o + COBJS-$(CONFIG_MXC_UART) += serial_mxc.o + COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o +--- /dev/null ++++ b/drivers/serial/serial_lantiq.c +@@ -0,0 +1,264 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <serial.h> ++#include <asm/errno.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/io.h> ++ ++#if CONFIG_CONSOLE_ASC == 0 ++#define LTQ_ASC_BASE LTQ_ASC0_BASE ++#else ++#define LTQ_ASC_BASE LTQ_ASC1_BASE ++#endif ++ ++#define LTQ_ASC_ID_TXFS_SHIFT 24 ++#define LTQ_ASC_ID_TXFS_MASK (0x3F << LTQ_ASC_ID_TXFS_SHIFT) ++#define LTQ_ASC_ID_RXFS_SHIFT 16 ++#define LTQ_ASC_ID_RXFS_MASK (0x3F << LTQ_ASC_ID_RXFS_SHIFT) ++ ++#define LTQ_ASC_MCON_R (1 << 15) ++#define LTQ_ASC_MCON_FDE (1 << 9) ++ ++#define LTQ_ASC_WHBSTATE_SETREN (1 << 1) ++#define LTQ_ASC_WHBSTATE_CLRREN (1 << 0) ++ ++#define LTQ_ASC_RXFCON_RXFITL_SHIFT 8 ++#define LTQ_ASC_RXFCON_RXFITL_MASK (0x3F << LTQ_ASC_RXFCON_RXFITL_SHIFT) ++#define LTQ_ASC_RXFCON_RXFITL_RXFFLU (1 << 1) ++#define LTQ_ASC_RXFCON_RXFITL_RXFEN (1 << 0) ++ ++#define LTQ_ASC_TXFCON_TXFITL_SHIFT 8 ++#define LTQ_ASC_TXFCON_TXFITL_MASK (0x3F << LTQ_ASC_TXFCON_TXFITL_SHIFT) ++#define LTQ_ASC_TXFCON_TXFITL_TXFFLU (1 << 1) ++#define LTQ_ASC_TXFCON_TXFITL_TXFEN (1 << 0) ++ ++#define LTQ_ASC_FSTAT_TXFREE_SHIFT 24 ++#define LTQ_ASC_FSTAT_TXFREE_MASK (0x3F << LTQ_ASC_FSTAT_TXFREE_SHIFT) ++#define LTQ_ASC_FSTAT_RXFREE_SHIFT 16 ++#define LTQ_ASC_FSTAT_RXFREE_MASK (0x3F << LTQ_ASC_FSTAT_RXFREE_SHIFT) ++#define LTQ_ASC_FSTAT_TXFFL_SHIFT 8 ++#define LTQ_ASC_FSTAT_TXFFL_MASK (0x3F << LTQ_ASC_FSTAT_TXFFL_SHIFT) ++#define LTQ_ASC_FSTAT_RXFFL_MASK 0x3F ++ ++#ifdef __BIG_ENDIAN ++#define LTQ_ASC_RBUF_OFFSET 3 ++#define LTQ_ASC_TBUF_OFFSET 3 ++#else ++#define LTQ_ASC_RBUF_OFFSET 0 ++#define LTQ_ASC_TBUF_OFFSET 0 ++#endif ++ ++struct ltq_asc_regs { ++ u32 clc; ++ u32 pisel; ++ u32 id; ++ u32 rsvd0; ++ u32 mcon; ++ u32 state; ++ u32 whbstate; ++ u32 rsvd1; ++ u8 tbuf[4]; ++ u8 rbuf[4]; ++ u32 rsvd2[2]; ++ u32 abcon; ++ u32 abstat; ++ u32 whbabcon; ++ u32 whbabstat; ++ u32 rxfcon; ++ u32 txfcon; ++ u32 fstat; ++ u32 rsvd3; ++ u32 bg; ++ u32 bg_timer; ++ u32 fdv; ++ u32 pmw; ++ u32 modcon; ++ u32 modstat; ++}; ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++static struct ltq_asc_regs *ltq_asc_regs = ++ (struct ltq_asc_regs *) CKSEG1ADDR(LTQ_ASC_BASE); ++ ++static int ltq_serial_init(void) ++{ ++ /* Set clock divider for normal run mode to 1 and enable module */ ++ ltq_writel(<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 = "ixp_serial", ++ .start = ltq_serial_init, ++ .stop = NULL, ++ .setbrg = ltq_serial_setbrg, ++ .putc = ltq_serial_putc, ++ .puts = default_serial_puts, ++ .getc = ltq_serial_getc, ++ .tstc = ltq_serial_tstc, ++}; ++ ++void ixp_serial_initialize(void) ++{ ++ serial_register(<q_serial_drv); ++} ++ ++__weak struct serial_device *default_serial_console(void) ++{ ++ return <q_serial_drv; ++} +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -36,6 +36,7 @@ COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o + COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o + COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o + COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o ++COBJS-$(CONFIG_LANTIQ_SPI) += lantiq_spi.o + COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o + COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o + COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o +--- /dev/null ++++ b/drivers/spi/lantiq_spi.c +@@ -0,0 +1,476 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <spi.h> ++#include <malloc.h> ++#include <watchdog.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/pm.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_SPI_CLC_RMC_SHIFT 8 ++#define LTQ_SPI_CLC_RMC_MASK (0xFF << LTQ_SPI_CLC_RMC_SHIFT) ++#define LTQ_SPI_CLC_DISS (1 << 1) ++#define LTQ_SPI_CLC_DISR 1 ++ ++#define LTQ_SPI_ID_TXFS_SHIFT 24 ++#define LTQ_SPI_ID_TXFS_MASK (0x3F << LTQ_SPI_ID_TXFS_SHIFT) ++#define LTQ_SPI_ID_RXFS_SHIFT 16 ++#define LTQ_SPI_ID_RXFS_MASK (0x3F << LTQ_SPI_ID_RXFS_SHIFT) ++ ++#define LTQ_SPI_CON_ENBV (1 << 22) ++#define LTQ_SPI_CON_BM_SHIFT 16 ++#define LTQ_SPI_CON_BM_MASK (0x1F << LTQ_SPI_CON_BM_SHIFT) ++#define LTQ_SPI_CON_LB (1 << 7) ++#define LTQ_SPI_CON_PO (1 << 6) ++#define LTQ_SPI_CON_PH (1 << 5) ++#define LTQ_SPI_CON_HB (1 << 4) ++#define LTQ_SPI_CON_RXOFF (1 << 1) ++#define LTQ_SPI_CON_TXOFF 1 ++ ++#define LTQ_SPI_STAT_RXBV_SHIFT 28 ++#define LTQ_SPI_STAT_RXBV_MASK (0x7 << LTQ_SPI_STAT_RXBV_SHIFT) ++#define LTQ_SPI_STAT_BSY (1 << 13) ++ ++#define LTQ_SPI_WHBSTATE_SETMS (1 << 3) ++#define LTQ_SPI_WHBSTATE_CLRMS (1 << 2) ++#define LTQ_SPI_WHBSTATE_SETEN (1 << 1) ++#define LTQ_SPI_WHBSTATE_CLREN 1 ++ ++#define LTQ_SPI_TXFCON_TXFLU (1 << 1) ++#define LTQ_SPI_TXFCON_TXFEN 1 ++ ++#define LTQ_SPI_RXFCON_RXFLU (1 << 1) ++#define LTQ_SPI_RXFCON_RXFEN 1 ++ ++#define LTQ_SPI_FSTAT_RXFFL_MASK 0x3f ++#define LTQ_SPI_FSTAT_TXFFL_SHIFT 8 ++#define LTQ_SPI_FSTAT_TXFFL_MASK (0x3f << LTQ_SPI_FSTAT_TXFFL_SHIFT) ++ ++#define LTQ_SPI_RXREQ_RXCNT_MASK 0xFFFF ++#define LTQ_SPI_RXCNT_TODO_MASK 0xFFFF ++ ++#define LTQ_SPI_GPIO_DIN 16 ++#define LTQ_SPI_GPIO_DOUT 17 ++#define LTQ_SPI_GPIO_CLK 18 ++ ++struct ltq_spi_regs { ++ u32 clc; /* Clock control */ ++ u32 pisel; /* Port input select */ ++ u32 id; /* Identification */ ++ u32 rsvd0; ++ u32 con; /* Control */ ++ u32 stat; /* Status */ ++ u32 whbstate; /* Write HW modified state */ ++ u32 rsvd1; ++ u32 tb; /* Transmit buffer */ ++ u32 rb; /* Receive buffer */ ++ u32 rsvd2[2]; ++ u32 rxfcon; /* Recevie FIFO control */ ++ u32 txfcon; /* Transmit FIFO control */ ++ u32 fstat; /* FIFO status */ ++ u32 rsvd3; ++ u32 brt; /* Baudrate timer */ ++ u32 brstat; /* Baudrate timer status */ ++ u32 rsvd4[6]; ++ u32 sfcon; /* Serial frame control */ ++ u32 sfstat; /* Serial frame status */ ++ u32 rsvd5[2]; ++ u32 gpocon; /* General purpose output control */ ++ u32 gpostat; /* General purpose output status */ ++ u32 fgpo; /* Force general purpose output */ ++ u32 rsvd6; ++ u32 rxreq; /* Receive request */ ++ u32 rxcnt; /* Receive count */ ++ u32 rsvd7[25]; ++ u32 dmacon; /* DMA control */ ++}; ++ ++struct ltq_spi_slave { ++ struct spi_slave slave; ++ unsigned int max_hz; ++ unsigned int mode; ++ unsigned int len; ++ unsigned int brt; ++ unsigned int tx_cnt; ++ unsigned int rx_cnt; ++ unsigned int rx_req; ++ const u8 *tx; ++ u8 *rx; ++ u8 txfs; ++ u8 rxfs; ++}; ++ ++static inline struct ltq_spi_slave *to_ltq_spi_slave(struct spi_slave *slave) ++{ ++ return container_of(slave, struct ltq_spi_slave, slave); ++} ++ ++#ifdef CONFIG_SPL_BUILD ++/* ++ * We do not have or want malloc in a SPI flash SPL. ++ * Neither we have to support multiple SPI slaves. Thus we put the ++ * SPI slave context in BSS for SPL builds. ++ */ ++static struct ltq_spi_slave ltq_spi_slave; ++ ++static inline struct ltq_spi_slave *ltq_spi_slave_alloc(void) ++{ ++ return <q_spi_slave; ++} ++ ++static inline void ltq_spi_slave_free(struct spi_slave *slave) ++{ ++} ++#else ++static inline struct ltq_spi_slave *ltq_spi_slave_alloc(void) ++{ ++ return malloc(sizeof(struct ltq_spi_slave)); ++} ++ ++static inline void ltq_spi_slave_free(struct spi_slave *slave) ++{ ++ struct ltq_spi_slave *sl; ++ ++ if (slave) { ++ sl = to_ltq_spi_slave(slave); ++ free(sl); ++ } ++} ++#endif ++ ++static struct ltq_spi_regs *ltq_spi_regs = ++ (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE); ++ ++void spi_init(void) ++{ ++ /* Power up SPI subsystem */ ++ ltq_pm_enable(LTQ_PM_SPI); ++ ++ /* Enable module and set clock divider to 1 */ ++ ltq_writel(<q_spi_regs->clc, 1 << LTQ_SPI_CLC_RMC_SHIFT); ++ ++ /* SPI/DIN input */ ++ gpio_set_altfunc(16, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN); ++ /* SPI/DOUT output */ ++ gpio_set_altfunc(17, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* SPI/CLK output */ ++ gpio_set_altfunc(18, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++} ++ ++static inline u32 ltq_spi_calc_br(unsigned int max_hz) ++{ ++ u32 speed_hz, spi_hz; ++ u16 brt; ++ ++ /* SPI module clock is same as FPI bus clock */ ++ spi_hz = ltq_get_bus_clock(); ++ ++ /* ++ * f_SPI ++ * baudrate = -------------- ++ * 2 * (BR + 1) ++ */ ++ spi_hz /= 2; ++ ++ for (brt = 0; brt < 0xFFFF; brt++) { ++ speed_hz = spi_hz / (brt + 1); ++ if (speed_hz <= max_hz) ++ break; ++ } ++ ++ return brt; ++} ++ ++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, ++ unsigned int max_hz, unsigned int mode) ++{ ++ u32 id; ++ struct ltq_spi_slave *sl; ++ ++ if (!spi_cs_is_valid(bus, cs)) ++ return NULL; ++ ++ sl = ltq_spi_slave_alloc(); ++ if (!sl) ++ return NULL; ++ ++ /* Read HW capabilities */ ++ id = ltq_readl(<q_spi_regs->id); ++ sl->txfs = (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT; ++ sl->rxfs = (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT; ++ ++ sl->slave.bus = bus; ++ sl->slave.cs = cs; ++ sl->max_hz = max_hz; ++ sl->mode = mode; ++ ++ sl->brt = ltq_spi_calc_br(max_hz); ++ ++ return &sl->slave; ++} ++ ++void spi_free_slave(struct spi_slave *slave) ++{ ++ ltq_spi_slave_free(slave); ++} ++ ++static int ltq_spi_wait_ready(struct ltq_spi_slave *sl) ++{ ++ u32 stat; ++ const unsigned long timeout = 20000; ++ unsigned long timebase; ++ ++ timebase = get_timer(0); ++ ++ do { ++ WATCHDOG_RESET(); ++ ++ stat = ltq_readl(<q_spi_regs->stat); ++ ++ if (!(stat & LTQ_SPI_STAT_BSY)) ++ return 0; ++ } while (get_timer(timebase) < timeout); ++ ++ return 1; ++} ++ ++int spi_claim_bus(struct spi_slave *slave) ++{ ++ struct ltq_spi_slave *sl = to_ltq_spi_slave(slave); ++ u32 con; ++ int ret; ++ ++ /* Put module in configuration mode */ ++ ltq_setbits(<q_spi_regs->whbstate, LTQ_SPI_WHBSTATE_CLREN); ++ ++ /* Enable and flush RX and TX FIFOs */ ++ ltq_setbits(<q_spi_regs->txfcon, ++ LTQ_SPI_TXFCON_TXFLU | LTQ_SPI_TXFCON_TXFEN); ++ ltq_setbits(<q_spi_regs->rxfcon, ++ LTQ_SPI_RXFCON_RXFLU | LTQ_SPI_RXFCON_RXFEN); ++ ++ ret = ltq_spi_wait_ready(sl); ++ if (ret) ++ return ret; ++ ++ /* Set baudrate */ ++ ltq_writel(<q_spi_regs->brt, sl->brt); ++ ++ /* ++ * Disable byte valid control (ENBV = 0) and ++ * set data width to 8 bit (BM = 7) ++ */ ++ con = (7 << LTQ_SPI_CON_BM_SHIFT); ++ ++ /* Disable transmitter and receiver */ ++ con |= (LTQ_SPI_CON_RXOFF | LTQ_SPI_CON_TXOFF); ++ ++ /* Set SPI mode ++ * Mapping: Mode CPOL CPHA CON.PO CON.PH ++ * 0 0 0 0 1 ++ * 1 0 1 0 0 ++ * 2 1 0 1 1 ++ * 3 1 1 1 0 ++ */ ++ if (sl->mode & SPI_CPHA) ++ con &= ~LTQ_SPI_CON_PH; ++ else ++ con |= LTQ_SPI_CON_PH; ++ ++ if (sl->mode & SPI_CPOL) ++ con |= LTQ_SPI_CON_PO; ++ else ++ con &= ~LTQ_SPI_CON_PO; ++ ++ /* Set heading control */ ++ if (sl->mode & SPI_LSB_FIRST) ++ con &= ~LTQ_SPI_CON_HB; ++ else ++ con |= LTQ_SPI_CON_HB; ++ ++ /* Set loopback control */ ++ if (sl->mode & SPI_LOOP) ++ con |= LTQ_SPI_CON_LB; ++ else ++ con &= ~LTQ_SPI_CON_LB; ++ ++ ltq_writel(<q_spi_regs->con, con); ++ ++ /* Set SPI master mode and enable SPI */ ++ ltq_setbits(<q_spi_regs->whbstate, ++ LTQ_SPI_WHBSTATE_SETEN | LTQ_SPI_WHBSTATE_SETMS); ++ ++ return 0; ++} ++ ++void spi_release_bus(struct spi_slave *slave) ++{ ++ /* Put module in configuration mode */ ++ ltq_setbits(<q_spi_regs->whbstate, LTQ_SPI_WHBSTATE_CLREN); ++ ++ /* Flush RX and TX FIFOs */ ++ ltq_setbits(<q_spi_regs->txfcon, LTQ_SPI_TXFCON_TXFLU); ++ ltq_setbits(<q_spi_regs->rxfcon, LTQ_SPI_RXFCON_RXFLU); ++} ++ ++static inline void ltq_spi_txfifo_write(struct ltq_spi_slave *sl) ++{ ++ u32 fstat, tb; ++ u16 fifo_space; ++ ++ fstat = ltq_readl(<q_spi_regs->fstat); ++ fifo_space = sl->txfs - ((fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >> ++ LTQ_SPI_FSTAT_TXFFL_SHIFT); ++ ++ while (sl->tx_cnt < sl->len && fifo_space) { ++ tb = *sl->tx++; ++ ltq_writel(<q_spi_regs->tb, tb); ++ fifo_space--; ++ sl->tx_cnt++; ++ } ++} ++ ++static inline void ltq_spi_rx_request(struct ltq_spi_slave *sl) ++{ ++ u32 rxreq, rxreq_max; ++ ++ /* ++ * In RX-only mode the serial clock is activated only after writing ++ * the expected amount of RX bytes into RXREQ register. ++ * To avoid receive overflows at high clocks it is better to request ++ * only the amount of bytes that fits into all FIFOs. This value ++ * depends on the FIFO size implemented in hardware. ++ */ ++ rxreq = sl->len - sl->rx_cnt; ++ rxreq_max = sl->rxfs << 2; ++ rxreq = min(rxreq_max, rxreq); ++ ++ if (!sl->rx_req && rxreq && sl->rx_cnt < sl->len) { ++ ltq_writel(<q_spi_regs->rxreq, rxreq); ++ sl->rx_req = rxreq; ++ } ++} ++ ++static void ltq_spi_rxfifo_read(struct ltq_spi_slave *sl) ++{ ++ u32 fstat, data, *rx32; ++ u16 fifo_fill; ++ u8 rxbv, shift, *rx8; ++ ++ /* Determine how much FIFOs are filled with RX data */ ++ fstat = ltq_readl(<q_spi_regs->fstat); ++ fifo_fill = fstat & LTQ_SPI_FSTAT_RXFFL_MASK; ++ ++ /* ++ * The 32 bit FIFO is always used completely independent from the ++ * bits_per_word value. Thus four bytes have to be read at once ++ * per FIFO. ++ */ ++ rx32 = (u32 *) sl->rx; ++ while (sl->len - sl->rx_cnt >= 4 && fifo_fill) { ++ data = ltq_readl(<q_spi_regs->rb); ++ *rx32++ = data; ++ sl->rx_cnt += 4; ++ sl->rx_req -= 4; ++ sl->rx += 4; ++ fifo_fill--; ++ } ++ ++ /* ++ * If there are remaining bytes, read byte count from STAT.RXBV ++ * register and read the data byte-wise. ++ */ ++ while (fifo_fill && sl->rx_cnt < sl->len) { ++ fstat = ltq_readl(<q_spi_regs->stat); ++ rxbv = (fstat & LTQ_SPI_STAT_RXBV_MASK) >> ++ LTQ_SPI_STAT_RXBV_SHIFT; ++ ++ if (!rxbv) ++ break; ++ ++ data = ltq_readl(<q_spi_regs->rb); ++ ++ shift = (rxbv - 1) * 8; ++ rx8 = sl->rx; ++ ++ while (rxbv) { ++ *rx8++ = (data >> shift) & 0xFF; ++ rxbv--; ++ shift -= 8; ++ sl->rx_cnt++; ++ sl->rx_req--; ++ sl->rx++; ++ } ++ ++ fifo_fill--; ++ } ++} ++ ++int spi_xfer(struct spi_slave *slave, unsigned int bitlen, ++ const void *dout, void *din, unsigned long flags) ++{ ++ struct ltq_spi_slave *sl = to_ltq_spi_slave(slave); ++ int ret; ++ ++ if (bitlen % 8) ++ return 1; ++ ++ if (!bitlen) { ++ ret = 0; ++ goto done; ++ } ++ ++ sl->len = bitlen / 8; ++ sl->tx = dout; ++ sl->rx = din; ++ sl->tx_cnt = 0; ++ sl->rx_cnt = 0; ++ sl->rx_req = 0; ++ ++ if (flags & SPI_XFER_BEGIN) ++ spi_cs_activate(slave); ++ ++ /* Enable transmitter */ ++ if (sl->tx) ++ ltq_clrbits(<q_spi_regs->con, LTQ_SPI_CON_TXOFF); ++ ++ /* Enable receiver */ ++ if (sl->rx) ++ ltq_clrbits(<q_spi_regs->con, LTQ_SPI_CON_RXOFF); ++ ++ if (sl->tx) ++ ltq_spi_txfifo_write(sl); ++ else if (sl->rx) ++ ltq_spi_rx_request(sl); ++ ++ while (sl->tx_cnt != sl->len && sl->rx_cnt != sl->len) { ++ if (sl->rx) { ++ ltq_spi_rxfifo_read(sl); ++ ++ if (sl->tx) ++ ltq_spi_txfifo_write(sl); ++ else ++ ltq_spi_rx_request(sl); ++ } else if (sl->tx) ++ ltq_spi_txfifo_write(sl); ++ } ++ ++ ret = ltq_spi_wait_ready(sl); ++ ++done: ++ /* Disable transmitter and receiver */ ++ ltq_setbits(<q_spi_regs->con, LTQ_SPI_CON_TXOFF | LTQ_SPI_CON_RXOFF); ++ ++ if (flags & SPI_XFER_END) ++ spi_cs_deactivate(slave); ++ ++ return ret; ++} +--- /dev/null ++++ b/include/configs/easy50712.h +@@ -0,0 +1,78 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "EASY50712" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Lantiq EASY50712 Danube Reference Board" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPI_FLASH ++#define CONFIG_SPI_FLASH_ATMEL /* Have an AT45DB321D serial flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */ ++ ++#define CONFIG_LTQ_SPL_COMP_LZO ++#define CONFIG_LTQ_SPL_CONSOLE ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_ADM6996I ++ ++/* Environment */ ++#define CONFIG_ENV_SPI_BUS 0 ++#define CONFIG_ENV_SPI_CS 2 ++#define CONFIG_ENV_SPI_MAX_HZ 20000000 ++#define CONFIG_ENV_SPI_MODE 0 ++ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (256 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#elif defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (128 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR ++ ++#endif /* __CONFIG_H */ +--- /dev/null ++++ b/include/configs/easy80920.h +@@ -0,0 +1,93 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "EASY80920" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Lantiq EASY80920 VRX200 Family Board" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPI_FLASH ++#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29LV620 serial flash */ ++ ++#define CONFIG_LTQ_SUPPORT_NAND_FLASH ++ ++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */ ++#define CONFIG_SPL_SPI_BUS 0 ++#define CONFIG_SPL_SPI_CS 4 ++#define CONFIG_SPL_SPI_MAX_HZ 25000000 ++#define CONFIG_SPL_SPI_MODE 0 ++ ++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */ ++ ++#define CONFIG_LTQ_SPL_COMP_LZO ++#define CONFIG_LTQ_SPL_CONSOLE ++ ++#define CONFIG_SYS_DRAM_PROBE ++ ++/* Environment */ ++#define CONFIG_ENV_SPI_BUS CONFIG_SPL_SPI_BUS ++#define CONFIG_ENV_SPI_CS CONFIG_SPL_SPI_CS ++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SPL_SPI_MAX_HZ ++#define CONFIG_ENV_SPI_MODE CONFIG_SPL_SPI_MODE ++ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (384 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#elif defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#elif defined(CONFIG_SYS_BOOT_SFSPL) ++#define CONFIG_ENV_IS_IN_SPI_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_SF \ ++ "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ CONFIG_ENV_UPDATE_UBOOT_SF ++ ++#endif /* __CONFIG_H */ +--- a/include/phy.h ++++ b/include/phy.h +@@ -220,6 +220,7 @@ int gen10g_discover_mmds(struct phy_devi + int phy_atheros_init(void); + int phy_broadcom_init(void); + int phy_davicom_init(void); ++int phy_lantiq_init(void); + int phy_lxt_init(void); + int phy_marvell_init(void); + int phy_micrel_init(void); +--- a/spl/Makefile ++++ b/spl/Makefile +@@ -81,6 +81,8 @@ LIBS-$(CONFIG_SPL_POST_MEM_SUPPORT) += p + LIBS-$(CONFIG_SPL_NET_SUPPORT) += net/libnet.o + LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/libnet.o + LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/libphy.o ++LIBS-$(CONFIG_SPL_LZMA_SUPPORT) += lib/lzma/liblzma.o ++LIBS-$(CONFIG_SPL_LZO_SUPPORT) += lib/lzo/liblzo.o + + ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) + LIBS-y += $(CPUDIR)/omap-common/libomap-common.o +--- a/tools/.gitignore ++++ b/tools/.gitignore +@@ -2,6 +2,7 @@ + /envcrc + /gen_eth_addr + /img2srec ++/ltq-boot-image + /kwboot + /mkenvimage + /mkimage +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -65,6 +65,7 @@ BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_lo + BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX) + BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX) + BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX) ++BIN_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image$(SFX) + BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX) + BIN_FILES-y += mkenvimage$(SFX) + BIN_FILES-y += mkimage$(SFX) +@@ -89,6 +90,7 @@ OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envc + NOPED_OBJ_FILES-y += fit_image.o + OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o + OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o ++OBJ_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image.o + OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o + NOPED_OBJ_FILES-y += aisimage.o + NOPED_OBJ_FILES-y += kwbimage.o +@@ -193,6 +195,10 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ + $(HOSTSTRIP) $@ + ++$(obj)ltq-boot-image$(SFX): $(obj)ltq-boot-image.o ++ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ ++ $(HOSTSTRIP) $@ ++ + $(obj)xway-swap-bytes$(SFX): $(obj)xway-swap-bytes.o + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ + $(HOSTSTRIP) $@ +--- /dev/null ++++ b/tools/ltq-boot-image.c +@@ -0,0 +1,316 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <unistd.h> ++#include <getopt.h> ++#include <compiler.h> ++#include <sys/stat.h> ++ ++enum image_types { ++ IMAGE_NONE, ++ IMAGE_SFSPL ++}; ++ ++/* Lantiq non-volatile bootstrap command IDs */ ++enum nvb_cmd_ids { ++ NVB_CMD_DEBUG = 0x11, ++ NVB_CMD_REGCFG = 0x22, ++ NVB_CMD_IDWNLD = 0x33, ++ NVB_CMD_CDWNLD = 0x44, ++ NVB_CMD_DWNLD = 0x55, ++ NVB_CMD_IFCFG = 0x66, ++ NVB_CMD_START = 0x77 ++}; ++ ++/* Lantiq non-volatile bootstrap command flags */ ++enum nvb_cmd_flags { ++ NVB_FLAG_START = 1, ++ NVB_FLAG_DEC = (1 << 1), ++ NVB_FLAG_DBG = (1 << 2), ++ NVB_FLAG_SDBG = (1 << 3), ++ NVB_FLAG_CFG0 = (1 << 4), ++ NVB_FLAG_CFG1 = (1 << 5), ++ NVB_FLAG_CFG2 = (1 << 6), ++ NVB_FLAG_RST = (1 << 7) ++}; ++ ++struct args { ++ enum image_types type; ++ __u32 entry_addr; ++ const char *uboot_bin; ++ const char *spl_bin; ++ const char *out_bin; ++}; ++ ++static void usage_msg(const char *name) ++{ ++ fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n", ++ name); ++ fprintf(stderr, " Image types:\n" ++ " sfspl - SPL + [compressed] U-Boot for SPI flash\n"); ++} ++ ++static enum image_types parse_image_type(const char *type) ++{ ++ if (!type) ++ return IMAGE_NONE; ++ ++ if (!strncmp(type, "sfspl", 6)) ++ return IMAGE_SFSPL; ++ ++ return IMAGE_NONE; ++} ++ ++static int parse_args(int argc, char *argv[], struct args *arg) ++{ ++ int opt; ++ ++ memset(arg, 0, sizeof(*arg)); ++ ++ while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) { ++ switch (opt) { ++ case 'h': ++ usage_msg(argv[0]); ++ return 1; ++ case 't': ++ arg->type = parse_image_type(optarg); ++ break; ++ case 'e': ++ arg->entry_addr = strtoul(optarg, NULL, 16); ++ break; ++ case 'u': ++ arg->uboot_bin = optarg; ++ break; ++ case 's': ++ arg->spl_bin = optarg; ++ break; ++ case 'o': ++ arg->out_bin = optarg; ++ break; ++ default: ++ fprintf(stderr, "Invalid option -%c\n", opt); ++ goto parse_error; ++ } ++ } ++ ++ if (arg->type == IMAGE_NONE) { ++ fprintf(stderr, "Invalid image type\n"); ++ goto parse_error; ++ } ++ ++ if (!arg->uboot_bin) { ++ fprintf(stderr, "Missing U-Boot binary\n"); ++ goto parse_error; ++ } ++ ++ if (!arg->out_bin) { ++ fprintf(stderr, "Missing output binary\n"); ++ goto parse_error; ++ } ++ ++ if (arg->type == IMAGE_SFSPL && !arg->spl_bin) { ++ fprintf(stderr, "Missing SPL binary\n"); ++ goto parse_error; ++ } ++ ++ return 0; ++ ++parse_error: ++ usage_msg(argv[0]); ++ return -1; ++} ++ ++static __u32 build_nvb_command(unsigned cmdid, unsigned cmdflags) ++{ ++ __u32 cmd; ++ __u16 tag; ++ ++ tag = (cmdid << 8) | cmdflags; ++ cmd = (tag << 16) | (0xFFFF - tag); ++ ++ return cpu_to_be32(cmd); ++} ++ ++static int write_header(int fd, const void *hdr, size_t size) ++{ ++ ssize_t n; ++ ++ n = write(fd, hdr, size); ++ if (n != size) { ++ fprintf(stderr, "Cannot write header: %s\n", ++ strerror(errno)); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int write_nvb_dwnld_header(int fd, size_t size, __u32 addr) ++{ ++ __u32 hdr[3]; ++ ++ hdr[0] = build_nvb_command(NVB_CMD_DWNLD, NVB_FLAG_START | ++ NVB_FLAG_SDBG); ++ hdr[1] = cpu_to_be32(size + 4); ++ hdr[2] = cpu_to_be32(addr); ++ ++ return write_header(fd, hdr, sizeof(hdr)); ++} ++ ++static int write_nvb_start_header(int fd, __u32 addr) ++{ ++ __u32 hdr[3]; ++ ++ hdr[0] = build_nvb_command(NVB_CMD_START, NVB_FLAG_SDBG); ++ hdr[1] = cpu_to_be32(4); ++ hdr[2] = cpu_to_be32(addr); ++ ++ return write_header(fd, hdr, sizeof(hdr)); ++} ++ ++static int open_input_bin(const char *name, void **ptr, size_t *size) ++{ ++ struct stat sbuf; ++ int ret, fd; ++ ++ fd = open(name, O_RDONLY | O_BINARY); ++ if (0 > fd) { ++ fprintf(stderr, "Cannot open %s: %s\n", name, ++ strerror(errno)); ++ return -1; ++ } ++ ++ ret = fstat(fd, &sbuf); ++ if (0 > ret) { ++ fprintf(stderr, "Cannot fstat %s: %s\n", name, ++ strerror(errno)); ++ return -1; ++ } ++ ++ *ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); ++ if (*ptr == MAP_FAILED) { ++ fprintf(stderr, "Cannot mmap %s: %s\n", name, ++ strerror(errno)); ++ return -1; ++ } ++ ++ *size = sbuf.st_size; ++ ++ return fd; ++} ++ ++static void close_input_bin(int fd, void *ptr, size_t size) ++{ ++ munmap(ptr, size); ++ close(fd); ++} ++ ++static int copy_bin(int fd, void *ptr, size_t size) ++{ ++ ssize_t n; ++ ++ n = write(fd, ptr, size); ++ if (n != size) { ++ fprintf(stderr, "Cannot copy binary: %s\n", strerror(errno)); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int open_output_bin(const char *name) ++{ ++ int fd; ++ ++ fd = open(name, O_RDWR | O_CREAT | O_TRUNC | O_SYNC | O_BINARY, 0666); ++ if (0 > fd) { ++ fprintf(stderr, "Cannot open %s: %s\n", name, ++ strerror(errno)); ++ return -1; ++ } ++ ++ return fd; ++} ++ ++static int create_sfspl(const struct args *arg) ++{ ++ int out_fd, uboot_fd, spl_fd, ret; ++ void *uboot_ptr, *spl_ptr; ++ size_t uboot_size, spl_size; ++ ++ out_fd = open_output_bin(arg->out_bin); ++ if (0 > out_fd) ++ goto err; ++ ++ spl_fd = open_input_bin(arg->spl_bin, &spl_ptr, &spl_size); ++ if (0 > spl_fd) ++ goto err_spl; ++ ++ uboot_fd = open_input_bin(arg->uboot_bin, &uboot_ptr, &uboot_size); ++ if (0 > uboot_fd) ++ goto err_uboot; ++ ++ ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr); ++ if (ret) ++ goto err_write; ++ ++ ret = copy_bin(out_fd, spl_ptr, spl_size); ++ if (ret) ++ goto err_write; ++ ++ ret = write_nvb_start_header(out_fd, arg->entry_addr); ++ if (ret) ++ goto err_write; ++ ++ ret = copy_bin(out_fd, uboot_ptr, uboot_size); ++ if (ret) ++ goto err_write; ++ ++ close_input_bin(uboot_fd, uboot_ptr, uboot_size); ++ close_input_bin(spl_fd, spl_ptr, spl_size); ++ close(out_fd); ++ ++ return 0; ++ ++err_write: ++ close_input_bin(uboot_fd, uboot_ptr, uboot_size); ++err_uboot: ++ close_input_bin(spl_fd, spl_ptr, spl_size); ++err_spl: ++ close(out_fd); ++err: ++ return -1; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int ret; ++ struct args arg; ++ ++ ret = parse_args(argc, argv, &arg); ++ if (ret) ++ goto done; ++ ++ switch (arg.type) { ++ case IMAGE_SFSPL: ++ ret = create_sfspl(&arg); ++ break; ++ default: ++ fprintf(stderr, "Image type not implemented\n"); ++ ret = -1; ++ break; ++ } ++ ++done: ++ if (ret >= 0) ++ return EXIT_SUCCESS; ++ ++ return EXIT_FAILURE; ++} diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch.svn-base new file mode 100644 index 0000000..ba24bae --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch.svn-base @@ -0,0 +1,33 @@ +From 2c6115188c7353a601835885a6c544240cfc479e Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Fri, 30 Nov 2012 18:09:25 +0100 +Subject: MIPS: VRX200: add option to boot from AVM EVA loader + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/arch/mips/cpu/mips32/vrx200/config.mk ++++ b/arch/mips/cpu/mips32/vrx200/config.mk +@@ -17,6 +17,9 @@ endif + LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o + + ifndef CONFIG_SPL_BUILD ++ifdef CONFIG_SYS_BOOT_EVA ++ALL-y += $(obj)u-boot.bin.lzma ++endif + ifdef CONFIG_SYS_BOOT_SFSPL + ALL-y += $(obj)u-boot.ltq.sfspl + ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl +--- a/arch/mips/include/asm/arch-vrx200/config.h ++++ b/arch/mips/include/asm/arch-vrx200/config.h +@@ -161,6 +161,11 @@ + #define CONFIG_SYS_DISABLE_CACHE + #endif + ++#if defined(CONFIG_SYS_BOOT_EVA) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#endif ++ + #if defined(CONFIG_SYS_BOOT_NOR) + #define CONFIG_SYS_TEXT_BASE 0xB0000000 + #endif diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch.svn-base new file mode 100644 index 0000000..b680a97 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch.svn-base @@ -0,0 +1,355 @@ +From 51f04c00e831b49587f9f766ff1af67d2122feb2 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Fri, 30 Nov 2012 18:09:47 +0100 +Subject: MIPS: add board support for AVM FritzBox 3370 + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/avm/fb3370/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/avm/fb3370/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/avm/fb3370/ddr_settings.h +@@ -0,0 +1,70 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define MC_CCR00_VALUE 0x101 ++#define MC_CCR01_VALUE 0x1000100 ++#define MC_CCR02_VALUE 0x1010000 ++#define MC_CCR03_VALUE 0x101 ++#define MC_CCR04_VALUE 0x1000000 ++#define MC_CCR05_VALUE 0x1000101 ++#define MC_CCR06_VALUE 0x1000100 ++#define MC_CCR07_VALUE 0x1010000 ++#define MC_CCR08_VALUE 0x1000101 ++#define MC_CCR09_VALUE 0x0 ++#define MC_CCR10_VALUE 0x2000100 ++#define MC_CCR11_VALUE 0x2000300 ++#define MC_CCR12_VALUE 0x30000 ++#define MC_CCR13_VALUE 0x202 ++#define MC_CCR14_VALUE 0x7080A0F ++#define MC_CCR15_VALUE 0x2040F ++#define MC_CCR16_VALUE 0x40000 ++#define MC_CCR17_VALUE 0x70102 ++#define MC_CCR18_VALUE 0x4020002 ++#define MC_CCR19_VALUE 0x30302 ++#define MC_CCR20_VALUE 0x8000700 ++#define MC_CCR21_VALUE 0x40F020A ++#define MC_CCR22_VALUE 0x0 ++#define MC_CCR23_VALUE 0xC020000 ++#define MC_CCR24_VALUE 0x4401B04 ++#define MC_CCR25_VALUE 0x0 ++#define MC_CCR26_VALUE 0x0 ++#define MC_CCR27_VALUE 0x6420000 ++#define MC_CCR28_VALUE 0x0 ++#define MC_CCR29_VALUE 0x0 ++#define MC_CCR30_VALUE 0x798 ++#define MC_CCR31_VALUE 0x0 ++#define MC_CCR32_VALUE 0x0 ++#define MC_CCR33_VALUE 0x650000 ++#define MC_CCR34_VALUE 0x200C8 ++#define MC_CCR35_VALUE 0x1D445D ++#define MC_CCR36_VALUE 0xC8 ++#define MC_CCR37_VALUE 0xC351 ++#define MC_CCR38_VALUE 0x0 ++#define MC_CCR39_VALUE 0x141F04 ++#define MC_CCR40_VALUE 0x142704 ++#define MC_CCR41_VALUE 0x141b42 ++#define MC_CCR42_VALUE 0x141b42 ++#define MC_CCR43_VALUE 0x566504 ++#define MC_CCR44_VALUE 0x566504 ++#define MC_CCR45_VALUE 0x565F17 ++#define MC_CCR46_VALUE 0x565F17 ++#define MC_CCR47_VALUE 0x0 ++#define MC_CCR48_VALUE 0x0 ++#define MC_CCR49_VALUE 0x0 ++#define MC_CCR50_VALUE 0x0 ++#define MC_CCR51_VALUE 0x0 ++#define MC_CCR52_VALUE 0x133 ++#define MC_CCR53_VALUE 0xF3014B27 ++#define MC_CCR54_VALUE 0xF3014B27 ++#define MC_CCR55_VALUE 0xF3014B27 ++#define MC_CCR56_VALUE 0xF3014B27 ++#define MC_CCR57_VALUE 0x7800301 ++#define MC_CCR58_VALUE 0x7800301 ++#define MC_CCR59_VALUE 0x7800301 ++#define MC_CCR60_VALUE 0x7800301 ++#define MC_CCR61_VALUE 0x4 +--- /dev/null ++++ b/board/avm/fb3370/fb3370.c +@@ -0,0 +1,139 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <spi.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/lantiq/cpu.h> ++#include <asm/arch/gphy.h> ++ ++#if defined(CONFIG_SPL_BUILD) ++#define do_gpio_init 1 ++#define do_pll_init 1 ++#define do_dcdc_init 0 ++#elif defined(CONFIG_SYS_BOOT_RAM) ++#define do_gpio_init 1 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#elif defined(CONFIG_SYS_BOOT_NOR) ++#define do_gpio_init 1 ++#define do_pll_init 1 ++#define do_dcdc_init 1 ++#else ++#define do_gpio_init 0 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#endif ++ ++static void gpio_init(void) ++{ ++ /* SPI CS 0.4 to serial flash */ ++ gpio_direction_output(10, 1); ++ ++ /* EBU.FL_CS1 as output for NAND CE */ ++ gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* EBU.FL_A23 as output for NAND CLE */ ++ gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* EBU.FL_A24 as output for NAND ALE */ ++ gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* GPIO 3.0 as input for NAND Ready Busy */ ++ gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN); ++ /* GPIO 3.1 as output for NAND Read */ ++ gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++} ++ ++int board_early_init_f(void) ++{ ++ if (do_gpio_init) ++ gpio_init(); ++ ++ if (do_pll_init) ++ ltq_pll_init(); ++ ++ if (do_dcdc_init) ++ ltq_dcdc_init(0x7F); ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */ ++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */ ++ { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */ ++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC3: unused */ ++ { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE }, ++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */ ++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */ ++ { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t * bis) ++{ ++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0; ++ const ulong fw_addr = 0x80FF0000; ++ ++ ltq_gphy_phy11g_a1x_load(fw_addr); ++ ++ ltq_cgu_gphy_clk_src(clk); ++ ++ ltq_rcu_gphy_boot(0, fw_addr); ++ ltq_rcu_gphy_boot(1, fw_addr); ++ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++int spi_cs_is_valid(unsigned int bus, unsigned int cs) ++{ ++ if (bus) ++ return 0; ++ ++ if (cs == 4) ++ return 1; ++ ++ return 0; ++} ++ ++void spi_cs_activate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 4: ++ gpio_set_value(10, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++void spi_cs_deactivate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 4: ++ gpio_set_value(10, 1); ++ break; ++ default: ++ break; ++ } ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -451,6 +451,9 @@ incaip mips + incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000 + incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000 + incaip_150MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=150000000 ++fb3370_ram mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_RAM ++fb3370_eva mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_EVA ++fb3370_sfspl mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_SFSPL + easy80920_nor mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NOR + easy80920_norspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NORSPL + easy80920_ram mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_RAM +--- /dev/null ++++ b/include/configs/fb3370.h +@@ -0,0 +1,75 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "FB3370" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "AVM FritzBox 3370" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_SPI_FLASH ++#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29LV620 serial flash */ ++ ++#define CONFIG_LTQ_SUPPORT_NAND_FLASH ++ ++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */ ++#define CONFIG_SPL_SPI_BUS 0 ++#define CONFIG_SPL_SPI_CS 4 ++#define CONFIG_SPL_SPI_MAX_HZ 25000000 ++#define CONFIG_SPL_SPI_MODE 0 ++ ++#define CONFIG_LTQ_SPL_COMP_LZO ++#define CONFIG_LTQ_SPL_CONSOLE ++ ++#define CONFIG_SYS_DRAM_PROBE ++ ++/* Environment */ ++#define CONFIG_ENV_SPI_BUS CONFIG_SPL_SPI_BUS ++#define CONFIG_ENV_SPI_CS CONFIG_SPL_SPI_CS ++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SPL_SPI_MAX_HZ ++#define CONFIG_ENV_SPI_MODE CONFIG_SPL_SPI_MODE ++ ++#if defined(CONFIG_SYS_BOOT_SFSPL) ++#define CONFIG_ENV_IS_IN_SPI_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++#define CONFIG_ENV_UPDATE_UBOOT_SF \ ++ "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_SF ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch.svn-base new file mode 100644 index 0000000..810770a --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch.svn-base @@ -0,0 +1,264 @@ +From 66b56aa3a4810f10e0b0c77bb87279a8d64b566b Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Fri, 16 Dec 2011 11:55:45 +0100 +Subject: MIPS: add board support for Gigaset SX76X + +Signed-off-by: Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/gigaset/sx76x/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/gigaset/sx76x/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/gigaset/sx76x/ddr_settings.h +@@ -0,0 +1,56 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * generated with lantiq_ram_extract_magic.awk ++ * ++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#define MC_DC00_VALUE 0x1B1B ++#define MC_DC01_VALUE 0x0 ++#define MC_DC02_VALUE 0x0 ++#define MC_DC03_VALUE 0x0 ++#define MC_DC04_VALUE 0x0 ++#define MC_DC05_VALUE 0x200 ++#define MC_DC06_VALUE 0x605 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x202 ++#define MC_DC09_VALUE 0x70A ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xC02 ++#define MC_DC12_VALUE 0x1C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0xF3E ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xD ++#define MC_DC18_VALUE 0x300 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0xF00 ++#define MC_DC22_VALUE 0xF0F ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x63 ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x100 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x514 ++#define MC_DC29_VALUE 0x2D89 ++#define MC_DC30_VALUE 0x8300 ++#define MC_DC31_VALUE 0x2002 ++#define MC_DC32_VALUE 0x0 ++#define MC_DC33_VALUE 0x0 ++#define MC_DC34_VALUE 0x0 ++#define MC_DC35_VALUE 0x0 ++#define MC_DC36_VALUE 0x0 ++#define MC_DC37_VALUE 0x0 ++#define MC_DC38_VALUE 0x0 ++#define MC_DC39_VALUE 0x0 ++#define MC_DC40_VALUE 0x0 ++#define MC_DC41_VALUE 0x0 ++#define MC_DC42_VALUE 0x0 ++#define MC_DC43_VALUE 0x0 ++#define MC_DC44_VALUE 0x0 ++#define MC_DC45_VALUE 0x500 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/gigaset/sx76x/sx76x.c +@@ -0,0 +1,66 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#include <common.h> ++#include <switch.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/chipid.h> ++ ++static void gpio_init(void) ++{ ++ /* Activate reset line of ADM6996I switch */ ++ gpio_direction_output(19, 0); ++} ++ ++int board_early_init_f(void) ++{ ++ gpio_init(); ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* MAC0: Lantiq ADM6996I switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t *bis) ++{ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++static struct switch_device adm6996i_dev = { ++ .name = "adm6996i", ++ .cpu_port = 5, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ /* Deactivate reset line of ADM6996I switch */ ++ gpio_set_value(19, 1); ++ ++ /* ADM6996I needs some time to come out of reset */ ++ __udelay(50000); ++ ++ return switch_device_register(&adm6996i_dev); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -447,6 +447,8 @@ pb1000 mips + easy50712_nor mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NOR + easy50712_norspl mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NORSPL + easy50712_ram mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_RAM ++gigasx76x_nor mips mips32 sx76x gigaset danube sx76x:SYS_BOOT_NOR ++gigasx76x_ram mips mips32 sx76x gigaset danube sx76x:SYS_BOOT_RAM + incaip mips mips32 incaip - incaip + incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000 + incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000 +--- /dev/null ++++ b/include/configs/sx76x.h +@@ -0,0 +1,71 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "GIGASX76X" ++#define CONFIG_IDENT_STRING " sx76x" ++#define CONFIG_BOARD_NAME "Gigaset sx76x" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_ADM6996I ++ ++/* Environment */ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (256 * 1024) ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#define CONFIG_ENV_SIZE (2 * 1024) ++#endif ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++/* Compression */ ++#define CONFIG_LZMA ++ ++/* Auto boot */ ++#define CONFIG_BOOTDELAY 2 ++ ++/* Environment configuration */ ++#define CONFIG_BOOTCOMMAND \ ++ "run addeth; bootm ${kernel_addr}" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "kernel_addr=0xB0040000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch.svn-base new file mode 100644 index 0000000..4156089 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch.svn-base @@ -0,0 +1,248 @@ +From 289f7ed5d725067b4eb4b1a105bb63d55bf20392 Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Wed, 29 Aug 2012 22:08:41 +0200 +Subject: MIPS: add board support for Arcadyan ARV7518 + +Signed-off-by: Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/arcadyan/arv7518pw/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/arcadyan/arv7518pw/arv7518pw.c +@@ -0,0 +1,52 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#include <common.h> ++#include <switch.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/chipid.h> ++ ++int board_early_init_f(void) ++{ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* MAC0: Atheros ar8216 switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t *bis) ++{ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++static struct switch_device ar8216_dev = { ++ .name = "ar8216", ++ .cpu_port = 0, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ return switch_device_register(&ar8216_dev); ++} +--- /dev/null ++++ b/board/arcadyan/arv7518pw/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv7518pw/ddr_settings.h +@@ -0,0 +1,56 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * generated with lantiq_ram_extract_magic.awk ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#define MC_DC00_VALUE 0x1B1B ++#define MC_DC01_VALUE 0x0 ++#define MC_DC02_VALUE 0x0 ++#define MC_DC03_VALUE 0x0 ++#define MC_DC04_VALUE 0x0 ++#define MC_DC05_VALUE 0x200 ++#define MC_DC06_VALUE 0x605 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x102 ++#define MC_DC09_VALUE 0x70A ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xC02 ++#define MC_DC12_VALUE 0x1C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x134 ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xD ++#define MC_DC18_VALUE 0x301 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA03 ++#define MC_DC21_VALUE 0x1400 ++#define MC_DC22_VALUE 0x1414 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x5B ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x510 ++#define MC_DC29_VALUE 0x4E20 ++#define MC_DC30_VALUE 0x8235 ++#define MC_DC31_VALUE 0x0 ++#define MC_DC32_VALUE 0x0 ++#define MC_DC33_VALUE 0x0 ++#define MC_DC34_VALUE 0x0 ++#define MC_DC35_VALUE 0x0 ++#define MC_DC36_VALUE 0x0 ++#define MC_DC37_VALUE 0x0 ++#define MC_DC38_VALUE 0x0 ++#define MC_DC39_VALUE 0x0 ++#define MC_DC40_VALUE 0x0 ++#define MC_DC41_VALUE 0x0 ++#define MC_DC42_VALUE 0x0 ++#define MC_DC43_VALUE 0x0 ++#define MC_DC44_VALUE 0x0 ++#define MC_DC45_VALUE 0x500 ++#define MC_DC46_VALUE 0x0 +--- a/boards.cfg ++++ b/boards.cfg +@@ -438,6 +438,8 @@ vct_premium mips + vct_premium_onenand mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND + vct_premium_onenand_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE + vct_premium_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_SMALL_IMAGE ++arv7518pw_ram mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_RAM ++arv7518pw_nor mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_NOR + dbau1000 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1000 + dbau1100 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1100 + dbau1500 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1500 +--- /dev/null ++++ b/include/configs/arv7518pw.h +@@ -0,0 +1,69 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ARV7518PW" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan ARV7518PW" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_AR8216 ++ ++/* Environment */ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SIZE (64 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#define CONFIG_ENV_SIZE (2 * 1024) ++#endif ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++/* Compression */ ++#define CONFIG_LZMA ++ ++/* Auto boot */ ++#define CONFIG_BOOTDELAY 2 ++ ++/* Environment configuration */ ++#define CONFIG_BOOTCOMMAND \ ++ "run addeth; bootm ${kernel_addr}" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "kernel_addr=0xB0040000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch.svn-base new file mode 100644 index 0000000..4698e67 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch.svn-base @@ -0,0 +1,248 @@ +From 4a738c02a7190756e01ba58c93c4b07bc6d6c2aa Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Wed, 29 Aug 2012 22:08:42 +0200 +Subject: MIPS: add board support for Arcadyan ARV4519 + +Signed-off-by: Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/arcadyan/arv4519pw/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/arcadyan/arv4519pw/arv4519pw.c +@@ -0,0 +1,52 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#include <common.h> ++#include <switch.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/chipid.h> ++ ++int board_early_init_f(void) ++{ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* MAC0: Atheros ar8216 switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t *bis) ++{ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++static struct switch_device ar8216_dev = { ++ .name = "ar8216", ++ .cpu_port = 0, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ return switch_device_register(&ar8216_dev); ++} +--- /dev/null ++++ b/board/arcadyan/arv4519pw/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv4519pw/ddr_settings.h +@@ -0,0 +1,56 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * generated with lantiq_ram_extract_magic.awk ++ * ++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#define MC_DC00_VALUE 0x1B1B ++#define MC_DC01_VALUE 0x0 ++#define MC_DC02_VALUE 0x0 ++#define MC_DC03_VALUE 0x0 ++#define MC_DC04_VALUE 0x0 ++#define MC_DC05_VALUE 0x200 ++#define MC_DC06_VALUE 0x605 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x102 ++#define MC_DC09_VALUE 0x70A ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xC02 ++#define MC_DC12_VALUE 0x1C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x131 ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xD ++#define MC_DC18_VALUE 0x301 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0x1700 ++#define MC_DC22_VALUE 0x1717 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x5A ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x510 ++#define MC_DC29_VALUE 0x4E20 ++#define MC_DC30_VALUE 0x8235 ++#define MC_DC31_VALUE 0x0 ++#define MC_DC32_VALUE 0x0 ++#define MC_DC33_VALUE 0x0 ++#define MC_DC34_VALUE 0x0 ++#define MC_DC35_VALUE 0x0 ++#define MC_DC36_VALUE 0x0 ++#define MC_DC37_VALUE 0x0 ++#define MC_DC38_VALUE 0x0 ++#define MC_DC39_VALUE 0x0 ++#define MC_DC40_VALUE 0x0 ++#define MC_DC41_VALUE 0x0 ++#define MC_DC42_VALUE 0x0 ++#define MC_DC43_VALUE 0x0 ++#define MC_DC44_VALUE 0x0 ++#define MC_DC45_VALUE 0x500 ++#define MC_DC46_VALUE 0x0 +--- a/boards.cfg ++++ b/boards.cfg +@@ -438,6 +438,8 @@ vct_premium mips + vct_premium_onenand mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND + vct_premium_onenand_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE + vct_premium_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_SMALL_IMAGE ++arv4519pw_ram mips mips32 arv4519pw arcadyan danube arv4519pw:SYS_BOOT_RAM ++arv4519pw_nor mips mips32 arv4519pw arcadyan danube arv4519pw:SYS_BOOT_NOR + arv7518pw_ram mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_RAM + arv7518pw_nor mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_NOR + dbau1000 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1000 +--- /dev/null ++++ b/include/configs/arv4519pw.h +@@ -0,0 +1,69 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ARV4519PW" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan ARV4519PW" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_AR8216 ++ ++/* Environment */ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SIZE (64 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#define CONFIG_ENV_SIZE (2 * 1024) ++#endif ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++/* Compression */ ++#define CONFIG_LZMA ++ ++/* Auto boot */ ++#define CONFIG_BOOTDELAY 2 ++ ++/* Environment configuration */ ++#define CONFIG_BOOTCOMMAND \ ++ "run addeth; bootm ${kernel_addr}" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "kernel_addr=0xB0040000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/.svn/text-base/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch.svn-base b/package/boot/uboot-lantiq/patches/.svn/text-base/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch.svn-base new file mode 100644 index 0000000..77d48d1 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/.svn/text-base/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch.svn-base @@ -0,0 +1,361 @@ +From 1b77d4249b5addbf3b0848db6992a445019a1865 Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Wed, 29 Aug 2012 22:08:42 +0200 +Subject: tools: add some helper tools for Lantiq SoCs + +Signed-off-by: Luka Perkov Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/tools/gct.pl +@@ -0,0 +1,155 @@ ++#!/usr/bin/perl ++ ++#use strict; ++#use Cwd; ++#use Env; ++ ++my $aline; ++my $lineid; ++my $length; ++my $address; ++my @bytes; ++my $addstr; ++my $chsum=0; ++my $count=0; ++my $firstime=1; ++my $i; ++my $currentaddr; ++my $tmp; ++my $holder=""; ++my $loadaddr; ++ ++if(@ARGV < 2){ ++ die("\n Syntax: perl gct.pl uart_ddr_settings.conf u-boot.srec u-boot.asc\n"); ++} ++ ++open(IN_UART_DDR_SETTINGS, "<$ARGV[0]") || die("failed to open uart_ddr_settings.conf\n"); ++open(IN_UART_SREC, "<$ARGV[1]") || die("failed to open u-boot.srec\n"); ++open(OUT_UBOOT_ASC, ">$ARGV[2]") || die("failed to open u-boot.asc\n"); ++ ++$i=0; ++while ($line = <IN_UART_DDR_SETTINGS>){ ++ if($line=~/\w/){ ++ if($line!~/[;#\*]/){ ++ if($i eq 0){ ++ printf OUT_UBOOT_ASC ("33333333"); ++ } ++ chomp($line); ++ $line=~s/\t//; ++ @array=split(/ +/,$line); ++ $j=0; ++ while(@array[$j]!~/\w/){ ++ $j=$j+1; ++ } ++ $addr=@array[$j]; ++ $regval=@array[$j+1]; ++ $addr=~s/0x//; ++ $regval=~s/0x//; ++ printf OUT_UBOOT_ASC ("%08x%08x",hex($addr),hex($regval)); ++ $i=$i+1; ++ if($i eq 8){ ++ $i=0; ++ printf OUT_UBOOT_ASC ("\n"); ++ } ++ } ++ } ++} ++ ++while($i lt 8 && $i gt 0){ ++ printf OUT_UBOOT_ASC "00"x8; ++ $i=$i+1; ++} ++ ++if($i eq 8){ ++ printf OUT_UBOOT_ASC ("\n"); ++} ++ ++while($aline=<IN_UART_SREC>){ ++ $aline=uc($aline); ++ chomp($aline); ++ next if(($aline=~/^S0/) || ($aline=~/^S7/)); ++ ($lineid, $length, $address, @bytes) = unpack"A2A2A8"."A2"x300, $aline; ++ $length = hex($length); ++ $address = hex($address); ++ $length -=5; ++ $i=0; ++ ++ while($length>0){ ++ if($firstime==1){ ++ $addstr = sprintf("%x", $address); ++ $addstr = "0"x(8-length($addstr)).$addstr; ++ print OUT_UBOOT_ASC $addstr; ++ addchsum($addstr); ++ $firstime=0; ++ $currentaddr=$address; ++ $loadaddr = $addstr; ++ } ++ else{ ++ if($count==64){ ++ $addstr = sprintf("%x", $currentaddr); ++ $addstr = "0"x(8-length($addstr)).$addstr; ++ print OUT_UBOOT_ASC $addstr; ++ addchsum($addstr); ++ $count=0; ++ } ++#printf("*** %x != %x\n", $address, $currentaddr) if $address != $currentaddr; ++ } ++ if($currentaddr < $address) { ++ print OUT_UBOOT_ASC "00"; ++ addchsum("00"); ++ $count++; ++ $currentaddr++; ++ } ++ else { ++ while($count<64){ ++ $bytes[$i]=~tr/ABCDEF/abcdef/; ++ print OUT_UBOOT_ASC "$bytes[$i]"; ++ addchsum($bytes[$i]); ++ $i++; ++ $count++; ++ $currentaddr++; ++ $length--; ++ last if($length==0); ++ } ++ } ++ if($count==64){ ++ print OUT_UBOOT_ASC "\n"; ++ } ++ } ++} ++if($count != 64){ ++ $tmp = "00"; ++ for($i=0;$i<(64-$count);$i++){ ++ print OUT_UBOOT_ASC "00"; ++ addchsum($tmp); ++ } ++ print OUT_UBOOT_ASC "\n"; ++} ++ ++ ++print OUT_UBOOT_ASC "11"x4; ++use integer; ++$chsum=$chsum & 0xffffffff; ++$chsum = sprintf("%X", $chsum); ++$chsum = "0"x(8-length($chsum)).$chsum; ++$chsum =~tr/ABCDEF/abcdef/; ++print OUT_UBOOT_ASC $chsum; ++print OUT_UBOOT_ASC "00"x60; ++print OUT_UBOOT_ASC "\n"; ++ ++print OUT_UBOOT_ASC "99"x4; ++print OUT_UBOOT_ASC $loadaddr; ++print OUT_UBOOT_ASC "00"x60; ++print OUT_UBOOT_ASC "\n"; ++ ++close OUT_UBOOT_ASC; ++ ++sub addchsum{ ++ my $cc=$_[0]; ++ $holder=$holder.$cc; ++ if(length($holder)==8){ ++ $holder = hex($holder); ++ $chsum+=$holder; ++ $holder=""; ++ } ++} +--- /dev/null ++++ b/tools/lantiq_extract_openwrt_patches.sh +@@ -0,0 +1,15 @@ ++#!/bin/bash ++ ++set -e ++set -x ++ ++test $# -eq 1 ++ ++openwrt_root=$(readlink -f $1) ++test -d $openwrt_root ++ ++uboot_lantiq_dir=$openwrt_root/package/boot/uboot-lantiq/patches ++test -d $uboot_lantiq_dir ++ ++rm -vf $uboot_lantiq_dir/* ++git format-patch -k -p --no-renames --text --full-index -o $uboot_lantiq_dir v2012.10..openwrt/v2013.01 +--- /dev/null ++++ b/tools/lantiq_ram_extract_magic.awk +@@ -0,0 +1,70 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++# ++# usage: mips-openwrt-linux-objdump -EB -b binary -m mips:isa32r2 -D YOUR_IMAGE_DUMP | awk -f lantiq_ram_extract_magic.awk ++# ++ ++BEGIN { ++ print "/* " ++ print " * This file is released under the terms of GPL v2 and any later version. " ++ print " * See the file COPYING in the root directory of the source tree for details. " ++ print " * " ++ print " * generated with lantiq_ram_extract_magic.awk " ++ print " * " ++ print " * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> " ++ print " */ " ++ print "" ++ ++ mc_dc_value=0 ++ mc_dc_number=0 ++ right_section=0 ++ mc_dc_value_print=0 ++ mc_dc_number_print=0 ++} ++ ++/t2,[0-9]+$/ { ++ if (right_section) { ++ split($4, tmp, ",") ++ mc_dc_value=sprintf("%X", tmp[2]) ++ mc_dc_value_print=1 ++ } ++} ++ ++/t2,0x[0-9a-f]+$/ { ++ if (right_section) { ++ split($4, tmp, ",0x") ++ mc_dc_value=sprintf("%s", tmp[2]) ++ mc_dc_value=toupper(mc_dc_value) ++ mc_dc_value_print=1 ++ } ++} ++ ++/t2,[0-9]+\(t1\)$/ { ++ if (right_section) { ++ split($4, tmp, ",") ++ split(tmp[2], tmp, "(") ++ mc_dc_number=tmp[1]/16 ++ mc_dc_number_print=1 ++ } ++} ++ ++{ ++ if (right_section && mc_dc_number_print && mc_dc_value_print) { ++ if (mc_dc_number < 10) ++ print "#define MC_DC0" mc_dc_number "_VALUE\t0x" mc_dc_value ++ else ++ print "#define MC_DC" mc_dc_number "_VALUE\t0x" mc_dc_value ++ mc_dc_value_print=0 ++ mc_dc_number_print=0 ++ } ++ ++ if ($4 == "t1,t1,0x1000") ++ right_section=1 ++ ++ ++ if ($4 == "t2,736(t1)") ++ right_section=0 ++} +--- /dev/null ++++ b/tools/lantiq_ram_init_uart.awk +@@ -0,0 +1,101 @@ ++#!/usr/bin/awk -f ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011-2012 Luka Perkov <luka@openwrt.org> ++# Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@gmail.com> ++# ++# usage: awk -f lantiq_ram_init_uart.awk -v soc=<danube|ar9|vr9> PATH_TO_BOARD/ddr_settings.h ++# ++ ++function print_header() ++{ ++ print "; " ++ print "; This file is released under the terms of GPL v2 and any later version. " ++ print "; See the file COPYING in the root directory of the source tree for details. " ++ print "; " ++ print "; generated with lantiq_ram_init_uart.awk " ++ print "; " ++ print "; Copyright (C) 2011-2012 Luka Perkov <luka@openwrt.org> " ++ print "; Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@gmail.com> " ++ print "; " ++ print "" ++} ++ ++function mc_ddr1_prologue() ++{ ++ /* Clear access error log registers */ ++ print "0xbf800010", "0x0" ++ print "0xbf800020", "0x0" ++ ++ /* Enable DDR and SRAM module in memory controller */ ++ print "0xbf800060", "0x5" ++ ++ /* Clear start bit of DDR memory controller */ ++ print "0xbf801030", "0x0" ++} ++ ++function mc_ddr1_epilogue() ++{ ++ /* Set start bit of DDR memory controller */ ++ print "0xbf801030", "0x100" ++} ++ ++function mc_ddr2_prologue() ++{ ++ /* Put memory controller in inactive mode */ ++ print "0xbf401070", "0x0" ++} ++ ++function mc_ddr2_epilogue(mc_ccr07_value) ++{ ++ /* Put memory controller in active mode */ ++ mc_ccr07_value = or(mc_ccr07_value, 0x100) ++ printf("0xbf401070 0x%x\n", mc_ccr07_value) ++} ++ ++BEGIN { ++ switch (soc) { ++ case "danube": ++ case "ar9": ++ reg_base = 0xbf801000 ++ print_header() ++ mc_ddr1_prologue() ++ break ++ case "vr9": ++ reg_base = 0xbf401000 ++ print_header() ++ mc_ddr2_prologue() ++ break ++ default: ++ print "Invalid or no value for soc specified!" ++ exit 1 ++ } ++ ++ mc_ccr07_value = 0 ++} ++ ++/^#define/ { ++ printf("0x%x %s\n", reg_base, tolower($3)) ++ reg_base += 0x10 ++} ++ ++/^#define(.*)MC_CCR07_VALUE/ { ++ printf("0x%x %s\n", reg_base, tolower($3)) ++ reg_base += 0x10 ++ mc_ccr07_value = strtonum($3) ++} ++ ++END { ++ switch (soc) { ++ case "danube": ++ case "ar9": ++ mc_ddr1_epilogue() ++ break ++ case "vr9": ++ mc_ddr2_epilogue(mc_ccr07_value) ++ break ++ default: ++ } ++} diff --git a/package/boot/uboot-lantiq/patches/0002-sf-handle-CONFIG_MANUAL_RELOC.patch b/package/boot/uboot-lantiq/patches/0002-sf-handle-CONFIG_MANUAL_RELOC.patch new file mode 100644 index 0000000..63a21af --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0002-sf-handle-CONFIG_MANUAL_RELOC.patch @@ -0,0 +1,46 @@ +From 60e8a35f0efa5a7e5d797a3f239971c84061ef11 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 21:39:47 +0100 +Subject: sf: handle CONFIG_MANUAL_RELOC + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -293,7 +293,7 @@ int spi_flash_cmd_write_status(struct sp + */ + #define IDCODE_CONT_LEN 0 + #define IDCODE_PART_LEN 5 +-static const struct { ++static struct { + const u8 shift; + const u8 idcode; + struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode); +@@ -335,6 +335,10 @@ static const struct { + }; + #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN) + ++#ifdef CONFIG_NEEDS_MANUAL_RELOC ++DECLARE_GLOBAL_DATA_PTR; ++#endif ++ + struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int spi_mode) + { +@@ -342,6 +346,16 @@ struct spi_flash *spi_flash_probe(unsign + struct spi_flash *flash = NULL; + int ret, i, shift; + u8 idcode[IDCODE_LEN], *idp; ++#ifdef CONFIG_NEEDS_MANUAL_RELOC ++ static int relocated; ++ ++ if (!relocated) { ++ for (i = 0; i < ARRAY_SIZE(flashes); i++) ++ flashes[i].probe += gd->reloc_off; ++ ++ relocated = 1; ++ } ++#endif + + spi = spi_setup_slave(bus, cs, max_hz, spi_mode); + if (!spi) { diff --git a/package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch b/package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch new file mode 100644 index 0000000..7f44675 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0003-sf-factor-out-malloc-from-SPI-flash-drivers.patch @@ -0,0 +1,719 @@ +From 73d127565b5a4b19bcaacabc505689ee039f16fd Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Sun, 11 Nov 2012 03:11:38 +0100 +Subject: sf: factor out malloc from SPI flash drivers + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/atmel.c ++++ b/drivers/mtd/spi/atmel.c +@@ -40,18 +40,6 @@ struct atmel_spi_flash_params { + const char *name; + }; + +-/* spi_flash needs to be first so upper layers can free() it */ +-struct atmel_spi_flash { +- struct spi_flash flash; +- const struct atmel_spi_flash_params *params; +-}; +- +-static inline struct atmel_spi_flash * +-to_atmel_spi_flash(struct spi_flash *flash) +-{ +- return container_of(flash, struct atmel_spi_flash, flash); +-} +- + static const struct atmel_spi_flash_params atmel_spi_flash_table[] = { + { + .idcode1 = 0x22, +@@ -156,7 +144,8 @@ static int at45_wait_ready(struct spi_fl + * Assemble the address part of a command for AT45 devices in + * non-power-of-two page size mode. + */ +-static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset) ++static void at45_build_address(const struct atmel_spi_flash_params *params, ++ u8 *cmd, u32 offset) + { + unsigned long page_addr; + unsigned long byte_addr; +@@ -167,7 +156,7 @@ static void at45_build_address(struct at + * The "extra" space per page is the power-of-two page size + * divided by 32. + */ +- page_shift = asf->params->l2_page_size; ++ page_shift = params->l2_page_size; + page_size = (1 << page_shift) + (1 << (page_shift - 5)); + page_shift++; + page_addr = offset / page_size; +@@ -181,11 +170,11 @@ static void at45_build_address(struct at + static int dataflash_read_fast_at45(struct spi_flash *flash, + u32 offset, size_t len, void *buf) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + u8 cmd[5]; + + cmd[0] = CMD_READ_ARRAY_FAST; +- at45_build_address(asf, cmd + 1, offset); ++ at45_build_address(params, cmd + 1, offset); + cmd[4] = 0x00; + + return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len); +@@ -197,7 +186,7 @@ static int dataflash_read_fast_at45(stru + static int dataflash_write_p2(struct spi_flash *flash, + u32 offset, size_t len, const void *buf) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + unsigned long page_size; + u32 addr = offset; + size_t chunk_len; +@@ -211,7 +200,7 @@ static int dataflash_write_p2(struct spi + * the other is being programmed into main memory. + */ + +- page_size = (1 << asf->params->l2_page_size); ++ page_size = (1 << params->l2_page_size); + + ret = spi_claim_bus(flash->spi); + if (ret) { +@@ -263,7 +252,7 @@ out: + static int dataflash_write_at45(struct spi_flash *flash, + u32 offset, size_t len, const void *buf) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + unsigned long page_addr; + unsigned long byte_addr; + unsigned long page_size; +@@ -279,7 +268,7 @@ static int dataflash_write_at45(struct s + * the other is being programmed into main memory. + */ + +- page_shift = asf->params->l2_page_size; ++ page_shift = params->l2_page_size; + page_size = (1 << page_shift) + (1 << (page_shift - 5)); + page_shift++; + page_addr = offset / page_size; +@@ -338,7 +327,7 @@ out: + */ + static int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + unsigned long page_size; + + size_t actual; +@@ -351,7 +340,7 @@ static int dataflash_erase_p2(struct spi + * when possible. + */ + +- page_size = (1 << asf->params->l2_page_size); ++ page_size = (1 << params->l2_page_size); + + if (offset % page_size || len % page_size) { + debug("SF: Erase offset/length not multiple of page size\n"); +@@ -397,7 +386,7 @@ out: + + static int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len) + { +- struct atmel_spi_flash *asf = to_atmel_spi_flash(flash); ++ const struct atmel_spi_flash_params *params = flash->priv; + unsigned long page_addr; + unsigned long page_size; + unsigned int page_shift; +@@ -411,7 +400,7 @@ static int dataflash_erase_at45(struct s + * when possible. + */ + +- page_shift = asf->params->l2_page_size; ++ page_shift = params->l2_page_size; + page_size = (1 << page_shift) + (1 << (page_shift - 5)); + page_shift++; + page_addr = offset / page_size; +@@ -458,12 +447,12 @@ out: + return ret; + } + +-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode) + { + const struct atmel_spi_flash_params *params; ++ struct spi_slave *spi = flash->spi; + unsigned page_size; + unsigned int family; +- struct atmel_spi_flash *asf; + unsigned int i; + int ret; + u8 status; +@@ -477,18 +466,11 @@ struct spi_flash *spi_flash_probe_atmel( + if (i == ARRAY_SIZE(atmel_spi_flash_table)) { + debug("SF: Unsupported DataFlash ID %02x\n", + idcode[1]); +- return NULL; +- } +- +- asf = malloc(sizeof(struct atmel_spi_flash)); +- if (!asf) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; ++ return 0; + } + +- asf->params = params; +- asf->flash.spi = spi; +- asf->flash.name = params->name; ++ flash->priv = (void *)params; ++ flash->name = params->name; + + /* Assuming power-of-two page size initially. */ + page_size = 1 << params->l2_page_size; +@@ -503,48 +485,44 @@ struct spi_flash *spi_flash_probe_atmel( + */ + ret = spi_flash_cmd(spi, CMD_AT45_READ_STATUS, &status, 1); + if (ret) +- goto err; ++ return -1; + + debug("SF: AT45 status register: %02x\n", status); + + if (!(status & AT45_STATUS_P2_PAGE_SIZE)) { +- asf->flash.read = dataflash_read_fast_at45; +- asf->flash.write = dataflash_write_at45; +- asf->flash.erase = dataflash_erase_at45; ++ flash->read = dataflash_read_fast_at45; ++ flash->write = dataflash_write_at45; ++ flash->erase = dataflash_erase_at45; + page_size += 1 << (params->l2_page_size - 5); + } else { +- asf->flash.read = spi_flash_cmd_read_fast; +- asf->flash.write = dataflash_write_p2; +- asf->flash.erase = dataflash_erase_p2; ++ flash->read = spi_flash_cmd_read_fast; ++ flash->write = dataflash_write_p2; ++ flash->erase = dataflash_erase_p2; + } + +- asf->flash.page_size = page_size; +- asf->flash.sector_size = page_size; ++ flash->page_size = page_size; ++ flash->sector_size = page_size; + break; + + case DF_FAMILY_AT26F: + case DF_FAMILY_AT26DF: +- asf->flash.read = spi_flash_cmd_read_fast; +- asf->flash.write = spi_flash_cmd_write_multi; +- asf->flash.erase = spi_flash_cmd_erase; +- asf->flash.page_size = page_size; +- asf->flash.sector_size = 4096; ++ flash->read = spi_flash_cmd_read_fast; ++ flash->write = spi_flash_cmd_write_multi; ++ flash->erase = spi_flash_cmd_erase; ++ flash->page_size = page_size; ++ flash->sector_size = 4096; + /* clear SPRL# bit for locked flash */ +- spi_flash_cmd_write_status(&asf->flash, 0); ++ spi_flash_cmd_write_status(flash, 0); + break; + + default: + debug("SF: Unsupported DataFlash family %u\n", family); +- goto err; ++ return -1; + } + +- asf->flash.size = page_size * params->pages_per_block ++ flash->size = page_size * params->pages_per_block + * params->blocks_per_sector + * params->nr_sectors; + +- return &asf->flash; +- +-err: +- free(asf); +- return NULL; ++ return 1; + } +--- a/drivers/mtd/spi/eon.c ++++ b/drivers/mtd/spi/eon.c +@@ -29,10 +29,9 @@ static const struct eon_spi_flash_params + }, + }; + +-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode) + { + const struct eon_spi_flash_params *params; +- struct spi_flash *flash; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) { +@@ -43,16 +42,10 @@ struct spi_flash *spi_flash_probe_eon(st + + if (i == ARRAY_SIZE(eon_spi_flash_table)) { + debug("SF: Unsupported EON ID %02x\n", idcode[1]); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -63,5 +56,5 @@ struct spi_flash *spi_flash_probe_eon(st + flash->size = 256 * 16 + * params->nr_sectors; + +- return flash; ++ return 1; + } +--- a/drivers/mtd/spi/macronix.c ++++ b/drivers/mtd/spi/macronix.c +@@ -79,10 +79,9 @@ static const struct macronix_spi_flash_p + }, + }; + +-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode) + { + const struct macronix_spi_flash_params *params; +- struct spi_flash *flash; + unsigned int i; + u16 id = idcode[2] | idcode[1] << 8; + +@@ -94,16 +93,10 @@ struct spi_flash *spi_flash_probe_macron + + if (i == ARRAY_SIZE(macronix_spi_flash_table)) { + debug("SF: Unsupported Macronix ID %04x\n", id); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -116,5 +109,5 @@ struct spi_flash *spi_flash_probe_macron + /* Clear BP# bits for read-only flash */ + spi_flash_cmd_write_status(flash, 0); + +- return flash; ++ return 1; + } +--- a/drivers/mtd/spi/ramtron.c ++++ b/drivers/mtd/spi/ramtron.c +@@ -69,17 +69,6 @@ struct ramtron_spi_fram_params { + const char *name; /* name for display and/or matching */ + }; + +-struct ramtron_spi_fram { +- struct spi_flash flash; +- const struct ramtron_spi_fram_params *params; +-}; +- +-static inline struct ramtron_spi_fram *to_ramtron_spi_fram(struct spi_flash +- *flash) +-{ +- return container_of(flash, struct ramtron_spi_fram, flash); +-} +- + /* + * table describing supported FRAM chips: + * chips without RDID command must have the values 0xff for id1 and id2 +@@ -155,18 +144,18 @@ static const struct ramtron_spi_fram_par + static int ramtron_common(struct spi_flash *flash, + u32 offset, size_t len, void *buf, u8 command) + { +- struct ramtron_spi_fram *sn = to_ramtron_spi_fram(flash); ++ const struct ramtron_spi_fram_params *params = flash->priv; + u8 cmd[4]; + int cmd_len; + int ret; + +- if (sn->params->addr_len == 3 && sn->params->merge_cmd == 0) { ++ if (params->addr_len == 3 && params->merge_cmd == 0) { + cmd[0] = command; + cmd[1] = offset >> 16; + cmd[2] = offset >> 8; + cmd[3] = offset; + cmd_len = 4; +- } else if (sn->params->addr_len == 2 && sn->params->merge_cmd == 0) { ++ } else if (params->addr_len == 2 && params->merge_cmd == 0) { + cmd[0] = command; + cmd[1] = offset >> 8; + cmd[2] = offset; +@@ -230,10 +219,9 @@ static int ramtron_erase(struct spi_flas + * nore: we are called here with idcode pointing to the first non-0x7f byte + * already! + */ +-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode) ++int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode) + { + const struct ramtron_spi_fram_params *params; +- struct ramtron_spi_fram *sn; + unsigned int i; + #ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC + int ret; +@@ -259,11 +247,11 @@ struct spi_flash *spi_fram_probe_ramtron + */ + ret = spi_flash_cmd(spi, CMD_READ_STATUS, &sr, 1); + if (ret) +- return NULL; ++ return 0; + + /* Bits 5,4,0 are fixed 0 for all devices */ + if ((sr & 0x31) != 0x00) +- return NULL; ++ return 0; + /* now find the device */ + for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) { + params = &ramtron_spi_fram_table[i]; +@@ -281,23 +269,16 @@ struct spi_flash *spi_fram_probe_ramtron + /* arriving here means no method has found a device we can handle */ + debug("SF/ramtron: unsupported device id0=%02x id1=%02x id2=%02x\n", + idcode[0], idcode[1], idcode[2]); +- return NULL; ++ return 0; + + found: +- sn = malloc(sizeof(*sn)); +- if (!sn) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } ++ flash->priv = (void *)params; ++ flash->name = params->name; + +- sn->params = params; +- sn->flash.spi = spi; +- sn->flash.name = params->name; +- +- sn->flash.write = ramtron_write; +- sn->flash.read = ramtron_read; +- sn->flash.erase = ramtron_erase; +- sn->flash.size = params->size; ++ flash->write = ramtron_write; ++ flash->read = ramtron_read; ++ flash->erase = ramtron_erase; ++ flash->size = params->size; + +- return &sn->flash; ++ return 1; + } +--- a/drivers/mtd/spi/spansion.c ++++ b/drivers/mtd/spi/spansion.c +@@ -105,10 +105,9 @@ static const struct spansion_spi_flash_p + }, + }; + +-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode) + { + const struct spansion_spi_flash_params *params; +- struct spi_flash *flash; + unsigned int i; + unsigned short jedec, ext_jedec; + +@@ -125,16 +124,10 @@ struct spi_flash *spi_flash_probe_spansi + + if (i == ARRAY_SIZE(spansion_spi_flash_table)) { + debug("SF: Unsupported SPANSION ID %04x %04x\n", jedec, ext_jedec); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -144,5 +137,5 @@ struct spi_flash *spi_flash_probe_spansi + flash->sector_size = 256 * params->pages_per_sector; + flash->size = flash->sector_size * params->nr_sectors; + +- return flash; ++ return 1; + } +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -296,7 +296,7 @@ int spi_flash_cmd_write_status(struct sp + static struct { + const u8 shift; + const u8 idcode; +- struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode); ++ int (*probe) (struct spi_flash *flash, u8 *idcode); + } flashes[] = { + /* Keep it sorted by define name */ + #ifdef CONFIG_SPI_FLASH_ATMEL +@@ -343,7 +343,7 @@ struct spi_flash *spi_flash_probe(unsign + unsigned int max_hz, unsigned int spi_mode) + { + struct spi_slave *spi; +- struct spi_flash *flash = NULL; ++ struct spi_flash *flash; + int ret, i, shift; + u8 idcode[IDCODE_LEN], *idp; + #ifdef CONFIG_NEEDS_MANUAL_RELOC +@@ -379,6 +379,15 @@ struct spi_flash *spi_flash_probe(unsign + print_buffer(0, idcode, 1, sizeof(idcode), 0); + #endif + ++ flash = malloc(sizeof(*flash)); ++ if (!flash) { ++ debug("SF: failed to alloc memory\n"); ++ goto err_malloc; ++ } ++ ++ memset(flash, 0, sizeof(*flash)); ++ flash->spi = spi; ++ + /* count the number of continuation bytes */ + for (shift = 0, idp = idcode; + shift < IDCODE_CONT_LEN && *idp == 0x7f; +@@ -389,12 +398,12 @@ struct spi_flash *spi_flash_probe(unsign + for (i = 0; i < ARRAY_SIZE(flashes); ++i) + if (flashes[i].shift == shift && flashes[i].idcode == *idp) { + /* we have a match, call probe */ +- flash = flashes[i].probe(spi, idp); +- if (flash) ++ ret = flashes[i].probe(flash, idp); ++ if (ret) + break; + } + +- if (!flash) { ++ if (ret <= 0) { + printf("SF: Unsupported manufacturer %02x\n", *idp); + goto err_manufacturer_probe; + } +@@ -408,6 +417,8 @@ struct spi_flash *spi_flash_probe(unsign + return flash; + + err_manufacturer_probe: ++ free(flash); ++err_malloc: + err_read_id: + spi_release_bus(spi); + err_claim_bus: +--- a/drivers/mtd/spi/spi_flash_internal.h ++++ b/drivers/mtd/spi/spi_flash_internal.h +@@ -98,11 +98,11 @@ int spi_flash_cmd_wait_ready(struct spi_ + int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len); + + /* Manufacturer-specific probe functions */ +-struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode); +-struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode); ++int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_stmicro(struct spi_flash *flash, u8 *idcode); ++int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode); ++int spi_fram_probe_ramtron(struct spi_flash *flash, u8 *idcode); +--- a/drivers/mtd/spi/sst.c ++++ b/drivers/mtd/spi/sst.c +@@ -39,11 +39,6 @@ struct sst_spi_flash_params { + const char *name; + }; + +-struct sst_spi_flash { +- struct spi_flash flash; +- const struct sst_spi_flash_params *params; +-}; +- + static const struct sst_spi_flash_params sst_spi_flash_table[] = { + { + .idcode1 = 0x8d, +@@ -185,11 +180,9 @@ sst_write_wp(struct spi_flash *flash, u3 + return ret; + } + +-struct spi_flash * +-spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_sst(struct spi_flash *flash, u8 *idcode) + { + const struct sst_spi_flash_params *params; +- struct sst_spi_flash *stm; + size_t i; + + for (i = 0; i < ARRAY_SIZE(sst_spi_flash_table); ++i) { +@@ -200,31 +193,24 @@ spi_flash_probe_sst(struct spi_slave *sp + + if (i == ARRAY_SIZE(sst_spi_flash_table)) { + debug("SF: Unsupported SST ID %02x\n", idcode[1]); +- return NULL; +- } +- +- stm = malloc(sizeof(*stm)); +- if (!stm) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; ++ return 0; + } + +- stm->params = params; +- stm->flash.spi = spi; +- stm->flash.name = params->name; ++ flash->priv = (void *)params; ++ flash->name = params->name; + +- if (stm->params->flags & SST_FEAT_WP) +- stm->flash.write = sst_write_wp; ++ if (params->flags & SST_FEAT_WP) ++ flash->write = sst_write_wp; + else +- stm->flash.write = spi_flash_cmd_write_multi; +- stm->flash.erase = spi_flash_cmd_erase; +- stm->flash.read = spi_flash_cmd_read_fast; +- stm->flash.page_size = 256; +- stm->flash.sector_size = 4096; +- stm->flash.size = stm->flash.sector_size * params->nr_sectors; ++ flash->write = spi_flash_cmd_write_multi; ++ flash->erase = spi_flash_cmd_erase; ++ flash->read = spi_flash_cmd_read_fast; ++ flash->page_size = 256; ++ flash->sector_size = 4096; ++ flash->size = flash->sector_size * params->nr_sectors; + + /* Flash powers up read-only, so clear BP# bits */ +- spi_flash_cmd_write_status(&stm->flash, 0); ++ spi_flash_cmd_write_status(flash, 0); + +- return &stm->flash; ++ return 1; + } +--- a/drivers/mtd/spi/stmicro.c ++++ b/drivers/mtd/spi/stmicro.c +@@ -112,10 +112,10 @@ static const struct stmicro_spi_flash_pa + }, + }; + +-struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode) ++int spi_flash_probe_stmicro(struct spi_flash *flash, u8 * idcode) + { + const struct stmicro_spi_flash_params *params; +- struct spi_flash *flash; ++ struct spi_slave *spi = flash->spi; + unsigned int i; + u16 id; + +@@ -123,13 +123,13 @@ struct spi_flash *spi_flash_probe_stmicr + i = spi_flash_cmd(spi, CMD_M25PXX_RES, + idcode, 4); + if (i) +- return NULL; ++ return 0; + if ((idcode[3] & 0xf0) == 0x10) { + idcode[0] = 0x20; + idcode[1] = 0x20; + idcode[2] = idcode[3] + 1; + } else +- return NULL; ++ return 0; + } + + id = ((idcode[1] << 8) | idcode[2]); +@@ -143,16 +143,10 @@ struct spi_flash *spi_flash_probe_stmicr + + if (i == ARRAY_SIZE(stmicro_spi_flash_table)) { + debug("SF: Unsupported STMicro ID %04x\n", id); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -162,5 +156,5 @@ struct spi_flash *spi_flash_probe_stmicr + flash->sector_size = 256 * params->pages_per_sector; + flash->size = flash->sector_size * params->nr_sectors; + +- return flash; ++ return 1; + } +--- a/drivers/mtd/spi/winbond.c ++++ b/drivers/mtd/spi/winbond.c +@@ -69,10 +69,9 @@ static const struct winbond_spi_flash_pa + }, + }; + +-struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode) ++int spi_flash_probe_winbond(struct spi_flash *flash, u8 *idcode) + { + const struct winbond_spi_flash_params *params; +- struct spi_flash *flash; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) { +@@ -84,16 +83,10 @@ struct spi_flash *spi_flash_probe_winbon + if (i == ARRAY_SIZE(winbond_spi_flash_table)) { + debug("SF: Unsupported Winbond ID %02x%02x\n", + idcode[1], idcode[2]); +- return NULL; ++ return 0; + } + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: Failed to allocate memory\n"); +- return NULL; +- } +- +- flash->spi = spi; ++ flash->priv = (void *)params; + flash->name = params->name; + + flash->write = spi_flash_cmd_write_multi; +@@ -103,5 +96,5 @@ struct spi_flash *spi_flash_probe_winbon + flash->sector_size = 4096; + flash->size = 4096 * 16 * params->nr_blocks; + +- return flash; ++ return 1; + } +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -31,6 +31,7 @@ struct spi_flash { + struct spi_slave *spi; + + const char *name; ++ void *priv; + + /* Total flash size */ + u32 size; diff --git a/package/boot/uboot-lantiq/patches/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch b/package/boot/uboot-lantiq/patches/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch new file mode 100644 index 0000000..7a1ef3b --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0004-sf-add-malloc-free-probe-functions-dedicated-for-SPL.patch @@ -0,0 +1,131 @@ +From f9ab44c271fbd82a5702b6ba067fa90e33a30089 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:29:27 +0100 +Subject: sf: add malloc-free probe functions dedicated for SPL + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -339,11 +339,11 @@ static struct { + DECLARE_GLOBAL_DATA_PTR; + #endif + +-struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, +- unsigned int max_hz, unsigned int spi_mode) ++int spi_flash_probe_spl(struct spi_flash *flash, unsigned int bus, ++ unsigned int cs, unsigned int max_hz, ++ unsigned int spi_mode) + { + struct spi_slave *spi; +- struct spi_flash *flash; + int ret, i, shift; + u8 idcode[IDCODE_LEN], *idp; + #ifdef CONFIG_NEEDS_MANUAL_RELOC +@@ -359,8 +359,8 @@ struct spi_flash *spi_flash_probe(unsign + + spi = spi_setup_slave(bus, cs, max_hz, spi_mode); + if (!spi) { +- printf("SF: Failed to set up slave\n"); +- return NULL; ++ debug("SF: Failed to set up slave\n"); ++ return -1; + } + + ret = spi_claim_bus(spi); +@@ -379,13 +379,6 @@ struct spi_flash *spi_flash_probe(unsign + print_buffer(0, idcode, 1, sizeof(idcode), 0); + #endif + +- flash = malloc(sizeof(*flash)); +- if (!flash) { +- debug("SF: failed to alloc memory\n"); +- goto err_malloc; +- } +- +- memset(flash, 0, sizeof(*flash)); + flash->spi = spi; + + /* count the number of continuation bytes */ +@@ -404,30 +397,58 @@ struct spi_flash *spi_flash_probe(unsign + } + + if (ret <= 0) { +- printf("SF: Unsupported manufacturer %02x\n", *idp); ++ debug("SF: Unsupported manufacturer %02x\n", *idp); + goto err_manufacturer_probe; + } + +- printf("SF: Detected %s with page size ", flash->name); +- print_size(flash->sector_size, ", total "); +- print_size(flash->size, "\n"); +- + spi_release_bus(spi); + +- return flash; ++ return 0; + + err_manufacturer_probe: +- free(flash); +-err_malloc: + err_read_id: + spi_release_bus(spi); + err_claim_bus: + spi_free_slave(spi); ++ ++ return ret; ++} ++ ++struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, ++ unsigned int max_hz, unsigned int spi_mode) ++{ ++ struct spi_flash *flash; ++ int ret; ++ ++ flash = malloc(sizeof(*flash)); ++ if (!flash) { ++ debug("SF: Failed to malloc spi_flash\n"); ++ return NULL; ++ } ++ memset(flash, 0, sizeof(*flash)); ++ ++ ret = spi_flash_probe_spl(flash, bus, cs, max_hz, spi_mode); ++ if (ret) ++ goto err_probe; ++ ++ printf("SF: %s, page size ", flash->name); ++ print_size(flash->sector_size, ", total "); ++ print_size(flash->size, "\n"); ++ ++ return flash; ++ ++err_probe: ++ free(flash); + return NULL; + } + +-void spi_flash_free(struct spi_flash *flash) ++void spi_flash_free_spl(struct spi_flash *flash) + { + spi_free_slave(flash->spi); ++} ++ ++void spi_flash_free(struct spi_flash *flash) ++{ ++ spi_flash_free_spl(flash); + free(flash); + } +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -52,6 +52,11 @@ struct spi_flash *spi_flash_probe(unsign + unsigned int max_hz, unsigned int spi_mode); + void spi_flash_free(struct spi_flash *flash); + ++int spi_flash_probe_spl(struct spi_flash *flash, unsigned int bus, ++ unsigned int cs, unsigned int max_hz, ++ unsigned int spi_mode); ++void spi_flash_free_spl(struct spi_flash *flash); ++ + static inline int spi_flash_read(struct spi_flash *flash, u32 offset, + size_t len, void *buf) + { diff --git a/package/boot/uboot-lantiq/patches/0005-sf-factor-out-the-flash-address-calculation.patch b/package/boot/uboot-lantiq/patches/0005-sf-factor-out-the-flash-address-calculation.patch new file mode 100644 index 0000000..356db59 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0005-sf-factor-out-the-flash-address-calculation.patch @@ -0,0 +1,107 @@ +From acb2721e1cd2e7488a7b08a4ed590177369a1689 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 19:10:40 +0100 +Subject: sf: factor out the flash address calculation + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -15,12 +15,22 @@ + + #include "spi_flash_internal.h" + +-static void spi_flash_addr(u32 addr, u8 *cmd) ++static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd, u8 *cmd_len) + { + /* cmd[0] is actual command */ + cmd[1] = addr >> 16; + cmd[2] = addr >> 8; + cmd[3] = addr >> 0; ++ *cmd_len = 4; ++} ++ ++static void spi_flash_page_addr(struct spi_flash *flash, u32 page_addr, u32 byte_addr, u8 *cmd, u8 *cmd_len) ++{ ++ /* cmd[0] is actual command */ ++ cmd[1] = page_addr >> 8; ++ cmd[2] = page_addr >> 0; ++ cmd[3] = byte_addr; ++ *cmd_len = 4; + } + + static int spi_flash_read_write(struct spi_slave *spi, +@@ -71,7 +81,7 @@ int spi_flash_cmd_write_multi(struct spi + unsigned long page_addr, byte_addr, page_size; + size_t chunk_len, actual; + int ret; +- u8 cmd[4]; ++ u8 cmd[4], cmd_len; + + page_size = flash->page_size; + page_addr = offset / page_size; +@@ -87,9 +97,7 @@ int spi_flash_cmd_write_multi(struct spi + for (actual = 0; actual < len; actual += chunk_len) { + chunk_len = min(len - actual, page_size - byte_addr); + +- cmd[1] = page_addr >> 8; +- cmd[2] = page_addr; +- cmd[3] = byte_addr; ++ spi_flash_page_addr(flash, page_addr, byte_addr, cmd, &cmd_len); + + debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", + buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); +@@ -100,7 +108,7 @@ int spi_flash_cmd_write_multi(struct spi + break; + } + +- ret = spi_flash_cmd_write(flash->spi, cmd, 4, ++ ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, + buf + actual, chunk_len); + if (ret < 0) { + debug("SF: write failed\n"); +@@ -138,13 +146,13 @@ int spi_flash_read_common(struct spi_fla + int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, + size_t len, void *data) + { +- u8 cmd[5]; ++ u8 cmd[5], cmd_len; + + cmd[0] = CMD_READ_ARRAY_FAST; +- spi_flash_addr(offset, cmd); +- cmd[4] = 0x00; ++ spi_flash_addr(flash, offset, cmd, &cmd_len); ++ cmd[cmd_len] = 0x00; + +- return spi_flash_read_common(flash, cmd, sizeof(cmd), data, len); ++ return spi_flash_read_common(flash, cmd, cmd_len + 1, data, len); + } + + int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout, +@@ -194,7 +202,7 @@ int spi_flash_cmd_erase(struct spi_flash + { + u32 start, end, erase_size; + int ret; +- u8 cmd[4]; ++ u8 cmd[4], cmd_len; + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { +@@ -216,7 +224,7 @@ int spi_flash_cmd_erase(struct spi_flash + end = start + len; + + while (offset < end) { +- spi_flash_addr(offset, cmd); ++ spi_flash_addr(flash, offset, cmd, &cmd_len); + offset += erase_size; + + debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], +@@ -226,7 +234,7 @@ int spi_flash_cmd_erase(struct spi_flash + if (ret) + goto out; + +- ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0); ++ ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, NULL, 0); + if (ret) + goto out; + diff --git a/package/boot/uboot-lantiq/patches/0006-sf-add-generic-support-for-4-byte-address-mode.patch b/package/boot/uboot-lantiq/patches/0006-sf-add-generic-support-for-4-byte-address-mode.patch new file mode 100644 index 0000000..1623b15 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0006-sf-add-generic-support-for-4-byte-address-mode.patch @@ -0,0 +1,161 @@ +From fb9ed0ef6f0ba6b6535c64dcfcf45c161723e56f Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 19:31:38 +0100 +Subject: sf: add generic support for 4-byte address mode + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -18,19 +18,35 @@ + static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd, u8 *cmd_len) + { + /* cmd[0] is actual command */ +- cmd[1] = addr >> 16; +- cmd[2] = addr >> 8; +- cmd[3] = addr >> 0; +- *cmd_len = 4; ++ if (spi_flash_use_4byte_mode(flash)) { ++ cmd[1] = addr >> 24; ++ cmd[2] = addr >> 16; ++ cmd[3] = addr >> 8; ++ cmd[4] = addr >> 0; ++ *cmd_len = 5; ++ } else { ++ cmd[1] = addr >> 16; ++ cmd[2] = addr >> 8; ++ cmd[3] = addr >> 0; ++ *cmd_len = 4; ++ } + } + + static void spi_flash_page_addr(struct spi_flash *flash, u32 page_addr, u32 byte_addr, u8 *cmd, u8 *cmd_len) + { + /* cmd[0] is actual command */ +- cmd[1] = page_addr >> 8; +- cmd[2] = page_addr >> 0; +- cmd[3] = byte_addr; +- *cmd_len = 4; ++ if (spi_flash_use_4byte_mode(flash)) { ++ cmd[1] = page_addr >> 16; ++ cmd[2] = page_addr >> 8; ++ cmd[3] = page_addr >> 0; ++ cmd[4] = byte_addr; ++ *cmd_len = 5; ++ } else { ++ cmd[1] = page_addr >> 8; ++ cmd[2] = page_addr >> 0; ++ cmd[3] = byte_addr; ++ *cmd_len = 4; ++ } + } + + static int spi_flash_read_write(struct spi_slave *spi, +@@ -81,7 +97,7 @@ int spi_flash_cmd_write_multi(struct spi + unsigned long page_addr, byte_addr, page_size; + size_t chunk_len, actual; + int ret; +- u8 cmd[4], cmd_len; ++ u8 cmd[5], cmd_len; + + page_size = flash->page_size; + page_addr = offset / page_size; +@@ -99,8 +115,8 @@ int spi_flash_cmd_write_multi(struct spi + + spi_flash_page_addr(flash, page_addr, byte_addr, cmd, &cmd_len); + +- debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", +- buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); ++ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x%02x } chunk_len = %zu\n", ++ buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], chunk_len); + + ret = spi_flash_cmd_write_enable(flash); + if (ret < 0) { +@@ -146,7 +162,7 @@ int spi_flash_read_common(struct spi_fla + int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, + size_t len, void *data) + { +- u8 cmd[5], cmd_len; ++ u8 cmd[6], cmd_len; + + cmd[0] = CMD_READ_ARRAY_FAST; + spi_flash_addr(flash, offset, cmd, &cmd_len); +@@ -202,7 +218,7 @@ int spi_flash_cmd_erase(struct spi_flash + { + u32 start, end, erase_size; + int ret; +- u8 cmd[4], cmd_len; ++ u8 cmd[5], cmd_len; + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { +@@ -227,8 +243,8 @@ int spi_flash_cmd_erase(struct spi_flash + spi_flash_addr(flash, offset, cmd, &cmd_len); + offset += erase_size; + +- debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], +- cmd[2], cmd[3], offset); ++ debug("SF: erase %2x %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], ++ cmd[2], cmd[3], cmd[4], offset); + + ret = spi_flash_cmd_write_enable(flash); + if (ret) +@@ -409,6 +425,12 @@ int spi_flash_probe_spl(struct spi_flash + goto err_manufacturer_probe; + } + ++ ret = spi_flash_set_4byte_mode(flash); ++ if (ret) { ++ debug("SF: Failed to enable 4 byte mode: %d\n", ret); ++ goto err_manufacturer_probe; ++ } ++ + spi_release_bus(spi); + + return 0; +--- a/drivers/mtd/spi/spi_flash_internal.h ++++ b/drivers/mtd/spi/spi_flash_internal.h +@@ -97,6 +97,31 @@ int spi_flash_cmd_wait_ready(struct spi_ + /* Erase sectors. */ + int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len); + ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++static inline int spi_flash_use_4byte_mode(struct spi_flash *flash) ++{ ++ return NULL != flash->set_4byte_mode; ++} ++ ++static inline int spi_flash_set_4byte_mode(struct spi_flash *flash) ++{ ++ if (spi_flash_use_4byte_mode(flash)) ++ return flash->set_4byte_mode(flash); ++ ++ return 0; ++} ++#else ++static inline int spi_flash_use_4byte_mode(struct spi_flash *flash) ++{ ++ return 0; ++} ++ ++static inline int spi_flash_set_4byte_mode(struct spi_flash *flash) ++{ ++ return 0; ++} ++#endif ++ + /* Manufacturer-specific probe functions */ + int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode); + int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode); +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -46,6 +46,9 @@ struct spi_flash { + size_t len, const void *buf); + int (*erase)(struct spi_flash *flash, u32 offset, + size_t len); ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++ int (*set_4byte_mode)(struct spi_flash *flash); ++#endif + }; + + struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, diff --git a/package/boot/uboot-lantiq/patches/0007-sf-eon-use-16-bit-ID-for-comparison.patch b/package/boot/uboot-lantiq/patches/0007-sf-eon-use-16-bit-ID-for-comparison.patch new file mode 100644 index 0000000..6836674 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0007-sf-eon-use-16-bit-ID-for-comparison.patch @@ -0,0 +1,45 @@ +From d32f45357f0475a2f810752eeb9412fe692e1c0a Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:09:21 +0100 +Subject: sf: eon: use 16 bit ID for comparison + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/eon.c ++++ b/drivers/mtd/spi/eon.c +@@ -11,19 +11,19 @@ + #include "spi_flash_internal.h" + + struct eon_spi_flash_params { +- u8 idcode1; ++ u16 idcode; + u16 nr_sectors; + const char *name; + }; + + static const struct eon_spi_flash_params eon_spi_flash_table[] = { + { +- .idcode1 = 0x16, ++ .idcode = 0x3016, + .nr_sectors = 1024, + .name = "EN25Q32B", + }, + { +- .idcode1 = 0x18, ++ .idcode = 0x3018, + .nr_sectors = 4096, + .name = "EN25Q128", + }, +@@ -33,10 +33,11 @@ int spi_flash_probe_eon(struct spi_flash + { + const struct eon_spi_flash_params *params; + unsigned int i; ++ u16 id = idcode[2] | idcode[1] << 8; + + for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) { + params = &eon_spi_flash_table[i]; +- if (params->idcode1 == idcode[2]) ++ if (params->idcode == id) + break; + } + diff --git a/package/boot/uboot-lantiq/patches/0008-sf-eon-add-support-for-4-byte-address-mode.patch b/package/boot/uboot-lantiq/patches/0008-sf-eon-add-support-for-4-byte-address-mode.patch new file mode 100644 index 0000000..c037a86 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0008-sf-eon-add-support-for-4-byte-address-mode.patch @@ -0,0 +1,43 @@ +From 37254e3284f61ea495f73a78b7c8efae983781e2 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:10:07 +0100 +Subject: sf: eon: add support for 4-byte address mode + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/eon.c ++++ b/drivers/mtd/spi/eon.c +@@ -10,6 +10,8 @@ + + #include "spi_flash_internal.h" + ++#define EN25XX_EN4B 0xb7 /* Enter 4-byte mode */ ++ + struct eon_spi_flash_params { + u16 idcode; + u16 nr_sectors; +@@ -29,6 +31,13 @@ static const struct eon_spi_flash_params + }, + }; + ++static __maybe_unused int eon_set_4byte_mode(struct spi_flash *flash) ++{ ++ struct spi_slave *spi = flash->spi; ++ ++ return spi_flash_cmd(spi, EN25XX_EN4B, NULL, 0); ++} ++ + int spi_flash_probe_eon(struct spi_flash *flash, u8 *idcode) + { + const struct eon_spi_flash_params *params; +@@ -57,5 +66,10 @@ int spi_flash_probe_eon(struct spi_flash + flash->size = 256 * 16 + * params->nr_sectors; + ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++ if (flash->size > (1 << 24)) ++ flash->set_4byte_mode = eon_set_4byte_mode; ++#endif ++ + return 1; + } diff --git a/package/boot/uboot-lantiq/patches/0009-sf-eon-add-support-for-EN25QH256.patch b/package/boot/uboot-lantiq/patches/0009-sf-eon-add-support-for-EN25QH256.patch new file mode 100644 index 0000000..18f5823 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0009-sf-eon-add-support-for-EN25QH256.patch @@ -0,0 +1,21 @@ +From e510be1145796cd44cf5800e187a94ad7c19e764 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:10:34 +0100 +Subject: sf: eon: add support for EN25QH256 + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/eon.c ++++ b/drivers/mtd/spi/eon.c +@@ -29,6 +29,11 @@ static const struct eon_spi_flash_params + .nr_sectors = 4096, + .name = "EN25Q128", + }, ++ { ++ .idcode = 0x7019, ++ .nr_sectors = 8192, ++ .name = "EN25QH256", ++ }, + }; + + static __maybe_unused int eon_set_4byte_mode(struct spi_flash *flash) diff --git a/package/boot/uboot-lantiq/patches/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch b/package/boot/uboot-lantiq/patches/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch new file mode 100644 index 0000000..af8c7a1 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0010-sf-spansion-fix-device-IDs-and-sector-architecture-f.patch @@ -0,0 +1,30 @@ +From 81a8e9e192d53ce8b5cafd47190d6c6826519d09 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:58:59 +0100 +Subject: sf: spansion: fix device IDs and sector architecture for S25FL256S + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spansion.c ++++ b/drivers/mtd/spi/spansion.c +@@ -97,11 +97,18 @@ static const struct spansion_spi_flash_p + .name = "S25FL129P_64K", + }, + { +- .idcode1 = 0x2019, ++ .idcode1 = 0x0219, + .idcode2 = 0x4d01, + .pages_per_sector = 256, + .nr_sectors = 512, +- .name = "S25FL256S", ++ .name = "S25FL256S_64K", ++ }, ++ { ++ .idcode1 = 0x0219, ++ .idcode2 = 0x4d00, ++ .pages_per_sector = 1024, ++ .nr_sectors = 128, ++ .name = "S25FL256S_256K", + }, + }; + diff --git a/package/boot/uboot-lantiq/patches/0011-sf-spansion-add-support-for-4-byte-address-mode.patch b/package/boot/uboot-lantiq/patches/0011-sf-spansion-add-support-for-4-byte-address-mode.patch new file mode 100644 index 0000000..9471d47 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0011-sf-spansion-add-support-for-4-byte-address-mode.patch @@ -0,0 +1,55 @@ +From 0add8e5c60961d2b99174610df8d3d9d6d192b74 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 14:16:11 +0100 +Subject: sf: spansion: add support for 4-byte address mode + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spansion.c ++++ b/drivers/mtd/spi/spansion.c +@@ -31,6 +31,10 @@ + + #include "spi_flash_internal.h" + ++#define S25FLXX_BRRD 0x16 /* Read Bank Register */ ++#define S25FLXX_BRWR 0x17 /* Write Bank Register */ ++#define S25FLXX_BAR_EXTADD (1 << 7) /* Extended address enable */ ++ + struct spansion_spi_flash_params { + u16 idcode1; + u16 idcode2; +@@ -112,6 +116,23 @@ static const struct spansion_spi_flash_p + }, + }; + ++static __maybe_unused int spansion_set_4byte_mode(struct spi_flash *flash) ++{ ++ struct spi_slave *spi = flash->spi; ++ u8 bar, cmd; ++ int err; ++ ++ cmd = S25FLXX_BRRD; ++ err = spi_flash_cmd(spi, cmd, &bar, 1); ++ if (err) ++ return err; ++ ++ bar |= S25FLXX_BAR_EXTADD; ++ cmd = S25FLXX_BRWR; ++ ++ return spi_flash_cmd_write(spi, &cmd, 1, &bar, 1); ++} ++ + int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode) + { + const struct spansion_spi_flash_params *params; +@@ -144,5 +165,10 @@ int spi_flash_probe_spansion(struct spi_ + flash->sector_size = 256 * params->pages_per_sector; + flash->size = flash->sector_size * params->nr_sectors; + ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++ if (flash->size > (1 << 24)) ++ flash->set_4byte_mode = spansion_set_4byte_mode; ++#endif ++ + return 1; + } diff --git a/package/boot/uboot-lantiq/patches/0012-sf-spansion-add-support-for-S25FL512S.patch b/package/boot/uboot-lantiq/patches/0012-sf-spansion-add-support-for-S25FL512S.patch new file mode 100644 index 0000000..5f415a9 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0012-sf-spansion-add-support-for-S25FL512S.patch @@ -0,0 +1,23 @@ +From bff335ac524843bc90163c3b231091a5016f8670 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:07:54 +0100 +Subject: sf: spansion: add support for S25FL512S + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spansion.c ++++ b/drivers/mtd/spi/spansion.c +@@ -114,6 +114,13 @@ static const struct spansion_spi_flash_p + .nr_sectors = 128, + .name = "S25FL256S_256K", + }, ++ { ++ .idcode1 = 0x0220, ++ .idcode2 = 0x4d00, ++ .pages_per_sector = 1024, ++ .nr_sectors = 256, ++ .name = "S25FL512S_256K", ++ }, + }; + + static __maybe_unused int spansion_set_4byte_mode(struct spi_flash *flash) diff --git a/package/boot/uboot-lantiq/patches/0013-sf-macronix-add-support-for-4-byte-address-mode.patch b/package/boot/uboot-lantiq/patches/0013-sf-macronix-add-support-for-4-byte-address-mode.patch new file mode 100644 index 0000000..70015c9 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0013-sf-macronix-add-support-for-4-byte-address-mode.patch @@ -0,0 +1,44 @@ +From 207662a9270cc542709fbab0d25fbc361b39748c Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:13:49 +0100 +Subject: sf: macronix: add support for 4-byte address mode + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/macronix.c ++++ b/drivers/mtd/spi/macronix.c +@@ -35,6 +35,8 @@ + + #include "spi_flash_internal.h" + ++#define MX25XX_EN4B 0xb7 /* Enter 4-byte mode */ ++ + struct macronix_spi_flash_params { + u16 idcode; + u16 nr_blocks; +@@ -79,6 +81,13 @@ static const struct macronix_spi_flash_p + }, + }; + ++static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash) ++{ ++ struct spi_slave *spi = flash->spi; ++ ++ return spi_flash_cmd(spi, MX25XX_EN4B, NULL, 0); ++} ++ + int spi_flash_probe_macronix(struct spi_flash *flash, u8 *idcode) + { + const struct macronix_spi_flash_params *params; +@@ -106,6 +115,11 @@ int spi_flash_probe_macronix(struct spi_ + flash->sector_size = 256 * 16 * 16; + flash->size = flash->sector_size * params->nr_blocks; + ++#ifdef CONFIG_SPI_FLASH_4BYTE_MODE ++ if (flash->size > (1 << 24)) ++ flash->set_4byte_mode = macronix_set_4byte_mode; ++#endif ++ + /* Clear BP# bits for read-only flash */ + spi_flash_cmd_write_status(flash, 0); + diff --git a/package/boot/uboot-lantiq/patches/0014-sf-macronix-add-support-for-MX25L25635E.patch b/package/boot/uboot-lantiq/patches/0014-sf-macronix-add-support-for-MX25L25635E.patch new file mode 100644 index 0000000..8e33836 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0014-sf-macronix-add-support-for-MX25L25635E.patch @@ -0,0 +1,21 @@ +From 0f31fef3d6a5110684ea31c5064c45fc448013d6 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:14:24 +0100 +Subject: sf: macronix: add support for MX25L25635E + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/macronix.c ++++ b/drivers/mtd/spi/macronix.c +@@ -79,6 +79,11 @@ static const struct macronix_spi_flash_p + .nr_blocks = 256, + .name = "MX25L12855E", + }, ++ { ++ .idcode = 0x2019, ++ .nr_blocks = 512, ++ .name = "MX25L25635E", ++ }, + }; + + static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash) diff --git a/package/boot/uboot-lantiq/patches/0015-sf-macronix-add-support-for-MX66L51235L.patch b/package/boot/uboot-lantiq/patches/0015-sf-macronix-add-support-for-MX66L51235L.patch new file mode 100644 index 0000000..fbc22e4 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0015-sf-macronix-add-support-for-MX66L51235L.patch @@ -0,0 +1,21 @@ +From a2d80b6b91ac63beea31455ce8d136230c030500 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 7 Nov 2012 15:14:40 +0100 +Subject: sf: macronix: add support for MX66L51235L + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/macronix.c ++++ b/drivers/mtd/spi/macronix.c +@@ -84,6 +84,11 @@ static const struct macronix_spi_flash_p + .nr_blocks = 512, + .name = "MX25L25635E", + }, ++ { ++ .idcode = 0x201A, ++ .nr_blocks = 1024, ++ .name = "MX66L51235L", ++ }, + }; + + static __maybe_unused int macronix_set_4byte_mode(struct spi_flash *flash) diff --git a/package/boot/uboot-lantiq/patches/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch b/package/boot/uboot-lantiq/patches/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch new file mode 100644 index 0000000..a9ee560 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0016-sf-add-MTD-layer-driver-for-SPI-flash-devices.patch @@ -0,0 +1,133 @@ +From 7f6ded11965b09daf6da44d4fa98da17b9fba36c Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 19:41:26 +0100 +Subject: sf: add MTD layer driver for SPI flash devices + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/Makefile ++++ b/drivers/mtd/spi/Makefile +@@ -30,6 +30,7 @@ COBJS-$(CONFIG_SPL_SPI_LOAD) += spi_spl_ + endif + + COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o ++COBJS-$(CONFIG_SPI_FLASH_MTD) += spi_flash_mtd.o + COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o + COBJS-$(CONFIG_SPI_FLASH_EON) += eon.o + COBJS-$(CONFIG_SPI_FLASH_MACRONIX) += macronix.o +--- a/drivers/mtd/spi/spi_flash_internal.h ++++ b/drivers/mtd/spi/spi_flash_internal.h +@@ -122,6 +122,9 @@ static inline int spi_flash_set_4byte_mo + } + #endif + ++/* SPI flash MTD adapter init */ ++int spi_flash_mtd_init(struct spi_flash *flash); ++ + /* Manufacturer-specific probe functions */ + int spi_flash_probe_spansion(struct spi_flash *flash, u8 *idcode); + int spi_flash_probe_atmel(struct spi_flash *flash, u8 *idcode); +--- /dev/null ++++ b/drivers/mtd/spi/spi_flash_mtd.c +@@ -0,0 +1,101 @@ ++/* ++ * (C) Copyright 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * MTD layer driver for SPI flash devices ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <asm/errno.h> ++#include <linux/mtd/mtd.h> ++#include <spi_flash.h> ++ ++static struct mtd_info sf_mtd_info; ++static char sf_mtd_name[8]; ++ ++static int spi_flash_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ struct spi_flash *flash = mtd->priv; ++ int err; ++ ++ instr->state = MTD_ERASING; ++ ++ err = spi_flash_erase(flash, instr->addr, instr->len); ++ if (err) { ++ instr->state = MTD_ERASE_FAILED; ++ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; ++ return -EIO; ++ } ++ ++ instr->state = MTD_ERASE_DONE; ++ mtd_erase_callback(instr); ++ ++ return 0; ++} ++ ++static int spi_flash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ struct spi_flash *flash = mtd->priv; ++ int err; ++ ++ err = spi_flash_read(flash, from, len, buf); ++ if (!err) ++ *retlen = len; ++ ++ return err; ++} ++ ++static int spi_flash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ struct spi_flash *flash = mtd->priv; ++ int err; ++ ++ err = spi_flash_write(flash, to, len, buf); ++ if (!err) ++ *retlen = len; ++ ++ return err; ++} ++ ++static void spi_flash_mtd_sync(struct mtd_info *mtd) ++{ ++} ++ ++static int spi_flash_mtd_number(void) ++{ ++#ifdef CONFIG_SYS_MAX_FLASH_BANKS ++ return CONFIG_SYS_MAX_FLASH_BANKS; ++#else ++ return 0; ++#endif ++} ++ ++int spi_flash_mtd_init(struct spi_flash *flash) ++{ ++ memset(&sf_mtd_info, 0, sizeof(sf_mtd_info)); ++ sprintf(sf_mtd_name, "nor%d", spi_flash_mtd_number()); ++ ++ sf_mtd_info.name = sf_mtd_name; ++ sf_mtd_info.type = MTD_NORFLASH; ++ sf_mtd_info.flags = MTD_CAP_NORFLASH; ++ sf_mtd_info.writesize = 1; ++ ++ sf_mtd_info.erase = spi_flash_mtd_erase; ++ sf_mtd_info.read = spi_flash_mtd_read; ++ sf_mtd_info.write = spi_flash_mtd_write; ++ sf_mtd_info.sync = spi_flash_mtd_sync; ++ ++ sf_mtd_info.size = flash->size; ++ sf_mtd_info.priv = flash; ++ ++ /* Only uniform flash devices for now */ ++ sf_mtd_info.numeraseregions = 0; ++ sf_mtd_info.erasesize = flash->sector_size; ++ ++ return add_mtd_device(&sf_mtd_info); ++} diff --git a/package/boot/uboot-lantiq/patches/0017-sf-add-init-function.patch b/package/boot/uboot-lantiq/patches/0017-sf-add-init-function.patch new file mode 100644 index 0000000..2d29051 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0017-sf-add-init-function.patch @@ -0,0 +1,57 @@ +From aa9d5d64ca6441cb24e22dc3c1f707da62da2887 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 19:35:17 +0100 +Subject: sf: add init function + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/mtd/spi/spi_flash.c ++++ b/drivers/mtd/spi/spi_flash.c +@@ -482,3 +482,36 @@ void spi_flash_free(struct spi_flash *fl + spi_flash_free_spl(flash); + free(flash); + } ++ ++#ifdef CONFIG_SPI_FLASH_MTD ++static int spi_flash_mtd_register(void) ++{ ++ struct spi_flash *flash; ++ int err; ++ ++ flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, ++ CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); ++ if (!flash) ++ return -1; ++ ++ err = spi_flash_mtd_init(flash); ++ if (err) ++ spi_flash_free(flash); ++ ++ return err; ++} ++#else ++static int spi_flash_mtd_register(void) ++{ ++ return 0; ++} ++#endif ++ ++int spi_flash_init(void) ++{ ++ int err; ++ ++ err = spi_flash_mtd_register(); ++ ++ return err; ++} +--- a/include/spi_flash.h ++++ b/include/spi_flash.h +@@ -51,6 +51,8 @@ struct spi_flash { + #endif + }; + ++int spi_flash_init(void); ++ + struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int spi_mode); + void spi_flash_free(struct spi_flash *flash); diff --git a/package/boot/uboot-lantiq/patches/0018-MIPS-add-SPI-flash-init-hook.patch b/package/boot/uboot-lantiq/patches/0018-MIPS-add-SPI-flash-init-hook.patch new file mode 100644 index 0000000..71f094b --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0018-MIPS-add-SPI-flash-init-hook.patch @@ -0,0 +1,47 @@ +From 888b33e84082fe72d60d528c05c885c0c9d70bc4 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Tue, 6 Nov 2012 21:19:43 +0100 +Subject: MIPS: add SPI flash init hook + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/arch/mips/lib/board.c ++++ b/arch/mips/lib/board.c +@@ -32,6 +32,7 @@ + #include <nand.h> + #include <onenand_uboot.h> + #include <spi.h> ++#include <spi_flash.h> + + #ifdef CONFIG_BITBANGMII + #include <miiphy.h> +@@ -312,6 +313,16 @@ void board_init_r(gd_t *id, ulong dest_a + onenand_init(); + #endif + ++#ifdef CONFIG_CMD_SPI ++ puts("SPI: "); ++ spi_init(); /* go init the SPI */ ++ puts("ready\n"); ++#endif ++ ++#if defined(CONFIG_SPI_FLASH) ++ spi_flash_init(); ++#endif ++ + /* relocate environment function pointers etc. */ + env_relocate(); + +@@ -335,12 +346,6 @@ void board_init_r(gd_t *id, ulong dest_a + /* Initialize from environment */ + load_addr = getenv_ulong("loadaddr", 16, load_addr); + +-#ifdef CONFIG_CMD_SPI +- puts("SPI: "); +- spi_init(); /* go init the SPI */ +- puts("ready\n"); +-#endif +- + #if defined(CONFIG_MISC_INIT_R) + /* miscellaneous platform dependent initialisations */ + misc_init_r(); diff --git a/package/boot/uboot-lantiq/patches/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch b/package/boot/uboot-lantiq/patches/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch new file mode 100644 index 0000000..a215d1a --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0019-net-switchlib-add-framework-for-ethernet-switch-driv.patch @@ -0,0 +1,239 @@ +From d8b1597130d228bc7e2bafd0c8d097529018c833 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 29 Aug 2012 22:08:15 +0200 +Subject: net: switchlib: add framework for ethernet switch drivers + +Add a generic framework similar to phylib for ethernet switch +drivers and devices. This is useful to share the init and +setup code for switch devices across different boards. + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Cc: Joe Hershberger <joe.hershberger@gmail.com> + +--- a/Makefile ++++ b/Makefile +@@ -291,6 +291,7 @@ LIBS-y += drivers/mtd/ubi/libubi.o + LIBS-y += drivers/mtd/spi/libspi_flash.o + LIBS-y += drivers/net/libnet.o + LIBS-y += drivers/net/phy/libphy.o ++LIBS-y += drivers/net/switch/libswitch.o + LIBS-y += drivers/pci/libpci.o + LIBS-y += drivers/pcmcia/libpcmcia.o + LIBS-y += drivers/power/libpower.o \ +--- /dev/null ++++ b/drivers/net/switch/Makefile +@@ -0,0 +1,31 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB := $(obj)libswitch.o ++ ++COBJS-$(CONFIG_SWITCH_MULTI) += switch.o ++ ++COBJS := $(COBJS-y) ++SRCS := $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++ ++all: $(LIB) ++ ++$(LIB): $(obj).depend $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/drivers/net/switch/switch.c +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <switch.h> ++ ++static struct list_head switch_drivers; ++static struct list_head switch_devices; ++ ++void switch_init(void) ++{ ++ INIT_LIST_HEAD(&switch_drivers); ++ INIT_LIST_HEAD(&switch_devices); ++ ++ board_switch_init(); ++} ++ ++void switch_driver_register(struct switch_driver *drv) ++{ ++ INIT_LIST_HEAD(&drv->list); ++ list_add_tail(&drv->list, &switch_drivers); ++} ++ ++int switch_device_register(struct switch_device *dev) ++{ ++ struct switch_driver *drv; ++ ++ /* Add switch device only, if an adequate driver is registered */ ++ list_for_each_entry(drv, &switch_drivers, list) { ++ if (!strcmp(drv->name, dev->name)) { ++ dev->drv = drv; ++ ++ INIT_LIST_HEAD(&dev->list); ++ list_add_tail(&dev->list, &switch_devices); ++ ++ return 0; ++ } ++ } ++ ++ return -1; ++} ++ ++struct switch_device *switch_connect(struct mii_dev *bus) ++{ ++ struct switch_device *sw; ++ int err; ++ ++ list_for_each_entry(sw, &switch_devices, list) { ++ sw->bus = bus; ++ ++ err = sw->drv->probe(sw); ++ if (!err) ++ return sw; ++ } ++ ++ return NULL; ++} +--- /dev/null ++++ b/include/switch.h +@@ -0,0 +1,95 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __SWITCH_H ++#define __SWITCH_H ++ ++#include <linux/list.h> ++ ++#define SWITCH_NAME_SIZE 32 ++ ++struct switch_device; ++struct mii_dev; ++ ++struct switch_driver { ++ struct list_head list; ++ ++ /* Switch device name */ ++ const char name[SWITCH_NAME_SIZE]; ++ ++ /* ++ * Called to probe the switch chip. Must return 0 if the switch ++ * chip matches the given switch device/driver combination. Otherwise ++ * 1 must be returned. ++ */ ++ int (*probe) (struct switch_device *dev); ++ ++ /* ++ * Called to initialize the switch chip. ++ */ ++ void (*setup) (struct switch_device *dev); ++}; ++ ++struct switch_device { ++ struct list_head list; ++ struct switch_driver *drv; ++ ++ /* MII bus the switch chip is connected to */ ++ struct mii_dev *bus; ++ ++ /* Switch device name */ ++ const char name[SWITCH_NAME_SIZE]; ++ ++ /* Bitmask for board specific setup of used switch ports */ ++ u16 port_mask; ++ ++ /* Number of switch port that is connected to host CPU */ ++ u16 cpu_port; ++}; ++ ++/* ++ * Board specific switch initialization. ++ * ++ * Called from switch_init to register the board specific switch_device ++ * structure. ++ */ ++extern int board_switch_init(void); ++ ++/* Initialize switch subsystem */ ++#ifdef CONFIG_SWITCH_MULTI ++extern void switch_init(void); ++#else ++static inline void switch_init(void) ++{ ++} ++#endif ++ ++/* Register a switch driver */ ++extern void switch_driver_register(struct switch_driver *drv); ++ ++/* Register a switch device */ ++extern int switch_device_register(struct switch_device *dev); ++ ++/* ++ * Probe the available switch chips and connect the found one ++ * with the given MII bus ++ */ ++extern struct switch_device *switch_connect(struct mii_dev *bus); ++ ++/* ++ * Setup the given switch device ++ */ ++static inline void switch_setup(struct switch_device *dev) ++{ ++ if (dev->drv->setup) ++ dev->drv->setup(dev); ++} ++ ++/* Init functions for supported Switch drivers */ ++ ++#endif /* __SWITCH_H */ ++ +--- a/net/eth.c ++++ b/net/eth.c +@@ -26,6 +26,7 @@ + #include <net.h> + #include <miiphy.h> + #include <phy.h> ++#include <switch.h> + + void eth_parse_enetaddr(const char *addr, uchar *enetaddr) + { +@@ -303,6 +304,8 @@ int eth_initialize(bd_t *bis) + phy_init(); + #endif + ++ switch_init(); ++ + eth_env_init(bis); + + /* diff --git a/package/boot/uboot-lantiq/patches/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch b/package/boot/uboot-lantiq/patches/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch new file mode 100644 index 0000000..c017e0f --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0020-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch @@ -0,0 +1,162 @@ +From b8c666eda693906488637c414db9db35b6760e4a Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 29 Aug 2012 22:08:15 +0200 +Subject: net: switchlib: add driver for Lantiq PSB697X switch family + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/net/switch/Makefile ++++ b/drivers/net/switch/Makefile +@@ -11,6 +11,7 @@ include $(TOPDIR)/config.mk + LIB := $(obj)libswitch.o + + COBJS-$(CONFIG_SWITCH_MULTI) += switch.o ++COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +--- /dev/null ++++ b/drivers/net/switch/psb697x.c +@@ -0,0 +1,119 @@ ++/* ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <switch.h> ++#include <miiphy.h> ++ ++#define PSB697X_CHIPID1 0x2599 ++#define PSB697X_PORT_COUNT 7 ++ ++#define PSB697X_PORT_BASE(p) (p * 0x20) ++#define PSB697X_REG_PS(p) (PSB697X_PORT_BASE(p) + 0x00) ++#define PSB697X_REG_PBC(p) (PSB697X_PORT_BASE(p) + 0x01) ++#define PSB697X_REG_PEC(p) (PSB697X_PORT_BASE(p) + 0x02) ++ ++#define PSB697X_REG_SGC1 0x0E0 /* Switch Global Control Register 1 */ ++#define PSB697X_REG_SGC2 0x0E1 /* Switch Global Control Register 2 */ ++#define PSB697X_REG_CMH 0x0E2 /* CPU Port & Mirror Control */ ++#define PSB697X_REG_MIICR 0x0F5 /* MII Port Control */ ++#define PSB697X_REG_CI0 0x100 /* Chip Identifier 0 */ ++#define PSB697X_REG_CI1 0x101 /* Chip Identifier 1 */ ++#define PSB697X_REG_MIIAC 0x120 /* MII Indirect Access Control */ ++#define PSB697X_REG_MIIWD 0x121 /* MII Indirect Write Data */ ++#define PSB697X_REG_MIIRD 0x122 /* MII Indirect Read Data */ ++ ++#define PSB697X_REG_PORT_FLP (1 << 2) /* Force link up */ ++#define PSB697X_REG_PORT_FLD (1 << 1) /* Force link down */ ++ ++#define PSB697X_REG_SGC2_SE (1 << 15) /* Switch enable */ ++ ++#define PSB697X_REG_CMH_CPN_MASK 0x7 ++#define PSB697X_REG_CMH_CPN_SHIFT 5 ++ ++ ++static inline int psb697x_mii_read(struct mii_dev *bus, u16 reg) ++{ ++ int ret; ++ ++ ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f); ++ ++ return ret; ++} ++ ++static inline int psb697x_mii_write(struct mii_dev *bus, u16 reg, u16 val) ++{ ++ int ret; ++ ++ ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, ++ reg & 0x1f, val); ++ ++ return ret; ++} ++ ++static int psb697x_probe(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ int ci1; ++ ++ ci1 = psb697x_mii_read(bus, PSB697X_REG_CI1); ++ ++ if (ci1 == PSB697X_CHIPID1) ++ return 0; ++ ++ return 1; ++} ++ ++static void psb697x_setup(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ int i, state; ++ ++ /* Enable switch */ ++ psb697x_mii_write(bus, PSB697X_REG_SGC2, PSB697X_REG_SGC2_SE); ++ ++ /* ++ * Force 100 Mbps as default value for CPU ports 5 and 6 to get ++ * full speed. ++ */ ++ psb697x_mii_write(bus, PSB697X_REG_MIICR, 0x0773); ++ ++ for (i = 0; i < PSB697X_PORT_COUNT; i++) { ++ state = dev->port_mask & (1 << i); ++ ++ /* ++ * Software workaround from Errata Sheet: ++ * Force link down and reset internal PHY, keep that state ++ * for all unconnected ports and disable force link down ++ * for all connected ports ++ */ ++ psb697x_mii_write(bus, PSB697X_REG_PBC(i), ++ PSB697X_REG_PORT_FLD); ++ ++ if (i == dev->cpu_port) ++ /* Force link up for CPU port */ ++ psb697x_mii_write(bus, PSB697X_REG_PBC(i), ++ PSB697X_REG_PORT_FLP); ++ else if (state) ++ /* Disable force link down for active LAN ports */ ++ psb697x_mii_write(bus, PSB697X_REG_PBC(i), 0); ++ } ++} ++ ++static struct switch_driver psb697x_drv = { ++ .name = "psb697x", ++}; ++ ++void switch_psb697x_init(void) ++{ ++ /* For archs with manual relocation */ ++ psb697x_drv.probe = psb697x_probe; ++ psb697x_drv.setup = psb697x_setup; ++ ++ switch_driver_register(&psb697x_drv); ++} +--- a/drivers/net/switch/switch.c ++++ b/drivers/net/switch/switch.c +@@ -18,6 +18,10 @@ void switch_init(void) + INIT_LIST_HEAD(&switch_drivers); + INIT_LIST_HEAD(&switch_devices); + ++#if defined(CONFIG_SWITCH_PSB697X) ++ switch_psb697x_init(); ++#endif ++ + board_switch_init(); + } + +--- a/include/switch.h ++++ b/include/switch.h +@@ -90,6 +90,7 @@ static inline void switch_setup(struct s + } + + /* Init functions for supported Switch drivers */ ++extern void switch_psb697x_init(void); + + #endif /* __SWITCH_H */ + diff --git a/package/boot/uboot-lantiq/patches/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch b/package/boot/uboot-lantiq/patches/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch new file mode 100644 index 0000000..342fa46 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0021-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch @@ -0,0 +1,158 @@ +From fcbbb1beb2ae862f5c703c5719ed0e155cbbf82f Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 29 Aug 2012 22:08:16 +0200 +Subject: net: switchlib: add driver for Lantiq ADM6996I switch family + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/net/switch/Makefile ++++ b/drivers/net/switch/Makefile +@@ -12,6 +12,7 @@ LIB := $(obj)libswitch.o + + COBJS-$(CONFIG_SWITCH_MULTI) += switch.o + COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o ++COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +--- /dev/null ++++ b/drivers/net/switch/adm6996i.c +@@ -0,0 +1,116 @@ ++/* ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <switch.h> ++#include <miiphy.h> ++ ++#define ADM6996I_CHIPID0 0x1020 ++#define ADM6996I_CHIPID1 0x0007 ++#define ADM6996I_PORT_COUNT 6 ++ ++#define ADM6996I_REG_P0BC 0x001 /* P0 Basic Control */ ++#define ADM6996I_REG_P1BC 0x003 /* P1 Basic Control */ ++#define ADM6996I_REG_P2BC 0x005 /* P2 Basic Control */ ++#define ADM6996I_REG_P3BC 0x007 /* P3 Basic Control */ ++#define ADM6996I_REG_P4BC 0x008 /* P4 Basic Control */ ++#define ADM6996I_REG_P5BC 0x009 /* P5 Basic Control */ ++ ++#define ADM6996I_REG_P0EC 0x002 /* P0 Extended Control */ ++#define ADM6996I_REG_P1EC 0x002 /* P1 Extended Control */ ++#define ADM6996I_REG_P2EC 0x004 /* P2 Extended Control */ ++#define ADM6996I_REG_P3EC 0x004 /* P3 Extended Control */ ++#define ADM6996I_REG_P4EC 0x006 /* P4 Extended Control */ ++#define ADM6996I_REG_P5EC 0x006 /* P5 Extended Control */ ++ ++#define ADM6996I_REG_SC4 0x012 /* System Control 4 */ ++ ++#define ADM6996I_REG_CI0 0xA0 /* Chip Identifier 0 */ ++#define ADM6996I_REG_CI1 0xA1 /* Chip Identifier 1 */ ++ ++#define ADM6996I_REG_PXBC_DEFAULT 0x040F ++#define ADM6996I_REG_PXBC_CROSS_EE (1 << 15) ++#define ADM6996I_REG_PXBC_PD (1 << 5) ++ ++#define ADM6996I_REG_SC4_DEFAULT 0x3600 ++#define ADM6996I_REG_SC4_LED_ENABLE (1 << 1) ++ ++#define ADM6996I_REG_CI0_PC_MASK 0xFFF0 ++#define ADM6996I_REG_CI0_VN_MASK 0xF ++#define ADM6996I_REG_CI1_PC_MASK 0xF ++ ++ ++static inline int adm6996i_mii_read(struct mii_dev *bus, u16 reg) ++{ ++ int ret; ++ ++ ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f); ++ ++ return ret; ++} ++ ++static inline int adm6996i_mii_write(struct mii_dev *bus, u16 reg, u16 val) ++{ ++ int ret; ++ ++ ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, ++ reg & 0x1f, val); ++ ++ return ret; ++} ++ ++static int adm6996i_probe(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ u16 ci0, ci1; ++ ++ ci0 = adm6996i_mii_read(bus, ADM6996I_REG_CI0); ++ ci1 = adm6996i_mii_read(bus, ADM6996I_REG_CI1); ++ ++ ci0 &= ADM6996I_REG_CI0_PC_MASK; ++ ci1 &= ADM6996I_REG_CI1_PC_MASK; ++ ++ if (ci0 == ADM6996I_CHIPID0 && ci1 == ADM6996I_CHIPID1) ++ return 0; ++ ++ return 1; ++} ++ ++static void adm6996i_setup(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ u16 val; ++ ++ /* ++ * Write default values (Port enable, 100 Mbps, Full Duplex, ++ * Auto negotiation, Flow control) and enable crossover auto-detect ++ */ ++ val = ADM6996I_REG_PXBC_DEFAULT | ADM6996I_REG_PXBC_CROSS_EE; ++ adm6996i_mii_write(bus, ADM6996I_REG_P0BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P1BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P2BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P3BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P4BC, val); ++ adm6996i_mii_write(bus, ADM6996I_REG_P5BC, val); ++ ++ val = ADM6996I_REG_SC4_DEFAULT | ADM6996I_REG_SC4_LED_ENABLE; ++ adm6996i_mii_write(bus, ADM6996I_REG_SC4, val); ++} ++ ++static struct switch_driver adm6996i_drv = { ++ .name = "adm6996i", ++}; ++ ++void switch_adm6996i_init(void) ++{ ++ /* For archs with manual relocation */ ++ adm6996i_drv.probe = adm6996i_probe; ++ adm6996i_drv.setup = adm6996i_setup; ++ ++ switch_driver_register(&adm6996i_drv); ++} +--- a/drivers/net/switch/switch.c ++++ b/drivers/net/switch/switch.c +@@ -21,6 +21,9 @@ void switch_init(void) + #if defined(CONFIG_SWITCH_PSB697X) + switch_psb697x_init(); + #endif ++#if defined(CONFIG_SWITCH_ADM6996I) ++ switch_adm6996i_init(); ++#endif + + board_switch_init(); + } +--- a/include/switch.h ++++ b/include/switch.h +@@ -91,6 +91,7 @@ static inline void switch_setup(struct s + + /* Init functions for supported Switch drivers */ + extern void switch_psb697x_init(void); ++extern void switch_adm6996i_init(void); + + #endif /* __SWITCH_H */ + diff --git a/package/boot/uboot-lantiq/patches/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch b/package/boot/uboot-lantiq/patches/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch new file mode 100644 index 0000000..127c0d8 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0022-net-switchlib-add-driver-for-Atheros-AR8216.patch @@ -0,0 +1,158 @@ +From 16b8c52f80f20e07866e397ff52ff9658766437b Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Wed, 29 Aug 2012 22:08:16 +0200 +Subject: net: switchlib: add driver for Atheros AR8216 + +Signed-off-by: Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/drivers/net/switch/Makefile ++++ b/drivers/net/switch/Makefile +@@ -13,6 +13,7 @@ LIB := $(obj)libswitch.o + COBJS-$(CONFIG_SWITCH_MULTI) += switch.o + COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o + COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o ++COBJS-$(CONFIG_SWITCH_AR8216) += ar8216.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +--- /dev/null ++++ b/drivers/net/switch/ar8216.c +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ * ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <miiphy.h> ++#include <switch.h> ++#include <netdev.h> ++ ++#define BITS(_s, _n) (((1UL << (_n)) - 1) << _s) ++ ++#define AR8216_REG_CTRL 0x0000 ++#define AR8216_CTRL_REVISION BITS(0, 8) ++#define AR8216_CTRL_VERSION BITS(8, 8) ++ ++#define AR8216_PROBE_RETRIES 10 ++ ++static void split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) ++{ ++ regaddr >>= 1; ++ *r1 = regaddr & 0x1e; ++ ++ regaddr >>= 5; ++ *r2 = regaddr & 0x7; ++ ++ regaddr >>= 3; ++ *page = regaddr & 0x1ff; ++} ++ ++static int ar8216_mii_read(struct mii_dev *bus, u32 reg) ++{ ++ u16 r1, r2, page; ++ u16 lo, hi; ++ ++ split_addr(reg, &r1, &r2, &page); ++ ++ bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, page); ++ __udelay(1000); ++ ++ lo = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1); ++ hi = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1); ++ ++ return (hi << 16) | lo; ++} ++ ++static void ar8216_mii_write(struct mii_dev *bus, u16 reg, u32 val) ++{ ++ u16 r1, r2, r3; ++ u16 lo, hi; ++ ++ split_addr((u32) reg, &r1, &r2, &r3); ++ ++ bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, r3); ++ __udelay(1000); ++ ++ lo = val & 0xffff; ++ hi = (u16) (val >> 16); ++ bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1, hi); ++ bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1, lo); ++} ++ ++static int ar8216_probe(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ u32 val; ++ u16 id; ++ ++ val = ar8216_mii_read(bus, AR8216_REG_CTRL); ++ if (val == ~0) ++ return 1; ++ ++ id = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION); ++ ++ switch (id) { ++ case 0x0101: ++ return 0; ++ default: ++ return 1; ++ } ++} ++ ++static void ar8216_setup(struct switch_device *dev) ++{ ++ struct mii_dev *bus = dev->bus; ++ ++ ar8216_mii_write(bus, 0x200, 0x200); ++ ar8216_mii_write(bus, 0x300, 0x200); ++ ar8216_mii_write(bus, 0x400, 0x200); ++ ar8216_mii_write(bus, 0x500, 0x200); ++ ar8216_mii_write(bus, 0x600, 0x7d); ++ ar8216_mii_write(bus, 0x38, 0xc000050e); ++ ar8216_mii_write(bus, 0x104, 0x4004); ++ ar8216_mii_write(bus, 0x60, 0xffffffff); ++ ar8216_mii_write(bus, 0x64, 0xaaaaaaaa); ++ ar8216_mii_write(bus, 0x68, 0x55555555); ++ ar8216_mii_write(bus, 0x6c, 0x0); ++ ar8216_mii_write(bus, 0x70, 0x41af); ++} ++ ++static struct switch_driver ar8216_drv = { ++ .name = "ar8216", ++}; ++ ++void switch_ar8216_init(void) ++{ ++ /* for archs with manual relocation */ ++ ar8216_drv.probe = ar8216_probe; ++ ar8216_drv.setup = ar8216_setup; ++ ++ switch_driver_register(&ar8216_drv); ++} +--- a/drivers/net/switch/switch.c ++++ b/drivers/net/switch/switch.c +@@ -24,6 +24,9 @@ void switch_init(void) + #if defined(CONFIG_SWITCH_ADM6996I) + switch_adm6996i_init(); + #endif ++#if defined(CONFIG_SWITCH_AR8216) ++ switch_ar8216_init(); ++#endif + + board_switch_init(); + } +--- a/include/switch.h ++++ b/include/switch.h +@@ -92,6 +92,7 @@ static inline void switch_setup(struct s + /* Init functions for supported Switch drivers */ + extern void switch_psb697x_init(void); + extern void switch_adm6996i_init(void); ++extern void switch_ar8216_init(void); + + #endif /* __SWITCH_H */ + diff --git a/package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch b/package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch new file mode 100644 index 0000000..2582c16 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch @@ -0,0 +1,9496 @@ +From ed2effe0839929d00f05ec0e1e16fb467f324e1b Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Thu, 20 Dec 2012 19:05:54 +0100 +Subject: MIPS: add support for Lantiq XWAY SoCs + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/.gitignore ++++ b/.gitignore +@@ -44,6 +44,13 @@ + /u-boot.sb + /u-boot.geany + /include/u-boot.lst ++/u-boot.bin.lzma ++/u-boot.bin.lzo ++/u-boot.ltq.lzma.norspl ++/u-boot.ltq.lzo.norspl ++/u-boot.ltq.norspl ++/u-boot.lzma.img ++/u-boot.lzo.img + + # + # Generated files +--- a/Makefile ++++ b/Makefile +@@ -441,6 +441,12 @@ $(obj)u-boot.bin: $(obj)u-boot + $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ + $(BOARD_SIZE_CHECK) + ++$(obj)u-boot.bin.lzma: $(obj)u-boot.bin ++ cat $< | lzma -9 -f - > $@ ++ ++$(obj)u-boot.bin.lzo: $(obj)u-boot.bin ++ cat $< | lzop -9 -f - > $@ ++ + $(obj)u-boot.ldr: $(obj)u-boot + $(CREATE_LDR_ENV) + $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS) +@@ -460,13 +466,23 @@ ifndef CONFIG_SYS_UBOOT_START + CONFIG_SYS_UBOOT_START := 0 + endif + +-$(obj)u-boot.img: $(obj)u-boot.bin +- $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \ ++define GEN_UBOOT_IMAGE ++ $(obj)tools/mkimage -A $(ARCH) -T firmware -C $(1) \ + -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \ + -e $(CONFIG_SYS_UBOOT_START) \ + -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \ + sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \ + -d $< $@ ++endef ++ ++$(obj)u-boot.img: $(obj)u-boot.bin ++ $(call GEN_UBOOT_IMAGE,none) ++ ++$(obj)u-boot.lzma.img: $(obj)u-boot.bin.lzma ++ $(call GEN_UBOOT_IMAGE,lzma) ++ ++$(obj)u-boot.lzo.img: $(obj)u-boot.bin.lzo ++ $(call GEN_UBOOT_IMAGE,lzo) + + $(obj)u-boot.imx: $(obj)u-boot.bin + $(obj)tools/mkimage -n $(CONFIG_IMX_CONFIG) -T imximage \ +@@ -549,6 +565,27 @@ endif + $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img + cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@ + ++$(obj)u-boot.ltq.sfspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin ++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \ ++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@ ++ ++$(obj)u-boot.ltq.lzo.sfspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin ++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \ ++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@ ++ ++$(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin ++ $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \ ++ -s $(obj)spl/u-boot-spl.bin -u $< -o $@ ++ ++$(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin ++ cat $(obj)spl/u-boot-spl.bin $< > $@ ++ ++$(obj)u-boot.ltq.lzo.norspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin ++ cat $(obj)spl/u-boot-spl.bin $< > $@ ++ ++$(obj)u-boot.ltq.lzma.norspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin ++ cat $(obj)spl/u-boot-spl.bin $< > $@ ++ + ifeq ($(CONFIG_SANDBOX),y) + GEN_UBOOT = \ + cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \ +--- a/README ++++ b/README +@@ -460,6 +460,11 @@ The following options need to be configu + CONF_CM_CACHABLE_CUW + CONF_CM_CACHABLE_ACCELERATED + ++ CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ ++ Enable this to use extended cache initialization for recent ++ MIPS CPU cores. ++ + CONFIG_SYS_XWAY_EBU_BOOTCFG + + Special option for Lantiq XWAY SoCs for booting from NOR flash. +--- a/arch/mips/config.mk ++++ b/arch/mips/config.mk +@@ -61,7 +61,10 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__M + # On the other hand, we want PIC in the U-Boot code to relocate it from ROM + # to RAM. $28 is always used as gp. + # +-PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS) ++PF_ABICALLS ?= -mabicalls ++PF_PIC ?= -fpic ++ ++PLATFORM_CPPFLAGS += -G 0 $(PF_ABICALLS) $(PF_PIC) $(ENDIANNESS) + PLATFORM_CPPFLAGS += -msoft-float + PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS) + PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections +--- a/arch/mips/cpu/mips32/cache.S ++++ b/arch/mips/cpu/mips32/cache.S +@@ -45,7 +45,11 @@ + */ + #define MIPS_MAX_CACHE_SIZE 0x10000 + ++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT ++#define INDEX_BASE 0x9fc00000 ++#else + #define INDEX_BASE CKSEG0 ++#endif + + .macro cache_op op addr + .set push +@@ -81,7 +85,11 @@ + */ + LEAF(mips_init_icache) + blez a1, 9f ++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ mtc0 zero, CP0_ITAGLO ++#else + mtc0 zero, CP0_TAGLO ++#endif + /* clear tag to invalidate */ + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, a1 +@@ -106,7 +114,11 @@ LEAF(mips_init_icache) + */ + LEAF(mips_init_dcache) + blez a1, 9f ++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ mtc0 zero, CP0_DTAGLO ++#else + mtc0 zero, CP0_TAGLO ++#endif + /* clear all tags */ + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, a1 +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/Makefile +@@ -0,0 +1,33 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(SOC).o ++ ++COBJS-y += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o ++SOBJS-y += cgu_init.o mem_init.o ++ ++COBJS := $(COBJS-y) ++SOBJS := $(SOBJS-y) ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) ++ ++all: $(LIB) ++ ++$(LIB): $(obj).depend $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/cgu.c +@@ -0,0 +1,118 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_CGU_SYS_DDR_MASK 0x0003 ++#define LTQ_CGU_SYS_DDR_SHIFT 0 ++#define LTQ_CGU_SYS_CPU0_MASK 0x000C ++#define LTQ_CGU_SYS_CPU0_SHIFT 2 ++#define LTQ_CGU_SYS_FPI_MASK 0x0040 ++#define LTQ_CGU_SYS_FPI_SHIFT 6 ++ ++struct ltq_cgu_regs { ++ u32 rsvd0; ++ u32 pll0_cfg; /* PLL0 config */ ++ u32 pll1_cfg; /* PLL1 config */ ++ u32 pll2_cfg; /* PLL2 config */ ++ u32 sys; /* System clock */ ++ u32 update; /* CGU update control */ ++ u32 if_clk; /* Interface clock */ ++ u32 osc_con; /* Update OSC Control */ ++ u32 smd; /* SDRAM Memory Control */ ++ u32 rsvd1[3]; ++ u32 pcm_cr; /* PCM control */ ++ u32 pci_cr; /* PCI clock control */ ++}; ++ ++static struct ltq_cgu_regs *ltq_cgu_regs = ++ (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE); ++ ++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift) ++{ ++ return (ltq_readl(<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,143 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/asm.h> ++#include <asm/regdef.h> ++#include <asm/addrspace.h> ++#include <asm/arch/soc.h> ++ ++/* RCU module register */ ++#define LTQ_RCU_RST_REQ 0x0010 ++#define LTQ_RCU_RST_STAT 0x0014 ++#define LTQ_RCU_RST_REQ_VALUE 0x40000008 ++#define LTQ_RCU_RST_STAT_XTAL_F 0x20000 ++ ++/* CGU module register */ ++#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */ ++#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */ ++#define LTQ_CGU_PLL2_CFG 0x000C /* PLL2 config */ ++#define LTQ_CGU_SYS 0x0010 /* System clock */ ++ ++/* Valid SYS.CPU0/1 values */ ++#define LTQ_CGU_SYS_CPU0_SHIFT 2 ++#define LTQ_CGU_SYS_CPU1_SHIFT 4 ++#define LTQ_CGU_SYS_CPU_PLL0 0x0 ++#define LTQ_CGU_SYS_CPU_DDR_EQUAL 0x1 ++#define LTQ_CGU_SYS_CPU_DDR_TWICE 0x2 ++ ++/* Valid SYS.DDR values */ ++#define LTQ_CGU_SYS_DDR_SHIFT 0 ++#define LTQ_CGU_SYS_DDR_167_MHZ 0x0 ++#define LTQ_CGU_SYS_DDR_133_MHZ 0x1 ++#define LTQ_CGU_SYS_DDR_111_MHZ 0x2 ++#define LTQ_CGU_SYS_DDR_83_MHZ 0x3 ++ ++/* Valid SYS.FPI values */ ++#define LTQ_CGU_SYS_FPI_SHIFT 6 ++#define LTQ_CGU_SYS_FPI_DDR_EQUAL 0x0 ++#define LTQ_CGU_SYS_FPI_DDR_HALF 0x1 ++ ++/* Valid SYS.PPE values */ ++#define LTQ_CGU_SYS_PPE_SHIFT 7 ++#define LTQ_CGU_SYS_PPE_266_MHZ 0x0 ++#define LTQ_CGU_SYS_PPE_240_MHZ 0x1 ++#define LTQ_CGU_SYS_PPE_222_MHZ 0x2 ++#define LTQ_CGU_SYS_PPE_133_MHZ 0x3 ++ ++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167) ++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_TWICE ++#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_167_MHZ ++#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF ++#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_266_MHZ ++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111) ++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_EQUAL ++#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_111_MHZ ++#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF ++#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_133_MHZ ++#else ++#error "Invalid system clock configuration!" ++#endif ++ ++/* Build register values */ ++#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_PPE_CONFIG << \ ++ LTQ_CGU_SYS_PPE_SHIFT) | \ ++ (LTQ_CGU_SYS_FPI_CONFIG << \ ++ LTQ_CGU_SYS_FPI_SHIFT) | \ ++ (LTQ_CGU_SYS_CPU_CONFIG << \ ++ LTQ_CGU_SYS_CPU1_SHIFT) | \ ++ (LTQ_CGU_SYS_CPU_CONFIG << \ ++ LTQ_CGU_SYS_CPU0_SHIFT) | \ ++ LTQ_CGU_SYS_DDR_CONFIG) ++ ++/* Reset values for PLL registers for usage with 35.328 MHz crystal */ ++#define PLL0_35MHZ_CONFIG 0x9D861059 ++#define PLL1_35MHZ_CONFIG 0x1A260CD9 ++#define PLL2_35MHZ_CONFIG 0x8000f1e5 ++ ++/* Reset values for PLL registers for usage with 36 MHz crystal */ ++#define PLL0_36MHZ_CONFIG 0x1000125D ++#define PLL1_36MHZ_CONFIG 0x1B1E0C99 ++#define PLL2_36MHZ_CONFIG 0x8002f2a1 ++ ++LEAF(ltq_cgu_init) ++ /* Load current CGU register value */ ++ li t0, (LTQ_CGU_BASE | KSEG1) ++ lw t1, LTQ_CGU_SYS(t0) ++ ++ /* Load target CGU register values */ ++ li t3, LTQ_CGU_SYS_VALUE ++ ++ /* Only update registers if values differ */ ++ beq t1, t3, finished ++ ++ /* ++ * Check whether the XTAL_F bit in RST_STAT register is set or not. ++ * This bit is latched in via pin strapping. If bit is set then ++ * clock source is a 36 MHz crystal. Otherwise a 35.328 MHz crystal. ++ */ ++ li t1, (LTQ_RCU_BASE | KSEG1) ++ lw t2, LTQ_RCU_RST_STAT(t1) ++ and t2, t2, LTQ_RCU_RST_STAT_XTAL_F ++ beq t2, LTQ_RCU_RST_STAT_XTAL_F, boot_36mhz ++ ++boot_35mhz: ++ /* Configure PLL for 35.328 MHz */ ++ li t2, PLL0_35MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL0_CFG(t0) ++ li t2, PLL1_35MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL1_CFG(t0) ++ li t2, PLL2_35MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL2_CFG(t0) ++ ++ b do_reset ++ ++boot_36mhz: ++ /* Configure PLL for 36 MHz */ ++ li t2, PLL0_36MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL0_CFG(t0) ++ li t2, PLL1_36MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL1_CFG(t0) ++ li t2, PLL2_36MHZ_CONFIG ++ sw t2, LTQ_CGU_PLL2_CFG(t0) ++ ++do_reset: ++ /* Store new clock config */ ++ sw t3, LTQ_CGU_SYS(t0) ++ ++ /* Perform software reset to activate new clock config */ ++ li t2, LTQ_RCU_RST_REQ_VALUE ++ sw t2, LTQ_RCU_RST_REQ(t1) ++ ++wait_reset: ++ b wait_reset ++ ++finished: ++ jr ra ++ ++ END(ltq_cgu_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/chipid.c +@@ -0,0 +1,60 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_CHIPID_VERSION_SHIFT 28 ++#define LTQ_CHIPID_VERSION_MASK (0xF << LTQ_CHIPID_VERSION_SHIFT) ++#define LTQ_CHIPID_PNUM_SHIFT 12 ++#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT) ++ ++struct ltq_chipid_regs { ++ u32 manid; /* Manufacturer identification */ ++ u32 chipid; /* Chip identification */ ++}; ++ ++static struct ltq_chipid_regs *ltq_chipid_regs = ++ (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE); ++ ++unsigned int ltq_chip_version_get(void) ++{ ++ u32 chipid; ++ ++ chipid = ltq_readl(<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,27 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,) ++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE) ++ ++ifdef CONFIG_SPL_BUILD ++PF_ABICALLS := -mno-abicalls ++PF_PIC := -fno-pic ++USE_PRIVATE_LIBGCC := yes ++endif ++ ++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o ++ ++ifndef CONFIG_SPL_BUILD ++ifdef CONFIG_SYS_BOOT_NORSPL ++ALL-y += $(obj)u-boot.ltq.norspl ++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl ++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl ++endif ++endif ++ ++LDSCRIPT := $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot.lds +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/ebu.c +@@ -0,0 +1,51 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_EBU_CON_0_RST_VAL 0x8001F7FF ++ ++#define LTQ_EBU_CON_WRDIS (1 << 31) ++ ++struct ltq_ebu_regs { ++ u32 clc; ++ u32 rsvd0[3]; ++ u32 con; ++ u32 rsvd1[3]; ++ u32 addr_sel_0; ++ u32 addr_sel_1; ++ u32 rsvd2[14]; ++ u32 con_0; ++ u32 con_1; ++}; ++ ++static struct ltq_ebu_regs *ltq_ebu_regs = ++ (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE); ++ ++void ltq_ebu_init(void) ++{ ++ /* ++ * Map EBU region 0 to range 0x10000000-0x13ffffff and enable ++ * region control. This supports up to 32 MiB NOR flash in ++ * bank 0. ++ */ ++ ltq_writel(<q_ebu_regs->addr_sel_0, 0x10000011); ++ ++ /* ++ * Restore reset value to fix modifications by internal BootROM. ++ * Also disable write protection. ++ */ ++ ltq_writel(<q_ebu_regs->con_0, ++ LTQ_EBU_CON_0_RST_VAL & ~LTQ_EBU_CON_WRDIS); ++} ++ ++void *flash_swap_addr(unsigned long addr) ++{ ++ return (void *)(addr ^ 2); ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/mem.c +@@ -0,0 +1,31 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE); ++ ++static inline u32 ltq_mc_dc_read(u32 index) ++{ ++ return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index)); ++} ++ ++phys_size_t initdram(int board_type) ++{ ++ u32 col, row, dc04, dc19, dc20; ++ ++ dc04 = ltq_mc_dc_read(4); ++ dc19 = ltq_mc_dc_read(19); ++ dc20 = ltq_mc_dc_read(20); ++ ++ row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8); ++ col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7); ++ ++ return (1 << (row + col)) * 4 * 2; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/mem_init.S +@@ -0,0 +1,115 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/asm.h> ++#include <asm/regdef.h> ++#include <asm/addrspace.h> ++#include <asm/arch/soc.h> ++ ++/* Must be configured in BOARDDIR */ ++#include <ddr_settings.h> ++ ++#define LTQ_MC_GEN_ERRCAUSE 0x0010 ++#define LTQ_MC_GEN_ERRADDR 0x0020 ++#define LTQ_MC_GEN_CON 0x0060 ++#define LTQ_MC_GEN_STAT 0x0070 ++#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE 0x5 ++#define LTQ_MC_GEN_STAT_DLCK_PWRON 0xC ++ ++#define LTQ_MC_DDR_DC03_MC_START 0x100 ++ ++ /* Store given value in MC DDR CCRx register */ ++ .macro dc_sw num, val ++ li t2, \val ++ sw t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1) ++ .endm ++ ++LEAF(ltq_mem_init) ++ /* Load MC General and MC DDR module base */ ++ li t0, (LTQ_MC_GEN_BASE | KSEG1) ++ li t1, (LTQ_MC_DDR_BASE | KSEG1) ++ ++ /* Clear access error log registers */ ++ sw zero, LTQ_MC_GEN_ERRCAUSE(t0) ++ sw zero, LTQ_MC_GEN_ERRADDR(t0) ++ ++ /* Enable DDR and SRAM module in memory controller */ ++ li t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE ++ sw t2, LTQ_MC_GEN_CON(t0) ++ ++ /* Clear start bit of DDR memory controller */ ++ sw zero, LTQ_MC_DDR_DC_OFFSET(3)(t1) ++ ++ /* Init memory controller registers with values ddr_settings.h */ ++ dc_sw 0, MC_DC00_VALUE ++ dc_sw 1, MC_DC01_VALUE ++ dc_sw 2, MC_DC02_VALUE ++ dc_sw 4, MC_DC04_VALUE ++ dc_sw 5, MC_DC05_VALUE ++ dc_sw 6, MC_DC06_VALUE ++ dc_sw 7, MC_DC07_VALUE ++ dc_sw 8, MC_DC08_VALUE ++ dc_sw 9, MC_DC09_VALUE ++ ++ dc_sw 10, MC_DC10_VALUE ++ dc_sw 11, MC_DC11_VALUE ++ dc_sw 12, MC_DC12_VALUE ++ dc_sw 13, MC_DC13_VALUE ++ dc_sw 14, MC_DC14_VALUE ++ dc_sw 15, MC_DC15_VALUE ++ dc_sw 16, MC_DC16_VALUE ++ dc_sw 17, MC_DC17_VALUE ++ dc_sw 18, MC_DC18_VALUE ++ dc_sw 19, MC_DC19_VALUE ++ ++ dc_sw 20, MC_DC20_VALUE ++ dc_sw 21, MC_DC21_VALUE ++ dc_sw 22, MC_DC22_VALUE ++ dc_sw 23, MC_DC23_VALUE ++ dc_sw 24, MC_DC24_VALUE ++ dc_sw 25, MC_DC25_VALUE ++ dc_sw 26, MC_DC26_VALUE ++ dc_sw 27, MC_DC27_VALUE ++ dc_sw 28, MC_DC28_VALUE ++ dc_sw 29, MC_DC29_VALUE ++ ++ dc_sw 30, MC_DC30_VALUE ++ dc_sw 31, MC_DC31_VALUE ++ dc_sw 32, MC_DC32_VALUE ++ dc_sw 33, MC_DC33_VALUE ++ dc_sw 34, MC_DC34_VALUE ++ dc_sw 35, MC_DC35_VALUE ++ dc_sw 36, MC_DC36_VALUE ++ dc_sw 37, MC_DC37_VALUE ++ dc_sw 38, MC_DC38_VALUE ++ dc_sw 39, MC_DC39_VALUE ++ ++ dc_sw 40, MC_DC40_VALUE ++ dc_sw 41, MC_DC41_VALUE ++ dc_sw 42, MC_DC42_VALUE ++ dc_sw 43, MC_DC43_VALUE ++ dc_sw 44, MC_DC44_VALUE ++ dc_sw 45, MC_DC45_VALUE ++ dc_sw 46, MC_DC46_VALUE ++ ++ /* Set start bit of DDR memory controller */ ++ li t2, LTQ_MC_DDR_DC03_MC_START ++ sw t2, LTQ_MC_DDR_DC_OFFSET(3)(t1) ++ ++ /* Wait until DLL has locked and core is ready for data transfers */ ++wait_ready: ++ lw t2, LTQ_MC_GEN_STAT(t0) ++ li t3, LTQ_MC_GEN_STAT_DLCK_PWRON ++ and t2, t3 ++ bne t2, t3, wait_ready ++ ++finished: ++ jr ra ++ ++ END(ltq_mem_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/danube/pmu.c +@@ -0,0 +1,118 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/pm.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_PMU_PWDCR_RESERVED 0xFD0C001C ++ ++#define LTQ_PMU_PWDCR_TDM (1 << 25) ++#define LTQ_PMU_PWDCR_PPE_ENET0 (1 << 23) ++#define LTQ_PMU_PWDCR_PPE_ENET1 (1 << 22) ++#define LTQ_PMU_PWDCR_PPE_TC (1 << 21) ++#define LTQ_PMU_PWDCR_DEU (1 << 20) ++#define LTQ_PMU_PWDCR_UART1 (1 << 17) ++#define LTQ_PMU_PWDCR_SDIO (1 << 16) ++#define LTQ_PMU_PWDCR_AHB (1 << 15) ++#define LTQ_PMU_PWDCR_FPI0 (1 << 14) ++#define LTQ_PMU_PWDCR_PPE (1 << 13) ++#define LTQ_PMU_PWDCR_GPTC (1 << 12) ++#define LTQ_PMU_PWDCR_LEDC (1 << 11) ++#define LTQ_PMU_PWDCR_EBU (1 << 10) ++#define LTQ_PMU_PWDCR_DSL (1 << 9) ++#define LTQ_PMU_PWDCR_SPI (1 << 8) ++#define LTQ_PMU_PWDCR_UART0 (1 << 7) ++#define LTQ_PMU_PWDCR_USB (1 << 6) ++#define LTQ_PMU_PWDCR_DMA (1 << 5) ++#define LTQ_PMU_PWDCR_FPI1 (1 << 1) ++#define LTQ_PMU_PWDCR_USB_PHY (1 << 0) ++ ++struct ltq_pmu_regs { ++ u32 rsvd0[7]; ++ u32 pwdcr; ++ u32 sr; ++ u32 pwdcr1; ++ u32 sr1; ++}; ++ ++static struct ltq_pmu_regs *ltq_pmu_regs = ++ (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE); ++ ++u32 ltq_pm_map(enum ltq_pm_modules module) ++{ ++ u32 val; ++ ++ switch (module) { ++ case LTQ_PM_CORE: ++ val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 | ++ LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU; ++ break; ++ case LTQ_PM_DMA: ++ val = LTQ_PMU_PWDCR_DMA; ++ break; ++ case LTQ_PM_ETH: ++ val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC | ++ LTQ_PMU_PWDCR_PPE; ++ break; ++ case LTQ_PM_SPI: ++ val = LTQ_PMU_PWDCR_SPI; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ ++ return val; ++} ++ ++int ltq_pm_enable(enum ltq_pm_modules module) ++{ ++ const unsigned long timeout = 1000; ++ unsigned long timebase; ++ u32 sr, val; ++ ++ val = ltq_pm_map(module); ++ if (unlikely(!val)) ++ return 1; ++ ++ ltq_clrbits(<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,126 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/cpu.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */ ++#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */ ++#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */ ++#define LTQ_RCU_RD_DFE_AFE (1 << 12) /* Voice DFE/AFE */ ++#define LTQ_RCU_RD_DSL_AFE (1 << 11) /* DSL AFE */ ++#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */ ++#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */ ++#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */ ++#define LTQ_RCU_RD_ARC_DFE (1 << 7) /* ARC/DFE core */ ++#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */ ++#define LTQ_RCU_RD_ENET_MAC1 (1 << 5) /* Ethernet MAC1 */ ++#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */ ++#define LTQ_RCU_RD_CPU1 (1 << 3) /* CPU1 subsystem */ ++#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */ ++#define LTQ_RCU_RD_CPU0 (1 << 1) /* CPU0 subsystem */ ++#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */ ++ ++#define LTQ_RCU_STAT_BOOT_SHIFT 18 ++#define LTQ_RCU_STAT_BOOT_MASK (0x7 << LTQ_RCU_STAT_BOOT_SHIFT) ++ ++struct ltq_rcu_regs { ++ u32 rsvd0[4]; ++ u32 req; /* Reset request */ ++ u32 stat; /* Reset status */ ++ u32 usb_cfg; /* USB configure */ ++ u32 rsvd1[2]; ++ u32 pci_rdy; /* PCI boot ready */ ++}; ++ ++static struct ltq_rcu_regs *ltq_rcu_regs = ++ (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE); ++ ++u32 ltq_reset_map(enum ltq_reset_modules module) ++{ ++ u32 val; ++ ++ switch (module) { ++ case LTQ_RESET_CORE: ++ case LTQ_RESET_SOFT: ++ val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1; ++ break; ++ case LTQ_RESET_DMA: ++ val = LTQ_RCU_RD_DMA; ++ break; ++ case LTQ_RESET_ETH: ++ val = LTQ_RCU_RD_PPE; ++ break; ++ case LTQ_RESET_HARD: ++ val = LTQ_RCU_RD_HRST; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ ++ return val; ++} ++ ++int ltq_reset_activate(enum ltq_reset_modules module) ++{ ++ u32 val; ++ ++ val = ltq_reset_map(module); ++ if (unlikely(!val)) ++ return 1; ++ ++ ltq_setbits(<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/danube/u-boot.lds +@@ -0,0 +1,69 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") ++OUTPUT_ARCH(mips) ++ENTRY(_start) ++SECTIONS ++{ ++ . = 0x00000000; ++ ++ . = ALIGN(4); ++ .text : { ++ *(.text*) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { ++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) ++ } ++ ++ . = ALIGN(4); ++ .data : { ++ *(.data*) ++ } ++ ++ . = ALIGN(4); ++ .sdata : { ++ *(.sdata*) ++ } ++ ++ . = .; ++ _gp = ALIGN(16) + 0x7ff0; ++ ++ .got : { ++ __got_start = .; ++ *(.got) ++ __got_end = .; ++ } ++ ++ num_got_entries = (__got_end - __got_start) >> 2; ++ ++#ifndef CONFIG_SPL_BUILD ++ . = ALIGN(4); ++ .u_boot_list : { ++ #include <u-boot.lst> ++ } ++#endif ++ ++ . = ALIGN(4); ++ __image_copy_end = .; ++ uboot_end_data = .; ++ ++ .bss (NOLOAD) : { ++ __bss_start = .; ++ *(.bss*) ++ *(.sbss*) ++ . = ALIGN(4); ++ __bss_end = .; ++ } ++ ++ . = ALIGN(4); ++ __end = .; ++ uboot_end = .; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/Makefile +@@ -0,0 +1,36 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)liblantiq-common.o ++ ++START = start.o ++COBJS-y = cpu.o pmu.o ++COBJS-$(CONFIG_SPL_BUILD) += spl.o ++SOBJS-y = lowlevel_init.o ++ ++COBJS := $(COBJS-y) ++SOBJS := $(SOBJS-y) ++SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) ++START := $(addprefix $(obj),$(START)) ++ ++all: $(LIB) ++ ++$(LIB): $(obj).depend $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c +@@ -0,0 +1,60 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/cpu.h> ++ ++static const char ltq_bootsel_strings[][16] = { ++ "NOR", ++ "NOR w/o BootROM", ++ "UART", ++ "UART w/o EEPROM", ++ "SPI", ++ "NAND", ++ "PCI", ++ "MII0", ++ "RMII0", ++ "RGMII1", ++ "unknown", ++}; ++ ++const char *ltq_boot_select_str(void) ++{ enum ltq_boot_select bootsel = ltq_boot_select(); ++ ++ if (bootsel > BOOT_UNKNOWN) ++ bootsel = BOOT_UNKNOWN; ++ ++ return ltq_bootsel_strings[bootsel]; ++} ++ ++void ltq_chip_print_info(void) ++{ ++ char buf[32]; ++ ++ printf("SoC: Lantiq %s v1.%u\n", ltq_chip_partnum_str(), ++ ltq_chip_version_get()); ++ printf("CPU: %s MHz\n", strmhz(buf, ltq_get_cpu_clock())); ++ printf("IO: %s MHz\n", strmhz(buf, ltq_get_io_region_clock())); ++ printf("BUS: %s MHz\n", strmhz(buf, ltq_get_bus_clock())); ++ printf("BOOT: %s\n", ltq_boot_select_str()); ++} ++ ++int arch_cpu_init(void) ++{ ++ ltq_pmu_init(); ++ ltq_ebu_init(); ++ ++ return 0; ++} ++ ++void _machine_restart(void) ++{ ++ ltq_reset_activate(LTQ_RESET_CORE); ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S +@@ -0,0 +1,21 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <asm/asm.h> ++#include <asm/regdef.h> ++ ++NESTED(lowlevel_init, 0, ra) ++ move t8, ra ++ ++ la t7, ltq_cgu_init ++ jalr t7 ++ ++ la t7, ltq_mem_init ++ jalr t7 ++ ++ jr t8 ++ END(lowlevel_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c +@@ -0,0 +1,10 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/pm.h> ++ +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/spl.c +@@ -0,0 +1,385 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <image.h> ++#include <version.h> ++#include <spi_flash.h> ++#include <linux/compiler.h> ++#include <lzma/LzmaDec.h> ++#include <linux/lzo.h> ++#include <asm/mipsregs.h> ++ ++#if defined(CONFIG_LTQ_SPL_CONSOLE) ++#define spl_has_console 1 ++ ++#if defined(CONFIG_LTQ_SPL_DEBUG) ++#define spl_has_debug 1 ++#else ++#define spl_has_debug 0 ++#endif ++ ++#else ++#define spl_has_console 0 ++#endif ++ ++#define spl_debug(fmt, args...) \ ++ do { \ ++ if (spl_has_debug) \ ++ printf(fmt, ##args); \ ++ } while (0) ++ ++#define spl_puts(msg) \ ++ do { \ ++ if (spl_has_console) \ ++ puts(msg); \ ++ } while (0) ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL) ++#define spl_boot_spi_flash 1 ++#else ++#define spl_boot_spi_flash 0 ++#ifndef CONFIG_SPL_SPI_BUS ++#define CONFIG_SPL_SPI_BUS 0 ++#endif ++#ifndef CONFIG_SPL_SPI_CS ++#define CONFIG_SPL_SPI_CS 0 ++#endif ++#ifndef CONFIG_SPL_SPI_MAX_HZ ++#define CONFIG_SPL_SPI_MAX_HZ 0 ++#endif ++#ifndef CONFIG_SPL_SPI_MODE ++#define CONFIG_SPL_SPI_MODE 0 ++#endif ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL) ++#define spl_boot_nor_flash 1 ++#else ++#define spl_boot_nor_flash 0 ++#endif ++ ++#define spl_sync() __asm__ __volatile__("sync"); ++ ++struct spl_image { ++ ulong data_addr; ++ ulong entry_addr; ++ size_t data_size; ++ size_t entry_size; ++ u8 comp; ++}; ++ ++extern ulong __image_copy_end; ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* Emulated malloc area needed for LZMA allocator in BSS */ ++static u8 *spl_mem_ptr __maybe_unused; ++static size_t spl_mem_size __maybe_unused; ++ ++static int spl_is_comp_lzma(const struct spl_image *spl) ++{ ++#if defined(CONFIG_LTQ_SPL_COMP_LZMA) ++ return spl->comp == IH_COMP_LZMA; ++#else ++ return 0; ++#endif ++} ++ ++static int spl_is_comp_lzo(const struct spl_image *spl) ++{ ++#if defined(CONFIG_LTQ_SPL_COMP_LZO) ++ return spl->comp == IH_COMP_LZO; ++#else ++ return 0; ++#endif ++} ++ ++static int spl_is_compressed(const struct spl_image *spl) ++{ ++ if (spl_is_comp_lzma(spl)) ++ return 1; ++ ++ if (spl_is_comp_lzo(spl)) ++ return 1; ++ ++ return 0; ++} ++ ++static void spl_console_init(void) ++{ ++ if (!spl_has_console) ++ return; ++ ++ gd->flags |= GD_FLG_RELOC; ++ gd->baudrate = CONFIG_BAUDRATE; ++ ++ serial_init(); ++ ++ gd->have_console = 1; ++ ++ spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ ++ U_BOOT_TIME ")\n"); ++} ++ ++static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl) ++{ ++ u32 magic; ++ ++ spl_puts("SPL: checking U-Boot image\n"); ++ ++ magic = image_get_magic(hdr); ++ if (magic != IH_MAGIC) ++ return -1; ++ ++ spl->data_addr += image_get_header_size(); ++ spl->entry_addr = image_get_load(hdr); ++ spl->data_size = image_get_data_size(hdr); ++ spl->comp = image_get_comp(hdr); ++ ++ spl_debug("SPL: data %08lx, size %zu, entry %08lx, comp %u\n", ++ spl->data_addr, spl->data_size, spl->entry_addr, spl->comp); ++ ++ return 0; ++} ++ ++static void *spl_lzma_alloc(void *p, size_t size) ++{ ++ u8 *ret; ++ ++ if (size > spl_mem_size) ++ return NULL; ++ ++ ret = spl_mem_ptr; ++ spl_mem_ptr += size; ++ spl_mem_size -= size; ++ ++ return ret; ++} ++ ++static void spl_lzma_free(void *p, void *addr) ++{ ++} ++ ++static int spl_copy_image(struct spl_image *spl) ++{ ++ spl_puts("SPL: copying U-Boot to RAM\n"); ++ ++ memcpy((void *) spl->entry_addr, (const void *) spl->data_addr, ++ spl->data_size); ++ ++ spl->entry_size = spl->data_size; ++ ++ return 0; ++} ++ ++static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr) ++{ ++ SRes res; ++ const Byte *prop = (const Byte *) loadaddr; ++ const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE + ++ sizeof(uint64_t); ++ Byte *dest = (Byte *) spl->entry_addr; ++ SizeT dest_len = 0xFFFFFFFF; ++ SizeT src_len = spl->data_size - LZMA_PROPS_SIZE; ++ ELzmaStatus status = 0; ++ ISzAlloc alloc; ++ ++ spl_puts("SPL: decompressing U-Boot with LZMA\n"); ++ ++ alloc.Alloc = spl_lzma_alloc; ++ alloc.Free = spl_lzma_free; ++ spl_mem_ptr = (u8 *) CONFIG_SPL_MALLOC_BASE; ++ spl_mem_size = CONFIG_SPL_MALLOC_MAX_SIZE; ++ ++ res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE, ++ LZMA_FINISH_ANY, &status, &alloc); ++ if (res != SZ_OK) ++ return 1; ++ ++ spl->entry_size = dest_len; ++ ++ return 0; ++} ++ ++static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr) ++{ ++ size_t len; ++ int ret; ++ ++ spl_puts("SPL: decompressing U-Boot with LZO\n"); ++ ++ ret = lzop_decompress( ++ (const unsigned char*) loadaddr, spl->data_size, ++ (unsigned char *) spl->entry_addr, &len); ++ ++ spl->entry_size = len; ++ ++ return ret; ++} ++ ++static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr) ++{ ++ int ret; ++ ++ if (spl_is_comp_lzma(spl)) ++ ret = spl_uncompress_lzma(spl, loadaddr); ++ else if (spl_is_comp_lzo(spl)) ++ ret = spl_uncompress_lzo(spl, loadaddr); ++ else ++ ret = 1; ++ ++ return ret; ++} ++ ++static int spl_load_spi_flash(struct spl_image *spl) ++{ ++ struct spi_flash sf; ++ image_header_t hdr; ++ int ret; ++ unsigned long loadaddr; ++ ++ /* ++ * Image format: ++ * ++ * - 12 byte non-volatile bootstrap header ++ * - SPL binary ++ * - 12 byte non-volatile bootstrap header ++ * - 64 byte U-Boot mkimage header ++ * - U-Boot binary ++ */ ++ spl->data_addr = (ulong) &__image_copy_end - CONFIG_SPL_TEXT_BASE + 24; ++ ++ spl_puts("SPL: probing SPI flash\n"); ++ ++ spi_init(); ++ ret = spi_flash_probe_spl(&sf, CONFIG_SPL_SPI_BUS, CONFIG_SPL_SPI_CS, ++ CONFIG_SPL_SPI_MAX_HZ, CONFIG_SPL_SPI_MODE); ++ if (ret) ++ return ret; ++ ++ spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr); ++ ++ ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr); ++ if (ret) ++ return ret; ++ ++ spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr); ++ ++ ret = spl_parse_image(&hdr, spl); ++ if (ret) ++ return ret; ++ ++ if (spl_is_compressed(spl)) ++ loadaddr = CONFIG_LOADADDR; ++ else ++ loadaddr = spl->entry_addr; ++ ++ spl_puts("SPL: loading U-Boot to RAM\n"); ++ ++ ret = spi_flash_read(&sf, spl->data_addr, spl->data_size, ++ (void *) loadaddr); ++ ++ if (spl_is_compressed(spl)) ++ ret = spl_uncompress(spl, loadaddr); ++ ++ return ret; ++} ++ ++static int spl_load_nor_flash(struct spl_image *spl) ++{ ++ const image_header_t *hdr; ++ int ret; ++ ++ /* ++ * Image format: ++ * ++ * - SPL binary ++ * - 64 byte U-Boot mkimage header ++ * - U-Boot binary ++ */ ++ spl->data_addr = (ulong) &__image_copy_end; ++ hdr = (const image_header_t *) &__image_copy_end; ++ ++ spl_debug("SPL: checking image header at address %p\n", hdr); ++ ++ ret = spl_parse_image(hdr, spl); ++ if (ret) ++ return ret; ++ ++ if (spl_is_compressed(spl)) ++ ret = spl_uncompress(spl, spl->data_addr); ++ else ++ ret = spl_copy_image(spl); ++ ++ return ret; ++} ++ ++static int spl_load(struct spl_image *spl) ++{ ++ int ret; ++ ++ if (spl_boot_spi_flash) ++ ret = spl_load_spi_flash(spl); ++ else if (spl_boot_nor_flash) ++ ret = spl_load_nor_flash(spl); ++ else ++ ret = 1; ++ ++ return ret; ++} ++ ++void __noreturn spl_lantiq_init(void) ++{ ++ void (*uboot)(void) __noreturn; ++ struct spl_image spl; ++ gd_t gd_data; ++ int ret; ++ ++ gd = &gd_data; ++ barrier(); ++ memset((void *)gd, 0, sizeof(gd_t)); ++ ++ spl_console_init(); ++ ++ spl_debug("SPL: initializing\n"); ++ ++#if 0 ++ spl_debug("CP0_CONFIG: %08x\n", read_c0_config()); ++ spl_debug("CP0_CONFIG1: %08x\n", read_c0_config1()); ++ spl_debug("CP0_CONFIG2: %08x\n", read_c0_config2()); ++ spl_debug("CP0_CONFIG3: %08x\n", read_c0_config3()); ++ spl_debug("CP0_CONFIG6: %08x\n", read_c0_config6()); ++ spl_debug("CP0_CONFIG7: %08x\n", read_c0_config7()); ++ spl_debug("CP0_STATUS: %08x\n", read_c0_status()); ++ spl_debug("CP0_PRID: %08x\n", read_c0_prid()); ++#endif ++ ++ board_early_init_f(); ++ timer_init(); ++ ++ memset(&spl, 0, sizeof(spl)); ++ ++ ret = spl_load(&spl); ++ if (ret) ++ goto hang; ++ ++ spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr); ++ spl_puts("SPL: jumping to U-Boot\n"); ++ ++ flush_cache(spl.entry_addr, spl.entry_size); ++ spl_sync(); ++ ++ uboot = (void *) spl.entry_addr; ++ uboot(); ++ ++hang: ++ spl_puts("SPL: cannot start U-Boot\n"); ++ ++ for (;;) ++ ; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/start.S +@@ -0,0 +1,144 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2003 Wolfgang Denk, wd@denx.de ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/regdef.h> ++#include <asm/mipsregs.h> ++ ++#define S_PRIdCoID 16 /* Company ID (R) */ ++#define M_PRIdCoID (0xff << S_PRIdCoID) ++#define S_PRIdImp 8 /* Implementation ID (R) */ ++#define M_PRIdImp (0xff << S_PRIdImp) ++ ++#define K_CacheAttrCWTnWA 0 /* Cacheable, write-thru, no write allocate */ ++#define K_CacheAttrCWTWA 1 /* Cacheable, write-thru, write allocate */ ++#define K_CacheAttrU 2 /* Uncached */ ++#define K_CacheAttrC 3 /* Cacheable */ ++#define K_CacheAttrCN 3 /* Cacheable, non-coherent */ ++#define K_CacheAttrCCE 4 /* Cacheable, coherent, exclusive */ ++#define K_CacheAttrCCS 5 /* Cacheable, coherent, shared */ ++#define K_CacheAttrCCU 6 /* Cacheable, coherent, update */ ++#define K_CacheAttrUA 7 /* Uncached accelerated */ ++ ++#define S_ConfigK23 28 /* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */ ++#define M_ConfigK23 (0x7 << S_ConfigK23) ++#define W_ConfigK23 3 ++#define S_ConfigKU 25 /* Kuseg coherency algorithm (FM MMU only) (R/W) */ ++#define M_ConfigKU (0x7 << S_ConfigKU) ++#define W_ConfigKU 3 ++ ++#define S_ConfigMM 18 /* Merge mode (implementation specific) */ ++#define M_ConfigMM (0x1 << S_ConfigMM) ++ ++#define S_StatusBEV 22 /* Enable Boot Exception Vectors (R/W) */ ++#define M_StatusBEV (0x1 << S_StatusBEV) ++ ++#define S_StatusFR 26 /* Enable 64-bit FPRs (R/W) */ ++#define M_StatusFR (0x1 << S_StatusFR) ++ ++#define S_ConfigK0 0 /* Kseg0 coherency algorithm (R/W) */ ++#define M_ConfigK0 (0x7 << S_ConfigK0) ++ ++#define CONFIG0_MIPS32_64_MSK 0x8000ffff ++#define STATUS_MIPS32_64_MSK 0xfffcffff ++ ++#define STATUS_MIPS24K 0 ++#define CONFIG0_MIPS24K ((K_CacheAttrCN << S_ConfigK23) |\ ++ (K_CacheAttrCN << S_ConfigKU) |\ ++ (M_ConfigMM)) ++ ++#define STATUS_MIPS34K 0 ++#define CONFIG0_MIPS34K ((K_CacheAttrCN << S_ConfigK23) |\ ++ (K_CacheAttrCN << S_ConfigKU) |\ ++ (M_ConfigMM)) ++ ++#define STATUS_MIPS32_64 (M_StatusBEV | M_StatusFR) ++#define CONFIG0_MIPS32_64 (K_CacheAttrCN << S_ConfigK0) ++ ++#ifdef CONFIG_SOC_XWAY_DANUBE ++#define CONFIG0_LANTIQ (CONFIG0_MIPS24K | CONFIG0_MIPS32_64) ++#define STATUS_LANTIQ (STATUS_MIPS24K | STATUS_MIPS32_64) ++#endif ++ ++#ifdef CONFIG_SOC_XWAY_VRX200 ++#define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64) ++#define STATUS_LANTIQ (STATUS_MIPS34K | STATUS_MIPS32_64) ++#endif ++ ++ ++ .set noreorder ++ ++ .globl _start ++ .text ++_start: ++ /* Entry point */ ++ b main ++ nop ++ ++ /* Lantiq SoC Boot config word */ ++ .org 0x10 ++#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG ++ .word CONFIG_SYS_XWAY_EBU_BOOTCFG ++#else ++ .word 0 ++#endif ++ .word 0 ++ ++ .align 4 ++main: ++ ++ /* Init Timer */ ++ mtc0 zero, CP0_COUNT ++ mtc0 zero, CP0_COMPARE ++ ++ /* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */ ++ mfc0 t0, CP0_CONFIG ++ li t1, CONFIG0_MIPS32_64_MSK ++ and t0, t1 ++ li t1, CONFIG0_LANTIQ ++ or t0, t1 ++ mtc0 t0, CP0_CONFIG ++ ++ mfc0 t0, CP0_STATUS ++ li t1, STATUS_MIPS32_64_MSK ++ and t0, t1 ++ li t1, STATUS_LANTIQ ++ or t0, t1 ++ mtc0 t0, CP0_STATUS ++ ++ /* Initialize CGU */ ++ la t9, ltq_cgu_init ++ jalr t9 ++ nop ++ ++ /* Initialize memory controller */ ++ la t9, ltq_mem_init ++ jalr t9 ++ nop ++ ++ /* Initialize caches... */ ++ la t9, mips_cache_reset ++ jalr t9 ++ nop ++ ++ /* Clear BSS */ ++ la t1, __bss_start ++ la t2, __bss_end ++ sub t1, 4 ++1: ++ addi t1, 4 ++ bltl t1, t2, 1b ++ sw zero, 0(t1) ++ ++ /* Setup stack pointer and force alignment on a 16 byte boundary */ ++ li t0, (CONFIG_SPL_STACK_BASE & ~0xF) ++ la sp, 0(t0) ++ ++ la t9, spl_lantiq_init ++ jr t9 ++ nop +--- /dev/null ++++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds +@@ -0,0 +1,49 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \ ++ LENGTH = CONFIG_SPL_MAX_SIZE } ++MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_BASE, \ ++ LENGTH = CONFIG_SPL_BSS_MAX_SIZE } ++ ++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") ++OUTPUT_ARCH(mips) ++ENTRY(_start) ++SECTIONS ++{ ++ . = ALIGN(4); ++ .text : { ++ *(.text*) ++ } > .spl_mem ++ ++ . = ALIGN(4); ++ .rodata : { ++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) ++ } > .spl_mem ++ ++ . = ALIGN(4); ++ .data : { ++ *(SORT_BY_ALIGNMENT(.data*)) ++ *(SORT_BY_ALIGNMENT(.sdata*)) ++ } > .spl_mem ++ ++ . = ALIGN(4); ++ __image_copy_end = .; ++ uboot_end_data = .; ++ ++ .bss : { ++ __bss_start = .; ++ *(.bss*) ++ *(.sbss*) ++ . = ALIGN(4); ++ __bss_end = .; ++ } > .bss_mem ++ ++ . = ALIGN(4); ++ __end = .; ++ uboot_end = .; ++} +--- a/arch/mips/cpu/mips32/start.S ++++ b/arch/mips/cpu/mips32/start.S +@@ -55,166 +55,63 @@ + #endif + .endm + +-#define RVECENT(f,n) \ +- b f; nop +-#define XVECENT(f,bev) \ +- b f ; \ +- li k0,bev +- +- .set noreorder +- +- .globl _start +- .text +-_start: +- RVECENT(reset,0) # U-boot entry point +- RVECENT(reset,1) # software reboot +-#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG + /* + * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to + * access external NOR flashes. If the board boots from NOR flash the + * internal BootROM does a blind read at address 0xB0000010 to read the + * initial configuration for that EBU in order to access the flash + * device with correct parameters. This config option is board-specific. ++ * Default to 0 if this option is not set. + */ +- .word CONFIG_SYS_XWAY_EBU_BOOTCFG +- .word 0x00000000 ++ .macro lantiq_soc_bootcfg ++ .set push ++ .set noreorder ++ .org 0x10 ++#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG ++ .word CONFIG_SYS_XWAY_EBU_BOOTCFG + #else +- RVECENT(romReserved,2) ++ .word 0 + #endif +- RVECENT(romReserved,3) +- RVECENT(romReserved,4) +- RVECENT(romReserved,5) +- RVECENT(romReserved,6) +- RVECENT(romReserved,7) +- RVECENT(romReserved,8) +- RVECENT(romReserved,9) +- RVECENT(romReserved,10) +- RVECENT(romReserved,11) +- RVECENT(romReserved,12) +- RVECENT(romReserved,13) +- RVECENT(romReserved,14) +- RVECENT(romReserved,15) +- RVECENT(romReserved,16) +- RVECENT(romReserved,17) +- RVECENT(romReserved,18) +- RVECENT(romReserved,19) +- RVECENT(romReserved,20) +- RVECENT(romReserved,21) +- RVECENT(romReserved,22) +- RVECENT(romReserved,23) +- RVECENT(romReserved,24) +- RVECENT(romReserved,25) +- RVECENT(romReserved,26) +- RVECENT(romReserved,27) +- RVECENT(romReserved,28) +- RVECENT(romReserved,29) +- RVECENT(romReserved,30) +- RVECENT(romReserved,31) +- RVECENT(romReserved,32) +- RVECENT(romReserved,33) +- RVECENT(romReserved,34) +- RVECENT(romReserved,35) +- RVECENT(romReserved,36) +- RVECENT(romReserved,37) +- RVECENT(romReserved,38) +- RVECENT(romReserved,39) +- RVECENT(romReserved,40) +- RVECENT(romReserved,41) +- RVECENT(romReserved,42) +- RVECENT(romReserved,43) +- RVECENT(romReserved,44) +- RVECENT(romReserved,45) +- RVECENT(romReserved,46) +- RVECENT(romReserved,47) +- RVECENT(romReserved,48) +- RVECENT(romReserved,49) +- RVECENT(romReserved,50) +- RVECENT(romReserved,51) +- RVECENT(romReserved,52) +- RVECENT(romReserved,53) +- RVECENT(romReserved,54) +- RVECENT(romReserved,55) +- RVECENT(romReserved,56) +- RVECENT(romReserved,57) +- RVECENT(romReserved,58) +- RVECENT(romReserved,59) +- RVECENT(romReserved,60) +- RVECENT(romReserved,61) +- RVECENT(romReserved,62) +- RVECENT(romReserved,63) +- XVECENT(romExcHandle,0x200) # bfc00200: R4000 tlbmiss vector +- RVECENT(romReserved,65) +- RVECENT(romReserved,66) +- RVECENT(romReserved,67) +- RVECENT(romReserved,68) +- RVECENT(romReserved,69) +- RVECENT(romReserved,70) +- RVECENT(romReserved,71) +- RVECENT(romReserved,72) +- RVECENT(romReserved,73) +- RVECENT(romReserved,74) +- RVECENT(romReserved,75) +- RVECENT(romReserved,76) +- RVECENT(romReserved,77) +- RVECENT(romReserved,78) +- RVECENT(romReserved,79) +- XVECENT(romExcHandle,0x280) # bfc00280: R4000 xtlbmiss vector +- RVECENT(romReserved,81) +- RVECENT(romReserved,82) +- RVECENT(romReserved,83) +- RVECENT(romReserved,84) +- RVECENT(romReserved,85) +- RVECENT(romReserved,86) +- RVECENT(romReserved,87) +- RVECENT(romReserved,88) +- RVECENT(romReserved,89) +- RVECENT(romReserved,90) +- RVECENT(romReserved,91) +- RVECENT(romReserved,92) +- RVECENT(romReserved,93) +- RVECENT(romReserved,94) +- RVECENT(romReserved,95) +- XVECENT(romExcHandle,0x300) # bfc00300: R4000 cache vector +- RVECENT(romReserved,97) +- RVECENT(romReserved,98) +- RVECENT(romReserved,99) +- RVECENT(romReserved,100) +- RVECENT(romReserved,101) +- RVECENT(romReserved,102) +- RVECENT(romReserved,103) +- RVECENT(romReserved,104) +- RVECENT(romReserved,105) +- RVECENT(romReserved,106) +- RVECENT(romReserved,107) +- RVECENT(romReserved,108) +- RVECENT(romReserved,109) +- RVECENT(romReserved,110) +- RVECENT(romReserved,111) +- XVECENT(romExcHandle,0x380) # bfc00380: R4000 general vector +- RVECENT(romReserved,113) +- RVECENT(romReserved,114) +- RVECENT(romReserved,115) +- RVECENT(romReserved,116) +- RVECENT(romReserved,116) +- RVECENT(romReserved,118) +- RVECENT(romReserved,119) +- RVECENT(romReserved,120) +- RVECENT(romReserved,121) +- RVECENT(romReserved,122) +- RVECENT(romReserved,123) +- RVECENT(romReserved,124) +- RVECENT(romReserved,125) +- RVECENT(romReserved,126) +- RVECENT(romReserved,127) ++ .word 0 ++ .set pop ++ .endm ++ ++ .macro reset_vector branch ++ .set push ++ .set noreorder ++ b \branch ++ nop ++ .set pop ++ .endm ++ ++ .macro exception_vector offset branch ++ .set push ++ .set noreorder ++ .org \offset ++ b \branch ++ li k0, \offset ++ .set pop ++ .endm ++ ++ .set noreorder ++ ++ .globl _start ++ .text ++_start: ++ reset_vector reset # U-boot entry point ++ reset_vector reset # software reboot ++ ++ lantiq_soc_bootcfg # Lantiq SoC Boot config word ++ ++ exception_vector 0x200, halt # TLB miss ++ exception_vector 0x280, halt # XTLB miss ++ exception_vector 0x300, halt # Cache error ++ exception_vector 0x380, halt # General ++ exception_vector 0x400, halt # Interrupt, CauseIV ++ exception_vector 0x480, ejtag_exception # EJTAG debug + +- /* +- * We hope there are no more reserved vectors! +- * 128 * 8 == 1024 == 0x400 +- * so this is address R_VEC+0x400 == 0xbfc00400 +- */ + .align 4 + reset: +- + /* Clear watch registers */ + mtc0 zero, CP0_WATCHLO + mtc0 zero, CP0_WATCHHI +@@ -222,13 +119,15 @@ reset: + /* WP(Watch Pending), SW0/1 should be cleared */ + mtc0 zero, CP0_CAUSE + ++#if 0 + setup_c0_status_reset ++#endif + + /* Init Timer */ + mtc0 zero, CP0_COUNT + mtc0 zero, CP0_COMPARE + +-#ifndef CONFIG_SKIP_LOWLEVEL_INIT ++#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_SYS_DISABLE_CACHE) + /* CONFIG0 register */ + li t0, CONF_CM_UNCACHED + mtc0 t0, CP0_CONFIG +@@ -323,6 +222,8 @@ relocate_code: + jalr t9 + nop + ++ sync ++ + /* Jump to where we've relocated ourselves */ + addi t0, s2, in_ram - _start + jr t0 +@@ -378,8 +279,12 @@ in_ram: + .end relocate_code + + /* Exception handlers */ +-romReserved: +- b romReserved ++ejtag_exception: ++ /* Set DEPC to halt and exit debug mode */ ++ la k1, halt ++ mtc0 k1, CP0_DEPC ++ deret ++ nop + +-romExcHandle: +- b romExcHandle ++halt: ++ b halt +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/Makefile +@@ -0,0 +1,34 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(SOC).o ++ ++COBJS-y += cgu.o chipid.o dcdc.o ebu.o gphy.o mem.o pmu.o rcu.o ++SOBJS-y += cgu_init.o mem_init.o ++SOBJS-y += gphy_fw.o ++ ++COBJS := $(COBJS-y) ++SOBJS := $(SOBJS-y) ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) ++ ++all: $(LIB) ++ ++$(LIB): $(obj).depend $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/cgu.c +@@ -0,0 +1,209 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/gphy.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_CGU_PLL1_PLLN_SHIFT 6 ++#define LTQ_CGU_PLL1_PLLN_MASK (0x3F << LTQ_CGU_PLL1_PLLN_SHIFT) ++#define LTQ_CGU_PLL1_PLLM_SHIFT 2 ++#define LTQ_CGU_PLL1_PLLM_MASK (0xF << LTQ_CGU_PLL1_PLLM_SHIFT) ++#define LTQ_CGU_PLL1_PLLL (1 << 1) ++#define LTQ_CGU_PLL1_PLL_EN 1 ++ ++#define LTQ_CGU_SYS_OCP_SHIFT 0 ++#define LTQ_CGU_SYS_OCP_MASK (0x3 << LTQ_CGU_SYS_OCP_SHIFT) ++#define LTQ_CGU_SYS_CPU_SHIFT 4 ++#define LTQ_CGU_SYS_CPU_MASK (0xF << LTQ_CGU_SYS_CPU_SHIFT) ++ ++#define LTQ_CGU_UPDATE 1 ++ ++#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT 2 ++#define LTQ_CGU_IFCLK_GPHY_SEL_MASK (0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT) ++ ++struct ltq_cgu_regs { ++ u32 rsvd0; ++ u32 pll0_cfg; /* PLL0 config */ ++ u32 pll1_cfg; /* PLL1 config */ ++ u32 sys; /* System clock */ ++ u32 clk_fsr; /* Clock frequency select */ ++ u32 clk_gsr; /* Clock gating status */ ++ u32 clk_gcr0; /* Clock gating control 0 */ ++ u32 clk_gcr1; /* Clock gating control 1 */ ++ u32 update; /* CGU update control */ ++ u32 if_clk; /* Interface clock */ ++ u32 ddr; /* DDR memory control */ ++ u32 ct1_sr; /* CT status 1 */ ++ u32 ct_kval; /* CT K value */ ++ u32 pcm_cr; /* PCM control */ ++ u32 pci_cr; /* PCI clock control */ ++ u32 rsvd1; ++ u32 gphy1_cfg; /* GPHY1 config */ ++ u32 gphy0_cfg; /* GPHY0 config */ ++ u32 rsvd2[6]; ++ u32 pll2_cfg; /* PLL2 config */ ++}; ++ ++static struct ltq_cgu_regs *ltq_cgu_regs = ++ (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE); ++ ++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift) ++{ ++ return (ltq_readl(<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,120 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/asm.h> ++#include <asm/regdef.h> ++#include <asm/addrspace.h> ++#include <asm/arch/soc.h> ++ ++/* RCU module register */ ++#define LTQ_RCU_RST_REQ 0x0010 /* Reset request */ ++#define LTQ_RCU_RST_REQ_VALUE ((1 << 14) | (1 << 1)) ++ ++/* CGU module register */ ++#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */ ++#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */ ++#define LTQ_CGU_PLL2_CFG 0x0060 /* PLL2 config */ ++#define LTQ_CGU_SYS 0x000C /* System clock */ ++#define LTQ_CGU_CLK_FSR 0x0010 /* Clock frequency select */ ++#define LTQ_CGU_UPDATE 0x0020 /* Clock update control */ ++ ++/* Valid SYS.CPU values */ ++#define LTQ_CGU_SYS_CPU_SHIFT 4 ++#define LTQ_CGU_SYS_CPU_600_MHZ 0x0 ++#define LTQ_CGU_SYS_CPU_500_MHZ 0x1 ++#define LTQ_CGU_SYS_CPU_393_MHZ 0x2 ++#define LTQ_CGU_SYS_CPU_333_MHZ 0x3 ++#define LTQ_CGU_SYS_CPU_197_MHZ 0x5 ++#define LTQ_CGU_SYS_CPU_166_MHZ 0x7 ++#define LTQ_CGU_SYS_CPU_125_MHZ 0x9 ++ ++/* Valid SYS.OCP values */ ++#define LTQ_CGU_SYS_OCP_SHIFT 0 ++#define LTQ_CGU_SYS_OCP_1 0x0 ++#define LTQ_CGU_SYS_OCP_2 0x2 ++#define LTQ_CGU_SYS_OCP_2_5 0x3 ++#define LTQ_CGU_SYS_OCP_3 0x4 ++ ++/* Valid CLK_FSR.ETH values */ ++#define LTQ_CGU_CLK_FSR_ETH_SHIFT 24 ++#define LTQ_CGU_CLK_FSR_ETH_50_MHZ 0x0 ++#define LTQ_CGU_CLK_FSR_ETH_25_MHZ 0x1 ++#define LTQ_CGU_CLK_FSR_ETH_2_5_MHZ 0x2 ++#define LTQ_CGU_CLK_FSR_ETH_125_MHZ 0x3 ++ ++/* Valid CLK_FSR.PPE values */ ++#define LTQ_CGU_CLK_FSR_PPE_SHIFT 16 ++#define LTQ_CGU_CLK_FSR_PPE_500_MHZ 0x0 /* Overclock frequency */ ++#define LTQ_CGU_CLK_FSR_PPE_450_MHZ 0x1 /* High frequency */ ++#define LTQ_CGU_CLK_FSR_PPE_400_MHZ 0x2 /* Low frequency */ ++ ++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_500_DDR_250) ++#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_500_MHZ ++#define LTQ_CGU_SYS_OCP_CONFIG LTQ_CGU_SYS_OCP_2 ++#define LTQ_CGU_CLK_FSR_ETH_CONFIG LTQ_CGU_CLK_FSR_ETH_125_MHZ ++#define LTQ_CGU_CLK_FSR_PPE_CONFIG LTQ_CGU_CLK_FSR_PPE_450_MHZ ++#else ++#error "Invalid system clock configuration!" ++#endif ++ ++/* Build register values */ ++#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_CPU_CONFIG << \ ++ LTQ_CGU_SYS_CPU_SHIFT) | \ ++ LTQ_CGU_SYS_OCP_CONFIG) ++ ++#define LTQ_CGU_CLK_FSR_VALUE ((LTQ_CGU_CLK_FSR_ETH_CONFIG << \ ++ LTQ_CGU_CLK_FSR_ETH_SHIFT) | \ ++ (LTQ_CGU_CLK_FSR_PPE_CONFIG << \ ++ LTQ_CGU_CLK_FSR_PPE_SHIFT)) ++ ++ .set noreorder ++ ++LEAF(ltq_cgu_init) ++ /* Load current CGU register values */ ++ li t0, (LTQ_CGU_BASE | KSEG1) ++ lw t1, LTQ_CGU_SYS(t0) ++ lw t2, LTQ_CGU_CLK_FSR(t0) ++ ++ /* Load target CGU register values */ ++ li t3, LTQ_CGU_SYS_VALUE ++ li t4, LTQ_CGU_CLK_FSR_VALUE ++ ++ /* Only update registers if values differ */ ++ bne t1, t3, update ++ nop ++ beq t2, t4, finished ++ nop ++ ++update: ++ /* Store target register values */ ++ sw t3, LTQ_CGU_SYS(t0) ++ sw t4, LTQ_CGU_CLK_FSR(t0) ++ ++ /* Perform software reset to activate new clock config */ ++#if 0 ++ li t0, (LTQ_RCU_BASE | KSEG1) ++ lw t1, LTQ_RCU_RST_REQ(t0) ++ or t1, LTQ_RCU_RST_REQ_VALUE ++ sw t1, LTQ_RCU_RST_REQ(t0) ++#else ++ li t1, 1 ++ sw t1, LTQ_CGU_UPDATE(t0) ++#endif ++ ++#if 0 ++wait_reset: ++ b wait_reset ++ nop ++#endif ++ ++finished: ++ jr ra ++ nop ++ ++ END(ltq_cgu_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/chipid.c +@@ -0,0 +1,63 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_CHIPID_VERSION_SHIFT 28 ++#define LTQ_CHIPID_VERSION_MASK (0x7 << LTQ_CHIPID_VERSION_SHIFT) ++#define LTQ_CHIPID_PNUM_SHIFT 12 ++#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT) ++ ++struct ltq_chipid_regs { ++ u32 manid; /* Manufacturer identification */ ++ u32 chipid; /* Chip identification */ ++}; ++ ++static struct ltq_chipid_regs *ltq_chipid_regs = ++ (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE); ++ ++unsigned int ltq_chip_version_get(void) ++{ ++ u32 chipid; ++ ++ chipid = ltq_readl(<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,32 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,) ++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX) ++ ++ifdef CONFIG_SPL_BUILD ++PF_ABICALLS := -mno-abicalls ++PF_PIC := -fno-pic ++USE_PRIVATE_LIBGCC := yes ++endif ++ ++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o ++ ++ifndef CONFIG_SPL_BUILD ++ifdef CONFIG_SYS_BOOT_SFSPL ++ALL-y += $(obj)u-boot.ltq.sfspl ++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl ++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl ++endif ++ifdef CONFIG_SYS_BOOT_NORSPL ++ALL-y += $(obj)u-boot.ltq.norspl ++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl ++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl ++endif ++endif ++ ++LDSCRIPT := $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot.lds +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/dcdc.c +@@ -0,0 +1,107 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_DCDC_CLK_SET0_CLK_SEL_P (1 << 6) ++#define LTQ_DCDC_CLK_SET1_SEL_DIV25 (1 << 5) ++#define LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE (1 << 5) ++ ++struct ltq_dcdc_regs { ++ u8 b0_coeh; /* Coefficient b0 */ ++ u8 b0_coel; /* Coefficient b0 */ ++ u8 b1_coeh; /* Coefficient b1 */ ++ u8 b1_coel; /* Coefficient b1 */ ++ u8 b2_coeh; /* Coefficient b2 */ ++ u8 b2_coel; /* Coefficient b2 */ ++ u8 clk_set0; /* Clock setup */ ++ u8 clk_set1; /* Clock setup */ ++ u8 pwm_confh; /* Configure PWM */ ++ u8 pwm_confl; /* Configure PWM */ ++ u8 bias_vreg0; /* Bias and regulator setup */ ++ u8 bias_vreg1; /* Bias and regulator setup */ ++ u8 adc_gen0; /* ADC and general control */ ++ u8 adc_gen1; /* ADC and general control */ ++ u8 adc_con0; /* ADC and general config */ ++ u8 adc_con1; /* ADC and general config */ ++ u8 conf_test_ana; /* not documented */ ++ u8 conf_test_dig; /* not documented */ ++ u8 dcdc_status; /* not documented */ ++ u8 pid_status; /* not documented */ ++ u8 duty_cycle; /* not documented */ ++ u8 non_ov_delay; /* not documented */ ++ u8 analog_gain; /* not documented */ ++ u8 duty_cycle_max_sat; /* not documented */ ++ u8 duty_cycle_min_sat; /* not documented */ ++ u8 duty_cycle_max; /* not documented */ ++ u8 duty_cycle_min; /* not documented */ ++ u8 error_max; /* not documented */ ++ u8 error_read; /* not documented */ ++ u8 delay_deglitch; /* not documented */ ++ u8 latch_control; /* not documented */ ++ u8 rsvd[240]; ++ u8 osc_conf; /* OSC general config */ ++ u8 osc_stat; /* OSC general status */ ++}; ++ ++static struct ltq_dcdc_regs *ltq_dcdc_regs = ++ (struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE); ++ ++void ltq_dcdc_init(unsigned int dig_ref) ++{ ++ u8 dig_ref_cur, val; ++ ++ /* Set duty cycle max sat. to 70/90, enable PID freeze */ ++ ltq_writeb(<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,112 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4) ++#define EBU_ADDRSEL_REGEN (1 << 0) ++ ++#define EBU_CON_WRDIS (1 << 31) ++#define EBU_CON_AGEN_DEMUX (0x0 << 24) ++#define EBU_CON_AGEN_MUX (0x2 << 24) ++#define EBU_CON_SETUP (1 << 22) ++#define EBU_CON_WAIT_DIS (0x0 << 20) ++#define EBU_CON_WAIT_ASYNC (0x1 << 20) ++#define EBU_CON_WAIT_SYNC (0x2 << 20) ++#define EBU_CON_WINV (1 << 19) ++#define EBU_CON_PW_8BIT (0x0 << 16) ++#define EBU_CON_PW_16BIT (0x1 << 16) ++#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14) ++#define EBU_CON_BCGEN_CS (0x0 << 12) ++#define EBU_CON_BCGEN_INTEL (0x1 << 12) ++#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12) ++#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8) ++#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6) ++#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4) ++#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2) ++#define EBU_CON_CMULT_1 0x0 ++#define EBU_CON_CMULT_4 0x1 ++#define EBU_CON_CMULT_8 0x2 ++#define EBU_CON_CMULT_16 0x3 ++ ++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) ++#define ebu_region0_enable 1 ++#else ++#define ebu_region0_enable 0 ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH) ++#define ebu_region1_enable 1 ++#else ++#define ebu_region1_enable 0 ++#endif ++ ++struct ltq_ebu_regs { ++ u32 clc; ++ u32 rsvd0; ++ u32 id; ++ u32 rsvd1; ++ u32 con; ++ u32 rsvd2[3]; ++ u32 addr_sel_0; ++ u32 addr_sel_1; ++ u32 addr_sel_2; ++ u32 addr_sel_3; ++ u32 rsvd3[12]; ++ u32 con_0; ++ u32 con_1; ++ u32 con_2; ++ u32 con_3; ++}; ++ ++static struct ltq_ebu_regs *ltq_ebu_regs = ++ (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE); ++ ++void ltq_ebu_init(void) ++{ ++ if (ebu_region0_enable) { ++ /* ++ * Map EBU region 0 to range 0x10000000-0x13ffffff and enable ++ * region control. This supports up to 32 MiB NOR flash in ++ * bank 0. ++ */ ++ ltq_writel(<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,59 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/gphy.h> ++ ++static inline void ltq_gphy_copy(const void *fw_start, const void *fw_end, ++ ulong dst_addr) ++{ ++ const ulong fw_len = (ulong) fw_end - (ulong) fw_start; ++ const ulong addr = CKSEG1ADDR(dst_addr); ++ ++ debug("ltq_gphy_copy: addr %08lx, fw_start %p, fw_end %p\n", ++ addr, fw_start, fw_end); ++ ++ memcpy((void *) addr, fw_start, fw_len); ++} ++ ++void ltq_gphy_phy11g_a1x_load(ulong addr) ++{ ++ extern ulong __ltq_fw_phy11g_a1x_start; ++ extern ulong __ltq_fw_phy11g_a1x_end; ++ ++ ltq_gphy_copy(&__ltq_fw_phy11g_a1x_start, &__ltq_fw_phy11g_a1x_end, ++ addr); ++} ++ ++void ltq_gphy_phy11g_a2x_load(ulong addr) ++{ ++ extern ulong __ltq_fw_phy11g_a2x_start; ++ extern ulong __ltq_fw_phy11g_a2x_end; ++ ++ ltq_gphy_copy(&__ltq_fw_phy11g_a2x_start, &__ltq_fw_phy11g_a2x_end, ++ addr); ++} ++ ++void ltq_gphy_phy22f_a1x_load(ulong addr) ++{ ++ extern ulong __ltq_fw_phy22f_a1x_start; ++ extern ulong __ltq_fw_phy22f_a1x_end; ++ ++ ltq_gphy_copy(&__ltq_fw_phy22f_a1x_start, &__ltq_fw_phy22f_a1x_end, ++ addr); ++} ++ ++void ltq_gphy_phy22f_a2x_load(ulong addr) ++{ ++ extern ulong __ltq_fw_phy22f_a2x_start; ++ extern ulong __ltq_fw_phy22f_a2x_end; ++ ++ ltq_gphy_copy(&__ltq_fw_phy22f_a2x_start, &__ltq_fw_phy22f_a2x_end, ++ addr); ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S +@@ -0,0 +1,28 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <asm/asm.h> ++ ++ .section .rodata.__ltq_fw_phy11g_a1x ++EXPORT(__ltq_fw_phy11g_a1x_start) ++ .incbin "fw_phy11g_a1x.bin" ++EXPORT(__ltq_fw_phy11g_a1x_end) ++ ++ .section .rodata.__ltq_fw_phy11g_a2x ++EXPORT(__ltq_fw_phy11g_a2x_start) ++ .incbin "fw_phy11g_a2x.bin" ++EXPORT(__ltq_fw_phy11g_a2x_end) ++ ++ .section .rodata.__ltq_fw_phy22f_a1x ++EXPORT(__ltq_fw_phy22f_a1x_start) ++ .incbin "fw_phy22f_a1x.bin" ++EXPORT(__ltq_fw_phy22f_a1x_end) ++ ++ .section .rodata.__ltq_fw_phy22f_a2x ++EXPORT(__ltq_fw_phy22f_a2x_start) ++ .incbin "fw_phy22f_a2x.bin" ++EXPORT(__ltq_fw_phy22f_a2x_end) +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/mem.c +@@ -0,0 +1,58 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/io.h> ++ ++#define LTQ_CCR03_EIGHT_BANK_MODE (1 << 0) ++#define LTQ_CCR08_CS_MAP_SHIFT 24 ++#define LTQ_CCR08_CS_MAP_MASK (0x3 << LTQ_CCR08_CS_MAP_SHIFT) ++#define LTQ_CCR11_COLUMN_SIZE_SHIFT 24 ++#define LTQ_CCR11_COLUMN_SIZE_MASK (0x7 << LTQ_CCR11_COLUMN_SIZE_SHIFT) ++#define LTQ_CCR11_ADDR_PINS_MASK 0x7 ++#define LTQ_CCR15_MAX_COL_REG_SHIFT 24 ++#define LTQ_CCR15_MAX_COL_REG_MASK (0xF << LTQ_CCR15_MAX_COL_REG_SHIFT) ++#define LTQ_CCR16_MAX_ROW_REG_MASK 0xF ++ ++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE); ++ ++static inline u32 ltq_mc_ccr_read(u32 index) ++{ ++ return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index)); ++} ++ ++phys_size_t initdram(int board_type) ++{ ++ u32 max_col_reg, max_row_reg, column_size, addr_pins; ++ u32 banks, cs_map; ++ phys_size_t size; ++ ++ banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4; ++ ++ cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >> ++ LTQ_CCR08_CS_MAP_SHIFT; ++ ++ column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >> ++ LTQ_CCR11_COLUMN_SIZE_SHIFT; ++ ++ addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK; ++ ++ max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >> ++ LTQ_CCR15_MAX_COL_REG_SHIFT; ++ ++ max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK; ++ ++ /* ++ * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects ++ * * datawidth (bytes) ++ */ ++ size = (2 << (max_col_reg - column_size - 1)) * ++ (2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2; ++ ++ return size; ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/mem_init.S +@@ -0,0 +1,234 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <config.h> ++#include <asm/asm.h> ++#include <asm/regdef.h> ++#include <asm/addrspace.h> ++#include <asm/arch/soc.h> ++ ++/* Must be configured in BOARDDIR */ ++#include <ddr_settings.h> ++ ++#define LTQ_MC_DDR_START (1 << 8) ++#define LTQ_MC_DDR_DLL_LOCK_IND 1 ++ ++#define CCS_ALWAYS_LAST 0x0430 ++#define CCS_AHBM_CR_BURST_EN (1 << 2) ++#define CCS_FPIM_CR_BURST_EN (1 << 1) ++ ++#define CCR03_EIGHT_BANK_MODE (1 << 0) ++ ++ /* Store given value in MC DDR CCRx register */ ++ .macro ccr_sw num, val ++ li t1, \val ++ sw t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0) ++ .endm ++ ++LEAF(ltq_mem_init) ++ /* Load MC DDR module base */ ++ li t0, (LTQ_MC_DDR_BASE | KSEG1) ++ ++ /* Put memory controller in inactive mode */ ++ sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0) ++ ++ /* Init MC DDR CCR registers with values from ddr_settings.h */ ++ ccr_sw 0, MC_CCR00_VALUE ++ ccr_sw 1, MC_CCR01_VALUE ++ ccr_sw 2, MC_CCR02_VALUE ++ ccr_sw 3, MC_CCR03_VALUE ++ ccr_sw 4, MC_CCR04_VALUE ++ ccr_sw 5, MC_CCR05_VALUE ++ ccr_sw 6, MC_CCR06_VALUE ++ ccr_sw 7, MC_CCR07_VALUE ++ ccr_sw 8, MC_CCR08_VALUE ++ ccr_sw 9, MC_CCR09_VALUE ++ ++ ccr_sw 10, MC_CCR10_VALUE ++ ccr_sw 11, MC_CCR11_VALUE ++ ccr_sw 12, MC_CCR12_VALUE ++ ccr_sw 13, MC_CCR13_VALUE ++ ccr_sw 14, MC_CCR14_VALUE ++ ccr_sw 15, MC_CCR15_VALUE ++ ccr_sw 16, MC_CCR16_VALUE ++ ccr_sw 17, MC_CCR17_VALUE ++ ccr_sw 18, MC_CCR18_VALUE ++ ccr_sw 19, MC_CCR19_VALUE ++ ++ ccr_sw 20, MC_CCR20_VALUE ++ ccr_sw 21, MC_CCR21_VALUE ++ ccr_sw 22, MC_CCR22_VALUE ++ ccr_sw 23, MC_CCR23_VALUE ++ ccr_sw 24, MC_CCR24_VALUE ++ ccr_sw 25, MC_CCR25_VALUE ++ ccr_sw 26, MC_CCR26_VALUE ++ ccr_sw 27, MC_CCR27_VALUE ++ ccr_sw 28, MC_CCR28_VALUE ++ ccr_sw 29, MC_CCR29_VALUE ++ ++ ccr_sw 30, MC_CCR30_VALUE ++ ccr_sw 31, MC_CCR31_VALUE ++ ccr_sw 32, MC_CCR32_VALUE ++ ccr_sw 33, MC_CCR33_VALUE ++ ccr_sw 34, MC_CCR34_VALUE ++ ccr_sw 35, MC_CCR35_VALUE ++ ccr_sw 36, MC_CCR36_VALUE ++ ccr_sw 37, MC_CCR37_VALUE ++ ccr_sw 38, MC_CCR38_VALUE ++ ccr_sw 39, MC_CCR39_VALUE ++ ++ ccr_sw 40, MC_CCR40_VALUE ++ ccr_sw 41, MC_CCR41_VALUE ++ ccr_sw 42, MC_CCR42_VALUE ++ ccr_sw 43, MC_CCR43_VALUE ++ ccr_sw 44, MC_CCR44_VALUE ++ ccr_sw 45, MC_CCR45_VALUE ++ ccr_sw 46, MC_CCR46_VALUE ++ ++ ccr_sw 52, MC_CCR52_VALUE ++ ccr_sw 53, MC_CCR53_VALUE ++ ccr_sw 54, MC_CCR54_VALUE ++ ccr_sw 55, MC_CCR55_VALUE ++ ccr_sw 56, MC_CCR56_VALUE ++ ccr_sw 57, MC_CCR57_VALUE ++ ccr_sw 58, MC_CCR58_VALUE ++ ccr_sw 59, MC_CCR59_VALUE ++ ++ ccr_sw 60, MC_CCR60_VALUE ++ ccr_sw 61, MC_CCR61_VALUE ++ ++ /* Disable bursts between FPI Master bus and XBAR bus */ ++ li t4, (LTQ_MC_GLOBAL_BASE | KSEG1) ++ li t5, CCS_AHBM_CR_BURST_EN ++ sw t5, CCS_ALWAYS_LAST(t4) ++ ++ /* Init abort condition for DRAM probe */ ++ move t4, zero ++ ++ /* ++ * Put memory controller in active mode and start initialitation ++ * sequence for connected DDR-SDRAM device ++ */ ++mc_start: ++ lw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0) ++ li t2, LTQ_MC_DDR_START ++ or t1, t1, t2 ++ sw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0) ++ ++ /* ++ * Wait until DLL has locked and core is ready for data transfers. ++ * DLL lock indication is in register CCR47 and CCR48 ++ */ ++wait_ready: ++ li t1, LTQ_MC_DDR_DLL_LOCK_IND ++ lw t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0) ++ and t2, t2, t1 ++ bne t1, t2, wait_ready ++ ++ lw t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0) ++ and t2, t2, t1 ++ bne t1, t2, wait_ready ++ ++#ifdef CONFIG_SYS_DRAM_PROBE ++dram_probe: ++ /* Initialization is finished after the second MC start */ ++ bnez t4, mc_finished ++ ++ /* ++ * Preload register values for CCR03 and CCR11. Initial settings ++ * are 8-bank mode enabled, 14 use address row bits, 10 used ++ * column address bits. ++ */ ++ li t1, CONFIG_SYS_SDRAM_BASE_UC ++ li t5, MC_CCR03_VALUE ++ li t6, MC_CCR11_VALUE ++ addi t4, t4, 1 ++ ++ /* ++ * Store test values to DRAM at offsets 0 and 2^13 (bit 2 in bank select ++ * address BA[3]) and read back the value at offset 0. If the resulting ++ * value is equal to 1 we can skip to the next test. Otherwise ++ * the 8-bank mode does not work with the current DRAM device, ++ * thus we need to clear the according bit in register CCR03. ++ */ ++ li t2, 1 ++ sw t2, 0x0(t1) ++ li t3, (1 << 13) ++ add t3, t3, t1 ++ sw zero, 0(t3) ++ lw t3, 0(t1) ++ bnez t3, row_col_test ++ ++ /* Clear CCR03.EIGHT_BANK_MODE */ ++ li t3, ~CCR03_EIGHT_BANK_MODE ++ and t5, t5, t3 ++ ++row_col_test: ++ /* ++ * Store test values to DRAM at offsets 0, 2^27 (bit 13 of row address ++ * RA[14]) and 2^26 (bit 12 of RA[14]). The chosen test values ++ * represent the difference between max. row address bits (14) and used ++ * row address bits. Then the read back value at offset 0 indicates ++ * the useable row address bits with the current DRAM device. This ++ * value must be set in the CCR11 register. ++ */ ++ sw zero, 0(t1) ++ ++ li t2, 1 ++ li t3, (1 << 27) ++ add t3, t3, t1 ++ sw t2, 0(t3) ++ ++ li t2, 2 ++ li t3, (1 << 26) ++ add t3, t3, t1 ++ sw t2, 0(t3) ++ ++ /* Update CCR11.ADDR_PINS */ ++ lw t3, 0(t1) ++ add t6, t6, t3 ++ ++ /* ++ * Store test values to DRAM at offsets 0, 2^10 (bit 9 of column address ++ * CA[10]) and 2^9 (bit 8 of CA[10]). The chosen test values represent ++ * the difference between max. column address bits (12) and used ++ * column address bits. Then the read back value at offset 0 indicates ++ * the useable column address bits with the current DRAM device. This ++ * value must be set in the CCR11 register. ++ */ ++ sw zero, 0(t1) ++ ++ li t2, 1 ++ li t3, (1 << 10) ++ add t3, t3, t1 ++ sw t2, 0(t3) ++ ++ li t2, 2 ++ li t3, (1 << 9) ++ add t3, t3, t1 ++ sw t2, 0(t3) ++ ++ /* Update CCR11.COLUMN_SIZE */ ++ lw t3, 0(t1) ++ sll t3, t3, 24 ++ add t6, t6, t3 ++ ++ /* Put memory controller in inactive mode */ ++ sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0) ++ ++ /* Update CCR03 and CCR11 and restart memory controller initialiation */ ++ sw t5, LTQ_MC_DDR_CCR_OFFSET(3)(t0) ++ sw t6, LTQ_MC_DDR_CCR_OFFSET(11)(t0) ++ b mc_start ++ ++mc_finished: ++#endif /* CONFIG_SYS_DRAM_PROBE */ ++ ++ jr ra ++ ++ END(ltq_mem_init) +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/pmu.c +@@ -0,0 +1,131 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/pm.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_PMU_PWDCR_RESERVED ((1 << 13) | (1 << 4)) ++ ++#define LTQ_PMU_PWDCR_PCIELOC_EN (1 << 31) ++#define LTQ_PMU_PWDCR_GPHY (1 << 30) ++#define LTQ_PMU_PWDCR_PPE_TOP (1 << 29) ++#define LTQ_PMU_PWDCR_SWITCH (1 << 28) ++#define LTQ_PMU_PWDCR_USB1 (1 << 27) ++#define LTQ_PMU_PWDCR_USB1_PHY (1 << 26) ++#define LTQ_PMU_PWDCR_TDM (1 << 25) ++#define LTQ_PMU_PWDCR_PPE_DPLUS (1 << 24) ++#define LTQ_PMU_PWDCR_PPE_DPLUM (1 << 23) ++#define LTQ_PMU_PWDCR_PPE_EMA (1 << 22) ++#define LTQ_PMU_PWDCR_PPE_TC (1 << 21) ++#define LTQ_PMU_PWDCR_DEU (1 << 20) ++#define LTQ_PMU_PWDCR_PPE_SLL01 (1 << 19) ++#define LTQ_PMU_PWDCR_PPE_QSB (1 << 18) ++#define LTQ_PMU_PWDCR_UART1 (1 << 17) ++#define LTQ_PMU_PWDCR_SDIO (1 << 16) ++#define LTQ_PMU_PWDCR_AHBM (1 << 15) ++#define LTQ_PMU_PWDCR_FPIM (1 << 14) ++#define LTQ_PMU_PWDCR_GPTC (1 << 12) ++#define LTQ_PMU_PWDCR_LEDC (1 << 11) ++#define LTQ_PMU_PWDCR_EBU (1 << 10) ++#define LTQ_PMU_PWDCR_DSL (1 << 9) ++#define LTQ_PMU_PWDCR_SPI (1 << 8) ++#define LTQ_PMU_PWDCR_USIF (1 << 7) ++#define LTQ_PMU_PWDCR_USB0 (1 << 6) ++#define LTQ_PMU_PWDCR_DMA (1 << 5) ++#define LTQ_PMU_PWDCR_DFEV1 (1 << 3) ++#define LTQ_PMU_PWDCR_DFEV0 (1 << 2) ++#define LTQ_PMU_PWDCR_FPIS (1 << 1) ++#define LTQ_PMU_PWDCR_USB0_PHY (1 << 0) ++ ++struct ltq_pmu_regs { ++ u32 rsvd0[7]; ++ u32 pwdcr; /* Power down control */ ++ u32 sr; /* Power down status */ ++ u32 pwdcr1; /* Power down control 1 */ ++ u32 sr1; /* Power down status 1 */ ++}; ++ ++static struct ltq_pmu_regs *ltq_pmu_regs = ++ (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE); ++ ++u32 ltq_pm_map(enum ltq_pm_modules module) ++{ ++ u32 val; ++ ++ switch (module) { ++ case LTQ_PM_CORE: ++ val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM | ++ LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU; ++ break; ++ case LTQ_PM_DMA: ++ val = LTQ_PMU_PWDCR_DMA; ++ break; ++ case LTQ_PM_ETH: ++ val = LTQ_PMU_PWDCR_GPHY | LTQ_PMU_PWDCR_PPE_TOP | ++ LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DPLUS | ++ LTQ_PMU_PWDCR_PPE_DPLUM | LTQ_PMU_PWDCR_PPE_EMA | ++ LTQ_PMU_PWDCR_PPE_TC | LTQ_PMU_PWDCR_PPE_SLL01 | ++ LTQ_PMU_PWDCR_PPE_QSB; ++ break; ++ case LTQ_PM_SPI: ++ val = LTQ_PMU_PWDCR_SPI; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ ++ return val; ++} ++ ++int ltq_pm_enable(enum ltq_pm_modules module) ++{ ++ const unsigned long timeout = 1000; ++ unsigned long timebase; ++ u32 sr, val; ++ ++ val = ltq_pm_map(module); ++ if (unlikely(!val)) ++ return 1; ++ ++ ltq_clrbits(<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,195 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/cpu.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_RCU_RD_GPHY0 (1 << 31) /* GPHY0 */ ++#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */ ++#define LTQ_RCU_RD_GPHY1 (1 << 29) /* GPHY1 */ ++#define LTQ_RCU_RD_ENMIP2 (1 << 28) /* Enable NMI of PLL2 */ ++#define LTQ_RCU_RD_REG25_PD (1 << 26) /* Power down 2.5V regulator */ ++#define LTQ_RCU_RD_ENDINIT (1 << 25) /* FPI slave bus access */ ++#define LTQ_RCU_RD_PPE_ATM_TC (1 << 23) /* PPE ATM TC */ ++#define LTQ_RCU_RD_PCIE (1 << 22) /* PCI-E core */ ++#define LTQ_RCU_RD_ETHSW (1 << 21) /* Ethernet switch */ ++#define LTQ_RCU_RD_DSP_DEN (1 << 20) /* Enable DSP JTAG */ ++#define LTQ_RCU_RD_TDM (1 << 19) /* TDM module interface */ ++#define LTQ_RCU_RD_ENMIP1 (1 << 18) /* Enable NMI of PLL1 */ ++#define LTQ_RCU_RD_SWBCK (1 << 17) /* Switch backward compat */ ++#define LTQ_RCU_RD_HSNAND (1 << 16) /* HSNAND controller */ ++#define LTQ_RCU_RD_ENMIP0 (1 << 15) /* Enable NMI of PLL0 */ ++#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */ ++#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */ ++#define LTQ_RCU_RD_PCIE_PHY (1 << 12) /* PCI-E Phy */ ++#define LTQ_RCU_RD_DFE_CORE (1 << 11) /* DFE core */ ++#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */ ++#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */ ++#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */ ++#define LTQ_RCU_RD_DFE (1 << 7) /* DFE core */ ++#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */ ++#define LTQ_RCU_RD_HRST_CFG (1 << 5) /* HW reset configuration */ ++#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */ ++#define LTQ_RCU_RD_PPE_DSP (1 << 3) /* PPE DSP interface */ ++#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */ ++#define LTQ_RCU_RD_CPU (1 << 1) /* CPU subsystem */ ++#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */ ++ ++#define LTQ_RCU_STAT_BOOT_SHIFT 17 ++#define LTQ_RCU_STAT_BOOT_MASK (0xF << LTQ_RCU_STAT_BOOT_SHIFT) ++#define LTQ_RCU_STAT_BOOT_H (1 << 12) ++ ++#define LTQ_RCU_GP_STRAP_CLOCKSOURCE (1 << 15) ++ ++struct ltq_rcu_regs { ++ u32 rsvd0[4]; ++ u32 req; /* Reset request */ ++ u32 stat; /* Reset status */ ++ u32 usb0_cfg; /* USB0 configure */ ++ u32 gp_strap; /* GPIO strapping */ ++ u32 gfs_add0; /* GPHY0 firmware base addr */ ++ u32 stat2; /* SLIC and USB reset status */ ++ u32 pci_rdy; /* PCI boot ready */ ++ u32 ppe_conf; /* PPE ethernet config */ ++ u32 pcie_phy_con; /* PCIE PHY config/status */ ++ u32 usb1_cfg; /* USB1 configure */ ++ u32 usb_ana_cfg1a; /* USB analog config 1a */ ++ u32 usb_ana_cfg1b; /* USB analog config 1b */ ++ u32 rsvd1; ++ u32 gf_mdio_add; /* GPHY0/1 MDIO address */ ++ u32 req2; /* SLIC and USB reset request */ ++ u32 ahb_endian; /* AHB bus endianess */ ++ u32 rsvd2[4]; ++ u32 gcc; /* General CPU config */ ++ u32 rsvd3; ++ u32 gfs_add1; /* GPHY1 firmware base addr */ ++}; ++ ++static struct ltq_rcu_regs *ltq_rcu_regs = ++ (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE); ++ ++u32 ltq_reset_map(enum ltq_reset_modules module) ++{ ++ u32 val; ++ ++ switch (module) { ++ case LTQ_RESET_CORE: ++ case LTQ_RESET_SOFT: ++ val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU | LTQ_RCU_RD_ENMIP2 | ++ LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0; ++ break; ++ case LTQ_RESET_DMA: ++ val = LTQ_RCU_RD_DMA; ++ break; ++ case LTQ_RESET_ETH: ++ val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW; ++ break; ++ case LTQ_RESET_PHY: ++ val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0; ++ break; ++ case LTQ_RESET_HARD: ++ val = LTQ_RCU_RD_HRST; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ ++ return val; ++} ++ ++int ltq_reset_activate(enum ltq_reset_modules module) ++{ ++ u32 val; ++ ++ val = ltq_reset_map(module); ++ if (unlikely(!val)) ++ return 1; ++ ++ ltq_setbits(<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/cpu/mips32/vrx200/u-boot.lds +@@ -0,0 +1,69 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") ++OUTPUT_ARCH(mips) ++ENTRY(_start) ++SECTIONS ++{ ++ . = 0x00000000; ++ ++ . = ALIGN(4); ++ .text : { ++ *(.text*) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { ++ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) ++ } ++ ++ . = ALIGN(4); ++ .data : { ++ *(.data*) ++ } ++ ++ . = ALIGN(4); ++ .sdata : { ++ *(.sdata*) ++ } ++ ++ . = .; ++ _gp = ALIGN(16) + 0x7ff0; ++ ++ .got : { ++ __got_start = .; ++ *(.got) ++ __got_end = .; ++ } ++ ++ num_got_entries = (__got_end - __got_start) >> 2; ++ ++#ifndef CONFIG_SPL_BUILD ++ . = ALIGN(4); ++ .u_boot_list : { ++ #include <u-boot.lst> ++ } ++#endif ++ ++ . = ALIGN(4); ++ __image_copy_end = .; ++ uboot_end_data = .; ++ ++ .bss (NOLOAD) : { ++ __bss_start = .; ++ *(.bss*) ++ *(.sbss*) ++ . = ALIGN(4); ++ __bss_end = .; ++ } ++ ++ . = ALIGN(4); ++ __end = .; ++ uboot_end = .; ++} +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/config.h +@@ -0,0 +1,156 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * Common board configuration for Lantiq XWAY Danube family ++ * ++ * Use following defines in your board config to enable specific features ++ * and drivers for this SoC: ++ * ++ * CONFIG_LTQ_SUPPORT_UART ++ * - support the Danube ASC/UART interface and console ++ * ++ * CONFIG_LTQ_SUPPORT_NOR_FLASH ++ * - support a parallel NOR flash via the CFI interface in flash bank 0 ++ * ++ * CONFIG_LTQ_SUPPORT_ETHERNET ++ * - support the Danube ETOP and MAC interface ++ * ++ * CONFIG_LTQ_SUPPORT_SPI_FLASH ++ * - support the Danube SPI interface and serial flash drivers ++ * - specific SPI flash drivers must be configured separately ++ */ ++ ++#ifndef __DANUBE_CONFIG_H__ ++#define __DANUBE_CONFIG_H__ ++ ++/* CPU and SoC type */ ++#define CONFIG_SOC_LANTIQ ++#define CONFIG_SOC_XWAY_DANUBE ++ ++/* Cache configuration */ ++#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT ++#define CONFIG_SYS_DCACHE_SIZE (16 * 1024) ++#define CONFIG_SYS_ICACHE_SIZE (16 * 1024) ++#define CONFIG_SYS_CACHELINE_SIZE 32 ++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ ++/* ++ * Supported clock modes ++ * PLL0 clock output is 333 MHz ++ * PLL1 clock output is 262.144 MHz ++ */ ++#define LTQ_CLK_CPU_333_DDR_167 0 /* Base PLL0, OCP 2 */ ++#define LTQ_CLK_CPU_111_DDR_111 1 /* Base PLL0, OCP 1 */ ++ ++/* CPU speed */ ++#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_333_DDR_167 ++#define CONFIG_SYS_MIPS_TIMER_FREQ 166666667 ++#define CONFIG_SYS_HZ 1000 ++ ++/* RAM */ ++#define CONFIG_NR_DRAM_BANKS 1 ++#define CONFIG_SYS_SDRAM_BASE 0x80000000 ++#define CONFIG_SYS_MEMTEST_START 0x81000000 ++#define CONFIG_SYS_MEMTEST_END 0x82000000 ++#define CONFIG_SYS_LOAD_ADDR 0x81000000 ++#define CONFIG_SYS_INIT_SP_OFFSET 0x4000 ++ ++/* SRAM */ ++#define CONFIG_SYS_SRAM_BASE 0xBE180000 ++#define CONFIG_SYS_SRAM_SIZE 0x10000 ++ ++/* ASC/UART driver and console */ ++#define CONFIG_LANTIQ_SERIAL ++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } ++ ++/* GPIO */ ++#define CONFIG_LANTIQ_GPIO ++#define CONFIG_LTQ_GPIO_MAX_BANKS 2 ++ ++/* FLASH driver */ ++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) ++#define CONFIG_SYS_MAX_FLASH_BANKS 1 ++#define CONFIG_SYS_MAX_FLASH_SECT 256 ++#define CONFIG_SYS_FLASH_BASE 0xB0000000 ++#define CONFIG_FLASH_16BIT ++#define CONFIG_SYS_FLASH_CFI ++#define CONFIG_FLASH_CFI_DRIVER ++#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT ++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE ++#define CONFIG_FLASH_SHOW_PROGRESS 50 ++#define CONFIG_SYS_FLASH_PROTECTION ++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP ++ ++#define CONFIG_CMD_FLASH ++#else ++#define CONFIG_SYS_NO_FLASH ++#endif /* CONFIG_NOR_FLASH */ ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH) ++#define CONFIG_LANTIQ_SPI ++#define CONFIG_SPI_FLASH ++ ++#define CONFIG_CMD_SF ++#define CONFIG_CMD_SPI ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET) ++#define CONFIG_LANTIQ_DMA ++#define CONFIG_LANTIQ_DANUBE_ETOP ++ ++#define CONFIG_PHYLIB ++#define CONFIG_MII ++ ++#define CONFIG_CMD_MII ++#define CONFIG_CMD_NET ++#endif ++ ++#define CONFIG_SPL_MAX_SIZE (32 * 1024) ++#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024) ++#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024) ++#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024) ++/*#define CONFIG_SPL_STACK_BSS_IN_SRAM*/ ++ ++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM) ++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \ ++ CONFIG_SPL_MAX_SIZE + \ ++ CONFIG_SPL_STACK_MAX_SIZE - 1) ++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1) ++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \ ++ CONFIG_SYS_INIT_SP_OFFSET) ++#else ++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \ ++ CONFIG_SYS_INIT_SP_OFFSET + \ ++ CONFIG_SPL_STACK_MAX_SIZE - 1) ++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1) ++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \ ++ CONFIG_SPL_BSS_MAX_SIZE) ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_RAM) ++#define CONFIG_SYS_TEXT_BASE 0xa0100000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_SYS_TEXT_BASE 0xB0000000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SPL_TEXT_BASE 0xB0000000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C ++#define CONFIG_XWAY_SWAP_BYTES ++#endif ++ ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE ++ ++#endif /* __DANUBE_CONFIG_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/gpio.h +@@ -0,0 +1,13 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __DANUBE_GPIO_H__ ++#define __DANUBE_GPIO_H__ ++ ++#include <asm/lantiq/gpio.h> ++ ++#endif /* __DANUBE_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/soc.h +@@ -0,0 +1,40 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __DANUBE_SOC_H__ ++#define __DANUBE_SOC_H__ ++ ++#define LTQ_ASC0_BASE 0x1E100400 ++#define LTQ_SPI_BASE 0x1E100800 ++#define LTQ_GPIO_BASE 0x1E100B00 ++#define LTQ_SSIO_BASE 0x1E100BB0 ++#define LTQ_ASC1_BASE 0x1E100C00 ++#define LTQ_DMA_BASE 0x1E104100 ++ ++#define LTQ_EBU_BASE 0x1E105300 ++#define LTQ_EBU_REGION0_BASE 0x10000000 ++#define LTQ_EBU_REGION0_SIZE (64 * 1024 * 1024) ++#define LTQ_EBU_REGION1_BASE 0x14000000 ++#define LTQ_EBU_REGION1_SIZE (32 * 1024 * 1024) ++ ++#define LTQ_PPE_BASE 0x1E180000 ++#define LTQ_PPE_ETOP_BASE (LTQ_PPE_BASE + 0x11800) ++#define LTQ_PPE_ENET0_BASE (LTQ_PPE_BASE + 0x11840) ++ ++#define LTQ_PMU_BASE 0x1F102000 ++#define LTQ_CGU_BASE 0x1F103000 ++#define LTQ_MPS_BASE 0x1F107000 ++#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340) ++#define LTQ_RCU_BASE 0x1F203000 ++ ++#define LTQ_MC_GEN_BASE 0x1F800000 ++#define LTQ_MC_SDR_BASE 0x1F800200 ++#define LTQ_MC_DDR_BASE 0x1F801000 ++#define LTQ_MC_DDR_DC_OFFSET(x) (x * 0x10) ++ ++#endif /* __DANUBE_SOC_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/config.h +@@ -0,0 +1,185 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * Common board configuration for Lantiq XWAY VRX200 family ++ * ++ * Use following defines in your board config to enable specific features ++ * and drivers for this SoC: ++ * ++ * CONFIG_LTQ_SUPPORT_UART ++ * - support the VRX200 ASC/UART interface and console ++ * ++ * CONFIG_LTQ_SUPPORT_NOR_FLASH ++ * - support a parallel NOR flash via the CFI interface in flash bank 0 ++ * ++ * CONFIG_LTQ_SUPPORT_SPI_FLASH ++ * - support the VRX200 SPI interface and serial flash drivers ++ * - specific SPI flash drivers must be configured separately ++ * ++ * CONFIG_LTQ_SUPPORT_ETHERNET ++ * - support the VRX200 internal switch ++ * ++ * CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH ++ * - build a preloader that runs in the internal SRAM and loads ++ * the U-Boot from SPI flash into RAM ++ */ ++ ++#ifndef __VRX200_CONFIG_H__ ++#define __VRX200_CONFIG_H__ ++ ++/* CPU and SoC type */ ++#define CONFIG_SOC_LANTIQ ++#define CONFIG_SOC_XWAY_VRX200 ++ ++/* Cache configuration */ ++#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT ++#define CONFIG_SYS_DCACHE_SIZE (32 * 1024) ++#define CONFIG_SYS_ICACHE_SIZE (32 * 1024) ++#define CONFIG_SYS_CACHELINE_SIZE 32 ++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT ++ ++/* ++ * Supported clock modes ++ * PLL0 clock output is 1000 MHz ++ * PLL1 clock output is 393.219 MHz ++ */ ++#define LTQ_CLK_CPU_600_DDR_300 0 /* Base PLL0, OCP 2 */ ++#define LTQ_CLK_CPU_600_DDR_200 1 /* Base PLL0, OCP 3 */ ++#define LTQ_CLK_CPU_500_DDR_250 2 /* Base PLL0, OCP 2 */ ++#define LTQ_CLK_CPU_500_DDR_200 3 /* Base PLL0, OCP 2.5 */ ++#define LTQ_CLK_CPU_333_DDR_167 4 /* Base PLL0, OCP 2 */ ++#define LTQ_CLK_CPU_167_DDR_167 5 /* Base PLL0, OCP 1 */ ++#define LTQ_CLK_CPU_125_DDR_125 6 /* Base PLL0, OCP 1 */ ++#define LTQ_CLK_CPU_393_DDR_197 7 /* Base PLL1, OCP 2 */ ++#define LTQ_CLK_CPU_197_DDR_197 8 /* Base PLL1, OCP 1 */ ++ ++/* CPU speed */ ++#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_500_DDR_250 ++#define CONFIG_SYS_MIPS_TIMER_FREQ 250000000 ++#define CONFIG_SYS_HZ 1000 ++ ++/* RAM */ ++#define CONFIG_NR_DRAM_BANKS 1 ++#define CONFIG_SYS_SDRAM_BASE 0x80000000 ++#define CONFIG_SYS_SDRAM_BASE_UC 0xa0000000 ++#define CONFIG_SYS_MEMTEST_START 0x81000000 ++#define CONFIG_SYS_MEMTEST_END 0x82000000 ++#define CONFIG_SYS_LOAD_ADDR 0x81000000 ++#define CONFIG_SYS_INIT_SP_OFFSET (32 * 1024) ++ ++/* SRAM */ ++#define CONFIG_SYS_SRAM_BASE 0xBE220000 ++#define CONFIG_SYS_SRAM_SIZE 0x10000 ++ ++/* ASC/UART driver and console */ ++#define CONFIG_LANTIQ_SERIAL ++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } ++ ++/* GPIO */ ++#define CONFIG_LANTIQ_GPIO ++#define CONFIG_LTQ_GPIO_MAX_BANKS 3 ++#define CONFIG_LTQ_HAS_GPIO_BANK3 ++ ++/* FLASH driver */ ++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) ++#define CONFIG_SYS_MAX_FLASH_BANKS 1 ++#define CONFIG_SYS_MAX_FLASH_SECT 256 ++#define CONFIG_SYS_FLASH_BASE 0xB0000000 ++#define CONFIG_FLASH_16BIT ++#define CONFIG_SYS_FLASH_CFI ++#define CONFIG_FLASH_CFI_DRIVER ++#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT ++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE ++#define CONFIG_FLASH_SHOW_PROGRESS 50 ++#define CONFIG_SYS_FLASH_PROTECTION ++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP ++ ++#define CONFIG_CMD_FLASH ++#else ++#define CONFIG_SYS_NO_FLASH ++#endif /* CONFIG_NOR_FLASH */ ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH) ++#define CONFIG_LANTIQ_SPI ++#define CONFIG_SPI_FLASH ++ ++#define CONFIG_CMD_SF ++#define CONFIG_CMD_SPI ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH) ++#define CONFIG_NAND_LANTIQ ++#define CONFIG_SYS_MAX_NAND_DEVICE 1 ++#define CONFIG_SYS_NAND_BASE 0xB4000000 ++ ++#define CONFIG_CMD_NAND ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET) ++#define CONFIG_LANTIQ_DMA ++#define CONFIG_LANTIQ_VRX200_SWITCH ++#define CONFIG_PHY_LANTIQ ++ ++#define CONFIG_SYS_RX_ETH_BUFFER 8 ++#define CONFIG_PHYLIB ++#define CONFIG_MII ++#define CONFIG_UDP_CHECKSUM ++ ++#define CONFIG_CMD_MII ++#define CONFIG_CMD_NET ++#endif ++ ++#define CONFIG_SPL_MAX_SIZE (32 * 1024) ++#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024) ++#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024) ++#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024) ++#define CONFIG_SPL_STACK_BSS_IN_SRAM ++ ++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM) ++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \ ++ CONFIG_SPL_MAX_SIZE + \ ++ CONFIG_SPL_STACK_MAX_SIZE - 1) ++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1) ++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \ ++ CONFIG_SYS_INIT_SP_OFFSET) ++#else ++#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \ ++ CONFIG_SYS_INIT_SP_OFFSET + \ ++ CONFIG_SPL_STACK_MAX_SIZE - 1) ++#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1) ++#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \ ++ CONFIG_SPL_BSS_MAX_SIZE) ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_RAM) ++#define CONFIG_SYS_TEXT_BASE 0xA0100000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_SYS_TEXT_BASE 0xB0000000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_SFSPL) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SPL_TEXT_BASE 0xBE220000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SPL_TEXT_BASE 0xB0000000 ++#endif ++ ++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C ++#define CONFIG_XWAY_SWAP_BYTES ++#endif ++ ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE ++ ++#endif /* __VRX200_CONFIG_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/gphy.h +@@ -0,0 +1,66 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __VRX200_GPHY_H__ ++#define __VRX200_GPHY_H__ ++ ++enum ltq_gphy_clk { ++ /* XTAL 36 MHz input */ ++ LTQ_GPHY_CLK_36MHZ_XTAL = 1, ++ /* 25 MHz from PLL0 with divider */ ++ LTQ_GPHY_CLK_25MHZ_PLL0 = 2, ++ /* derived from PLL2 output (XTAL is 36 MHz) */ ++ LTQ_GPHY_CLK_24MHZ_PLL2 = 3, ++ /* 25 MHz Clock from Pin GPIO3 */ ++ LTQ_GPHY_CLK_25MHZ_GPIO3 = 4, ++}; ++ ++/* ++ * Load PHY11G firmware for VRX200 v1.1 to given RAM address ++ * ++ * Address must be 16k aligned! ++ */ ++extern void ltq_gphy_phy11g_a1x_load(ulong addr); ++ ++/* ++ * Load PHY11G firmware for VRX200 v1.2 to given RAM address ++ * ++ * Address must be 16k aligned! ++ */ ++extern void ltq_gphy_phy11g_a2x_load(ulong addr); ++ ++/* ++ * Load PHY22F firmware for VRX200 v1.1 to given RAM address ++ * ++ * Address must be 16k aligned! ++ */ ++extern void ltq_gphy_phy22f_a1x_load(ulong addr); ++ ++/* ++ * Load PHY22F firmware for VRX200 v1.2 to given RAM address ++ * ++ * Address must be 16k aligned! ++ */ ++extern void ltq_gphy_phy22f_a2x_load(ulong addr); ++ ++/* ++ * Set clock source of internal GPHYs ++ * ++ * According registers resides in CGU address space. Thus this function ++ * is implemented by the CGU driver. ++ */ ++extern void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk); ++ ++/* ++ * Boot internal GPHY with id from given RAM address ++ * ++ * According registers resides in RCU address space. Thus this function ++ * is implemented by the RCU driver. ++ */ ++extern void ltq_rcu_gphy_boot(unsigned int id, ulong addr); ++ ++#endif /* __VRX200_GPHY_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/gpio.h +@@ -0,0 +1,13 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __VRX200_GPIO_H__ ++#define __VRX200_GPIO_H__ ++ ++#include <asm/lantiq/gpio.h> ++ ++#endif /* __VRX200_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/nand.h +@@ -0,0 +1,14 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#ifndef __VRX200_NAND_H__ ++#define __VRX200_NAND_H__ ++ ++struct nand_chip; ++int ltq_nand_init(struct nand_chip *nand); ++ ++#endif /* __VRX200_NAND_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/soc.h +@@ -0,0 +1,46 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __VRX200_SOC_H__ ++#define __VRX200_SOC_H__ ++ ++#define LTQ_ASC0_BASE 0x1E100400 ++#define LTQ_SPI_BASE 0x1E100800 ++#define LTQ_GPIO_BASE 0x1E100B00 ++#define LTQ_SSIO_BASE 0x1E100BB0 ++#define LTQ_ASC1_BASE 0x1E100C00 ++#define LTQ_DMA_BASE 0x1E104100 ++ ++#define LTQ_EBU_BASE 0x1E105300 ++#define LTQ_EBU_REGION0_BASE 0x10000000 ++#define LTQ_EBU_REGION1_BASE 0x14000000 ++#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0) ++ ++#define LTQ_SWITCH_BASE 0x1E108000 ++#define LTQ_SWITCH_CORE_BASE LTQ_SWITCH_BASE ++#define LTQ_SWITCH_TOP_PDI_BASE LTQ_SWITCH_CORE_BASE ++#define LTQ_SWITCH_BM_PDI_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x40) ++#define LTQ_SWITCH_MAC_PDI_0_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x900) ++#define LTQ_SWITCH_MAC_PDI_X_BASE(x) (LTQ_SWITCH_MAC_PDI_0_BASE + x * 0x30) ++#define LTQ_SWITCH_TOPLEVEL_BASE (LTQ_SWITCH_BASE + 4 * 0xC40) ++#define LTQ_SWITCH_MDIO_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE) ++#define LTQ_SWITCH_MII_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x36) ++#define LTQ_SWITCH_PMAC_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x82) ++ ++#define LTQ_PMU_BASE 0x1F102000 ++#define LTQ_CGU_BASE 0x1F103000 ++#define LTQ_DCDC_BASE 0x1F106A00 ++#define LTQ_MPS_BASE 0x1F107000 ++#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340) ++#define LTQ_RCU_BASE 0x1F203000 ++ ++#define LTQ_MC_GLOBAL_BASE 0x1F400000 ++#define LTQ_MC_DDR_BASE 0x1F401000 ++#define LTQ_MC_DDR_CCR_OFFSET(x) (x * 0x10) ++ ++#endif /* __VRX200_SOC_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/arch-vrx200/switch.h +@@ -0,0 +1,514 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com> ++ */ ++ ++#ifndef __VR9_SWITCH_H__ ++#define __VR9_SWITCH_H__ ++ ++/* Switch core registers */ ++struct vr9_switch_core_regs { ++ __be32 swres; ++ /* TODO: implement registers */ ++ __be32 rsvd0[0x3f]; ++}; ++ ++/* Switch buffer management registers */ ++struct vr9_switch_bm_regs { ++ struct bm_core { ++ __be32 ram_val3; /* RAM value 3 */ ++ __be32 ram_val2; /* RAM value 2 */ ++ __be32 ram_val1; /* RAM value 1 */ ++ __be32 ram_val0; /* RAM value 0 */ ++ __be32 ram_addr; /* RAM address */ ++ __be32 ram_ctrl; /* RAM access control */ ++ __be32 fsqm_gctrl; /* Free segment queue global control */ ++ __be32 cons_sel; /* Number of consumed segments */ ++ __be32 cons_pkt; /* Number of consumed packet pointers */ ++ __be32 gctrl; /* Global control */ ++ __be32 queue_gctrl; /* Queue manager global control */ ++ /* TODO: implement registers */ ++ __be32 rsvd0[0x35]; ++ } core; ++ ++ struct bm_port { ++ __be32 pcfg; /* Port config */ ++ __be32 rmon_ctrl; /* RMON control */ ++ } port[13]; ++ ++ __be32 rsvd0[0x66]; ++ ++ struct bm_queue { ++ __be32 rsvd0; ++ __be32 pqm_rs; /* Packet queue manager rate shape assignment */ ++ } queue[32]; ++ ++ struct bm_shaper { ++ __be32 ctrl; /* Rate shaper control */ ++ __be32 cbs; /* Rate shaper committed burst size */ ++ __be32 ibs; /* Rate shaper instantaneous burst size */ ++ __be32 cir_ext; /* Rate shaper rate exponent */ ++ __be32 cir_mant; /* Rate shaper rate mantissa */ ++ } shaper[16]; ++ ++ __be32 rsvd1[0x2a8]; ++}; ++ ++/* Switch parser and classification engine registers */ ++struct vr9_switch_pce_regs { ++ struct pce_core { ++ __be32 tbl_key[16]; /* Table key data */ ++ __be32 tbl_mask; /* Table mask */ ++ __be32 tbl_val[5]; /* Table value */ ++ __be32 tbl_addr; /* Table entry address */ ++ __be32 tbl_ctrl; /* Table access control */ ++ __be32 tbl_stat; /* Table general status */ ++ __be32 age_0; /* Aging counter config 0 */ ++ __be32 age_1; /* Aging counter config 1 */ ++ __be32 pmap_1; /* Port map (monitoring) */ ++ __be32 pmap_2; /* Port map (multicast) */ ++ __be32 pmap_3; /* Port map (unknown unicast) */ ++ __be32 gctrl_0; /* Global control 0 */ ++ __be32 gctrl_1; /* Global control 1 */ ++ __be32 tcm_gctrl; /* Three-color marker global control */ ++ __be32 igmp_ctrl; /* IGMP control */ ++ __be32 igmp_drpm; /* IGMP default router port map */ ++ __be32 igmp_age_0; /* IGMP aging 0 */ ++ __be32 igmp_age_1; /* IGMP aging 1 */ ++ __be32 igmp_stat; /* IGMP status */ ++ __be32 wol_gctrl; /* Wake-on-LAN control */ ++ __be32 wol_da_0; /* Wake-on-LAN destination address 0 */ ++ __be32 wol_da_1; /* Wake-on-LAN destination address 1 */ ++ __be32 wol_da_2; /* Wake-on-LAN destination address 2 */ ++ __be32 wol_pw_0; /* Wake-on-LAN password 0 */ ++ __be32 wol_pw_1; /* Wake-on-LAN password 1 */ ++ __be32 wol_pw_2; /* Wake-on-LAN password 2 */ ++ __be32 ier_0; /* PCE global interrupt enable 0 */ ++ __be32 ier_1; /* PCE global interrupt enable 1 */ ++ __be32 isr_0; /* PCE global interrupt status 0 */ ++ __be32 isr_1; /* PCE global interrupt status 1 */ ++ __be32 parser_stat; /* Parser status */ ++ __be32 rsvd0[0x6]; ++ } core; ++ ++ __be32 rsvd0[0x10]; ++ ++ struct pce_port { ++ __be32 pctrl_0; /* Port control 0 */ ++ __be32 pctrl_1; /* Port control 1 */ ++ __be32 pctrl_2; /* Port control 2 */ ++ __be32 pctrl_3; /* Port control 3 */ ++ __be32 wol_ctrl; /* Wake-on-LAN control */ ++ __be32 vlan_ctrl; /* VLAN control */ ++ __be32 def_pvid; /* Default port VID */ ++ __be32 pstat; /* Port status */ ++ __be32 pier; /* Interrupt enable */ ++ __be32 pisr; /* Interrupt status */ ++ } port[13]; ++ ++ __be32 rsvd1[0x7e]; ++ ++ struct pce_meter { ++ /* TODO: implement registers */ ++ __be32 rsvd0[0x7]; ++ } meter[8]; ++ ++ __be32 rsvd2[0x308]; ++}; ++ ++static inline unsigned int to_pce_tbl_key_id(unsigned int id) ++{ ++ BUG_ON(id > 15); ++ ++ return 15 - id; ++} ++ ++static inline unsigned int to_pce_tbl_value_id(unsigned int id) ++{ ++ BUG_ON(id > 4); ++ ++ return 4 - id; ++} ++ ++/* Switch ethernet MAC registers */ ++struct vr9_switch_mac_regs { ++ struct mac_core { ++ __be32 test; /* MAC test */ ++ __be32 pfad_cfg; /* Pause frame source address config */ ++ __be32 pfsa_0; /* Pause frame source address 0 */ ++ __be32 pfsa_1; /* Pause frame source address 1 */ ++ __be32 pfsa_2; /* Pause frame source address 2 */ ++ __be32 flen; /* Frame length */ ++ __be32 vlan_etype_0; /* VLAN ethertype 0 */ ++ __be32 vlan_etype_1; /* VLAN ethertype 1 */ ++ __be32 ier; /* Interrupt enable */ ++ __be32 isr; /* Interrupt status */ ++ __be32 rsvd0[0x36]; ++ } core; ++ ++ struct mac_port { ++ __be32 pstat; /* Port status */ ++ __be32 pisr; /* Interrupt status */ ++ __be32 pier; /* Interrupt enable */ ++ __be32 ctrl_0; /* Control 0 */ ++ __be32 ctrl_1; /* Control 1 */ ++ __be32 ctrl_2; /* Control 2 */ ++ __be32 ctrl_3; /* Control 3 */ ++ __be32 ctrl_4; /* Control 4 */ ++ __be32 ctrl_5; /* Control 5 */ ++ __be32 rsvd0[0x2]; ++ __be32 testen; /* Test enable */ ++ } port[13]; ++ ++ __be32 rsvd0[0xa4]; ++}; ++ ++/* Switch Fetch DMA registers */ ++struct vr9_switch_fdma_regs { ++ struct fdma_core { ++ __be32 ctrl; /* FDMA control */ ++ __be32 stetype; /* Special tag ethertype control */ ++ __be32 vtetype; /* VLAN tag ethertype control */ ++ __be32 stat; /* FDMA status */ ++ __be32 ier; /* FDMA interrupt enable */ ++ __be32 isr; /* FDMA interrupt status */ ++ } core; ++ ++ __be32 rsvd0[0x3a]; ++ ++ struct fdma_port { ++ __be32 pctrl; /* Port control */ ++ __be32 prio; /* Port priority */ ++ __be32 pstat_0; /* Port status 0 */ ++ __be32 pstat_1; /* Port status 1 */ ++ __be32 tstamp_0; /* Egress time stamp 0 */ ++ __be32 tstamp_1; /* Egress time stamp 1 */ ++ } port[13]; ++ ++ __be32 rsvd1[0x72]; ++}; ++ ++/* Switch Store DMA registers */ ++struct vr9_switch_sdma_regs { ++ struct sdma_core { ++ __be32 ctrl; /* SDMA Control */ ++ __be32 fcthr_1; /* Flow control threshold 1 */ ++ __be32 rsvd0; ++ __be32 fcthr_3; /* Flow control threshold 3 */ ++ __be32 fcthr_4; /* Flow control threshold 4 */ ++ __be32 fcthr_5; /* Flow control threshold 5 */ ++ __be32 fcthr_6; /* Flow control threshold 6 */ ++ __be32 fcthr_7; /* Flow control threshold 7 */ ++ __be32 stat_0; /* SDMA status 0 */ ++ __be32 stat_1; /* SDMA status 1 */ ++ __be32 stat_2; /* SDMA status 2 */ ++ __be32 ier; /* SDMA interrupt enable */ ++ __be32 isr; /* SDMA interrupt status */ ++ } core; ++ ++ __be32 rsvd0[0x73]; ++ ++ struct sdma_port { ++ __be32 pctrl; /* Port control */ ++ __be32 prio; /* Port priority */ ++ __be32 pstat_0; /* Port status 0 */ ++ __be32 pstat_1; /* Port status 1 */ ++ __be32 tstamp_0; /* Ingress time stamp 0 */ ++ __be32 tstamp_1; /* Ingress time stamp 1 */ ++ } port[13]; ++ ++ __be32 rsvd1[0x32]; ++}; ++ ++/* Switch MDIO control and status registers */ ++struct vr9_switch_mdio_regs { ++ __be32 glob_ctrl; /* Global control 0 */ ++ __be32 rsvd0[7]; ++ __be32 mdio_ctrl; /* MDIO control */ ++ __be32 mdio_read; /* MDIO read data */ ++ __be32 mdio_write; /* MDIO write data */ ++ __be32 mdc_cfg_0; /* MDC clock configuration 0 */ ++ __be32 mdc_cfg_1; /* MDC clock configuration 1 */ ++ __be32 rsvd1[0x3]; ++ __be32 phy_addr[6]; /* PHY address port 5..0 */ ++ __be32 mdio_stat[6]; /* MDIO PHY polling status port 0..5 */ ++ __be32 aneg_eee[6]; /* EEE auto-neg overrides port 0..5 */ ++ __be32 rsvd2[0x14]; ++}; ++ ++static inline unsigned int to_mdio_phyaddr_id(unsigned int id) ++{ ++ BUG_ON(id > 5); ++ ++ return 5 - id; ++} ++ ++/* Switch xMII control registers */ ++struct vr9_switch_mii_regs { ++ __be32 mii_cfg0; /* xMII port 0 configuration */ ++ __be32 pcdu0; /* Port 0 clock delay configuration */ ++ __be32 mii_cfg1; /* xMII port 1 configuration */ ++ __be32 pcdu1; /* Port 1 clock delay configuration */ ++ __be32 rsvd0[0x6]; ++ __be32 mii_cfg5; /* xMII port 5 configuration */ ++ __be32 pcdu5; /* Port 5 clock delay configuration */ ++ __be32 rsvd1[0x14]; ++ __be32 rxb_ctl_0; /* Port 0 receive buffer control */ ++ __be32 rxb_ctl_1; /* Port 1 receive buffer control */ ++ __be32 rxb_ctl_5; /* Port 5 receive buffer control */ ++ __be32 rsvd2[0x28]; ++ __be32 dbg_ctl; /* Debug control */ ++}; ++ ++/* Switch Pseudo-MAC registers */ ++struct vr9_switch_pmac_regs { ++ __be32 hd_ctl; /* PMAC header control */ ++ __be32 tl; /* PMAC type/length */ ++ __be32 sa1; /* PMAC source address 1 */ ++ __be32 sa2; /* PMAC source address 2 */ ++ __be32 sa3; /* PMAC source address 3 */ ++ __be32 da1; /* PMAC destination address 1 */ ++ __be32 da2; /* PMAC destination address 2 */ ++ __be32 da3; /* PMAC destination address 3 */ ++ __be32 vlan; /* PMAC VLAN */ ++ __be32 rx_ipg; /* PMAC interpacket gap in RX direction */ ++ __be32 st_etype; /* PMAC special tag ethertype */ ++ __be32 ewan; /* PMAC ethernet WAN group */ ++ __be32 ctl; /* PMAC control */ ++ __be32 rsvd0[0x2]; ++}; ++ ++struct vr9_switch_regs { ++ struct vr9_switch_core_regs core; ++ struct vr9_switch_bm_regs bm; ++ struct vr9_switch_pce_regs pce; ++ struct vr9_switch_mac_regs mac; ++ struct vr9_switch_fdma_regs fdma; ++ struct vr9_switch_sdma_regs sdma; ++ struct vr9_switch_mdio_regs mdio; ++ struct vr9_switch_mii_regs mii; ++ struct vr9_switch_pmac_regs pmac; ++}; ++ ++static inline void *to_pce_tbl_key(struct vr9_switch_regs *regs, ++ unsigned int id) ++{ ++ return ®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 +--- a/arch/mips/include/asm/asm.h ++++ b/arch/mips/include/asm/asm.h +@@ -53,6 +53,7 @@ + .align 2; \ + .type symbol, @function; \ + .ent symbol, 0; \ ++ .section .text.symbol,"x"; \ + symbol: .frame sp, 0, ra + + /* +@@ -62,7 +63,8 @@ symbol: .frame sp, 0, ra + .globl symbol; \ + .align 2; \ + .type symbol, @function; \ +- .ent symbol, 0; \ ++ .ent symbol, 0; \ ++ .section .text.symbol,"x"; \ + symbol: .frame sp, framesize, rpc + + /* +--- /dev/null ++++ b/arch/mips/include/asm/gpio.h +@@ -0,0 +1,7 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ */ ++ ++#include <asm/arch/gpio.h> ++#include <asm-generic/gpio.h> +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/chipid.h +@@ -0,0 +1,74 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_CHIPID_H__ ++#define __LANTIQ_CHIPID_H__ ++ ++enum ltq_chip_partnum { ++ LTQ_SOC_UNKNOWN = 0, ++ LTQ_SOC_VRX288_2 = 0x000B, /* VRX288 v1.2 */ ++ LTQ_SOC_VRX268_2 = 0x000C, /* VRX268 v1.2 */ ++ LTQ_SOC_GRX288_2 = 0x000D, /* GRX288 v1.2 */ ++ LTQ_SOC_DANUBE = 0x0129, ++ LTQ_SOC_DANUBE_S = 0x012B, ++ LTQ_SOC_TWINPASS = 0x012D, ++ LTQ_SOC_VRX288 = 0x01C0, /* VRX288 v1.1 */ ++ LTQ_SOC_VRX268 = 0x01C2, /* VRX268 v1.1 */ ++ LTQ_SOC_GRX288 = 0x01C9, /* GRX288 v1.1 */ ++}; ++ ++extern unsigned int ltq_chip_version_get(void); ++extern unsigned int ltq_chip_partnum_get(void); ++extern const char *ltq_chip_partnum_str(void); ++ ++extern void ltq_chip_print_info(void); ++ ++#ifdef CONFIG_SOC_XWAY_DANUBE ++static inline int ltq_soc_is_danube(void) ++{ ++ return 1; ++} ++#else ++static inline int ltq_soc_is_danube(void) ++{ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_SOC_XWAY_VRX200 ++static inline int ltq_soc_is_vrx200(void) ++{ ++ return 1; ++} ++ ++static inline int ltq_soc_is_vrx200_v1(void) ++{ ++ return ltq_chip_version_get() == 1; ++} ++ ++static inline int ltq_soc_is_vrx200_v2(void) ++{ ++ return ltq_chip_version_get() == 2; ++} ++#else ++static inline int ltq_soc_is_vrx200(void) ++{ ++ return 0; ++} ++ ++static inline int ltq_soc_is_vrx200_v1(void) ++{ ++ return 0; ++} ++ ++static inline int ltq_soc_is_vrx200_v2(void) ++{ ++ return 0; ++} ++#endif ++ ++#endif /* __LANTIQ_CHIPID_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/clk.h +@@ -0,0 +1,33 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * Based on Lantiq port in Linux kernel ++ */ ++ ++#ifndef __LANTIQ_CLK_H__ ++#define __LANTIQ_CLK_H__ ++ ++/* Symbolic clock speeds */ ++enum ltq_clk { ++ CLOCK_83_MHZ = 83333333, ++ CLOCK_111_MHZ = 111111111, ++ CLOCK_125_MHZ = 125000000, ++ CLOCK_133_MHZ = 133333333, ++ CLOCK_166_MHZ = 166666667, ++ CLOCK_197_MHZ = 197000000, ++ CLOCK_333_MHZ = 333333333, ++ CLOCK_393_MHZ = 393219000, ++ CLOCK_500_MHZ = 500000000, ++ CLOCK_600_MHZ = 600000000, ++ CLOCK_1000_MHZ = 1000000000, ++}; ++ ++extern unsigned long ltq_get_cpu_clock(void); ++extern unsigned long ltq_get_bus_clock(void); ++extern unsigned long ltq_get_io_region_clock(void); ++ ++#endif /* __LANTIQ_CLK_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/config.h +@@ -0,0 +1,166 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_CONFIG_H__ ++#define __LANTIQ_CONFIG_H__ ++ ++/* Memory usage */ ++#define CONFIG_SYS_MAXARGS 24 ++#define CONFIG_SYS_MALLOC_LEN 1024*1024 ++#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024 ++ ++/* Command line */ ++#define CONFIG_SYS_PROMPT CONFIG_MACH_TYPE " # " ++#define CONFIG_SYS_CBSIZE 512 ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ ++ sizeof(CONFIG_SYS_PROMPT)+16) ++ ++#define CONFIG_SYS_HUSH_PARSER ++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " ++ ++/* ++ * Enable advanced console features on demand to reduce ++ * flash and RAM footprint ++ */ ++#if defined(CONFIG_LTQ_ADVANCED_CONSOLE) ++#define CONFIG_SYS_LONGHELP ++#define CONFIG_AUTO_COMPLETE ++#define CONFIG_CMDLINE_EDITING ++#endif ++ ++/* SPI flash SPL */ ++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL) ++#define CONFIG_SPL ++#define CONFIG_SPL_SPI_SUPPORT ++#define CONFIG_SPL_SPI_FLASH_SUPPORT ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_SPL ++#endif ++ ++/* Common SPL */ ++#if defined(CONFIG_SPL) ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SPL_LIBGENERIC_SUPPORT ++#define CONFIG_SPL_GPIO_SUPPORT ++#define CONFIG_SPL_START_S_PATH \ ++ "arch/mips/cpu/mips32/lantiq-common" ++#define CONFIG_SPL_LDSCRIPT \ ++ "arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds" ++#endif ++ ++#if defined(CONFIG_LTQ_SPL_CONSOLE) ++#define CONFIG_SPL_SERIAL_SUPPORT ++#define CONFIG_SPL_LIBCOMMON_SUPPORT ++#endif ++ ++#if defined(CONFIG_LTQ_SPL_COMP_LZMA) ++#define CONFIG_LZMA ++#define CONFIG_SPL_LZMA_SUPPORT ++#endif ++ ++#if defined(CONFIG_LTQ_SPL_COMP_LZO) ++#define CONFIG_LZO ++#define CONFIG_SPL_LZO_SUPPORT ++#endif ++ ++/* Basic commands */ ++#define CONFIG_CMD_BDI ++#define CONFIG_CMD_EDITENV ++#define CONFIG_CMD_IMI ++#define CONFIG_CMD_MEMORY ++#define CONFIG_CMD_RUN ++#define CONFIG_CMD_SAVEENV ++#define CONFIG_CMD_LOADS ++#define CONFIG_CMD_LOADB ++ ++/* Other U-Boot settings */ ++#define CONFIG_UBOOT_VERSION ++#define CONFIG_TIMESTAMP ++ ++/* Default environment */ ++#define CONFIG_ENV_CONSOLEDEV \ ++ "consoledev=" CONFIG_CONSOLE_DEV "\0" ++ ++#define CONFIG_ENV_ADDCONSOLE \ ++ "addconsole=setenv bootargs $bootargs" \ ++ " console=$consoledev,$baudrate\0" ++ ++#if defined(CONFIG_NET_DEV) ++#define CONFIG_ENV_NETDEV \ ++ "netdev=" CONFIG_NET_DEV "\0" ++#else ++#define CONFIG_ENV_NETDEV \ ++ "netdev=eth0\0" ++#endif ++ ++#define CONFIG_ENV_ADDIP \ ++ "addip=setenv bootargs $bootargs" \ ++ " ip=$ipaddr:$serverip::::$netdev:off\0" ++ ++#define CONFIG_ENV_ADDETH \ ++ "addeth=setenv bootargs $bootargs" \ ++ " ethaddr=$ethaddr\0" ++ ++#define CONFIG_ENV_ADDMACHTYPE \ ++ "addmachtype=setenv bootargs $bootargs" \ ++ " machtype=" CONFIG_MACH_TYPE "\0" ++ ++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) ++#define CONFIG_ENV_WRITE_UBOOT_NOR \ ++ "write-uboot-nor=" \ ++ "protect off " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \ ++ "erase " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \ ++ "cp.b $fileaddr " __stringify(CONFIG_SYS_FLASH_BASE) " $filesize\0" ++ ++#define CONFIG_ENV_LOAD_UBOOT_NOR \ ++ "load-uboot-nor=tftpboot u-boot.bin\0" \ ++ "load-uboot-norspl=tftpboot u-boot.ltq.norspl\0" \ ++ "load-uboot-norspl-lzo=tftpboot u-boot.ltq.lzo.norspl\0" \ ++ "load-uboot-norspl-lzma=tftpboot u-boot.ltq.lzma.norspl\0" ++#else ++#define CONFIG_ENV_WRITE_UBOOT_NOR ++#define CONFIG_ENV_LOAD_UBOOT_NOR ++#endif ++ ++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH) ++#define CONFIG_ENV_SF_PROBE \ ++ "sf-probe=sf probe " __stringify(CONFIG_ENV_SPI_CS) " " \ ++ __stringify(CONFIG_ENV_SPI_MAX_HZ) " " \ ++ __stringify(CONFIG_ENV_SPI_MODE) " \0" ++ ++#define CONFIG_ENV_WRITE_UBOOT_SF \ ++ "write-uboot-sf=" \ ++ "run sf-probe && sf erase 0 +$filesize && " \ ++ "sf write $fileaddr 0 $filesize\0" ++ ++#define CONFIG_ENV_LOAD_UBOOT_SF \ ++ "load-uboot-sfspl=tftpboot u-boot.ltq.sfspl\0" \ ++ "load-uboot-sfspl-lzo=tftpboot u-boot.ltq.lzo.sfspl\0" \ ++ "load-uboot-sfspl-lzma=tftpboot u-boot.ltq.lzma.sfspl\0" ++#else ++#define CONFIG_ENV_SF_PROBE ++#define CONFIG_ENV_WRITE_UBOOT_SF ++#define CONFIG_ENV_LOAD_UBOOT_SF ++#endif ++ ++#define CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_CONSOLEDEV \ ++ CONFIG_ENV_ADDCONSOLE \ ++ CONFIG_ENV_NETDEV \ ++ CONFIG_ENV_ADDIP \ ++ CONFIG_ENV_ADDETH \ ++ CONFIG_ENV_ADDMACHTYPE \ ++ CONFIG_ENV_WRITE_UBOOT_NOR \ ++ CONFIG_ENV_LOAD_UBOOT_NOR \ ++ CONFIG_ENV_SF_PROBE \ ++ CONFIG_ENV_WRITE_UBOOT_SF \ ++ CONFIG_ENV_LOAD_UBOOT_SF ++ ++#endif /* __LANTIQ_CONFIG_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/cpu.h +@@ -0,0 +1,35 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#ifndef __LANTIQ_CPU_H__ ++#define __LANTIQ_CPU_H__ ++ ++enum ltq_boot_select { ++ BOOT_NOR, ++ BOOT_NOR_NO_BOOTROM, ++ BOOT_UART, ++ BOOT_UART_NO_EEPROM, ++ BOOT_SPI, ++ BOOT_NAND, ++ BOOT_PCI, ++ BOOT_MII0, ++ BOOT_RMII0, ++ BOOT_RGMII1, ++ BOOT_UNKNOWN, ++}; ++ ++enum ltq_boot_select ltq_boot_select(void); ++const char *ltq_boot_select_str(void); ++ ++void ltq_pmu_init(void); ++void ltq_ebu_init(void); ++void ltq_gpio_init(void); ++ ++void ltq_pll_init(void); ++void ltq_dcdc_init(unsigned int dig_ref); ++ ++#endif /* __LANTIQ_CPU_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/dma.h +@@ -0,0 +1,95 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_DMA_H__ ++#define __LANTIQ_DMA_H__ ++ ++enum ltq_dma_endianess { ++ LTQ_DMA_ENDIANESS_B0_B1_B2_B3, /* No byte swapping */ ++ LTQ_DMA_ENDIANESS_B1_B0_B3_B2, /* B0B1B2B3 => B1B0B3B2 */ ++ LTQ_DMA_ENDIANESS_B2_B3_B0_B1, /* B0B1B2B3 => B2B3B0B1 */ ++ LTQ_DMA_ENDIANESS_B3_B2_B1_B0, /* B0B1B2B3 => B3B2B1B0 */ ++}; ++ ++enum ltq_dma_burst_len { ++ LTQ_DMA_BURST_2WORDS = 1, ++ LTQ_DMA_BURST_4WORDS = 2, ++ LTQ_DMA_BURST_8WORDS = 3, ++}; ++ ++struct ltq_dma_desc { ++ u32 ctl; ++ u32 addr; ++}; ++ ++struct ltq_dma_channel { ++ struct ltq_dma_device *dev; ++ u8 chan_no; ++ u8 class; ++ u16 num_desc; ++ struct ltq_dma_desc *desc_base; ++ void *mem_base; ++ u32 dma_addr; ++}; ++ ++struct ltq_dma_device { ++ enum ltq_dma_endianess rx_endian_swap; ++ enum ltq_dma_endianess tx_endian_swap; ++ enum ltq_dma_burst_len rx_burst_len; ++ enum ltq_dma_burst_len tx_burst_len; ++ struct ltq_dma_channel rx_chan; ++ struct ltq_dma_channel tx_chan; ++ u8 port; ++}; ++ ++/** ++ * Initialize DMA hardware and driver ++ */ ++void ltq_dma_init(void); ++ ++/** ++ * Register given DMA client context ++ * ++ * @returns 0 on success, negative value otherwise ++ */ ++int ltq_dma_register(struct ltq_dma_device *dev); ++ ++/** ++ * Reset and halt all channels related to given DMA client ++ */ ++void ltq_dma_reset(struct ltq_dma_device *dev); ++void ltq_dma_enable(struct ltq_dma_device *dev); ++void ltq_dma_disable(struct ltq_dma_device *dev); ++ ++/** ++ * Map RX DMA descriptor to memory region ++ * ++ * @returns 0 on success, negative value otherwise ++ */ ++int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len); ++ ++/** ++ * Check if new data is available. ++ * ++ * @returns length of received data, 0 otherwise ++ */ ++int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index); ++ ++int ltq_dma_rx_length(struct ltq_dma_device *dev, int index); ++ ++/** ++ * Map TX DMA descriptor to memory region ++ * ++ * @returns 0 on success, negative value otherwise ++ */ ++int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len, ++ unsigned long timeout); ++ ++int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index, ++ unsigned long timeout); ++ ++#endif /* __LANTIQ_DMA_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/eth.h +@@ -0,0 +1,36 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_ETH_H__ ++#define __LANTIQ_ETH_H__ ++ ++#include <phy.h> ++ ++enum LTQ_ETH_PORT_FLAGS { ++ LTQ_ETH_PORT_NONE = 0, ++ LTQ_ETH_PORT_PHY = 1, ++ LTQ_ETH_PORT_SWITCH = (1 << 1), ++ LTQ_ETH_PORT_MAC = (1 << 2), ++}; ++ ++struct ltq_eth_port_config { ++ u8 num; ++ u8 phy_addr; ++ u16 flags; ++ phy_interface_t phy_if; ++ u8 rgmii_rx_delay; ++ u8 rgmii_tx_delay; ++}; ++ ++struct ltq_eth_board_config { ++ const struct ltq_eth_port_config *ports; ++ int num_ports; ++}; ++ ++extern int ltq_eth_initialize(const struct ltq_eth_board_config *board_config); ++ ++#endif /* __LANTIQ_ETH_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/gpio.h +@@ -0,0 +1,51 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_GPIO_H__ ++#define __LANTIQ_GPIO_H__ ++ ++enum ltq_gpio_dir { ++ GPIO_DIR_IN = 0, ++ GPIO_DIR_OUT ++}; ++ ++enum ltq_gpio_od { ++ GPIO_OD_ACTIVE = 0, ++ GPIO_OD_NORMAL ++}; ++ ++enum ltq_gpio_altsel { ++ GPIO_ALTSEL_CLR = 0, ++ GPIO_ALTSEL_SET ++}; ++ ++extern int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir); ++extern int gpio_set_opendrain(unsigned gpio, int od); ++ ++static inline int gpio_to_port(unsigned gpio) ++{ ++ return gpio >> 4; ++} ++ ++static inline int gpio_to_pin(unsigned gpio) ++{ ++ return gpio & 0xF; ++} ++ ++static inline int gpio_to_bit(unsigned gpio) ++{ ++ return 1 << gpio_to_pin(gpio); ++} ++ ++static inline int gpio_to_gpio(unsigned port, unsigned pin) ++{ ++ return (port << 4) | (pin & 0xF); ++} ++ ++#include <asm-generic/gpio.h> ++ ++#endif /* __LANTIQ_GPIO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/io.h +@@ -0,0 +1,38 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 John Crispin <blogic@openwrt.org> ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_IO_H__ ++#define __LANTIQ_IO_H__ ++ ++#include <asm/io.h> ++ ++#define ltq_readb(a) __raw_readb(a) ++#define ltq_writeb(a, v) __raw_writeb(v, a) ++ ++#define ltq_readl(a) __raw_readl(a) ++#define ltq_writel(a, v) __raw_writel(v, a) ++ ++#define ltq_clrbits(a, clear) \ ++ ltq_writel(a, ltq_readl(a) & ~(clear)) ++ ++#define ltq_setbits(a, set) \ ++ ltq_writel(a, ltq_readl(a) | (set)) ++ ++#define ltq_clrsetbits(a, clear, set) \ ++ ltq_writel(a, (ltq_readl(a) & ~(clear)) | (set)) ++ ++static inline void ltq_reg_dump(const void *addr, const char *desc) ++{ ++ u32 data; ++ ++ data = ltq_readl(addr); ++ printf("ltq_reg_dump: %s 0x%p = 0x%08x\n", ++ desc, addr, data); ++} ++ ++#endif /* __LANTIQ_IO_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/pm.h +@@ -0,0 +1,22 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_PM_H__ ++#define __LANTIQ_PM_H__ ++ ++enum ltq_pm_modules { ++ LTQ_PM_CORE, ++ LTQ_PM_DMA, ++ LTQ_PM_ETH, ++ LTQ_PM_SPI, ++}; ++ ++u32 ltq_pm_map(enum ltq_pm_modules module); ++int ltq_pm_enable(enum ltq_pm_modules module); ++int ltq_pm_disable(enum ltq_pm_modules module); ++ ++#endif /* __LANTIQ_PM_H__ */ +--- /dev/null ++++ b/arch/mips/include/asm/lantiq/reset.h +@@ -0,0 +1,38 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __LANTIQ_RESET_H__ ++#define __LANTIQ_RESET_H__ ++ ++enum ltq_reset_modules { ++ LTQ_RESET_CORE, ++ LTQ_RESET_DMA, ++ LTQ_RESET_ETH, ++ LTQ_RESET_PHY, ++ LTQ_RESET_HARD, ++ LTQ_RESET_SOFT, ++}; ++ ++extern u32 ltq_reset_map(enum ltq_reset_modules module); ++extern int ltq_reset_activate(enum ltq_reset_modules module); ++extern int ltq_reset_deactivate(enum ltq_reset_modules module); ++ ++static inline int ltq_reset_once(enum ltq_reset_modules module, ulong usec) ++{ ++ int ret; ++ ++ ret = ltq_reset_activate(module); ++ if (ret) ++ return ret; ++ ++ __udelay(usec); ++ ret = ltq_reset_deactivate(module); ++ ++ return ret; ++} ++ ++#endif /* __LANTIQ_RESET_H__ */ +--- a/arch/mips/include/asm/mipsregs.h ++++ b/arch/mips/include/asm/mipsregs.h +@@ -46,7 +46,10 @@ + #define CP0_ENTRYLO1 $3 + #define CP0_CONF $3 + #define CP0_CONTEXT $4 ++#define CP0_CONTEXTCONFIG $4,1 ++#define CP0_USERLOCAL $4,1 + #define CP0_PAGEMASK $5 ++#define CP0_PAGEGRAIN $5,1 + #define CP0_WIRED $6 + #define CP0_INFO $7 + #define CP0_BADVADDR $8 +@@ -54,10 +57,19 @@ + #define CP0_ENTRYHI $10 + #define CP0_COMPARE $11 + #define CP0_STATUS $12 ++#define CP0_INTCTL $12,1 ++#define CP0_SRSCTL $12,2 ++#define CP0_SRSMAP $12,3 ++#define CP0_SRSHIGH $12,4 + #define CP0_CAUSE $13 + #define CP0_EPC $14 + #define CP0_PRID $15 ++#define CP0_EBASE $15,1 + #define CP0_CONFIG $16 ++#define CP0_CONFIG1 $16,1 ++#define CP0_CONFIG2 $16,2 ++#define CP0_CONFIG3 $16,3 ++#define CP0_CONFIG7 $16,7 + #define CP0_LLADDR $17 + #define CP0_WATCHLO $18 + #define CP0_WATCHHI $19 +@@ -70,7 +82,17 @@ + #define CP0_ECC $26 + #define CP0_CACHEERR $27 + #define CP0_TAGLO $28 ++#define CP0_ITAGLO $28 ++#define CP0_IDATALO $28,1 ++#define CP0_DTAGLO $28,2 ++#define CP0_DDATALO $28,3 ++#define CP0_L23TAGLO $28,4 ++#define CP0_L23DATALO $28,5 + #define CP0_TAGHI $29 ++#define CP0_IDATAHI $29,1 ++#define CP0_DTAGHI $29,2 ++#define CP0_L23TAGHI $29,4 ++#define CP0_L23DATAHI $29,5 + #define CP0_ERROREPC $30 + #define CP0_DESAVE $31 + +@@ -395,6 +417,12 @@ + #define CAUSEF_BD (_ULCAST_(1) << 31) + + /* ++ * Bits in the coprocessor 0 EBase register. ++ */ ++#define EBASEB_CPUNUM 0 ++#define EBASEF_CPUNUM (_ULCAST_(1023)) ++ ++/* + * Bits in the coprocessor 0 config register. + */ + /* Generic bits. */ +--- a/arch/mips/include/asm/u-boot-mips.h ++++ b/arch/mips/include/asm/u-boot-mips.h +@@ -9,3 +9,4 @@ extern ulong uboot_end_data; + extern ulong uboot_end; + + extern int incaip_set_cpuclk(void); ++extern int arch_cpu_init(void); +--- a/arch/mips/lib/board.c ++++ b/arch/mips/lib/board.c +@@ -50,6 +50,16 @@ static char *failed = "*** failed ***\n" + */ + const unsigned long mips_io_port_base = -1; + ++int __arch_cpu_init(void) ++{ ++ /* ++ * Nothing to do in this dummy implementation ++ */ ++ return 0; ++} ++int arch_cpu_init(void) ++ __attribute__((weak, alias("__arch_cpu_init"))); ++ + int __board_early_init_f(void) + { + /* +@@ -123,6 +133,7 @@ static int init_baudrate(void) + typedef int (init_fnc_t)(void); + + init_fnc_t *init_sequence[] = { ++ arch_cpu_init, + board_early_init_f, + timer_init, + env_init, /* initialize environment */ +--- /dev/null ++++ b/board/lantiq/easy50712/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/lantiq/easy50712/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/lantiq/easy50712/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define MC_DC00_VALUE 0x1B1B ++#define MC_DC01_VALUE 0x0 ++#define MC_DC02_VALUE 0x0 ++#define MC_DC03_VALUE 0x0 ++#define MC_DC04_VALUE 0x0 ++#define MC_DC05_VALUE 0x200 ++#define MC_DC06_VALUE 0x605 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x102 ++#define MC_DC09_VALUE 0x70a ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xc02 ++#define MC_DC12_VALUE 0x1C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x13c ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xd ++#define MC_DC18_VALUE 0x300 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0xd00 ++#define MC_DC22_VALUE 0xd0d ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x62 ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x510 ++#define MC_DC29_VALUE 0x2d89 ++#define MC_DC30_VALUE 0x8300 ++#define MC_DC31_VALUE 0x0 ++#define MC_DC32_VALUE 0x0 ++#define MC_DC33_VALUE 0x0 ++#define MC_DC34_VALUE 0x0 ++#define MC_DC35_VALUE 0x0 ++#define MC_DC36_VALUE 0x0 ++#define MC_DC37_VALUE 0x0 ++#define MC_DC38_VALUE 0x0 ++#define MC_DC39_VALUE 0x0 ++#define MC_DC40_VALUE 0x0 ++#define MC_DC41_VALUE 0x0 ++#define MC_DC42_VALUE 0x0 ++#define MC_DC43_VALUE 0x0 ++#define MC_DC44_VALUE 0x0 ++#define MC_DC45_VALUE 0x500 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/lantiq/easy50712/easy50712.c +@@ -0,0 +1,106 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <switch.h> ++#include <spi.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/chipid.h> ++ ++static void gpio_init(void) ++{ ++ /* SPI/CS output (low-active) for serial flash */ ++ gpio_direction_output(22, 1); ++ ++ /* enable CLK_OUT2 for external switch */ ++ gpio_set_altfunc(3, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++} ++ ++int board_early_init_f(void) ++{ ++ gpio_init(); ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* MAC0: Lantiq ADM6996I switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t *bis) ++{ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++static struct switch_device adm6996i_dev = { ++ .name = "adm6996i", ++ .cpu_port = 5, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ /* Deactivate HRST line to release reset of ADM6996I switch */ ++ ltq_reset_once(LTQ_RESET_HARD, 200000); ++ ++ /* ADM6996I needs some time to come out of reset */ ++ __udelay(50000); ++ ++ return switch_device_register(&adm6996i_dev); ++} ++ ++int spi_cs_is_valid(unsigned int bus, unsigned int cs) ++{ ++ if (bus) ++ return 0; ++ ++ switch (cs) { ++ case 2: ++ return 1; ++ default: ++ return 0; ++ } ++} ++ ++void spi_cs_activate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 2: ++ gpio_set_value(22, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++void spi_cs_deactivate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 2: ++ gpio_set_value(22, 1); ++ break; ++ default: ++ break; ++ } ++} +--- /dev/null ++++ b/board/lantiq/easy80920/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/lantiq/easy80920/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/lantiq/easy80920/ddr_settings.h +@@ -0,0 +1,70 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define MC_CCR00_VALUE 0x101 ++#define MC_CCR01_VALUE 0x1000100 ++#define MC_CCR02_VALUE 0x1010000 ++#define MC_CCR03_VALUE 0x101 ++#define MC_CCR04_VALUE 0x1000000 ++#define MC_CCR05_VALUE 0x1000101 ++#define MC_CCR06_VALUE 0x1000100 ++#define MC_CCR07_VALUE 0x1010000 ++#define MC_CCR08_VALUE 0x1000101 ++#define MC_CCR09_VALUE 0x0 ++#define MC_CCR10_VALUE 0x2000100 ++#define MC_CCR11_VALUE 0x2000300 ++#define MC_CCR12_VALUE 0x30000 ++#define MC_CCR13_VALUE 0x202 ++#define MC_CCR14_VALUE 0x7080A0F ++#define MC_CCR15_VALUE 0x2040F ++#define MC_CCR16_VALUE 0x40000 ++#define MC_CCR17_VALUE 0x70102 ++#define MC_CCR18_VALUE 0x4020002 ++#define MC_CCR19_VALUE 0x30302 ++#define MC_CCR20_VALUE 0x8000700 ++#define MC_CCR21_VALUE 0x40F020A ++#define MC_CCR22_VALUE 0x0 ++#define MC_CCR23_VALUE 0xC020000 ++#define MC_CCR24_VALUE 0x4401B04 ++#define MC_CCR25_VALUE 0x0 ++#define MC_CCR26_VALUE 0x0 ++#define MC_CCR27_VALUE 0x6420000 ++#define MC_CCR28_VALUE 0x0 ++#define MC_CCR29_VALUE 0x0 ++#define MC_CCR30_VALUE 0x798 ++#define MC_CCR31_VALUE 0x0 ++#define MC_CCR32_VALUE 0x0 ++#define MC_CCR33_VALUE 0x650000 ++#define MC_CCR34_VALUE 0x200C8 ++#define MC_CCR35_VALUE 0x1D445D ++#define MC_CCR36_VALUE 0xC8 ++#define MC_CCR37_VALUE 0xC351 ++#define MC_CCR38_VALUE 0x0 ++#define MC_CCR39_VALUE 0x141F04 ++#define MC_CCR40_VALUE 0x142704 ++#define MC_CCR41_VALUE 0x141b42 ++#define MC_CCR42_VALUE 0x141b42 ++#define MC_CCR43_VALUE 0x566504 ++#define MC_CCR44_VALUE 0x566504 ++#define MC_CCR45_VALUE 0x565F17 ++#define MC_CCR46_VALUE 0x565F17 ++#define MC_CCR47_VALUE 0x0 ++#define MC_CCR48_VALUE 0x0 ++#define MC_CCR49_VALUE 0x0 ++#define MC_CCR50_VALUE 0x0 ++#define MC_CCR51_VALUE 0x0 ++#define MC_CCR52_VALUE 0x133 ++#define MC_CCR53_VALUE 0xF3014B27 ++#define MC_CCR54_VALUE 0xF3014B27 ++#define MC_CCR55_VALUE 0xF3014B27 ++#define MC_CCR56_VALUE 0xF3014B27 ++#define MC_CCR57_VALUE 0x7800301 ++#define MC_CCR58_VALUE 0x7800301 ++#define MC_CCR59_VALUE 0x7800301 ++#define MC_CCR60_VALUE 0x7800301 ++#define MC_CCR61_VALUE 0x4 +--- /dev/null ++++ b/board/lantiq/easy80920/easy80920.c +@@ -0,0 +1,139 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <spi.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/lantiq/cpu.h> ++#include <asm/arch/gphy.h> ++ ++#if defined(CONFIG_SPL_BUILD) ++#define do_gpio_init 1 ++#define do_pll_init 1 ++#define do_dcdc_init 0 ++#elif defined(CONFIG_SYS_BOOT_RAM) ++#define do_gpio_init 1 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#elif defined(CONFIG_SYS_BOOT_NOR) ++#define do_gpio_init 1 ++#define do_pll_init 1 ++#define do_dcdc_init 1 ++#else ++#define do_gpio_init 0 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#endif ++ ++static void gpio_init(void) ++{ ++ /* SPI CS 0.4 to serial flash */ ++ gpio_direction_output(10, 1); ++ ++ /* EBU.FL_CS1 as output for NAND CE */ ++ gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* EBU.FL_A23 as output for NAND CLE */ ++ gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* EBU.FL_A24 as output for NAND ALE */ ++ gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* GPIO 3.0 as input for NAND Ready Busy */ ++ gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN); ++ /* GPIO 3.1 as output for NAND Read */ ++ gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++} ++ ++int board_early_init_f(void) ++{ ++ if (do_gpio_init) ++ gpio_init(); ++ ++ if (do_pll_init) ++ ltq_pll_init(); ++ ++ if (do_dcdc_init) ++ ltq_dcdc_init(0x7F); ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */ ++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */ ++ { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */ ++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC3: unused */ ++ { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE }, ++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */ ++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */ ++ { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t * bis) ++{ ++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0; ++ const ulong fw_addr = 0x80FF0000; ++ ++ ltq_gphy_phy11g_a1x_load(fw_addr); ++ ++ ltq_cgu_gphy_clk_src(clk); ++ ++ ltq_rcu_gphy_boot(0, fw_addr); ++ ltq_rcu_gphy_boot(1, fw_addr); ++ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++int spi_cs_is_valid(unsigned int bus, unsigned int cs) ++{ ++ if (bus) ++ return 0; ++ ++ if (cs == 4) ++ return 1; ++ ++ return 0; ++} ++ ++void spi_cs_activate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 4: ++ gpio_set_value(10, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++void spi_cs_deactivate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 4: ++ gpio_set_value(10, 1); ++ break; ++ default: ++ break; ++ } ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -444,10 +444,17 @@ dbau1500 mips + dbau1550 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550 + dbau1550_el mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN + pb1000 mips mips32 pb1x00 - au1x00 pb1x00:PB1000 ++easy50712_nor mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NOR ++easy50712_norspl mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NORSPL ++easy50712_ram mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_RAM + incaip mips mips32 incaip - incaip + incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000 + incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000 + incaip_150MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=150000000 ++easy80920_nor mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NOR ++easy80920_norspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NORSPL ++easy80920_ram mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_RAM ++easy80920_sfspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_SFSPL + qi_lb60 mips xburst qi_lb60 qi + adp-ag101 nds32 n1213 adp-ag101 AndesTech ag101 + adp-ag101p nds32 n1213 adp-ag101p AndesTech ag101 +--- a/drivers/dma/Makefile ++++ b/drivers/dma/Makefile +@@ -28,6 +28,7 @@ LIB := $(obj)libdma.o + COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o + COBJS-$(CONFIG_APBH_DMA) += apbh_dma.o + COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o ++COBJS-$(CONFIG_LANTIQ_DMA) += lantiq_dma.o + COBJS-$(CONFIG_OMAP3_DMA) += omap3_dma.o + + COBJS := $(COBJS-y) +--- /dev/null ++++ b/drivers/dma/lantiq_dma.c +@@ -0,0 +1,388 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <watchdog.h> ++#include <linux/compiler.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/dma.h> ++#include <asm/lantiq/pm.h> ++#include <asm/lantiq/reset.h> ++#include <asm/arch/soc.h> ++#include <asm/processor.h> ++ ++#define DMA_CTRL_PKTARB (1 << 31) ++#define DMA_CTRL_MBRSTARB (1 << 30) ++#define DMA_CTRL_MBRSTCNT_SHIFT 16 ++#define DMA_CTRL_MBRSTCNT_MASK (0x3ff << DMA_CTRL_MBRSTCNT_SHIFT) ++#define DMA_CTRL_DRB (1 << 8) ++#define DMA_CTRL_RESET (1 << 0) ++ ++#define DMA_CPOLL_EN (1 << 31) ++#define DMA_CPOLL_CNT_SHIFT 4 ++#define DMA_CPOLL_CNT_MASK (0xFFF << DMA_CPOLL_CNT_SHIFT) ++ ++#define DMA_CCTRL_TXWGT_SHIFT 16 ++#define DMA_CCTRL_TXWGT_MASK (0x3 << DMA_CCTRL_TXWGT_SHIFT) ++#define DMA_CCTRL_CLASS_SHIFT 9 ++#define DMA_CCTRL_CLASS_MASK (0x3 << DMA_CCTRL_CLASS_SHIFT) ++#define DMA_CCTRL_RST (1 << 1) ++#define DMA_CCTRL_ONOFF (1 << 0) ++ ++#define DMA_PCTRL_TXBL_SHIFT 4 ++#define DMA_PCTRL_TXBL_2WORDS (1 << DMA_PCTRL_TXBL_SHIFT) ++#define DMA_PCTRL_TXBL_4WORDS (2 << DMA_PCTRL_TXBL_SHIFT) ++#define DMA_PCTRL_TXBL_8WORDS (3 << DMA_PCTRL_TXBL_SHIFT) ++#define DMA_PCTRL_RXBL_SHIFT 2 ++#define DMA_PCTRL_RXBL_2WORDS (1 << DMA_PCTRL_RXBL_SHIFT) ++#define DMA_PCTRL_RXBL_4WORDS (2 << DMA_PCTRL_RXBL_SHIFT) ++#define DMA_PCTRL_RXBL_8WORDS (3 << DMA_PCTRL_RXBL_SHIFT) ++#define DMA_PCTRL_TXENDI_SHIFT 10 ++#define DMA_PCTRL_TXENDI_MASK (0x3 << DMA_PCTRL_TXENDI_SHIFT) ++#define DMA_PCTRL_RXENDI_SHIFT 8 ++#define DMA_PCTRL_RXENDI_MASK (0x3 << DMA_PCTRL_RXENDI_SHIFT) ++ ++#define DMA_DESC_OWN (1 << 31) ++#define DMA_DESC_C (1 << 30) ++#define DMA_DESC_SOP (1 << 29) ++#define DMA_DESC_EOP (1 << 28) ++#define DMA_DESC_TX_OFFSET(x) ((x & 0x1f) << 23) ++#define DMA_DESC_RX_OFFSET(x) ((x & 0x3) << 23) ++#define DMA_DESC_LENGTH(x) (x & 0xffff) ++ ++#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) ++ ++struct ltq_dma_regs { ++ u32 clc; /* Clock control */ ++ u32 rsvd0; ++ u32 id; /* Identification */ ++ u32 rsvd1; ++ u32 ctrl; /* Control */ ++ u32 cpoll; /* Channel polling */ ++ u32 cs; /* Channel select */ ++ u32 cctrl; /* Channel control */ ++ u32 cdba; /* Channel descriptor base address */ ++ u32 cdlen; /* Channel descriptor length */ ++ u32 cis; /* Channel interrupt status */ ++ u32 cie; /* Channel interrupt enable */ ++ u32 cgbl; /* Channel global buffer length */ ++ u32 cdptnrd; /* Current descriptor pointer */ ++ u32 rsvd2[2]; ++ u32 ps; /* Port select */ ++ u32 pctrl; /* Port control */ ++ u32 rsvd3[43]; ++ u32 irnen; /* Interrupt node enable */ ++ u32 irncr; /* Interrupt node control */ ++ u32 irnicr; /* Interrupt capture */ ++}; ++ ++static struct ltq_dma_regs *ltq_dma_regs = ++ (struct ltq_dma_regs *) CKSEG1ADDR(LTQ_DMA_BASE); ++ ++static inline unsigned long ltq_dma_addr_to_virt(u32 dma_addr) ++{ ++ return KSEG0ADDR(dma_addr); ++} ++ ++static inline u32 ltq_virt_to_dma_addr(void *addr) ++{ ++ return CPHYSADDR(addr); ++} ++ ++static inline int ltq_dma_burst_align(enum ltq_dma_burst_len burst_len) ++{ ++ switch (burst_len) { ++ case LTQ_DMA_BURST_2WORDS: ++ return 2 * 4; ++ case LTQ_DMA_BURST_4WORDS: ++ return 4 * 4; ++ case LTQ_DMA_BURST_8WORDS: ++ return 8 * 4; ++ } ++ ++ return 0; ++} ++ ++static inline void ltq_dma_sync(void) ++{ ++ __asm__ __volatile__("sync"); ++} ++ ++static inline void ltq_dma_dcache_wb_inv(const void *ptr, size_t size) ++{ ++ unsigned long addr = (unsigned long) ptr; ++ ++ flush_dcache_range(addr, addr + size); ++ ltq_dma_sync(); ++} ++ ++static inline void ltq_dma_dcache_inv(const void *ptr, size_t size) ++{ ++ unsigned long addr = (unsigned long) ptr; ++ ++ invalidate_dcache_range(addr, addr + size); ++} ++ ++void ltq_dma_init(void) ++{ ++ /* Power up DMA */ ++ ltq_pm_enable(LTQ_PM_DMA); ++ ++ /* Reset DMA */ ++ ltq_setbits(<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 +@@ -28,6 +28,7 @@ LIB := $(obj)libgpio.o + COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o + COBJS-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o + COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o ++COBJS-$(CONFIG_LANTIQ_GPIO) += lantiq_gpio.o + COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o + COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o + COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o +--- /dev/null ++++ b/drivers/gpio/lantiq_gpio.c +@@ -0,0 +1,330 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/gpio.h> ++#include <asm/lantiq/io.h> ++ ++#define SSIO_GPIO_BASE 64 ++ ++#define SSIO_CON0_SWU (1 << 31) ++#define SSIO_CON0_RZFL (1 << 26) ++#define SSIO_CON0_GPHY1_SHIFT 27 ++#define SSIO_CON0_GPHY1_CONFIG ((CONFIG_LTQ_SSIO_GPHY1_MODE & 0x7) << 27) ++ ++#define SSIO_CON1_US_FPI (2 << 30) ++#define SSIO_CON1_FPID_2HZ (0 << 23) ++#define SSIO_CON1_FPID_4HZ (1 << 23) ++#define SSIO_CON1_FPID_8HZ (2 << 23) ++#define SSIO_CON1_FPID_10HZ (3 << 23) ++#define SSIO_CON1_FPIS_1_2 (1 << 20) ++#define SSIO_CON1_FPIS_1_32 (2 << 20) ++#define SSIO_CON1_FPIS_1_64 (3 << 20) ++ ++#define SSIO_CON1_GPHY2_SHIFT 15 ++#define SSIO_CON1_GPHY2_CONFIG ((CONFIG_LTQ_SSIO_GPHY2_MODE & 0x7) << 15) ++ ++#define SSIO_CON1_GROUP2 (1 << 2) ++#define SSIO_CON1_GROUP1 (1 << 1) ++#define SSIO_CON1_GROUP0 (1 << 0) ++#define SSIO_CON1_GROUP_CONFIG (0x3) ++ ++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS ++#define enable_ssio 1 ++#else ++#define enable_ssio 0 ++ ++#define CONFIG_LTQ_SSIO_GPHY1_MODE 0 ++#define CONFIG_LTQ_SSIO_GPHY2_MODE 0 ++#define CONFIG_LTQ_SSIO_INIT_VALUE 0 ++#endif ++ ++#ifdef CONFIG_LTQ_SSIO_EDGE_FALLING ++#define SSIO_RZFL_CONFIG SSIO_CON0_RZFL ++#else ++#define SSIO_RZFL_CONFIG 0 ++#endif ++ ++struct ltq_gpio_port_regs { ++ __be32 out; ++ __be32 in; ++ __be32 dir; ++ __be32 altsel0; ++ __be32 altsel1; ++ __be32 od; ++ __be32 stoff; ++ __be32 pudsel; ++ __be32 puden; ++ __be32 rsvd1[3]; ++}; ++ ++struct ltq_gpio_regs { ++ u32 rsvd[4]; ++ struct ltq_gpio_port_regs ports[CONFIG_LTQ_GPIO_MAX_BANKS]; ++}; ++ ++struct ltq_gpio3_regs { ++ u32 rsvd0[13]; ++ __be32 od; ++ __be32 pudsel; ++ __be32 puden; ++ u32 rsvd1[9]; ++ __be32 altsel1; ++ u32 rsvd2[14]; ++ __be32 out; ++ __be32 in; ++ __be32 dir; ++ __be32 altsel0; ++}; ++ ++struct ltq_ssio_regs { ++ __be32 con0; ++ __be32 con1; ++ __be32 cpu0; ++ __be32 cpu1; ++ __be32 ar; ++}; ++ ++static struct ltq_gpio_regs *ltq_gpio_regs = ++ (struct ltq_gpio_regs *) CKSEG1ADDR(LTQ_GPIO_BASE); ++ ++static struct ltq_gpio3_regs *ltq_gpio3_regs = ++ (struct ltq_gpio3_regs *) CKSEG1ADDR(LTQ_GPIO_BASE); ++ ++static struct ltq_ssio_regs *ltq_ssio_regs = ++ (struct ltq_ssio_regs *) CKSEG1ADDR(LTQ_SSIO_BASE); ++ ++static int is_gpio_bank3(unsigned int port) ++{ ++#ifdef CONFIG_LTQ_HAS_GPIO_BANK3 ++ return port == 3; ++#else ++ return 0; ++#endif ++} ++ ++static int is_gpio_ssio(unsigned int gpio) ++{ ++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS ++ return gpio >= SSIO_GPIO_BASE; ++#else ++ return 0; ++#endif ++} ++ ++static inline int ssio_gpio_to_bit(unsigned gpio) ++{ ++ return 1 << (gpio - SSIO_GPIO_BASE); ++} ++ ++int ltq_gpio_init(void) ++{ ++ ltq_writel(<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 +@@ -177,6 +177,18 @@ u64 flash_read64(void *addr)__attribute_ + #define flash_read64 __flash_read64 + #endif + ++static inline void *__flash_swap_addr(unsigned long addr) ++{ ++ return (void *) addr; ++} ++ ++#ifdef CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP ++void *flash_swap_addr(unsigned long addr) ++ __attribute__((weak, alias("__flash_swap_addr"))); ++#else ++#define flash_swap_addr __flash_swap_addr ++#endif ++ + /*----------------------------------------------------------------------- + */ + #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) +@@ -212,7 +224,7 @@ flash_map (flash_info_t * info, flash_se + { + unsigned int byte_offset = offset * info->portwidth; + +- return (void *)(info->start[sect] + byte_offset); ++ return flash_swap_addr(info->start[sect] + byte_offset); + } + + static inline void flash_unmap(flash_info_t *info, flash_sect_t sect, +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -67,6 +67,7 @@ COBJS-$(CONFIG_NAND_JZ4740) += jz4740_na + COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o + COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o + COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o ++COBJS-$(CONFIG_NAND_LANTIQ) += lantiq_nand.o + COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o + COBJS-$(CONFIG_NAND_MXC) += mxc_nand.o + COBJS-$(CONFIG_NAND_MXS) += mxs_nand.o +--- /dev/null ++++ b/drivers/mtd/nand/lantiq_nand.c +@@ -0,0 +1,127 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ */ ++ ++#include <common.h> ++#include <linux/mtd/nand.h> ++#include <linux/compiler.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/nand.h> ++#include <asm/lantiq/io.h> ++ ++#define NAND_CON_ECC_ON (1 << 31) ++#define NAND_CON_LATCH_PRE (1 << 23) ++#define NAND_CON_LATCH_WP (1 << 22) ++#define NAND_CON_LATCH_SE (1 << 21) ++#define NAND_CON_LATCH_CS (1 << 20) ++#define NAND_CON_LATCH_CLE (1 << 19) ++#define NAND_CON_LATCH_ALE (1 << 18) ++#define NAND_CON_OUT_CS1 (1 << 10) ++#define NAND_CON_IN_CS1 (1 << 8) ++#define NAND_CON_PRE_P (1 << 7) ++#define NAND_CON_WP_P (1 << 6) ++#define NAND_CON_SE_P (1 << 5) ++#define NAND_CON_CS_P (1 << 4) ++#define NAND_CON_CLE_P (1 << 3) ++#define NAND_CON_ALE_P (1 << 2) ++#define NAND_CON_CSMUX (1 << 1) ++#define NAND_CON_NANDM (1 << 0) ++ ++#define NAND_WAIT_WR_C (1 << 3) ++#define NAND_WAIT_RDBY (1 << 0) ++ ++#define NAND_CMD_ALE (1 << 2) ++#define NAND_CMD_CLE (1 << 3) ++#define NAND_CMD_CS (1 << 4) ++#define NAND_CMD_SE (1 << 5) ++#define NAND_CMD_WP (1 << 6) ++#define NAND_CMD_PRE (1 << 7) ++ ++struct ltq_nand_regs { ++ __be32 con; /* NAND controller control */ ++ __be32 wait; /* NAND Flash Device RD/BY State */ ++ __be32 ecc0; /* NAND Flash ECC Register 0 */ ++ __be32 ecc_ac; /* NAND Flash ECC Register address counter */ ++ __be32 ecc_cr; /* NAND Flash ECC Comparison */ ++}; ++ ++static struct ltq_nand_regs *ltq_nand_regs = ++ (struct ltq_nand_regs *) CKSEG1ADDR(LTQ_EBU_NAND_BASE); ++ ++static void ltq_nand_wait_ready(void) ++{ ++ while ((ltq_readl(<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 +@@ -51,6 +51,8 @@ COBJS-$(CONFIG_GRETH) += greth.o + COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o + COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o + COBJS-$(CONFIG_LAN91C96) += lan91c96.o ++COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o ++COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o + COBJS-$(CONFIG_MACB) += macb.o + COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o + COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o +--- /dev/null ++++ b/drivers/net/lantiq_danube_etop.c +@@ -0,0 +1,411 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <switch.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/pm.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/dma.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_PPE_ETOP_MDIO_ACC_RA (1 << 31) ++#define LTQ_PPE_ETOP_MDIO_CFG_UMM1 (1 << 2) ++#define LTQ_PPE_ETOP_MDIO_CFG_UMM0 (1 << 1) ++ ++#define LTQ_PPE_ETOP_CFG_TCKINV1 (1 << 11) ++#define LTQ_PPE_ETOP_CFG_TCKINV0 (1 << 10) ++#define LTQ_PPE_ETOP_CFG_FEN1 (1 << 9) ++#define LTQ_PPE_ETOP_CFG_FEN0 (1 << 8) ++#define LTQ_PPE_ETOP_CFG_SEN1 (1 << 7) ++#define LTQ_PPE_ETOP_CFG_SEN0 (1 << 6) ++#define LTQ_PPE_ETOP_CFG_TURBO1 (1 << 5) ++#define LTQ_PPE_ETOP_CFG_REMII1 (1 << 4) ++#define LTQ_PPE_ETOP_CFG_OFF1 (1 << 3) ++#define LTQ_PPE_ETOP_CFG_TURBO0 (1 << 2) ++#define LTQ_PPE_ETOP_CFG_REMII0 (1 << 1) ++#define LTQ_PPE_ETOP_CFG_OFF0 (1 << 0) ++ ++#define LTQ_PPE_ENET0_MAC_CFG_CGEN (1 << 11) ++#define LTQ_PPE_ENET0_MAC_CFG_DUPLEX (1 << 2) ++#define LTQ_PPE_ENET0_MAC_CFG_SPEED (1 << 1) ++#define LTQ_PPE_ENET0_MAC_CFG_LINK (1 << 0) ++ ++#define LTQ_PPE_ENETS0_CFG_FTUC (1 << 28) ++ ++#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX ++#define LTQ_ETH_TX_BUFFER_CNT 8 ++#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN ++#define LTQ_ETH_IP_ALIGN 2 ++ ++#define LTQ_MDIO_DRV_NAME "ltq-mdio" ++#define LTQ_ETH_DRV_NAME "ltq-eth" ++ ++struct ltq_ppe_etop_regs { ++ u32 mdio_cfg; /* MDIO configuration */ ++ u32 mdio_acc; /* MDIO access */ ++ u32 cfg; /* ETOP configuration */ ++ u32 ig_vlan_cos; /* IG VLAN priority CoS mapping */ ++ u32 ig_dscp_cos3; /* IG DSCP CoS mapping 3 */ ++ u32 ig_dscp_cos2; /* IG DSCP CoS mapping 2 */ ++ u32 ig_dscp_cos1; /* IG DSCP CoS mapping 1 */ ++ u32 ig_dscp_cos0; /* IG DSCP CoS mapping 0 */ ++ u32 ig_plen_ctrl; /* IG frame length control */ ++ u32 rsvd0[3]; ++ u32 vpid; /* VLAN protocol ID */ ++}; ++ ++struct ltq_ppe_enet_regs { ++ u32 mac_cfg; /* MAC configuration */ ++ u32 rsvd0[3]; ++ u32 ig_cfg; /* Ingress configuration */ ++ u32 ig_pgcnt; /* Ingress buffer used page count */ ++ u32 rsvd1; ++ u32 ig_buf_ctrl; /* Ingress buffer backpressure ctrl */ ++ u32 cos_cfg; /* Classification configuration */ ++ u32 ig_drop; /* Total ingress drop frames */ ++ u32 ig_err; /* Total ingress error frames */ ++ u32 mac_da0; /* Ingress MAC address 0 */ ++ u32 mac_da1; /* Ingress MAC address 1 */ ++ u32 rsvd2[22]; ++ u32 pgcnt; /* Page counter */ ++ u32 rsvd3; ++ u32 hf_ctrl; /* Half duplex control */ ++ u32 tx_ctrl; /* Transmit control */ ++ u32 rsvd4; ++ u32 vlcos0; /* VLAN insertion config CoS 0 */ ++ u32 vlcos1; /* VLAN insertion config CoS 1 */ ++ u32 vlcos2; /* VLAN insertion config CoS 2 */ ++ u32 vlcos3; /* VLAN insertion config CoS 3 */ ++ u32 eg_col; /* Total egress collision frames */ ++ u32 eg_drop; /* Total egress drop frames */ ++}; ++ ++struct ltq_eth_priv { ++ struct ltq_dma_device dma_dev; ++ struct mii_dev *bus; ++ struct eth_device *dev; ++ int rx_num; ++ int tx_num; ++}; ++ ++struct ltq_mdio_access { ++ union { ++ struct { ++ unsigned ra:1; ++ unsigned rw:1; ++ unsigned rsvd:4; ++ unsigned phya:5; ++ unsigned rega:5; ++ unsigned phyd:16; ++ } reg; ++ u32 val; ++ }; ++}; ++ ++static struct ltq_ppe_etop_regs *ltq_ppe_etop_regs = ++ (struct ltq_ppe_etop_regs *) CKSEG1ADDR(LTQ_PPE_ETOP_BASE); ++ ++static struct ltq_ppe_enet_regs *ltq_ppe_enet0_regs = ++ (struct ltq_ppe_enet_regs *) CKSEG1ADDR(LTQ_PPE_ENET0_BASE); ++ ++static inline int ltq_mdio_poll(void) ++{ ++ struct ltq_mdio_access acc; ++ unsigned cnt = 10000; ++ ++ while (likely(cnt--)) { ++ acc.val = ltq_readl(<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,676 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010-2011 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define DEBUG ++ ++#include <common.h> ++#include <malloc.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <linux/compiler.h> ++#include <asm/gpio.h> ++#include <asm/processor.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/pm.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/dma.h> ++#include <asm/arch/soc.h> ++#include <asm/arch/switch.h> ++ ++#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX ++#define LTQ_ETH_TX_BUFFER_CNT 8 ++#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN ++#define LTQ_ETH_IP_ALIGN 2 ++ ++#define LTQ_MDIO_DRV_NAME "ltq-mdio" ++#define LTQ_ETH_DRV_NAME "ltq-eth" ++ ++#define LTQ_ETHSW_MAX_GMAC 6 ++#define LTQ_ETHSW_PMAC 6 ++ ++struct ltq_mdio_phy_addr_reg { ++ union { ++ struct { ++ unsigned rsvd:1; ++ unsigned lnkst:2; /* Link status control */ ++ unsigned speed:2; /* Speed control */ ++ unsigned fdup:2; /* Full duplex control */ ++ unsigned fcontx:2; /* Flow control mode TX */ ++ unsigned fconrx:2; /* Flow control mode RX */ ++ unsigned addr:5; /* PHY address */ ++ } bits; ++ u16 val; ++ }; ++}; ++ ++enum ltq_mdio_phy_addr_lnkst { ++ LTQ_MDIO_PHY_ADDR_LNKST_AUTO = 0, ++ LTQ_MDIO_PHY_ADDR_LNKST_UP = 1, ++ LTQ_MDIO_PHY_ADDR_LNKST_DOWN = 2, ++}; ++ ++enum ltq_mdio_phy_addr_speed { ++ LTQ_MDIO_PHY_ADDR_SPEED_M10 = 0, ++ LTQ_MDIO_PHY_ADDR_SPEED_M100 = 1, ++ LTQ_MDIO_PHY_ADDR_SPEED_G1 = 2, ++ LTQ_MDIO_PHY_ADDR_SPEED_AUTO = 3, ++}; ++ ++enum ltq_mdio_phy_addr_fdup { ++ LTQ_MDIO_PHY_ADDR_FDUP_AUTO = 0, ++ LTQ_MDIO_PHY_ADDR_FDUP_ENABLE = 1, ++ LTQ_MDIO_PHY_ADDR_FDUP_DISABLE = 3, ++}; ++ ++enum ltq_mdio_phy_addr_fcon { ++ LTQ_MDIO_PHY_ADDR_FCON_AUTO = 0, ++ LTQ_MDIO_PHY_ADDR_FCON_ENABLE = 1, ++ LTQ_MDIO_PHY_ADDR_FCON_DISABLE = 3, ++}; ++ ++struct ltq_mii_mii_cfg_reg { ++ union { ++ struct { ++ unsigned res:1; /* Hardware reset */ ++ unsigned en:1; /* xMII interface enable */ ++ unsigned isol:1; /* xMII interface isolate */ ++ unsigned ldclkdis:1; /* Link down clock disable */ ++ unsigned rsvd:1; ++ unsigned crs:2; /* CRS sensitivity config */ ++ unsigned rgmii_ibs:1; /* RGMII In Band status */ ++ unsigned rmii:1; /* RMII ref clock direction */ ++ unsigned miirate:3; /* xMII interface clock rate */ ++ unsigned miimode:4; /* xMII interface mode */ ++ } bits; ++ u16 val; ++ }; ++}; ++ ++enum ltq_mii_mii_cfg_miirate { ++ LTQ_MII_MII_CFG_MIIRATE_M2P5 = 0, ++ LTQ_MII_MII_CFG_MIIRATE_M25 = 1, ++ LTQ_MII_MII_CFG_MIIRATE_M125 = 2, ++ LTQ_MII_MII_CFG_MIIRATE_M50 = 3, ++ LTQ_MII_MII_CFG_MIIRATE_AUTO = 4, ++}; ++ ++enum ltq_mii_mii_cfg_miimode { ++ LTQ_MII_MII_CFG_MIIMODE_MIIP = 0, ++ LTQ_MII_MII_CFG_MIIMODE_MIIM = 1, ++ LTQ_MII_MII_CFG_MIIMODE_RMIIP = 2, ++ LTQ_MII_MII_CFG_MIIMODE_RMIIM = 3, ++ LTQ_MII_MII_CFG_MIIMODE_RGMII = 4, ++}; ++ ++struct ltq_eth_priv { ++ struct ltq_dma_device dma_dev; ++ struct mii_dev *bus; ++ struct eth_device *dev; ++ struct phy_device *phymap[LTQ_ETHSW_MAX_GMAC]; ++ int rx_num; ++ int tx_num; ++}; ++ ++static struct vr9_switch_regs *switch_regs = ++ (struct vr9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE); ++ ++static inline void vr9_switch_sync(void) ++{ ++ __asm__("sync"); ++} ++ ++static inline int vr9_switch_mdio_is_busy(void) ++{ ++ u32 mdio_ctrl = ltq_readl(&switch_regs->mdio.mdio_ctrl); ++ ++ return mdio_ctrl & MDIO_CTRL_MBUSY; ++} ++ ++static inline void vr9_switch_mdio_poll(void) ++{ ++ while (vr9_switch_mdio_is_busy()) ++ cpu_relax(); ++} ++ ++static int vr9_switch_mdio_read(struct mii_dev *bus, int phyad, int devad, ++ int regad) ++{ ++ u32 mdio_ctrl; ++ int retval; ++ ++ mdio_ctrl = MDIO_CTRL_OP_READ | ++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) | ++ (regad & MDIO_CTRL_REGAD_MASK); ++ ++ vr9_switch_mdio_poll(); ++ ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl); ++ vr9_switch_mdio_poll(); ++ retval = ltq_readl(&switch_regs->mdio.mdio_read); ++ ++ return retval; ++} ++ ++static int vr9_switch_mdio_write(struct mii_dev *bus, int phyad, int devad, ++ int regad, u16 val) ++{ ++ u32 mdio_ctrl; ++ ++ mdio_ctrl = MDIO_CTRL_OP_WRITE | ++ ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) | ++ (regad & MDIO_CTRL_REGAD_MASK); ++ ++ vr9_switch_mdio_poll(); ++ ltq_writel(&switch_regs->mdio.mdio_write, val); ++ ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl); ++ ++ return 0; ++} ++ ++static void ltq_eth_gmac_update(struct phy_device *phydev, int num) ++{ ++ struct ltq_mdio_phy_addr_reg phy_addr_reg; ++ struct ltq_mii_mii_cfg_reg mii_cfg_reg; ++ ++ phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num)); ++ ++ switch (num) { ++ case 0: ++ case 1: ++ case 5: ++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num)); ++ break; ++ default: ++ mii_cfg_reg.val = 0; ++ break; ++ } ++ ++ phy_addr_reg.bits.addr = phydev->addr; ++ ++ if (phydev->link) ++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_UP; ++ else ++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN; ++ ++ switch (phydev->speed) { ++ case SPEED_1000: ++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_G1; ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M125; ++ break; ++ case SPEED_100: ++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M100; ++ switch (mii_cfg_reg.bits.miimode) { ++ case LTQ_MII_MII_CFG_MIIMODE_RMIIM: ++ case LTQ_MII_MII_CFG_MIIMODE_RMIIP: ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M50; ++ break; ++ default: ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M25; ++ break; ++ } ++ break; ++ default: ++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10; ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5; ++ break; ++ } ++ ++ if (phydev->duplex == DUPLEX_FULL) ++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_ENABLE; ++ else ++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE; ++ ++ ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val); ++ ++ switch (num) { ++ case 0: ++ case 1: ++ case 5: ++ ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val); ++ break; ++ default: ++ break; ++ } ++} ++ ++static inline u8 *ltq_eth_rx_packet_align(int rx_num) ++{ ++ u8 *packet = (u8 *) NetRxPackets[rx_num]; ++ ++ /* ++ * IP header needs ++ */ ++ return packet + LTQ_ETH_IP_ALIGN; ++} ++ ++static int ltq_eth_init(struct eth_device *dev, bd_t * bis) ++{ ++ struct ltq_eth_priv *priv = dev->priv; ++ struct ltq_dma_device *dma_dev = &priv->dma_dev; ++ struct phy_device *phydev; ++ int i; ++ ++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) { ++ phydev = priv->phymap[i]; ++ if (!phydev) ++ continue; ++ ++ phy_startup(phydev); ++ ltq_eth_gmac_update(phydev, i); ++ } ++ ++ for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++) ++ ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i), ++ LTQ_ETH_RX_DATA_SIZE); ++ ++ ltq_dma_enable(dma_dev); ++ ++ priv->rx_num = 0; ++ priv->tx_num = 0; ++ ++ return 0; ++} ++ ++static void ltq_eth_halt(struct eth_device *dev) ++{ ++ struct ltq_eth_priv *priv = dev->priv; ++ struct ltq_dma_device *dma_dev = &priv->dma_dev; ++ struct phy_device *phydev; ++ int i; ++ ++ ltq_dma_reset(dma_dev); ++ ++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) { ++ phydev = priv->phymap[i]; ++ if (!phydev) ++ continue; ++ ++ phy_shutdown(phydev); ++ phydev->link = 0; ++ ltq_eth_gmac_update(phydev, i); ++ } ++} ++ ++static int ltq_eth_send(struct eth_device *dev, void *packet, int length) ++{ ++ struct ltq_eth_priv *priv = dev->priv; ++ struct ltq_dma_device *dma_dev = &priv->dma_dev; ++ ++#if 0 ++ printf("%s: packet %p, len %d\n", __func__, packet, length); ++#endif ++ ++ ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10); ++ priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT; ++ ++ return 0; ++} ++ ++static int ltq_eth_recv(struct eth_device *dev) ++{ ++ struct ltq_eth_priv *priv = dev->priv; ++ struct ltq_dma_device *dma_dev = &priv->dma_dev; ++ u8 *packet; ++ int len; ++ ++ if (!ltq_dma_rx_poll(dma_dev, priv->rx_num)) ++ return 0; ++ ++#if 0 ++ printf("%s: rx_num %d\n", __func__, priv->rx_num); ++#endif ++ ++ len = ltq_dma_rx_length(dma_dev, priv->rx_num); ++ packet = ltq_eth_rx_packet_align(priv->rx_num); ++ ++#if 0 ++ printf("%s: received: packet %p, len %u, rx_num %d\n", ++ __func__, packet, len, priv->rx_num); ++#endif ++ ++ if (len) ++ NetReceive(packet, len); ++ ++ ltq_dma_rx_map(dma_dev, priv->rx_num, packet, ++ LTQ_ETH_RX_DATA_SIZE); ++ ++ priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT; ++ ++ return 0; ++} ++ ++static void ltq_eth_gmac_init(int num) ++{ ++ struct ltq_mdio_phy_addr_reg phy_addr_reg; ++ struct ltq_mii_mii_cfg_reg mii_cfg_reg; ++ ++ /* Reset PHY status to link down */ ++ phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num)); ++ phy_addr_reg.bits.addr = num; ++ phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN; ++ phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10; ++ phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE; ++ ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val); ++ ++ /* Reset and disable MII interface */ ++ switch (num) { ++ case 0: ++ case 1: ++ case 5: ++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num)); ++ mii_cfg_reg.bits.en = 0; ++ mii_cfg_reg.bits.res = 1; ++ mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5; ++ ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val); ++ break; ++ default: ++ break; ++ } ++ ++ /* ++ * - enable frame checksum generation ++ * - enable padding of short frames ++ * - disable flow control ++ */ ++ ltq_writel(to_mac_ctrl(switch_regs, num, 0), ++ MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE); ++ ++ vr9_switch_sync(); ++} ++ ++static void ltq_eth_pmac_init(void) ++{ ++ /* ++ * WAR: buffer congestion: ++ * - shorten preambel to 1 byte ++ * - set TX IPG to 7 bytes ++ */ ++#if 1 ++ ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 1), ++ MAC_CTRL1_SHORTPRE | 7); ++#endif ++ ++ /* ++ * WAR: systematical concept weakness ACM bug ++ * - set maximum number of used buffer segments to 254 ++ * - soft-reset BM FSQM ++ */ ++#if 1 ++ ltq_writel(&switch_regs->bm.core.fsqm_gctrl, 253); ++ ltq_setbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES); ++ ltq_clrbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES); ++#endif ++ ++ /* ++ * WAR: switch MAC drop bug ++ */ ++#if 1 ++ ltq_writel(to_pce_tbl_key(switch_regs, 0), 0xf); ++ ltq_writel(to_pce_tbl_value(switch_regs, 0), 0x40); ++ ltq_writel(&switch_regs->pce.core.tbl_addr, 0x3); ++ ltq_writel(&switch_regs->pce.core.tbl_ctrl, 0x902f); ++#endif ++ ++ /* ++ * Configure frame header control: ++ * - enable flow control ++ * - enable CRC check for packets from DMA to PMAC ++ * - remove special tag from packets from PMAC to DMA ++ * - add CRC for packets from DMA to PMAC ++ */ ++ ltq_writel(&switch_regs->pmac.hd_ctl, /*PMAC_HD_CTL_FC |*/ ++ PMAC_HD_CTL_CCRC | PMAC_HD_CTL_RST | PMAC_HD_CTL_AC | ++ PMAC_HD_CTL_RC); ++ ++#if 1 ++ ltq_writel(&switch_regs->pmac.rx_ipg, 0x8b); ++#endif ++ ++ /* ++ * - enable frame checksum generation ++ * - enable padding of short frames ++ * - disable flow control ++ */ ++ ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 0), ++ MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE); ++ ++ vr9_switch_sync(); ++} ++ ++static void ltq_eth_hw_init(void) ++{ ++ int i; ++ ++ /* Power up ethernet and switch subsystems */ ++ ltq_pm_enable(LTQ_PM_ETH); ++ ++ /* Reset ethernet and switch subsystems */ ++#if 0 ++ ltq_reset_once(LTQ_RESET_ETH, 10); ++#endif ++ ++ /* Enable switch macro */ ++ ltq_setbits(&switch_regs->mdio.glob_ctrl, MDIO_GLOB_CTRL_SE); ++ ++ /* Disable MDIO auto-polling for all ports */ ++ ltq_writel(&switch_regs->mdio.mdc_cfg_0, 0); ++ ++ /* ++ * Enable and set MDIO management clock to 2.5 MHz. This is the ++ * maximum clock for FE PHYs. ++ * Formula for clock is: ++ * ++ * 50 MHz ++ * x = ----------- - 1 ++ * 2 * f_MDC ++ */ ++ ltq_writel(&switch_regs->mdio.mdc_cfg_1, MDIO_MDC_CFG1_RES | ++ MDIO_MDC_CFG1_MCEN | 5); ++ ++ vr9_switch_sync(); ++ ++ /* Init MAC connected to CPU */ ++ ltq_eth_pmac_init(); ++ ++ /* Init MACs connected to external MII interfaces */ ++ for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) ++ ltq_eth_gmac_init(i); ++} ++ ++static void ltq_eth_port_config(struct ltq_eth_priv *priv, ++ const struct ltq_eth_port_config *port) ++{ ++ struct ltq_mii_mii_cfg_reg mii_cfg_reg; ++ struct phy_device *phydev; ++ int setup_gpio = 0; ++ ++ switch (port->num) { ++ case 0: /* xMII0 */ ++ case 1: /* xMII1 */ ++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, ++ port->num)); ++ mii_cfg_reg.bits.en = port->flags ? 1 : 0; ++ ++ switch (port->phy_if) { ++ case PHY_INTERFACE_MODE_MII: ++ if (port->flags & LTQ_ETH_PORT_PHY) ++ /* MII MAC mode, connected to external PHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_MIIM; ++ else ++ /* MII PHY mode, connected to external MAC */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_MIIP; ++ setup_gpio = 1; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ if (port->flags & LTQ_ETH_PORT_PHY) ++ /* RMII MAC mode, connected to external PHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_RMIIM; ++ else ++ /* RMII PHY mode, connected to external MAC */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_RMIIP; ++ setup_gpio = 1; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ /* RGMII MAC mode, connected to external PHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_RGMII; ++ setup_gpio = 1; ++ ++ /* RGMII clock delays */ ++ ltq_writel(to_mii_pcdu(switch_regs, port->num), ++ port->rgmii_rx_delay << PCDU_RXDLY_SHIFT | ++ port->rgmii_tx_delay); ++ break; ++ default: ++ break; ++ } ++ ++ ltq_writel(to_mii_miicfg(switch_regs, port->num), ++ mii_cfg_reg.val); ++ break; ++ case 2: /* internal GPHY0 */ ++ case 3: /* internal GPHY0 */ ++ case 4: /* internal GPHY1 */ ++ switch (port->phy_if) { ++ case PHY_INTERFACE_MODE_MII: ++ case PHY_INTERFACE_MODE_GMII: ++ setup_gpio = 1; ++ break; ++ default: ++ break; ++ } ++ break; ++ case 5: /* internal GPHY1 or xMII2 */ ++ mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, ++ port->num)); ++ mii_cfg_reg.bits.en = port->flags ? 1 : 0; ++ ++ switch (port->phy_if) { ++ case PHY_INTERFACE_MODE_MII: ++ /* MII MAC mode, connected to internal GPHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_MIIM; ++ setup_gpio = 1; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ /* RGMII MAC mode, connected to external PHY */ ++ mii_cfg_reg.bits.miimode = ++ LTQ_MII_MII_CFG_MIIMODE_RGMII; ++ setup_gpio = 1; ++ ++ /* RGMII clock delays */ ++ ltq_writel(to_mii_pcdu(switch_regs, port->num), ++ port->rgmii_rx_delay << PCDU_RXDLY_SHIFT | ++ port->rgmii_tx_delay); ++ break; ++ default: ++ break; ++ } ++ ++ ltq_writel(to_mii_miicfg(switch_regs, port->num), ++ mii_cfg_reg.val); ++ break; ++ default: ++ break; ++ } ++ ++ /* Setup GPIOs for MII with external PHYs/MACs */ ++ if (setup_gpio) { ++ /* MII/MDIO */ ++ gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, ++ GPIO_DIR_OUT); ++ /* MII/MDC */ ++ gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, ++ GPIO_DIR_OUT); ++ } ++ ++ /* Connect to internal/external PHYs */ ++ if (port->flags & LTQ_ETH_PORT_PHY) { ++ phydev = phy_connect(priv->bus, port->phy_addr, priv->dev, ++ port->phy_if); ++ if (phydev) ++ phy_config(phydev); ++ ++ priv->phymap[port->num] = phydev; ++ } ++} ++ ++int ltq_eth_initialize(const struct ltq_eth_board_config *board_config) ++{ ++ struct eth_device *dev; ++ struct mii_dev *bus; ++ struct ltq_eth_priv *priv; ++ struct ltq_dma_device *dma_dev; ++ int i, ret; ++ ++ build_check_vr9_registers(); ++ ++ ltq_dma_init(); ++ ltq_eth_hw_init(); ++ ++ dev = calloc(1, sizeof(struct eth_device)); ++ if (!dev) ++ return -1; ++ ++ priv = calloc(1, sizeof(struct ltq_eth_priv)); ++ if (!priv) ++ return -1; ++ ++ bus = mdio_alloc(); ++ if (!bus) ++ return -1; ++ ++ sprintf(dev->name, LTQ_ETH_DRV_NAME); ++ dev->priv = priv; ++ dev->init = ltq_eth_init; ++ dev->halt = ltq_eth_halt; ++ dev->recv = ltq_eth_recv; ++ dev->send = ltq_eth_send; ++ ++ sprintf(bus->name, LTQ_MDIO_DRV_NAME); ++ bus->read = vr9_switch_mdio_read; ++ bus->write = vr9_switch_mdio_write; ++ bus->priv = priv; ++ ++ dma_dev = &priv->dma_dev; ++ dma_dev->port = 0; ++ dma_dev->rx_chan.chan_no = 0; ++ dma_dev->rx_chan.class = 0; ++ dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT; ++ dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0; ++ dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS; ++ dma_dev->tx_chan.chan_no = 1; ++ dma_dev->tx_chan.class = 0; ++ dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT; ++ dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0; ++ dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS; ++ ++ priv->bus = bus; ++ priv->dev = dev; ++ ++ ret = ltq_dma_register(dma_dev); ++ if (ret) ++ return -1; ++ ++ ret = mdio_register(bus); ++ if (ret) ++ return -1; ++ ++ ret = eth_register(dev); ++ if (ret) ++ return -1; ++ ++ for (i = 0; i < board_config->num_ports; i++) ++ ltq_eth_port_config(priv, &board_config->ports[i]); ++ ++ return 0; ++} +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -34,6 +34,7 @@ COBJS-$(CONFIG_PHYLIB_10G) += generic_10 + COBJS-$(CONFIG_PHY_ATHEROS) += atheros.o + COBJS-$(CONFIG_PHY_BROADCOM) += broadcom.o + COBJS-$(CONFIG_PHY_DAVICOM) += davicom.o ++COBJS-$(CONFIG_PHY_LANTIQ) += lantiq.o + COBJS-$(CONFIG_PHY_LXT) += lxt.o + COBJS-$(CONFIG_PHY_MARVELL) += marvell.o + COBJS-$(CONFIG_PHY_MICREL) += micrel.o +--- /dev/null ++++ b/drivers/net/phy/lantiq.c +@@ -0,0 +1,239 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define DEBUG ++ ++#include <common.h> ++#include <miiphy.h> ++ ++#define ADVERTIZE_MPD (1 << 10) ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* ++ * Update link status. ++ * ++ * Based on genphy_update_link in phylib.c ++ */ ++static int ltq_phy_update_link(struct phy_device *phydev) ++{ ++ unsigned int mii_reg; ++ ++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); ++ ++ /* ++ * If we already saw the link up, and it hasn't gone down, then ++ * we don't need to wait for autoneg again ++ */ ++ if (phydev->link && mii_reg & BMSR_LSTATUS) ++ return 0; ++ ++ if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) { ++ phydev->link = 0; ++ return 0; ++ } else { ++ /* Read the link a second time to clear the latched state */ ++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); ++ ++ if (mii_reg & BMSR_LSTATUS) ++ phydev->link = 1; ++ else ++ phydev->link = 0; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Update speed and duplex. ++ * ++ * Based on genphy_parse_link in phylib.c ++ */ ++static int ltq_phy_parse_link(struct phy_device *phydev) ++{ ++ unsigned int mii_reg; ++ ++ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); ++ ++ /* We're using autonegotiation */ ++ if (mii_reg & BMSR_ANEGCAPABLE) { ++ u32 lpa = 0; ++ u32 gblpa = 0; ++ ++ /* Check for gigabit capability */ ++ if (mii_reg & BMSR_ERCAP) { ++ /* We want a list of states supported by ++ * both PHYs in the link ++ */ ++ gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000); ++ gblpa &= phy_read(phydev, ++ MDIO_DEVAD_NONE, MII_CTRL1000) << 2; ++ } ++ ++ /* Set the baseline so we only have to set them ++ * if they're different ++ */ ++ phydev->speed = SPEED_10; ++ phydev->duplex = DUPLEX_HALF; ++ ++ /* Check the gigabit fields */ ++ if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) { ++ phydev->speed = SPEED_1000; ++ ++ if (gblpa & PHY_1000BTSR_1000FD) ++ phydev->duplex = DUPLEX_FULL; ++ ++ /* We're done! */ ++ return 0; ++ } ++ ++ lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE); ++ lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA); ++ ++ if (lpa & (LPA_100FULL | LPA_100HALF)) { ++ phydev->speed = SPEED_100; ++ ++ if (lpa & LPA_100FULL) ++ phydev->duplex = DUPLEX_FULL; ++ ++ } else if (lpa & LPA_10FULL) ++ phydev->duplex = DUPLEX_FULL; ++ } else { ++ u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); ++ ++ phydev->speed = SPEED_10; ++ phydev->duplex = DUPLEX_HALF; ++ ++ if (bmcr & BMCR_FULLDPLX) ++ phydev->duplex = DUPLEX_FULL; ++ ++ if (bmcr & BMCR_SPEED1000) ++ phydev->speed = SPEED_1000; ++ else if (bmcr & BMCR_SPEED100) ++ phydev->speed = SPEED_100; ++ } ++ ++ return 0; ++} ++ ++static int ltq_phy_config(struct phy_device *phydev) ++{ ++ u16 val; ++ ++ /* Advertise as Multi-port device */ ++ val = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); ++ val |= ADVERTIZE_MPD; ++ phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, val); ++ ++ genphy_config_aneg(phydev); ++ ++ return 0; ++} ++ ++static int ltq_phy_startup(struct phy_device *phydev) ++{ ++ /* ++ * Update PHY status immediately without any delays as genphy_startup ++ * does because VRX200 switch needs to be configured dependent ++ * on this information. ++ */ ++ ltq_phy_update_link(phydev); ++ ltq_phy_parse_link(phydev); ++ ++ debug("ltq_phy: addr %d, link %d, speed %d, duplex %d\n", ++ phydev->addr, phydev->link, phydev->speed, phydev->duplex); ++ ++ return 0; ++} ++ ++static struct phy_driver xrx_11g_13_driver = { ++ .name = "Lantiq XWAY XRX PHY11G v1.3 and earlier", ++ .uid = 0x030260D0, ++ .mask = 0xFFFFFFF0, ++ .features = PHY_GBIT_FEATURES, ++ .config = ltq_phy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++static struct phy_driver xrx_11g_14_driver = { ++ .name = "Lantiq XWAY XRX PHY11G v1.4 and later", ++ .uid = 0xd565a408, ++ .mask = 0xFFFFFFF8, ++ .features = PHY_GBIT_FEATURES, ++ .config = ltq_phy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++static struct phy_driver xrx_22f_14_driver = { ++ .name = "Lantiq XWAY XRX PHY22F v1.4 and later", ++ .uid = 0xd565a418, ++ .mask = 0xFFFFFFF8, ++ .features = PHY_BASIC_FEATURES, ++ .config = ltq_phy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++static struct phy_driver pef7071_driver = { ++ .name = "Lantiq XWAY PEF7071", ++ .uid = 0xd565a400, ++ .mask = 0xFFFFFFFF, ++ .features = PHY_GBIT_FEATURES, ++ .config = ltq_phy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++static struct phy_driver xrx_genphy_driver = { ++ .name = "Generic PHY at Lantiq XWAY XRX switch", ++ .uid = 0, ++ .mask = 0, ++ .features = 0, ++ .config = genphy_config, ++ .startup = ltq_phy_startup, ++ .shutdown = genphy_shutdown, ++}; ++ ++int phy_lantiq_init(void) ++{ ++#ifdef CONFIG_NEEDS_MANUAL_RELOC ++ xrx_11g_13_driver.config = ltq_phy_config; ++ xrx_11g_13_driver.startup = ltq_phy_startup; ++ xrx_11g_13_driver.shutdown = genphy_shutdown; ++ xrx_11g_13_driver.name += gd->reloc_off; ++ ++ xrx_11g_14_driver.config = ltq_phy_config; ++ xrx_11g_14_driver.startup = ltq_phy_startup; ++ xrx_11g_14_driver.shutdown = genphy_shutdown; ++ xrx_11g_14_driver.name += gd->reloc_off; ++ ++ xrx_22f_14_driver.config = ltq_phy_config; ++ xrx_22f_14_driver.startup = ltq_phy_startup; ++ xrx_22f_14_driver.shutdown = genphy_shutdown; ++ xrx_22f_14_driver.name += gd->reloc_off; ++ ++ pef7071_driver.config = ltq_phy_config; ++ pef7071_driver.startup = ltq_phy_startup; ++ pef7071_driver.shutdown = genphy_shutdown; ++ pef7071_driver.name += gd->reloc_off; ++ ++ xrx_genphy_driver.config = genphy_config; ++ xrx_genphy_driver.startup = ltq_phy_startup; ++ xrx_genphy_driver.shutdown = genphy_shutdown; ++ xrx_genphy_driver.name += gd->reloc_off; ++#endif ++ ++ phy_register(&xrx_11g_13_driver); ++ phy_register(&xrx_11g_14_driver); ++ phy_register(&xrx_22f_14_driver); ++ phy_register(&pef7071_driver); ++ phy_register(&xrx_genphy_driver); ++ ++ return 0; ++} +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -32,6 +32,8 @@ + #include <phy.h> + #include <errno.h> + ++DECLARE_GLOBAL_DATA_PTR; ++ + /* Generic PHY support and helper functions */ + + /** +@@ -420,6 +422,16 @@ static LIST_HEAD(phy_drivers); + + int phy_init(void) + { ++#ifdef CONFIG_NEEDS_MANUAL_RELOC ++ INIT_LIST_HEAD(&phy_drivers); ++ ++ genphy_driver.config = genphy_config; ++ genphy_driver.startup = genphy_startup; ++ genphy_driver.shutdown = genphy_shutdown; ++ ++ genphy_driver.name += gd->reloc_off; ++#endif ++ + #ifdef CONFIG_PHY_ATHEROS + phy_atheros_init(); + #endif +@@ -429,6 +441,9 @@ int phy_init(void) + #ifdef CONFIG_PHY_DAVICOM + phy_davicom_init(); + #endif ++#ifdef CONFIG_PHY_LANTIQ ++ phy_lantiq_init(); ++#endif + #ifdef CONFIG_PHY_LXT + phy_lxt_init(); + #endif +--- a/drivers/serial/Makefile ++++ b/drivers/serial/Makefile +@@ -42,6 +42,7 @@ COBJS-$(CONFIG_SYS_NS16550_SERIAL) += se + COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o + COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o + COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o ++COBJS-$(CONFIG_LANTIQ_SERIAL) += serial_lantiq.o + COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o + COBJS-$(CONFIG_MXC_UART) += serial_mxc.o + COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o +--- /dev/null ++++ b/drivers/serial/serial_lantiq.c +@@ -0,0 +1,264 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <serial.h> ++#include <asm/errno.h> ++#include <asm/arch/soc.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/io.h> ++ ++#if CONFIG_CONSOLE_ASC == 0 ++#define LTQ_ASC_BASE LTQ_ASC0_BASE ++#else ++#define LTQ_ASC_BASE LTQ_ASC1_BASE ++#endif ++ ++#define LTQ_ASC_ID_TXFS_SHIFT 24 ++#define LTQ_ASC_ID_TXFS_MASK (0x3F << LTQ_ASC_ID_TXFS_SHIFT) ++#define LTQ_ASC_ID_RXFS_SHIFT 16 ++#define LTQ_ASC_ID_RXFS_MASK (0x3F << LTQ_ASC_ID_RXFS_SHIFT) ++ ++#define LTQ_ASC_MCON_R (1 << 15) ++#define LTQ_ASC_MCON_FDE (1 << 9) ++ ++#define LTQ_ASC_WHBSTATE_SETREN (1 << 1) ++#define LTQ_ASC_WHBSTATE_CLRREN (1 << 0) ++ ++#define LTQ_ASC_RXFCON_RXFITL_SHIFT 8 ++#define LTQ_ASC_RXFCON_RXFITL_MASK (0x3F << LTQ_ASC_RXFCON_RXFITL_SHIFT) ++#define LTQ_ASC_RXFCON_RXFITL_RXFFLU (1 << 1) ++#define LTQ_ASC_RXFCON_RXFITL_RXFEN (1 << 0) ++ ++#define LTQ_ASC_TXFCON_TXFITL_SHIFT 8 ++#define LTQ_ASC_TXFCON_TXFITL_MASK (0x3F << LTQ_ASC_TXFCON_TXFITL_SHIFT) ++#define LTQ_ASC_TXFCON_TXFITL_TXFFLU (1 << 1) ++#define LTQ_ASC_TXFCON_TXFITL_TXFEN (1 << 0) ++ ++#define LTQ_ASC_FSTAT_TXFREE_SHIFT 24 ++#define LTQ_ASC_FSTAT_TXFREE_MASK (0x3F << LTQ_ASC_FSTAT_TXFREE_SHIFT) ++#define LTQ_ASC_FSTAT_RXFREE_SHIFT 16 ++#define LTQ_ASC_FSTAT_RXFREE_MASK (0x3F << LTQ_ASC_FSTAT_RXFREE_SHIFT) ++#define LTQ_ASC_FSTAT_TXFFL_SHIFT 8 ++#define LTQ_ASC_FSTAT_TXFFL_MASK (0x3F << LTQ_ASC_FSTAT_TXFFL_SHIFT) ++#define LTQ_ASC_FSTAT_RXFFL_MASK 0x3F ++ ++#ifdef __BIG_ENDIAN ++#define LTQ_ASC_RBUF_OFFSET 3 ++#define LTQ_ASC_TBUF_OFFSET 3 ++#else ++#define LTQ_ASC_RBUF_OFFSET 0 ++#define LTQ_ASC_TBUF_OFFSET 0 ++#endif ++ ++struct ltq_asc_regs { ++ u32 clc; ++ u32 pisel; ++ u32 id; ++ u32 rsvd0; ++ u32 mcon; ++ u32 state; ++ u32 whbstate; ++ u32 rsvd1; ++ u8 tbuf[4]; ++ u8 rbuf[4]; ++ u32 rsvd2[2]; ++ u32 abcon; ++ u32 abstat; ++ u32 whbabcon; ++ u32 whbabstat; ++ u32 rxfcon; ++ u32 txfcon; ++ u32 fstat; ++ u32 rsvd3; ++ u32 bg; ++ u32 bg_timer; ++ u32 fdv; ++ u32 pmw; ++ u32 modcon; ++ u32 modstat; ++}; ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++static struct ltq_asc_regs *ltq_asc_regs = ++ (struct ltq_asc_regs *) CKSEG1ADDR(LTQ_ASC_BASE); ++ ++static int ltq_serial_init(void) ++{ ++ /* Set clock divider for normal run mode to 1 and enable module */ ++ ltq_writel(<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 = "ixp_serial", ++ .start = ltq_serial_init, ++ .stop = NULL, ++ .setbrg = ltq_serial_setbrg, ++ .putc = ltq_serial_putc, ++ .puts = default_serial_puts, ++ .getc = ltq_serial_getc, ++ .tstc = ltq_serial_tstc, ++}; ++ ++void ixp_serial_initialize(void) ++{ ++ serial_register(<q_serial_drv); ++} ++ ++__weak struct serial_device *default_serial_console(void) ++{ ++ return <q_serial_drv; ++} +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -36,6 +36,7 @@ COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o + COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o + COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o + COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o ++COBJS-$(CONFIG_LANTIQ_SPI) += lantiq_spi.o + COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o + COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o + COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o +--- /dev/null ++++ b/drivers/spi/lantiq_spi.c +@@ -0,0 +1,476 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <spi.h> ++#include <malloc.h> ++#include <watchdog.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/io.h> ++#include <asm/lantiq/clk.h> ++#include <asm/lantiq/pm.h> ++#include <asm/arch/soc.h> ++ ++#define LTQ_SPI_CLC_RMC_SHIFT 8 ++#define LTQ_SPI_CLC_RMC_MASK (0xFF << LTQ_SPI_CLC_RMC_SHIFT) ++#define LTQ_SPI_CLC_DISS (1 << 1) ++#define LTQ_SPI_CLC_DISR 1 ++ ++#define LTQ_SPI_ID_TXFS_SHIFT 24 ++#define LTQ_SPI_ID_TXFS_MASK (0x3F << LTQ_SPI_ID_TXFS_SHIFT) ++#define LTQ_SPI_ID_RXFS_SHIFT 16 ++#define LTQ_SPI_ID_RXFS_MASK (0x3F << LTQ_SPI_ID_RXFS_SHIFT) ++ ++#define LTQ_SPI_CON_ENBV (1 << 22) ++#define LTQ_SPI_CON_BM_SHIFT 16 ++#define LTQ_SPI_CON_BM_MASK (0x1F << LTQ_SPI_CON_BM_SHIFT) ++#define LTQ_SPI_CON_LB (1 << 7) ++#define LTQ_SPI_CON_PO (1 << 6) ++#define LTQ_SPI_CON_PH (1 << 5) ++#define LTQ_SPI_CON_HB (1 << 4) ++#define LTQ_SPI_CON_RXOFF (1 << 1) ++#define LTQ_SPI_CON_TXOFF 1 ++ ++#define LTQ_SPI_STAT_RXBV_SHIFT 28 ++#define LTQ_SPI_STAT_RXBV_MASK (0x7 << LTQ_SPI_STAT_RXBV_SHIFT) ++#define LTQ_SPI_STAT_BSY (1 << 13) ++ ++#define LTQ_SPI_WHBSTATE_SETMS (1 << 3) ++#define LTQ_SPI_WHBSTATE_CLRMS (1 << 2) ++#define LTQ_SPI_WHBSTATE_SETEN (1 << 1) ++#define LTQ_SPI_WHBSTATE_CLREN 1 ++ ++#define LTQ_SPI_TXFCON_TXFLU (1 << 1) ++#define LTQ_SPI_TXFCON_TXFEN 1 ++ ++#define LTQ_SPI_RXFCON_RXFLU (1 << 1) ++#define LTQ_SPI_RXFCON_RXFEN 1 ++ ++#define LTQ_SPI_FSTAT_RXFFL_MASK 0x3f ++#define LTQ_SPI_FSTAT_TXFFL_SHIFT 8 ++#define LTQ_SPI_FSTAT_TXFFL_MASK (0x3f << LTQ_SPI_FSTAT_TXFFL_SHIFT) ++ ++#define LTQ_SPI_RXREQ_RXCNT_MASK 0xFFFF ++#define LTQ_SPI_RXCNT_TODO_MASK 0xFFFF ++ ++#define LTQ_SPI_GPIO_DIN 16 ++#define LTQ_SPI_GPIO_DOUT 17 ++#define LTQ_SPI_GPIO_CLK 18 ++ ++struct ltq_spi_regs { ++ u32 clc; /* Clock control */ ++ u32 pisel; /* Port input select */ ++ u32 id; /* Identification */ ++ u32 rsvd0; ++ u32 con; /* Control */ ++ u32 stat; /* Status */ ++ u32 whbstate; /* Write HW modified state */ ++ u32 rsvd1; ++ u32 tb; /* Transmit buffer */ ++ u32 rb; /* Receive buffer */ ++ u32 rsvd2[2]; ++ u32 rxfcon; /* Recevie FIFO control */ ++ u32 txfcon; /* Transmit FIFO control */ ++ u32 fstat; /* FIFO status */ ++ u32 rsvd3; ++ u32 brt; /* Baudrate timer */ ++ u32 brstat; /* Baudrate timer status */ ++ u32 rsvd4[6]; ++ u32 sfcon; /* Serial frame control */ ++ u32 sfstat; /* Serial frame status */ ++ u32 rsvd5[2]; ++ u32 gpocon; /* General purpose output control */ ++ u32 gpostat; /* General purpose output status */ ++ u32 fgpo; /* Force general purpose output */ ++ u32 rsvd6; ++ u32 rxreq; /* Receive request */ ++ u32 rxcnt; /* Receive count */ ++ u32 rsvd7[25]; ++ u32 dmacon; /* DMA control */ ++}; ++ ++struct ltq_spi_slave { ++ struct spi_slave slave; ++ unsigned int max_hz; ++ unsigned int mode; ++ unsigned int len; ++ unsigned int brt; ++ unsigned int tx_cnt; ++ unsigned int rx_cnt; ++ unsigned int rx_req; ++ const u8 *tx; ++ u8 *rx; ++ u8 txfs; ++ u8 rxfs; ++}; ++ ++static inline struct ltq_spi_slave *to_ltq_spi_slave(struct spi_slave *slave) ++{ ++ return container_of(slave, struct ltq_spi_slave, slave); ++} ++ ++#ifdef CONFIG_SPL_BUILD ++/* ++ * We do not have or want malloc in a SPI flash SPL. ++ * Neither we have to support multiple SPI slaves. Thus we put the ++ * SPI slave context in BSS for SPL builds. ++ */ ++static struct ltq_spi_slave ltq_spi_slave; ++ ++static inline struct ltq_spi_slave *ltq_spi_slave_alloc(void) ++{ ++ return <q_spi_slave; ++} ++ ++static inline void ltq_spi_slave_free(struct spi_slave *slave) ++{ ++} ++#else ++static inline struct ltq_spi_slave *ltq_spi_slave_alloc(void) ++{ ++ return malloc(sizeof(struct ltq_spi_slave)); ++} ++ ++static inline void ltq_spi_slave_free(struct spi_slave *slave) ++{ ++ struct ltq_spi_slave *sl; ++ ++ if (slave) { ++ sl = to_ltq_spi_slave(slave); ++ free(sl); ++ } ++} ++#endif ++ ++static struct ltq_spi_regs *ltq_spi_regs = ++ (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE); ++ ++void spi_init(void) ++{ ++ /* Power up SPI subsystem */ ++ ltq_pm_enable(LTQ_PM_SPI); ++ ++ /* Enable module and set clock divider to 1 */ ++ ltq_writel(<q_spi_regs->clc, 1 << LTQ_SPI_CLC_RMC_SHIFT); ++ ++ /* SPI/DIN input */ ++ gpio_set_altfunc(16, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN); ++ /* SPI/DOUT output */ ++ gpio_set_altfunc(17, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* SPI/CLK output */ ++ gpio_set_altfunc(18, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++} ++ ++static inline u32 ltq_spi_calc_br(unsigned int max_hz) ++{ ++ u32 speed_hz, spi_hz; ++ u16 brt; ++ ++ /* SPI module clock is same as FPI bus clock */ ++ spi_hz = ltq_get_bus_clock(); ++ ++ /* ++ * f_SPI ++ * baudrate = -------------- ++ * 2 * (BR + 1) ++ */ ++ spi_hz /= 2; ++ ++ for (brt = 0; brt < 0xFFFF; brt++) { ++ speed_hz = spi_hz / (brt + 1); ++ if (speed_hz <= max_hz) ++ break; ++ } ++ ++ return brt; ++} ++ ++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, ++ unsigned int max_hz, unsigned int mode) ++{ ++ u32 id; ++ struct ltq_spi_slave *sl; ++ ++ if (!spi_cs_is_valid(bus, cs)) ++ return NULL; ++ ++ sl = ltq_spi_slave_alloc(); ++ if (!sl) ++ return NULL; ++ ++ /* Read HW capabilities */ ++ id = ltq_readl(<q_spi_regs->id); ++ sl->txfs = (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT; ++ sl->rxfs = (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT; ++ ++ sl->slave.bus = bus; ++ sl->slave.cs = cs; ++ sl->max_hz = max_hz; ++ sl->mode = mode; ++ ++ sl->brt = ltq_spi_calc_br(max_hz); ++ ++ return &sl->slave; ++} ++ ++void spi_free_slave(struct spi_slave *slave) ++{ ++ ltq_spi_slave_free(slave); ++} ++ ++static int ltq_spi_wait_ready(struct ltq_spi_slave *sl) ++{ ++ u32 stat; ++ const unsigned long timeout = 20000; ++ unsigned long timebase; ++ ++ timebase = get_timer(0); ++ ++ do { ++ WATCHDOG_RESET(); ++ ++ stat = ltq_readl(<q_spi_regs->stat); ++ ++ if (!(stat & LTQ_SPI_STAT_BSY)) ++ return 0; ++ } while (get_timer(timebase) < timeout); ++ ++ return 1; ++} ++ ++int spi_claim_bus(struct spi_slave *slave) ++{ ++ struct ltq_spi_slave *sl = to_ltq_spi_slave(slave); ++ u32 con; ++ int ret; ++ ++ /* Put module in configuration mode */ ++ ltq_setbits(<q_spi_regs->whbstate, LTQ_SPI_WHBSTATE_CLREN); ++ ++ /* Enable and flush RX and TX FIFOs */ ++ ltq_setbits(<q_spi_regs->txfcon, ++ LTQ_SPI_TXFCON_TXFLU | LTQ_SPI_TXFCON_TXFEN); ++ ltq_setbits(<q_spi_regs->rxfcon, ++ LTQ_SPI_RXFCON_RXFLU | LTQ_SPI_RXFCON_RXFEN); ++ ++ ret = ltq_spi_wait_ready(sl); ++ if (ret) ++ return ret; ++ ++ /* Set baudrate */ ++ ltq_writel(<q_spi_regs->brt, sl->brt); ++ ++ /* ++ * Disable byte valid control (ENBV = 0) and ++ * set data width to 8 bit (BM = 7) ++ */ ++ con = (7 << LTQ_SPI_CON_BM_SHIFT); ++ ++ /* Disable transmitter and receiver */ ++ con |= (LTQ_SPI_CON_RXOFF | LTQ_SPI_CON_TXOFF); ++ ++ /* Set SPI mode ++ * Mapping: Mode CPOL CPHA CON.PO CON.PH ++ * 0 0 0 0 1 ++ * 1 0 1 0 0 ++ * 2 1 0 1 1 ++ * 3 1 1 1 0 ++ */ ++ if (sl->mode & SPI_CPHA) ++ con &= ~LTQ_SPI_CON_PH; ++ else ++ con |= LTQ_SPI_CON_PH; ++ ++ if (sl->mode & SPI_CPOL) ++ con |= LTQ_SPI_CON_PO; ++ else ++ con &= ~LTQ_SPI_CON_PO; ++ ++ /* Set heading control */ ++ if (sl->mode & SPI_LSB_FIRST) ++ con &= ~LTQ_SPI_CON_HB; ++ else ++ con |= LTQ_SPI_CON_HB; ++ ++ /* Set loopback control */ ++ if (sl->mode & SPI_LOOP) ++ con |= LTQ_SPI_CON_LB; ++ else ++ con &= ~LTQ_SPI_CON_LB; ++ ++ ltq_writel(<q_spi_regs->con, con); ++ ++ /* Set SPI master mode and enable SPI */ ++ ltq_setbits(<q_spi_regs->whbstate, ++ LTQ_SPI_WHBSTATE_SETEN | LTQ_SPI_WHBSTATE_SETMS); ++ ++ return 0; ++} ++ ++void spi_release_bus(struct spi_slave *slave) ++{ ++ /* Put module in configuration mode */ ++ ltq_setbits(<q_spi_regs->whbstate, LTQ_SPI_WHBSTATE_CLREN); ++ ++ /* Flush RX and TX FIFOs */ ++ ltq_setbits(<q_spi_regs->txfcon, LTQ_SPI_TXFCON_TXFLU); ++ ltq_setbits(<q_spi_regs->rxfcon, LTQ_SPI_RXFCON_RXFLU); ++} ++ ++static inline void ltq_spi_txfifo_write(struct ltq_spi_slave *sl) ++{ ++ u32 fstat, tb; ++ u16 fifo_space; ++ ++ fstat = ltq_readl(<q_spi_regs->fstat); ++ fifo_space = sl->txfs - ((fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >> ++ LTQ_SPI_FSTAT_TXFFL_SHIFT); ++ ++ while (sl->tx_cnt < sl->len && fifo_space) { ++ tb = *sl->tx++; ++ ltq_writel(<q_spi_regs->tb, tb); ++ fifo_space--; ++ sl->tx_cnt++; ++ } ++} ++ ++static inline void ltq_spi_rx_request(struct ltq_spi_slave *sl) ++{ ++ u32 rxreq, rxreq_max; ++ ++ /* ++ * In RX-only mode the serial clock is activated only after writing ++ * the expected amount of RX bytes into RXREQ register. ++ * To avoid receive overflows at high clocks it is better to request ++ * only the amount of bytes that fits into all FIFOs. This value ++ * depends on the FIFO size implemented in hardware. ++ */ ++ rxreq = sl->len - sl->rx_cnt; ++ rxreq_max = sl->rxfs << 2; ++ rxreq = min(rxreq_max, rxreq); ++ ++ if (!sl->rx_req && rxreq && sl->rx_cnt < sl->len) { ++ ltq_writel(<q_spi_regs->rxreq, rxreq); ++ sl->rx_req = rxreq; ++ } ++} ++ ++static void ltq_spi_rxfifo_read(struct ltq_spi_slave *sl) ++{ ++ u32 fstat, data, *rx32; ++ u16 fifo_fill; ++ u8 rxbv, shift, *rx8; ++ ++ /* Determine how much FIFOs are filled with RX data */ ++ fstat = ltq_readl(<q_spi_regs->fstat); ++ fifo_fill = fstat & LTQ_SPI_FSTAT_RXFFL_MASK; ++ ++ /* ++ * The 32 bit FIFO is always used completely independent from the ++ * bits_per_word value. Thus four bytes have to be read at once ++ * per FIFO. ++ */ ++ rx32 = (u32 *) sl->rx; ++ while (sl->len - sl->rx_cnt >= 4 && fifo_fill) { ++ data = ltq_readl(<q_spi_regs->rb); ++ *rx32++ = data; ++ sl->rx_cnt += 4; ++ sl->rx_req -= 4; ++ sl->rx += 4; ++ fifo_fill--; ++ } ++ ++ /* ++ * If there are remaining bytes, read byte count from STAT.RXBV ++ * register and read the data byte-wise. ++ */ ++ while (fifo_fill && sl->rx_cnt < sl->len) { ++ fstat = ltq_readl(<q_spi_regs->stat); ++ rxbv = (fstat & LTQ_SPI_STAT_RXBV_MASK) >> ++ LTQ_SPI_STAT_RXBV_SHIFT; ++ ++ if (!rxbv) ++ break; ++ ++ data = ltq_readl(<q_spi_regs->rb); ++ ++ shift = (rxbv - 1) * 8; ++ rx8 = sl->rx; ++ ++ while (rxbv) { ++ *rx8++ = (data >> shift) & 0xFF; ++ rxbv--; ++ shift -= 8; ++ sl->rx_cnt++; ++ sl->rx_req--; ++ sl->rx++; ++ } ++ ++ fifo_fill--; ++ } ++} ++ ++int spi_xfer(struct spi_slave *slave, unsigned int bitlen, ++ const void *dout, void *din, unsigned long flags) ++{ ++ struct ltq_spi_slave *sl = to_ltq_spi_slave(slave); ++ int ret; ++ ++ if (bitlen % 8) ++ return 1; ++ ++ if (!bitlen) { ++ ret = 0; ++ goto done; ++ } ++ ++ sl->len = bitlen / 8; ++ sl->tx = dout; ++ sl->rx = din; ++ sl->tx_cnt = 0; ++ sl->rx_cnt = 0; ++ sl->rx_req = 0; ++ ++ if (flags & SPI_XFER_BEGIN) ++ spi_cs_activate(slave); ++ ++ /* Enable transmitter */ ++ if (sl->tx) ++ ltq_clrbits(<q_spi_regs->con, LTQ_SPI_CON_TXOFF); ++ ++ /* Enable receiver */ ++ if (sl->rx) ++ ltq_clrbits(<q_spi_regs->con, LTQ_SPI_CON_RXOFF); ++ ++ if (sl->tx) ++ ltq_spi_txfifo_write(sl); ++ else if (sl->rx) ++ ltq_spi_rx_request(sl); ++ ++ while (sl->tx_cnt != sl->len && sl->rx_cnt != sl->len) { ++ if (sl->rx) { ++ ltq_spi_rxfifo_read(sl); ++ ++ if (sl->tx) ++ ltq_spi_txfifo_write(sl); ++ else ++ ltq_spi_rx_request(sl); ++ } else if (sl->tx) ++ ltq_spi_txfifo_write(sl); ++ } ++ ++ ret = ltq_spi_wait_ready(sl); ++ ++done: ++ /* Disable transmitter and receiver */ ++ ltq_setbits(<q_spi_regs->con, LTQ_SPI_CON_TXOFF | LTQ_SPI_CON_RXOFF); ++ ++ if (flags & SPI_XFER_END) ++ spi_cs_deactivate(slave); ++ ++ return ret; ++} +--- /dev/null ++++ b/include/configs/easy50712.h +@@ -0,0 +1,78 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "EASY50712" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Lantiq EASY50712 Danube Reference Board" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPI_FLASH ++#define CONFIG_SPI_FLASH_ATMEL /* Have an AT45DB321D serial flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */ ++ ++#define CONFIG_LTQ_SPL_COMP_LZO ++#define CONFIG_LTQ_SPL_CONSOLE ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_ADM6996I ++ ++/* Environment */ ++#define CONFIG_ENV_SPI_BUS 0 ++#define CONFIG_ENV_SPI_CS 2 ++#define CONFIG_ENV_SPI_MAX_HZ 20000000 ++#define CONFIG_ENV_SPI_MODE 0 ++ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (256 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#elif defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (128 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR ++ ++#endif /* __CONFIG_H */ +--- /dev/null ++++ b/include/configs/easy80920.h +@@ -0,0 +1,93 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "EASY80920" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Lantiq EASY80920 VRX200 Family Board" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPI_FLASH ++#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29LV620 serial flash */ ++ ++#define CONFIG_LTQ_SUPPORT_NAND_FLASH ++ ++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */ ++#define CONFIG_SPL_SPI_BUS 0 ++#define CONFIG_SPL_SPI_CS 4 ++#define CONFIG_SPL_SPI_MAX_HZ 25000000 ++#define CONFIG_SPL_SPI_MODE 0 ++ ++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */ ++ ++#define CONFIG_LTQ_SPL_COMP_LZO ++#define CONFIG_LTQ_SPL_CONSOLE ++ ++#define CONFIG_SYS_DRAM_PROBE ++ ++/* Environment */ ++#define CONFIG_ENV_SPI_BUS CONFIG_SPL_SPI_BUS ++#define CONFIG_ENV_SPI_CS CONFIG_SPL_SPI_CS ++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SPL_SPI_MAX_HZ ++#define CONFIG_ENV_SPI_MODE CONFIG_SPL_SPI_MODE ++ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (384 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#elif defined(CONFIG_SYS_BOOT_NORSPL) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#elif defined(CONFIG_SYS_BOOT_SFSPL) ++#define CONFIG_ENV_IS_IN_SPI_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_SF \ ++ "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ CONFIG_ENV_UPDATE_UBOOT_SF ++ ++#endif /* __CONFIG_H */ +--- a/include/phy.h ++++ b/include/phy.h +@@ -220,6 +220,7 @@ int gen10g_discover_mmds(struct phy_devi + int phy_atheros_init(void); + int phy_broadcom_init(void); + int phy_davicom_init(void); ++int phy_lantiq_init(void); + int phy_lxt_init(void); + int phy_marvell_init(void); + int phy_micrel_init(void); +--- a/spl/Makefile ++++ b/spl/Makefile +@@ -81,6 +81,8 @@ LIBS-$(CONFIG_SPL_POST_MEM_SUPPORT) += p + LIBS-$(CONFIG_SPL_NET_SUPPORT) += net/libnet.o + LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/libnet.o + LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/libphy.o ++LIBS-$(CONFIG_SPL_LZMA_SUPPORT) += lib/lzma/liblzma.o ++LIBS-$(CONFIG_SPL_LZO_SUPPORT) += lib/lzo/liblzo.o + + ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) + LIBS-y += $(CPUDIR)/omap-common/libomap-common.o +--- a/tools/.gitignore ++++ b/tools/.gitignore +@@ -2,6 +2,7 @@ + /envcrc + /gen_eth_addr + /img2srec ++/ltq-boot-image + /kwboot + /mkenvimage + /mkimage +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -65,6 +65,7 @@ BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_lo + BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX) + BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX) + BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX) ++BIN_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image$(SFX) + BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX) + BIN_FILES-y += mkenvimage$(SFX) + BIN_FILES-y += mkimage$(SFX) +@@ -89,6 +90,7 @@ OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envc + NOPED_OBJ_FILES-y += fit_image.o + OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o + OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o ++OBJ_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image.o + OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o + NOPED_OBJ_FILES-y += aisimage.o + NOPED_OBJ_FILES-y += kwbimage.o +@@ -193,6 +195,10 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ + $(HOSTSTRIP) $@ + ++$(obj)ltq-boot-image$(SFX): $(obj)ltq-boot-image.o ++ $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ ++ $(HOSTSTRIP) $@ ++ + $(obj)xway-swap-bytes$(SFX): $(obj)xway-swap-bytes.o + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ + $(HOSTSTRIP) $@ +--- /dev/null ++++ b/tools/ltq-boot-image.c +@@ -0,0 +1,316 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <unistd.h> ++#include <getopt.h> ++#include <compiler.h> ++#include <sys/stat.h> ++ ++enum image_types { ++ IMAGE_NONE, ++ IMAGE_SFSPL ++}; ++ ++/* Lantiq non-volatile bootstrap command IDs */ ++enum nvb_cmd_ids { ++ NVB_CMD_DEBUG = 0x11, ++ NVB_CMD_REGCFG = 0x22, ++ NVB_CMD_IDWNLD = 0x33, ++ NVB_CMD_CDWNLD = 0x44, ++ NVB_CMD_DWNLD = 0x55, ++ NVB_CMD_IFCFG = 0x66, ++ NVB_CMD_START = 0x77 ++}; ++ ++/* Lantiq non-volatile bootstrap command flags */ ++enum nvb_cmd_flags { ++ NVB_FLAG_START = 1, ++ NVB_FLAG_DEC = (1 << 1), ++ NVB_FLAG_DBG = (1 << 2), ++ NVB_FLAG_SDBG = (1 << 3), ++ NVB_FLAG_CFG0 = (1 << 4), ++ NVB_FLAG_CFG1 = (1 << 5), ++ NVB_FLAG_CFG2 = (1 << 6), ++ NVB_FLAG_RST = (1 << 7) ++}; ++ ++struct args { ++ enum image_types type; ++ __u32 entry_addr; ++ const char *uboot_bin; ++ const char *spl_bin; ++ const char *out_bin; ++}; ++ ++static void usage_msg(const char *name) ++{ ++ fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n", ++ name); ++ fprintf(stderr, " Image types:\n" ++ " sfspl - SPL + [compressed] U-Boot for SPI flash\n"); ++} ++ ++static enum image_types parse_image_type(const char *type) ++{ ++ if (!type) ++ return IMAGE_NONE; ++ ++ if (!strncmp(type, "sfspl", 6)) ++ return IMAGE_SFSPL; ++ ++ return IMAGE_NONE; ++} ++ ++static int parse_args(int argc, char *argv[], struct args *arg) ++{ ++ int opt; ++ ++ memset(arg, 0, sizeof(*arg)); ++ ++ while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) { ++ switch (opt) { ++ case 'h': ++ usage_msg(argv[0]); ++ return 1; ++ case 't': ++ arg->type = parse_image_type(optarg); ++ break; ++ case 'e': ++ arg->entry_addr = strtoul(optarg, NULL, 16); ++ break; ++ case 'u': ++ arg->uboot_bin = optarg; ++ break; ++ case 's': ++ arg->spl_bin = optarg; ++ break; ++ case 'o': ++ arg->out_bin = optarg; ++ break; ++ default: ++ fprintf(stderr, "Invalid option -%c\n", opt); ++ goto parse_error; ++ } ++ } ++ ++ if (arg->type == IMAGE_NONE) { ++ fprintf(stderr, "Invalid image type\n"); ++ goto parse_error; ++ } ++ ++ if (!arg->uboot_bin) { ++ fprintf(stderr, "Missing U-Boot binary\n"); ++ goto parse_error; ++ } ++ ++ if (!arg->out_bin) { ++ fprintf(stderr, "Missing output binary\n"); ++ goto parse_error; ++ } ++ ++ if (arg->type == IMAGE_SFSPL && !arg->spl_bin) { ++ fprintf(stderr, "Missing SPL binary\n"); ++ goto parse_error; ++ } ++ ++ return 0; ++ ++parse_error: ++ usage_msg(argv[0]); ++ return -1; ++} ++ ++static __u32 build_nvb_command(unsigned cmdid, unsigned cmdflags) ++{ ++ __u32 cmd; ++ __u16 tag; ++ ++ tag = (cmdid << 8) | cmdflags; ++ cmd = (tag << 16) | (0xFFFF - tag); ++ ++ return cpu_to_be32(cmd); ++} ++ ++static int write_header(int fd, const void *hdr, size_t size) ++{ ++ ssize_t n; ++ ++ n = write(fd, hdr, size); ++ if (n != size) { ++ fprintf(stderr, "Cannot write header: %s\n", ++ strerror(errno)); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int write_nvb_dwnld_header(int fd, size_t size, __u32 addr) ++{ ++ __u32 hdr[3]; ++ ++ hdr[0] = build_nvb_command(NVB_CMD_DWNLD, NVB_FLAG_START | ++ NVB_FLAG_SDBG); ++ hdr[1] = cpu_to_be32(size + 4); ++ hdr[2] = cpu_to_be32(addr); ++ ++ return write_header(fd, hdr, sizeof(hdr)); ++} ++ ++static int write_nvb_start_header(int fd, __u32 addr) ++{ ++ __u32 hdr[3]; ++ ++ hdr[0] = build_nvb_command(NVB_CMD_START, NVB_FLAG_SDBG); ++ hdr[1] = cpu_to_be32(4); ++ hdr[2] = cpu_to_be32(addr); ++ ++ return write_header(fd, hdr, sizeof(hdr)); ++} ++ ++static int open_input_bin(const char *name, void **ptr, size_t *size) ++{ ++ struct stat sbuf; ++ int ret, fd; ++ ++ fd = open(name, O_RDONLY | O_BINARY); ++ if (0 > fd) { ++ fprintf(stderr, "Cannot open %s: %s\n", name, ++ strerror(errno)); ++ return -1; ++ } ++ ++ ret = fstat(fd, &sbuf); ++ if (0 > ret) { ++ fprintf(stderr, "Cannot fstat %s: %s\n", name, ++ strerror(errno)); ++ return -1; ++ } ++ ++ *ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); ++ if (*ptr == MAP_FAILED) { ++ fprintf(stderr, "Cannot mmap %s: %s\n", name, ++ strerror(errno)); ++ return -1; ++ } ++ ++ *size = sbuf.st_size; ++ ++ return fd; ++} ++ ++static void close_input_bin(int fd, void *ptr, size_t size) ++{ ++ munmap(ptr, size); ++ close(fd); ++} ++ ++static int copy_bin(int fd, void *ptr, size_t size) ++{ ++ ssize_t n; ++ ++ n = write(fd, ptr, size); ++ if (n != size) { ++ fprintf(stderr, "Cannot copy binary: %s\n", strerror(errno)); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int open_output_bin(const char *name) ++{ ++ int fd; ++ ++ fd = open(name, O_RDWR | O_CREAT | O_TRUNC | O_SYNC | O_BINARY, 0666); ++ if (0 > fd) { ++ fprintf(stderr, "Cannot open %s: %s\n", name, ++ strerror(errno)); ++ return -1; ++ } ++ ++ return fd; ++} ++ ++static int create_sfspl(const struct args *arg) ++{ ++ int out_fd, uboot_fd, spl_fd, ret; ++ void *uboot_ptr, *spl_ptr; ++ size_t uboot_size, spl_size; ++ ++ out_fd = open_output_bin(arg->out_bin); ++ if (0 > out_fd) ++ goto err; ++ ++ spl_fd = open_input_bin(arg->spl_bin, &spl_ptr, &spl_size); ++ if (0 > spl_fd) ++ goto err_spl; ++ ++ uboot_fd = open_input_bin(arg->uboot_bin, &uboot_ptr, &uboot_size); ++ if (0 > uboot_fd) ++ goto err_uboot; ++ ++ ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr); ++ if (ret) ++ goto err_write; ++ ++ ret = copy_bin(out_fd, spl_ptr, spl_size); ++ if (ret) ++ goto err_write; ++ ++ ret = write_nvb_start_header(out_fd, arg->entry_addr); ++ if (ret) ++ goto err_write; ++ ++ ret = copy_bin(out_fd, uboot_ptr, uboot_size); ++ if (ret) ++ goto err_write; ++ ++ close_input_bin(uboot_fd, uboot_ptr, uboot_size); ++ close_input_bin(spl_fd, spl_ptr, spl_size); ++ close(out_fd); ++ ++ return 0; ++ ++err_write: ++ close_input_bin(uboot_fd, uboot_ptr, uboot_size); ++err_uboot: ++ close_input_bin(spl_fd, spl_ptr, spl_size); ++err_spl: ++ close(out_fd); ++err: ++ return -1; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int ret; ++ struct args arg; ++ ++ ret = parse_args(argc, argv, &arg); ++ if (ret) ++ goto done; ++ ++ switch (arg.type) { ++ case IMAGE_SFSPL: ++ ret = create_sfspl(&arg); ++ break; ++ default: ++ fprintf(stderr, "Image type not implemented\n"); ++ ret = -1; ++ break; ++ } ++ ++done: ++ if (ret >= 0) ++ return EXIT_SUCCESS; ++ ++ return EXIT_FAILURE; ++} diff --git a/package/boot/uboot-lantiq/patches/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch b/package/boot/uboot-lantiq/patches/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch new file mode 100644 index 0000000..ba24bae --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0024-MIPS-VRX200-add-option-to-boot-from-AVM-EVA-loader.patch @@ -0,0 +1,33 @@ +From 2c6115188c7353a601835885a6c544240cfc479e Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Fri, 30 Nov 2012 18:09:25 +0100 +Subject: MIPS: VRX200: add option to boot from AVM EVA loader + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/arch/mips/cpu/mips32/vrx200/config.mk ++++ b/arch/mips/cpu/mips32/vrx200/config.mk +@@ -17,6 +17,9 @@ endif + LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o + + ifndef CONFIG_SPL_BUILD ++ifdef CONFIG_SYS_BOOT_EVA ++ALL-y += $(obj)u-boot.bin.lzma ++endif + ifdef CONFIG_SYS_BOOT_SFSPL + ALL-y += $(obj)u-boot.ltq.sfspl + ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl +--- a/arch/mips/include/asm/arch-vrx200/config.h ++++ b/arch/mips/include/asm/arch-vrx200/config.h +@@ -161,6 +161,11 @@ + #define CONFIG_SYS_DISABLE_CACHE + #endif + ++#if defined(CONFIG_SYS_BOOT_EVA) ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#endif ++ + #if defined(CONFIG_SYS_BOOT_NOR) + #define CONFIG_SYS_TEXT_BASE 0xB0000000 + #endif diff --git a/package/boot/uboot-lantiq/patches/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch b/package/boot/uboot-lantiq/patches/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch new file mode 100644 index 0000000..b680a97 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0025-MIPS-add-board-support-for-AVM-FritzBox-3370.patch @@ -0,0 +1,355 @@ +From 51f04c00e831b49587f9f766ff1af67d2122feb2 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Fri, 30 Nov 2012 18:09:47 +0100 +Subject: MIPS: add board support for AVM FritzBox 3370 + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/avm/fb3370/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/avm/fb3370/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/avm/fb3370/ddr_settings.h +@@ -0,0 +1,70 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#define MC_CCR00_VALUE 0x101 ++#define MC_CCR01_VALUE 0x1000100 ++#define MC_CCR02_VALUE 0x1010000 ++#define MC_CCR03_VALUE 0x101 ++#define MC_CCR04_VALUE 0x1000000 ++#define MC_CCR05_VALUE 0x1000101 ++#define MC_CCR06_VALUE 0x1000100 ++#define MC_CCR07_VALUE 0x1010000 ++#define MC_CCR08_VALUE 0x1000101 ++#define MC_CCR09_VALUE 0x0 ++#define MC_CCR10_VALUE 0x2000100 ++#define MC_CCR11_VALUE 0x2000300 ++#define MC_CCR12_VALUE 0x30000 ++#define MC_CCR13_VALUE 0x202 ++#define MC_CCR14_VALUE 0x7080A0F ++#define MC_CCR15_VALUE 0x2040F ++#define MC_CCR16_VALUE 0x40000 ++#define MC_CCR17_VALUE 0x70102 ++#define MC_CCR18_VALUE 0x4020002 ++#define MC_CCR19_VALUE 0x30302 ++#define MC_CCR20_VALUE 0x8000700 ++#define MC_CCR21_VALUE 0x40F020A ++#define MC_CCR22_VALUE 0x0 ++#define MC_CCR23_VALUE 0xC020000 ++#define MC_CCR24_VALUE 0x4401B04 ++#define MC_CCR25_VALUE 0x0 ++#define MC_CCR26_VALUE 0x0 ++#define MC_CCR27_VALUE 0x6420000 ++#define MC_CCR28_VALUE 0x0 ++#define MC_CCR29_VALUE 0x0 ++#define MC_CCR30_VALUE 0x798 ++#define MC_CCR31_VALUE 0x0 ++#define MC_CCR32_VALUE 0x0 ++#define MC_CCR33_VALUE 0x650000 ++#define MC_CCR34_VALUE 0x200C8 ++#define MC_CCR35_VALUE 0x1D445D ++#define MC_CCR36_VALUE 0xC8 ++#define MC_CCR37_VALUE 0xC351 ++#define MC_CCR38_VALUE 0x0 ++#define MC_CCR39_VALUE 0x141F04 ++#define MC_CCR40_VALUE 0x142704 ++#define MC_CCR41_VALUE 0x141b42 ++#define MC_CCR42_VALUE 0x141b42 ++#define MC_CCR43_VALUE 0x566504 ++#define MC_CCR44_VALUE 0x566504 ++#define MC_CCR45_VALUE 0x565F17 ++#define MC_CCR46_VALUE 0x565F17 ++#define MC_CCR47_VALUE 0x0 ++#define MC_CCR48_VALUE 0x0 ++#define MC_CCR49_VALUE 0x0 ++#define MC_CCR50_VALUE 0x0 ++#define MC_CCR51_VALUE 0x0 ++#define MC_CCR52_VALUE 0x133 ++#define MC_CCR53_VALUE 0xF3014B27 ++#define MC_CCR54_VALUE 0xF3014B27 ++#define MC_CCR55_VALUE 0xF3014B27 ++#define MC_CCR56_VALUE 0xF3014B27 ++#define MC_CCR57_VALUE 0x7800301 ++#define MC_CCR58_VALUE 0x7800301 ++#define MC_CCR59_VALUE 0x7800301 ++#define MC_CCR60_VALUE 0x7800301 ++#define MC_CCR61_VALUE 0x4 +--- /dev/null ++++ b/board/avm/fb3370/fb3370.c +@@ -0,0 +1,139 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#include <common.h> ++#include <spi.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/chipid.h> ++#include <asm/lantiq/cpu.h> ++#include <asm/arch/gphy.h> ++ ++#if defined(CONFIG_SPL_BUILD) ++#define do_gpio_init 1 ++#define do_pll_init 1 ++#define do_dcdc_init 0 ++#elif defined(CONFIG_SYS_BOOT_RAM) ++#define do_gpio_init 1 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#elif defined(CONFIG_SYS_BOOT_NOR) ++#define do_gpio_init 1 ++#define do_pll_init 1 ++#define do_dcdc_init 1 ++#else ++#define do_gpio_init 0 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#endif ++ ++static void gpio_init(void) ++{ ++ /* SPI CS 0.4 to serial flash */ ++ gpio_direction_output(10, 1); ++ ++ /* EBU.FL_CS1 as output for NAND CE */ ++ gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* EBU.FL_A23 as output for NAND CLE */ ++ gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* EBU.FL_A24 as output for NAND ALE */ ++ gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++ /* GPIO 3.0 as input for NAND Ready Busy */ ++ gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN); ++ /* GPIO 3.1 as output for NAND Read */ ++ gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT); ++} ++ ++int board_early_init_f(void) ++{ ++ if (do_gpio_init) ++ gpio_init(); ++ ++ if (do_pll_init) ++ ltq_pll_init(); ++ ++ if (do_dcdc_init) ++ ltq_dcdc_init(0x7F); ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */ ++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */ ++ { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */ ++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC3: unused */ ++ { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE }, ++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */ ++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */ ++ { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t * bis) ++{ ++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0; ++ const ulong fw_addr = 0x80FF0000; ++ ++ ltq_gphy_phy11g_a1x_load(fw_addr); ++ ++ ltq_cgu_gphy_clk_src(clk); ++ ++ ltq_rcu_gphy_boot(0, fw_addr); ++ ltq_rcu_gphy_boot(1, fw_addr); ++ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++int spi_cs_is_valid(unsigned int bus, unsigned int cs) ++{ ++ if (bus) ++ return 0; ++ ++ if (cs == 4) ++ return 1; ++ ++ return 0; ++} ++ ++void spi_cs_activate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 4: ++ gpio_set_value(10, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++void spi_cs_deactivate(struct spi_slave *slave) ++{ ++ switch (slave->cs) { ++ case 4: ++ gpio_set_value(10, 1); ++ break; ++ default: ++ break; ++ } ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -451,6 +451,9 @@ incaip mips + incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000 + incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000 + incaip_150MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=150000000 ++fb3370_ram mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_RAM ++fb3370_eva mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_EVA ++fb3370_sfspl mips mips32 fb3370 avm vrx200 fb3370:SYS_BOOT_SFSPL + easy80920_nor mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NOR + easy80920_norspl mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_NORSPL + easy80920_ram mips mips32 easy80920 lantiq vrx200 easy80920:SYS_BOOT_RAM +--- /dev/null ++++ b/include/configs/fb3370.h +@@ -0,0 +1,75 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "FB3370" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "AVM FritzBox 3370" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_SPI_FLASH ++#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29LV620 serial flash */ ++ ++#define CONFIG_LTQ_SUPPORT_NAND_FLASH ++ ++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */ ++#define CONFIG_SPL_SPI_BUS 0 ++#define CONFIG_SPL_SPI_CS 4 ++#define CONFIG_SPL_SPI_MAX_HZ 25000000 ++#define CONFIG_SPL_SPI_MODE 0 ++ ++#define CONFIG_LTQ_SPL_COMP_LZO ++#define CONFIG_LTQ_SPL_CONSOLE ++ ++#define CONFIG_SYS_DRAM_PROBE ++ ++/* Environment */ ++#define CONFIG_ENV_SPI_BUS CONFIG_SPL_SPI_BUS ++#define CONFIG_ENV_SPI_CS CONFIG_SPL_SPI_CS ++#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SPL_SPI_MAX_HZ ++#define CONFIG_ENV_SPI_MODE CONFIG_SPL_SPI_MODE ++ ++#if defined(CONFIG_SYS_BOOT_SFSPL) ++#define CONFIG_ENV_IS_IN_SPI_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_ENV_SIZE (8 * 1024) ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++#define CONFIG_ENV_UPDATE_UBOOT_SF \ ++ "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_SF ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch b/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch new file mode 100644 index 0000000..810770a --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Gigaset-SX76X.patch @@ -0,0 +1,264 @@ +From 66b56aa3a4810f10e0b0c77bb87279a8d64b566b Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Fri, 16 Dec 2011 11:55:45 +0100 +Subject: MIPS: add board support for Gigaset SX76X + +Signed-off-by: Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/gigaset/sx76x/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/gigaset/sx76x/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/gigaset/sx76x/ddr_settings.h +@@ -0,0 +1,56 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * generated with lantiq_ram_extract_magic.awk ++ * ++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#define MC_DC00_VALUE 0x1B1B ++#define MC_DC01_VALUE 0x0 ++#define MC_DC02_VALUE 0x0 ++#define MC_DC03_VALUE 0x0 ++#define MC_DC04_VALUE 0x0 ++#define MC_DC05_VALUE 0x200 ++#define MC_DC06_VALUE 0x605 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x202 ++#define MC_DC09_VALUE 0x70A ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xC02 ++#define MC_DC12_VALUE 0x1C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0xF3E ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xD ++#define MC_DC18_VALUE 0x300 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0xF00 ++#define MC_DC22_VALUE 0xF0F ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x63 ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x100 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x514 ++#define MC_DC29_VALUE 0x2D89 ++#define MC_DC30_VALUE 0x8300 ++#define MC_DC31_VALUE 0x2002 ++#define MC_DC32_VALUE 0x0 ++#define MC_DC33_VALUE 0x0 ++#define MC_DC34_VALUE 0x0 ++#define MC_DC35_VALUE 0x0 ++#define MC_DC36_VALUE 0x0 ++#define MC_DC37_VALUE 0x0 ++#define MC_DC38_VALUE 0x0 ++#define MC_DC39_VALUE 0x0 ++#define MC_DC40_VALUE 0x0 ++#define MC_DC41_VALUE 0x0 ++#define MC_DC42_VALUE 0x0 ++#define MC_DC43_VALUE 0x0 ++#define MC_DC44_VALUE 0x0 ++#define MC_DC45_VALUE 0x500 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/gigaset/sx76x/sx76x.c +@@ -0,0 +1,66 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#include <common.h> ++#include <switch.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/chipid.h> ++ ++static void gpio_init(void) ++{ ++ /* Activate reset line of ADM6996I switch */ ++ gpio_direction_output(19, 0); ++} ++ ++int board_early_init_f(void) ++{ ++ gpio_init(); ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* MAC0: Lantiq ADM6996I switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t *bis) ++{ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++static struct switch_device adm6996i_dev = { ++ .name = "adm6996i", ++ .cpu_port = 5, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ /* Deactivate reset line of ADM6996I switch */ ++ gpio_set_value(19, 1); ++ ++ /* ADM6996I needs some time to come out of reset */ ++ __udelay(50000); ++ ++ return switch_device_register(&adm6996i_dev); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -447,6 +447,8 @@ pb1000 mips + easy50712_nor mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NOR + easy50712_norspl mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_NORSPL + easy50712_ram mips mips32 easy50712 lantiq danube easy50712:SYS_BOOT_RAM ++gigasx76x_nor mips mips32 sx76x gigaset danube sx76x:SYS_BOOT_NOR ++gigasx76x_ram mips mips32 sx76x gigaset danube sx76x:SYS_BOOT_RAM + incaip mips mips32 incaip - incaip + incaip_100MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=100000000 + incaip_133MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=133000000 +--- /dev/null ++++ b/include/configs/sx76x.h +@@ -0,0 +1,71 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "GIGASX76X" ++#define CONFIG_IDENT_STRING " sx76x" ++#define CONFIG_BOARD_NAME "Gigaset sx76x" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_ADM6996I ++ ++/* Environment */ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (256 * 1024) ++#define CONFIG_ENV_SIZE (8 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#define CONFIG_ENV_SIZE (2 * 1024) ++#endif ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++/* Compression */ ++#define CONFIG_LZMA ++ ++/* Auto boot */ ++#define CONFIG_BOOTDELAY 2 ++ ++/* Environment configuration */ ++#define CONFIG_BOOTCOMMAND \ ++ "run addeth; bootm ${kernel_addr}" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "kernel_addr=0xB0040000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch b/package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch new file mode 100644 index 0000000..4156089 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch @@ -0,0 +1,248 @@ +From 289f7ed5d725067b4eb4b1a105bb63d55bf20392 Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Wed, 29 Aug 2012 22:08:41 +0200 +Subject: MIPS: add board support for Arcadyan ARV7518 + +Signed-off-by: Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/arcadyan/arv7518pw/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/arcadyan/arv7518pw/arv7518pw.c +@@ -0,0 +1,52 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#include <common.h> ++#include <switch.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/chipid.h> ++ ++int board_early_init_f(void) ++{ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* MAC0: Atheros ar8216 switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t *bis) ++{ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++static struct switch_device ar8216_dev = { ++ .name = "ar8216", ++ .cpu_port = 0, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ return switch_device_register(&ar8216_dev); ++} +--- /dev/null ++++ b/board/arcadyan/arv7518pw/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv7518pw/ddr_settings.h +@@ -0,0 +1,56 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * generated with lantiq_ram_extract_magic.awk ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#define MC_DC00_VALUE 0x1B1B ++#define MC_DC01_VALUE 0x0 ++#define MC_DC02_VALUE 0x0 ++#define MC_DC03_VALUE 0x0 ++#define MC_DC04_VALUE 0x0 ++#define MC_DC05_VALUE 0x200 ++#define MC_DC06_VALUE 0x605 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x102 ++#define MC_DC09_VALUE 0x70A ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xC02 ++#define MC_DC12_VALUE 0x1C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x134 ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xD ++#define MC_DC18_VALUE 0x301 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA03 ++#define MC_DC21_VALUE 0x1400 ++#define MC_DC22_VALUE 0x1414 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x5B ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x510 ++#define MC_DC29_VALUE 0x4E20 ++#define MC_DC30_VALUE 0x8235 ++#define MC_DC31_VALUE 0x0 ++#define MC_DC32_VALUE 0x0 ++#define MC_DC33_VALUE 0x0 ++#define MC_DC34_VALUE 0x0 ++#define MC_DC35_VALUE 0x0 ++#define MC_DC36_VALUE 0x0 ++#define MC_DC37_VALUE 0x0 ++#define MC_DC38_VALUE 0x0 ++#define MC_DC39_VALUE 0x0 ++#define MC_DC40_VALUE 0x0 ++#define MC_DC41_VALUE 0x0 ++#define MC_DC42_VALUE 0x0 ++#define MC_DC43_VALUE 0x0 ++#define MC_DC44_VALUE 0x0 ++#define MC_DC45_VALUE 0x500 ++#define MC_DC46_VALUE 0x0 +--- a/boards.cfg ++++ b/boards.cfg +@@ -438,6 +438,8 @@ vct_premium mips + vct_premium_onenand mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND + vct_premium_onenand_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE + vct_premium_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_SMALL_IMAGE ++arv7518pw_ram mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_RAM ++arv7518pw_nor mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_NOR + dbau1000 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1000 + dbau1100 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1100 + dbau1500 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1500 +--- /dev/null ++++ b/include/configs/arv7518pw.h +@@ -0,0 +1,69 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ARV7518PW" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan ARV7518PW" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_AR8216 ++ ++/* Environment */ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SIZE (64 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#define CONFIG_ENV_SIZE (2 * 1024) ++#endif ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++/* Compression */ ++#define CONFIG_LZMA ++ ++/* Auto boot */ ++#define CONFIG_BOOTDELAY 2 ++ ++/* Environment configuration */ ++#define CONFIG_BOOTCOMMAND \ ++ "run addeth; bootm ${kernel_addr}" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "kernel_addr=0xB0040000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch b/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch new file mode 100644 index 0000000..4698e67 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-Arcadyan-ARV4519.patch @@ -0,0 +1,248 @@ +From 4a738c02a7190756e01ba58c93c4b07bc6d6c2aa Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Wed, 29 Aug 2012 22:08:42 +0200 +Subject: MIPS: add board support for Arcadyan ARV4519 + +Signed-off-by: Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/arcadyan/arv4519pw/Makefile +@@ -0,0 +1,29 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).o ++ ++COBJS = $(BOARD).o ++ ++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++SOBJS := $(addprefix $(obj),$(SOBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) $(SOBJS) ++ $(call cmd_link_o_target, $(OBJS) $(SOBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +--- /dev/null ++++ b/board/arcadyan/arv4519pw/arv4519pw.c +@@ -0,0 +1,52 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#include <common.h> ++#include <switch.h> ++#include <asm/gpio.h> ++#include <asm/lantiq/eth.h> ++#include <asm/lantiq/reset.h> ++#include <asm/lantiq/chipid.h> ++ ++int board_early_init_f(void) ++{ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: " CONFIG_BOARD_NAME "\n"); ++ ltq_chip_print_info(); ++ ++ return 0; ++} ++ ++static const struct ltq_eth_port_config eth_port_config[] = { ++ /* MAC0: Atheros ar8216 switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE }, ++}; ++ ++static const struct ltq_eth_board_config eth_board_config = { ++ .ports = eth_port_config, ++ .num_ports = ARRAY_SIZE(eth_port_config), ++}; ++ ++int board_eth_init(bd_t *bis) ++{ ++ return ltq_eth_initialize(ð_board_config); ++} ++ ++static struct switch_device ar8216_dev = { ++ .name = "ar8216", ++ .cpu_port = 0, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ return switch_device_register(&ar8216_dev); ++} +--- /dev/null ++++ b/board/arcadyan/arv4519pw/config.mk +@@ -0,0 +1,8 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++# ++ ++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) +--- /dev/null ++++ b/board/arcadyan/arv4519pw/ddr_settings.h +@@ -0,0 +1,56 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * generated with lantiq_ram_extract_magic.awk ++ * ++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#define MC_DC00_VALUE 0x1B1B ++#define MC_DC01_VALUE 0x0 ++#define MC_DC02_VALUE 0x0 ++#define MC_DC03_VALUE 0x0 ++#define MC_DC04_VALUE 0x0 ++#define MC_DC05_VALUE 0x200 ++#define MC_DC06_VALUE 0x605 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x102 ++#define MC_DC09_VALUE 0x70A ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xC02 ++#define MC_DC12_VALUE 0x1C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x131 ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xD ++#define MC_DC18_VALUE 0x301 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0x1700 ++#define MC_DC22_VALUE 0x1717 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x5A ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x510 ++#define MC_DC29_VALUE 0x4E20 ++#define MC_DC30_VALUE 0x8235 ++#define MC_DC31_VALUE 0x0 ++#define MC_DC32_VALUE 0x0 ++#define MC_DC33_VALUE 0x0 ++#define MC_DC34_VALUE 0x0 ++#define MC_DC35_VALUE 0x0 ++#define MC_DC36_VALUE 0x0 ++#define MC_DC37_VALUE 0x0 ++#define MC_DC38_VALUE 0x0 ++#define MC_DC39_VALUE 0x0 ++#define MC_DC40_VALUE 0x0 ++#define MC_DC41_VALUE 0x0 ++#define MC_DC42_VALUE 0x0 ++#define MC_DC43_VALUE 0x0 ++#define MC_DC44_VALUE 0x0 ++#define MC_DC45_VALUE 0x500 ++#define MC_DC46_VALUE 0x0 +--- a/boards.cfg ++++ b/boards.cfg +@@ -438,6 +438,8 @@ vct_premium mips + vct_premium_onenand mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND + vct_premium_onenand_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE + vct_premium_small mips mips32 vct micronas - vct:VCT_PREMIUM,VCT_SMALL_IMAGE ++arv4519pw_ram mips mips32 arv4519pw arcadyan danube arv4519pw:SYS_BOOT_RAM ++arv4519pw_nor mips mips32 arv4519pw arcadyan danube arv4519pw:SYS_BOOT_NOR + arv7518pw_ram mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_RAM + arv7518pw_nor mips mips32 arv7518pw arcadyan danube arv7518pw:SYS_BOOT_NOR + dbau1000 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1000 +--- /dev/null ++++ b/include/configs/arv4519pw.h +@@ -0,0 +1,69 @@ ++/* ++ * This file is released under the terms of GPL v2 and any later version. ++ * See the file COPYING in the root directory of the source tree for details. ++ * ++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org> ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ARV4519PW" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan ARV4519PW" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_AR8216 ++ ++/* Environment */ ++#if defined(CONFIG_SYS_BOOT_NOR) ++#define CONFIG_ENV_IS_IN_FLASH ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_OFFSET (192 * 1024) ++#define CONFIG_ENV_SIZE (64 * 1024) ++#define CONFIG_ENV_SECT_SIZE (64 * 1024) ++#else ++#define CONFIG_ENV_IS_NOWHERE ++#define CONFIG_ENV_SIZE (2 * 1024) ++#endif ++ ++#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR ++ ++/* Console */ ++#define CONFIG_LTQ_ADVANCED_CONSOLE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_CONSOLE_ASC 1 ++#define CONFIG_CONSOLE_DEV "ttyLTQ1" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++/* Compression */ ++#define CONFIG_LZMA ++ ++/* Auto boot */ ++#define CONFIG_BOOTDELAY 2 ++ ++/* Environment configuration */ ++#define CONFIG_BOOTCOMMAND \ ++ "run addeth; bootm ${kernel_addr}" ++ ++#define CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "update-uboot-nor=run load-uboot-nor write-uboot-nor\0" ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ "kernel_addr=0xB0040000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch b/package/boot/uboot-lantiq/patches/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch new file mode 100644 index 0000000..77d48d1 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0029-tools-add-some-helper-tools-for-Lantiq-SoCs.patch @@ -0,0 +1,361 @@ +From 1b77d4249b5addbf3b0848db6992a445019a1865 Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Wed, 29 Aug 2012 22:08:42 +0200 +Subject: tools: add some helper tools for Lantiq SoCs + +Signed-off-by: Luka Perkov Luka Perkov <luka@openwrt.org> +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/tools/gct.pl +@@ -0,0 +1,155 @@ ++#!/usr/bin/perl ++ ++#use strict; ++#use Cwd; ++#use Env; ++ ++my $aline; ++my $lineid; ++my $length; ++my $address; ++my @bytes; ++my $addstr; ++my $chsum=0; ++my $count=0; ++my $firstime=1; ++my $i; ++my $currentaddr; ++my $tmp; ++my $holder=""; ++my $loadaddr; ++ ++if(@ARGV < 2){ ++ die("\n Syntax: perl gct.pl uart_ddr_settings.conf u-boot.srec u-boot.asc\n"); ++} ++ ++open(IN_UART_DDR_SETTINGS, "<$ARGV[0]") || die("failed to open uart_ddr_settings.conf\n"); ++open(IN_UART_SREC, "<$ARGV[1]") || die("failed to open u-boot.srec\n"); ++open(OUT_UBOOT_ASC, ">$ARGV[2]") || die("failed to open u-boot.asc\n"); ++ ++$i=0; ++while ($line = <IN_UART_DDR_SETTINGS>){ ++ if($line=~/\w/){ ++ if($line!~/[;#\*]/){ ++ if($i eq 0){ ++ printf OUT_UBOOT_ASC ("33333333"); ++ } ++ chomp($line); ++ $line=~s/\t//; ++ @array=split(/ +/,$line); ++ $j=0; ++ while(@array[$j]!~/\w/){ ++ $j=$j+1; ++ } ++ $addr=@array[$j]; ++ $regval=@array[$j+1]; ++ $addr=~s/0x//; ++ $regval=~s/0x//; ++ printf OUT_UBOOT_ASC ("%08x%08x",hex($addr),hex($regval)); ++ $i=$i+1; ++ if($i eq 8){ ++ $i=0; ++ printf OUT_UBOOT_ASC ("\n"); ++ } ++ } ++ } ++} ++ ++while($i lt 8 && $i gt 0){ ++ printf OUT_UBOOT_ASC "00"x8; ++ $i=$i+1; ++} ++ ++if($i eq 8){ ++ printf OUT_UBOOT_ASC ("\n"); ++} ++ ++while($aline=<IN_UART_SREC>){ ++ $aline=uc($aline); ++ chomp($aline); ++ next if(($aline=~/^S0/) || ($aline=~/^S7/)); ++ ($lineid, $length, $address, @bytes) = unpack"A2A2A8"."A2"x300, $aline; ++ $length = hex($length); ++ $address = hex($address); ++ $length -=5; ++ $i=0; ++ ++ while($length>0){ ++ if($firstime==1){ ++ $addstr = sprintf("%x", $address); ++ $addstr = "0"x(8-length($addstr)).$addstr; ++ print OUT_UBOOT_ASC $addstr; ++ addchsum($addstr); ++ $firstime=0; ++ $currentaddr=$address; ++ $loadaddr = $addstr; ++ } ++ else{ ++ if($count==64){ ++ $addstr = sprintf("%x", $currentaddr); ++ $addstr = "0"x(8-length($addstr)).$addstr; ++ print OUT_UBOOT_ASC $addstr; ++ addchsum($addstr); ++ $count=0; ++ } ++#printf("*** %x != %x\n", $address, $currentaddr) if $address != $currentaddr; ++ } ++ if($currentaddr < $address) { ++ print OUT_UBOOT_ASC "00"; ++ addchsum("00"); ++ $count++; ++ $currentaddr++; ++ } ++ else { ++ while($count<64){ ++ $bytes[$i]=~tr/ABCDEF/abcdef/; ++ print OUT_UBOOT_ASC "$bytes[$i]"; ++ addchsum($bytes[$i]); ++ $i++; ++ $count++; ++ $currentaddr++; ++ $length--; ++ last if($length==0); ++ } ++ } ++ if($count==64){ ++ print OUT_UBOOT_ASC "\n"; ++ } ++ } ++} ++if($count != 64){ ++ $tmp = "00"; ++ for($i=0;$i<(64-$count);$i++){ ++ print OUT_UBOOT_ASC "00"; ++ addchsum($tmp); ++ } ++ print OUT_UBOOT_ASC "\n"; ++} ++ ++ ++print OUT_UBOOT_ASC "11"x4; ++use integer; ++$chsum=$chsum & 0xffffffff; ++$chsum = sprintf("%X", $chsum); ++$chsum = "0"x(8-length($chsum)).$chsum; ++$chsum =~tr/ABCDEF/abcdef/; ++print OUT_UBOOT_ASC $chsum; ++print OUT_UBOOT_ASC "00"x60; ++print OUT_UBOOT_ASC "\n"; ++ ++print OUT_UBOOT_ASC "99"x4; ++print OUT_UBOOT_ASC $loadaddr; ++print OUT_UBOOT_ASC "00"x60; ++print OUT_UBOOT_ASC "\n"; ++ ++close OUT_UBOOT_ASC; ++ ++sub addchsum{ ++ my $cc=$_[0]; ++ $holder=$holder.$cc; ++ if(length($holder)==8){ ++ $holder = hex($holder); ++ $chsum+=$holder; ++ $holder=""; ++ } ++} +--- /dev/null ++++ b/tools/lantiq_extract_openwrt_patches.sh +@@ -0,0 +1,15 @@ ++#!/bin/bash ++ ++set -e ++set -x ++ ++test $# -eq 1 ++ ++openwrt_root=$(readlink -f $1) ++test -d $openwrt_root ++ ++uboot_lantiq_dir=$openwrt_root/package/boot/uboot-lantiq/patches ++test -d $uboot_lantiq_dir ++ ++rm -vf $uboot_lantiq_dir/* ++git format-patch -k -p --no-renames --text --full-index -o $uboot_lantiq_dir v2012.10..openwrt/v2013.01 +--- /dev/null ++++ b/tools/lantiq_ram_extract_magic.awk +@@ -0,0 +1,70 @@ ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011 Luka Perkov <luka@openwrt.org> ++# ++# usage: mips-openwrt-linux-objdump -EB -b binary -m mips:isa32r2 -D YOUR_IMAGE_DUMP | awk -f lantiq_ram_extract_magic.awk ++# ++ ++BEGIN { ++ print "/* " ++ print " * This file is released under the terms of GPL v2 and any later version. " ++ print " * See the file COPYING in the root directory of the source tree for details. " ++ print " * " ++ print " * generated with lantiq_ram_extract_magic.awk " ++ print " * " ++ print " * Copyright (C) 2011 Luka Perkov <luka@openwrt.org> " ++ print " */ " ++ print "" ++ ++ mc_dc_value=0 ++ mc_dc_number=0 ++ right_section=0 ++ mc_dc_value_print=0 ++ mc_dc_number_print=0 ++} ++ ++/t2,[0-9]+$/ { ++ if (right_section) { ++ split($4, tmp, ",") ++ mc_dc_value=sprintf("%X", tmp[2]) ++ mc_dc_value_print=1 ++ } ++} ++ ++/t2,0x[0-9a-f]+$/ { ++ if (right_section) { ++ split($4, tmp, ",0x") ++ mc_dc_value=sprintf("%s", tmp[2]) ++ mc_dc_value=toupper(mc_dc_value) ++ mc_dc_value_print=1 ++ } ++} ++ ++/t2,[0-9]+\(t1\)$/ { ++ if (right_section) { ++ split($4, tmp, ",") ++ split(tmp[2], tmp, "(") ++ mc_dc_number=tmp[1]/16 ++ mc_dc_number_print=1 ++ } ++} ++ ++{ ++ if (right_section && mc_dc_number_print && mc_dc_value_print) { ++ if (mc_dc_number < 10) ++ print "#define MC_DC0" mc_dc_number "_VALUE\t0x" mc_dc_value ++ else ++ print "#define MC_DC" mc_dc_number "_VALUE\t0x" mc_dc_value ++ mc_dc_value_print=0 ++ mc_dc_number_print=0 ++ } ++ ++ if ($4 == "t1,t1,0x1000") ++ right_section=1 ++ ++ ++ if ($4 == "t2,736(t1)") ++ right_section=0 ++} +--- /dev/null ++++ b/tools/lantiq_ram_init_uart.awk +@@ -0,0 +1,101 @@ ++#!/usr/bin/awk -f ++# ++# This file is released under the terms of GPL v2 and any later version. ++# See the file COPYING in the root directory of the source tree for details. ++# ++# Copyright (C) 2011-2012 Luka Perkov <luka@openwrt.org> ++# Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@gmail.com> ++# ++# usage: awk -f lantiq_ram_init_uart.awk -v soc=<danube|ar9|vr9> PATH_TO_BOARD/ddr_settings.h ++# ++ ++function print_header() ++{ ++ print "; " ++ print "; This file is released under the terms of GPL v2 and any later version. " ++ print "; See the file COPYING in the root directory of the source tree for details. " ++ print "; " ++ print "; generated with lantiq_ram_init_uart.awk " ++ print "; " ++ print "; Copyright (C) 2011-2012 Luka Perkov <luka@openwrt.org> " ++ print "; Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@gmail.com> " ++ print "; " ++ print "" ++} ++ ++function mc_ddr1_prologue() ++{ ++ /* Clear access error log registers */ ++ print "0xbf800010", "0x0" ++ print "0xbf800020", "0x0" ++ ++ /* Enable DDR and SRAM module in memory controller */ ++ print "0xbf800060", "0x5" ++ ++ /* Clear start bit of DDR memory controller */ ++ print "0xbf801030", "0x0" ++} ++ ++function mc_ddr1_epilogue() ++{ ++ /* Set start bit of DDR memory controller */ ++ print "0xbf801030", "0x100" ++} ++ ++function mc_ddr2_prologue() ++{ ++ /* Put memory controller in inactive mode */ ++ print "0xbf401070", "0x0" ++} ++ ++function mc_ddr2_epilogue(mc_ccr07_value) ++{ ++ /* Put memory controller in active mode */ ++ mc_ccr07_value = or(mc_ccr07_value, 0x100) ++ printf("0xbf401070 0x%x\n", mc_ccr07_value) ++} ++ ++BEGIN { ++ switch (soc) { ++ case "danube": ++ case "ar9": ++ reg_base = 0xbf801000 ++ print_header() ++ mc_ddr1_prologue() ++ break ++ case "vr9": ++ reg_base = 0xbf401000 ++ print_header() ++ mc_ddr2_prologue() ++ break ++ default: ++ print "Invalid or no value for soc specified!" ++ exit 1 ++ } ++ ++ mc_ccr07_value = 0 ++} ++ ++/^#define/ { ++ printf("0x%x %s\n", reg_base, tolower($3)) ++ reg_base += 0x10 ++} ++ ++/^#define(.*)MC_CCR07_VALUE/ { ++ printf("0x%x %s\n", reg_base, tolower($3)) ++ reg_base += 0x10 ++ mc_ccr07_value = strtonum($3) ++} ++ ++END { ++ switch (soc) { ++ case "danube": ++ case "ar9": ++ mc_ddr1_epilogue() ++ break ++ case "vr9": ++ mc_ddr2_epilogue(mc_ccr07_value) ++ break ++ default: ++ } ++} diff --git a/package/boot/uboot-omap35xx/.svn/entries b/package/boot/uboot-omap35xx/.svn/entries new file mode 100644 index 0000000..9de4baa --- /dev/null +++ b/package/boot/uboot-omap35xx/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap35xx +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +9740ce10bcacfd7eca1e227f2f9acde9 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +1940 + diff --git a/package/boot/uboot-omap35xx/.svn/text-base/Makefile.svn-base b/package/boot/uboot-omap35xx/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..928acc7 --- /dev/null +++ b/package/boot/uboot-omap35xx/.svn/text-base/Makefile.svn-base @@ -0,0 +1,89 @@ +# +# Copyright (C) 2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2010.12 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:= +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/omap3_overo + TITLE:=U-boot for the gumstix board +endef + +UBOOTS:=omap3_overo + +define Package/uboot/template +define Package/uboot-omap35xx-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_omap35xx + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) +endef +endef + +define BuildUbootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Prepare + $(call Build/Prepare/Default) + $(CP) ./files/* $(PKG_BUILD_DIR) + find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf +endef + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/template +define Package/uboot-omap35xx-$(1)/install + $(INSTALL_DIR) $$(1) + $(CP) $(PKG_BUILD_DIR)/u-boot.bin $(BIN_DIR)/$(2) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.bin)) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUbootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-omap35xx-$(u))) \ +) diff --git a/package/boot/uboot-omap35xx/Makefile b/package/boot/uboot-omap35xx/Makefile new file mode 100644 index 0000000..928acc7 --- /dev/null +++ b/package/boot/uboot-omap35xx/Makefile @@ -0,0 +1,89 @@ +# +# Copyright (C) 2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2010.12 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:= +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/omap3_overo + TITLE:=U-boot for the gumstix board +endef + +UBOOTS:=omap3_overo + +define Package/uboot/template +define Package/uboot-omap35xx-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_omap35xx + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) +endef +endef + +define BuildUbootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Prepare + $(call Build/Prepare/Default) + $(CP) ./files/* $(PKG_BUILD_DIR) + find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf +endef + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/template +define Package/uboot-omap35xx-$(1)/install + $(INSTALL_DIR) $$(1) + $(CP) $(PKG_BUILD_DIR)/u-boot.bin $(BIN_DIR)/$(2) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.bin)) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUbootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-omap35xx-$(u))) \ +) diff --git a/package/boot/uboot-omap35xx/files/.svn/entries b/package/boot/uboot-omap35xx/files/.svn/entries new file mode 100644 index 0000000..62713ad --- /dev/null +++ b/package/boot/uboot-omap35xx/files/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap35xx/files +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +include +dir + diff --git a/package/boot/uboot-omap35xx/files/include/.svn/entries b/package/boot/uboot-omap35xx/files/include/.svn/entries new file mode 100644 index 0000000..7b6d6a1 --- /dev/null +++ b/package/boot/uboot-omap35xx/files/include/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap35xx/files/include +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +configs +dir + diff --git a/package/boot/uboot-omap35xx/files/include/configs/.svn/entries b/package/boot/uboot-omap35xx/files/include/configs/.svn/entries new file mode 100644 index 0000000..8d43469 --- /dev/null +++ b/package/boot/uboot-omap35xx/files/include/configs/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap35xx/files/include/configs +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +omap3_overo.h +file + + + + +2013-03-17T12:13:21.000000Z +3b947b5d726443e694c1a0a5c77058c6 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +9612 + diff --git a/package/boot/uboot-omap35xx/files/include/configs/.svn/text-base/omap3_overo.h.svn-base b/package/boot/uboot-omap35xx/files/include/configs/.svn/text-base/omap3_overo.h.svn-base new file mode 100644 index 0000000..e1c930d --- /dev/null +++ b/package/boot/uboot-omap35xx/files/include/configs/.svn/text-base/omap3_overo.h.svn-base @@ -0,0 +1,316 @@ +/* + * Configuration settings for the Gumstix Overo board. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMV7 1 /* This is an ARM V7 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP34XX 1 /* which is a 34XX */ +#define CONFIG_OMAP3430 1 /* which is in a 3430 */ +#define CONFIG_OMAP3_OVERO 1 /* working with overo */ + +#define CONFIG_SDRC /* The chip has SDRC controller */ + +#include <asm/arch/cpu.h> /* get chip and board defs */ +#include <asm/arch/omap3.h> + +/* + * Display CPU and Board information + */ +#define CONFIG_DISPLAY_CPUINFO 1 +#define CONFIG_DISPLAY_BOARDINFO 1 + +/* Clock Defines */ +#define V_OSCK 26000000 /* Clock output from T2 */ +#define V_SCLK (V_OSCK >> 1) + +#undef CONFIG_USE_IRQ /* no support for IRQs */ +#define CONFIG_MISC_INIT_R + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 +#define CONFIG_REVISION_TAG 1 + +/* + * Size of malloc() pool + */ +#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */ + /* Sector */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (128 << 10)) + /* initial data */ + +/* + * Hardware drivers + */ + +/* + * NS16550 Configuration + */ +#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ + +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE (-4) +#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK + +/* + * select serial console configuration + */ +#define CONFIG_CONS_INDEX 3 +#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 +#define CONFIG_SERIAL3 3 + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, \ + 115200} +#define CONFIG_GENERIC_MMC 1 +#define CONFIG_MMC 1 +#define CONFIG_OMAP_HSMMC 1 +#define CONFIG_DOS_PARTITION 1 + +/* DDR - I use Micron DDR */ +#define CONFIG_OMAP3_MICRON_DDR 1 + +/* commands to include */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_CACHE +#define CONFIG_CMD_EXT2 /* EXT2 Support */ +#define CONFIG_CMD_FAT /* FAT support */ +#define CONFIG_CMD_JFFS2 /* JFFS2 Support */ + +#define CONFIG_CMD_I2C /* I2C serial bus support */ +#define CONFIG_CMD_MMC /* MMC support */ +#define CONFIG_CMD_NAND /* NAND support */ + +#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ +#undef CONFIG_CMD_FPGA /* FPGA configuration Support */ +#undef CONFIG_CMD_IMI /* iminfo */ +#undef CONFIG_CMD_IMLS /* List all found images */ +#undef CONFIG_CMD_NFS /* NFS support */ +#define CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */ + +#define CONFIG_SYS_NO_FLASH +#define CONFIG_HARD_I2C 1 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 1 +#define CONFIG_SYS_I2C_BUS 0 +#define CONFIG_SYS_I2C_BUS_SELECT 1 +#define CONFIG_I2C_MULTI_BUS 1 +#define CONFIG_DRIVER_OMAP34XX_I2C 1 + +/* + * TWL4030 + */ +#define CONFIG_TWL4030_POWER 1 +#define CONFIG_TWL4030_LED 1 + +/* + * Board NAND Info. + */ +#define CONFIG_SYS_NAND_QUIET_TEST 1 +#define CONFIG_NAND_OMAP_GPMC +#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */ + /* to access nand */ +#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */ + /* to access nand */ + /* at CS0 */ +#define GPMC_NAND_ECC_LP_x16_LAYOUT 1 + +#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */ + /* devices */ +#define CONFIG_JFFS2_NAND +/* nand device jffs2 lives on */ +#define CONFIG_JFFS2_DEV "nand0" +/* start of jffs2 partition */ +#define CONFIG_JFFS2_PART_OFFSET 0x680000 +#define CONFIG_JFFS2_PART_SIZE 0xf980000 /* size of jffs2 */ + /* partition */ + +/* Environment information */ +#define CONFIG_BOOTDELAY 5 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "loadaddr=0x82000000\0" \ + "console=ttyO2,115200n8\0" \ + "mpurate=500\0" \ + "vram=12M\0" \ + "dvimode=1024x768MR-16@60\0" \ + "defaultdisplay=dvi\0" \ + "mmcdev=0\0" \ + "mmcroot=/dev/mmcblk0p2 rw\0" \ + "mmcrootfstype=ext3 rootwait\0" \ + "nandroot='ubi0:rootfs ubi.mtd=5 ubi.mtd=6 ubi.mtd=7'\0" \ + "nandrootfstype=ubifs\0" \ + "mmcargs=setenv bootargs console=${console} " \ + "mpurate=${mpurate} " \ + "vram=${vram} " \ + "omapfb.mode=dvi:${dvimode} " \ + "omapfb.debug=y " \ + "omapdss.def_disp=${defaultdisplay} " \ + "root=${mmcroot} " \ + "rootfstype=${mmcrootfstype}\0" \ + "nandargs=setenv bootargs console=${console} " \ + "mpurate=${mpurate} " \ + "vram=${vram} " \ + "omapfb.mode=dvi:${dvimode} " \ + "omapfb.debug=y " \ + "omapdss.def_disp=${defaultdisplay} " \ + "root=${nandroot} " \ + "rootfstype=${nandrootfstype}\0" \ + "loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr\0" \ + "bootscript=echo Running bootscript from mmc ...; " \ + "source ${loadaddr}\0" \ + "loaduimage=fatload mmc ${mmcdev} ${loadaddr} uImage\0" \ + "mmcboot=echo Booting from mmc ...; " \ + "run mmcargs; " \ + "bootm ${loadaddr}\0" \ + "nandboot=echo Booting from nand ...; " \ + "run nandargs; " \ + "nand read ${loadaddr} 280000 200000; " \ + "bootm ${loadaddr}\0" \ + +#define CONFIG_BOOTCOMMAND \ + "if mmc rescan ${mmcdev}; then " \ + "if run loadbootscript; then " \ + "run bootscript; " \ + "else " \ + "if run loaduimage; then " \ + "run mmcboot; " \ + "else run nandboot; " \ + "fi; " \ + "fi; " \ + "else run nandboot; fi" + +#define CONFIG_AUTO_COMPLETE 1 +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_PROMPT "Overo # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +/* Print Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command */ + /* args */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) +#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \ + 0x01F00000) /* 31MB */ + +#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default load */ + /* address */ +/* + * OMAP3 has 12 GP timers, they can be driven by the system clock + * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). + * This rate is divided by a local divisor. + */ +#define CONFIG_SYS_TIMERBASE OMAP34XX_GPT2 +#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ +#define CONFIG_SYS_HZ 1000 + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128 << 10) /* regular stack 128 KiB */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4 << 10) /* IRQ stack 4 KiB */ +#define CONFIG_STACKSIZE_FIQ (4 << 10) /* FIQ stack 4 KiB */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ +#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 +#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */ +#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1 + +/* SDRAM Bank Allocation method */ +#define SDRC_R_B_C 1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ + +/* **** PISMO SUPPORT *** */ + +/* Configure the PISMO */ +#define PISMO1_NAND_SIZE GPMC_SIZE_128M +#define PISMO1_ONEN_SIZE GPMC_SIZE_128M + +#define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */ + +#define CONFIG_SYS_FLASH_BASE boot_flash_base + +/* Monitor at start of flash */ +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE +#define CONFIG_SYS_ONENAND_BASE ONENAND_MAP + +#define CONFIG_ENV_IS_IN_NAND 1 +#define ONENAND_ENV_OFFSET 0x240000 /* environment starts here */ +#define SMNAND_ENV_OFFSET 0x240000 /* environment starts here */ + +#define CONFIG_SYS_ENV_SECT_SIZE boot_flash_sec +#define CONFIG_ENV_OFFSET boot_flash_off +#define CONFIG_ENV_ADDR SMNAND_ENV_OFFSET + +#ifndef __ASSEMBLY__ +extern unsigned int boot_flash_base; +extern volatile unsigned int boot_flash_env_addr; +extern unsigned int boot_flash_off; +extern unsigned int boot_flash_sec; +extern unsigned int boot_flash_type; +#endif + +#if defined(CONFIG_CMD_NET) +/*---------------------------------------------------------------------------- + * SMSC9211 Ethernet from SMSC9118 family + *---------------------------------------------------------------------------- + */ + +#define CONFIG_NET_MULTI +#define CONFIG_SMC911X 1 +#define CONFIG_SMC911X_32_BIT +#define CONFIG_SMC911X_BASE 0x2C000000 + +#endif /* (CONFIG_CMD_NET) */ + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define CONFIG_SYS_INIT_RAM_ADDR 0x4020f800 +#define CONFIG_SYS_INIT_RAM_SIZE 0x800 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ + CONFIG_SYS_INIT_RAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) + +#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-omap35xx/files/include/configs/omap3_overo.h b/package/boot/uboot-omap35xx/files/include/configs/omap3_overo.h new file mode 100644 index 0000000..e1c930d --- /dev/null +++ b/package/boot/uboot-omap35xx/files/include/configs/omap3_overo.h @@ -0,0 +1,316 @@ +/* + * Configuration settings for the Gumstix Overo board. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMV7 1 /* This is an ARM V7 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP34XX 1 /* which is a 34XX */ +#define CONFIG_OMAP3430 1 /* which is in a 3430 */ +#define CONFIG_OMAP3_OVERO 1 /* working with overo */ + +#define CONFIG_SDRC /* The chip has SDRC controller */ + +#include <asm/arch/cpu.h> /* get chip and board defs */ +#include <asm/arch/omap3.h> + +/* + * Display CPU and Board information + */ +#define CONFIG_DISPLAY_CPUINFO 1 +#define CONFIG_DISPLAY_BOARDINFO 1 + +/* Clock Defines */ +#define V_OSCK 26000000 /* Clock output from T2 */ +#define V_SCLK (V_OSCK >> 1) + +#undef CONFIG_USE_IRQ /* no support for IRQs */ +#define CONFIG_MISC_INIT_R + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 +#define CONFIG_REVISION_TAG 1 + +/* + * Size of malloc() pool + */ +#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */ + /* Sector */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (128 << 10)) + /* initial data */ + +/* + * Hardware drivers + */ + +/* + * NS16550 Configuration + */ +#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ + +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE (-4) +#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK + +/* + * select serial console configuration + */ +#define CONFIG_CONS_INDEX 3 +#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 +#define CONFIG_SERIAL3 3 + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, \ + 115200} +#define CONFIG_GENERIC_MMC 1 +#define CONFIG_MMC 1 +#define CONFIG_OMAP_HSMMC 1 +#define CONFIG_DOS_PARTITION 1 + +/* DDR - I use Micron DDR */ +#define CONFIG_OMAP3_MICRON_DDR 1 + +/* commands to include */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_CACHE +#define CONFIG_CMD_EXT2 /* EXT2 Support */ +#define CONFIG_CMD_FAT /* FAT support */ +#define CONFIG_CMD_JFFS2 /* JFFS2 Support */ + +#define CONFIG_CMD_I2C /* I2C serial bus support */ +#define CONFIG_CMD_MMC /* MMC support */ +#define CONFIG_CMD_NAND /* NAND support */ + +#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ +#undef CONFIG_CMD_FPGA /* FPGA configuration Support */ +#undef CONFIG_CMD_IMI /* iminfo */ +#undef CONFIG_CMD_IMLS /* List all found images */ +#undef CONFIG_CMD_NFS /* NFS support */ +#define CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */ + +#define CONFIG_SYS_NO_FLASH +#define CONFIG_HARD_I2C 1 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 1 +#define CONFIG_SYS_I2C_BUS 0 +#define CONFIG_SYS_I2C_BUS_SELECT 1 +#define CONFIG_I2C_MULTI_BUS 1 +#define CONFIG_DRIVER_OMAP34XX_I2C 1 + +/* + * TWL4030 + */ +#define CONFIG_TWL4030_POWER 1 +#define CONFIG_TWL4030_LED 1 + +/* + * Board NAND Info. + */ +#define CONFIG_SYS_NAND_QUIET_TEST 1 +#define CONFIG_NAND_OMAP_GPMC +#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */ + /* to access nand */ +#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */ + /* to access nand */ + /* at CS0 */ +#define GPMC_NAND_ECC_LP_x16_LAYOUT 1 + +#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */ + /* devices */ +#define CONFIG_JFFS2_NAND +/* nand device jffs2 lives on */ +#define CONFIG_JFFS2_DEV "nand0" +/* start of jffs2 partition */ +#define CONFIG_JFFS2_PART_OFFSET 0x680000 +#define CONFIG_JFFS2_PART_SIZE 0xf980000 /* size of jffs2 */ + /* partition */ + +/* Environment information */ +#define CONFIG_BOOTDELAY 5 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "loadaddr=0x82000000\0" \ + "console=ttyO2,115200n8\0" \ + "mpurate=500\0" \ + "vram=12M\0" \ + "dvimode=1024x768MR-16@60\0" \ + "defaultdisplay=dvi\0" \ + "mmcdev=0\0" \ + "mmcroot=/dev/mmcblk0p2 rw\0" \ + "mmcrootfstype=ext3 rootwait\0" \ + "nandroot='ubi0:rootfs ubi.mtd=5 ubi.mtd=6 ubi.mtd=7'\0" \ + "nandrootfstype=ubifs\0" \ + "mmcargs=setenv bootargs console=${console} " \ + "mpurate=${mpurate} " \ + "vram=${vram} " \ + "omapfb.mode=dvi:${dvimode} " \ + "omapfb.debug=y " \ + "omapdss.def_disp=${defaultdisplay} " \ + "root=${mmcroot} " \ + "rootfstype=${mmcrootfstype}\0" \ + "nandargs=setenv bootargs console=${console} " \ + "mpurate=${mpurate} " \ + "vram=${vram} " \ + "omapfb.mode=dvi:${dvimode} " \ + "omapfb.debug=y " \ + "omapdss.def_disp=${defaultdisplay} " \ + "root=${nandroot} " \ + "rootfstype=${nandrootfstype}\0" \ + "loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr\0" \ + "bootscript=echo Running bootscript from mmc ...; " \ + "source ${loadaddr}\0" \ + "loaduimage=fatload mmc ${mmcdev} ${loadaddr} uImage\0" \ + "mmcboot=echo Booting from mmc ...; " \ + "run mmcargs; " \ + "bootm ${loadaddr}\0" \ + "nandboot=echo Booting from nand ...; " \ + "run nandargs; " \ + "nand read ${loadaddr} 280000 200000; " \ + "bootm ${loadaddr}\0" \ + +#define CONFIG_BOOTCOMMAND \ + "if mmc rescan ${mmcdev}; then " \ + "if run loadbootscript; then " \ + "run bootscript; " \ + "else " \ + "if run loaduimage; then " \ + "run mmcboot; " \ + "else run nandboot; " \ + "fi; " \ + "fi; " \ + "else run nandboot; fi" + +#define CONFIG_AUTO_COMPLETE 1 +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_PROMPT "Overo # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +/* Print Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command */ + /* args */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) +#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \ + 0x01F00000) /* 31MB */ + +#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default load */ + /* address */ +/* + * OMAP3 has 12 GP timers, they can be driven by the system clock + * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). + * This rate is divided by a local divisor. + */ +#define CONFIG_SYS_TIMERBASE OMAP34XX_GPT2 +#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ +#define CONFIG_SYS_HZ 1000 + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128 << 10) /* regular stack 128 KiB */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4 << 10) /* IRQ stack 4 KiB */ +#define CONFIG_STACKSIZE_FIQ (4 << 10) /* FIQ stack 4 KiB */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ +#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 +#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */ +#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1 + +/* SDRAM Bank Allocation method */ +#define SDRC_R_B_C 1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ + +/* **** PISMO SUPPORT *** */ + +/* Configure the PISMO */ +#define PISMO1_NAND_SIZE GPMC_SIZE_128M +#define PISMO1_ONEN_SIZE GPMC_SIZE_128M + +#define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */ + +#define CONFIG_SYS_FLASH_BASE boot_flash_base + +/* Monitor at start of flash */ +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE +#define CONFIG_SYS_ONENAND_BASE ONENAND_MAP + +#define CONFIG_ENV_IS_IN_NAND 1 +#define ONENAND_ENV_OFFSET 0x240000 /* environment starts here */ +#define SMNAND_ENV_OFFSET 0x240000 /* environment starts here */ + +#define CONFIG_SYS_ENV_SECT_SIZE boot_flash_sec +#define CONFIG_ENV_OFFSET boot_flash_off +#define CONFIG_ENV_ADDR SMNAND_ENV_OFFSET + +#ifndef __ASSEMBLY__ +extern unsigned int boot_flash_base; +extern volatile unsigned int boot_flash_env_addr; +extern unsigned int boot_flash_off; +extern unsigned int boot_flash_sec; +extern unsigned int boot_flash_type; +#endif + +#if defined(CONFIG_CMD_NET) +/*---------------------------------------------------------------------------- + * SMSC9211 Ethernet from SMSC9118 family + *---------------------------------------------------------------------------- + */ + +#define CONFIG_NET_MULTI +#define CONFIG_SMC911X 1 +#define CONFIG_SMC911X_32_BIT +#define CONFIG_SMC911X_BASE 0x2C000000 + +#endif /* (CONFIG_CMD_NET) */ + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define CONFIG_SYS_INIT_RAM_ADDR 0x4020f800 +#define CONFIG_SYS_INIT_RAM_SIZE 0x800 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ + CONFIG_SYS_INIT_RAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) + +#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-omap4/.svn/entries b/package/boot/uboot-omap4/.svn/entries new file mode 100644 index 0000000..b8dfce9 --- /dev/null +++ b/package/boot/uboot-omap4/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-omap4 +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +5d245a30082c95e1b75afc31e6884530 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +2010 + diff --git a/package/boot/uboot-omap4/.svn/text-base/Makefile.svn-base b/package/boot/uboot-omap4/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..d128e16 --- /dev/null +++ b/package/boot/uboot-omap4/.svn/text-base/Makefile.svn-base @@ -0,0 +1,90 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2011.12 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=7f29b9f6da44d6e46e988e7561fd1d5f +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/omap4_panda + TITLE:=U-Boot for the Pandaboard +endef + +UBOOTS:=omap4_panda + +define Package/uboot/template +define Package/uboot-omap4-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_omap4 + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) +endef +endef + +define BuildUbootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Prepare + $(call Build/Prepare/Default) +# $(CP) ./files/* $(PKG_BUILD_DIR) + find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf +endef + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/template +define Package/uboot-omap4-$(1)/install + $(INSTALL_DIR) $$(1) + $(CP) $(PKG_BUILD_DIR)/MLO $(BIN_DIR)/MLO-$(BOARD) + $(CP) $(PKG_BUILD_DIR)/u-boot.img $(BIN_DIR)/$(2) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.img)) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUbootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-omap4-$(u))) \ +) diff --git a/package/boot/uboot-omap4/Makefile b/package/boot/uboot-omap4/Makefile new file mode 100644 index 0000000..d128e16 --- /dev/null +++ b/package/boot/uboot-omap4/Makefile @@ -0,0 +1,90 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2011.12 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=7f29b9f6da44d6e46e988e7561fd1d5f +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/omap4_panda + TITLE:=U-Boot for the Pandaboard +endef + +UBOOTS:=omap4_panda + +define Package/uboot/template +define Package/uboot-omap4-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_omap4 + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) +endef +endef + +define BuildUbootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Prepare + $(call Build/Prepare/Default) +# $(CP) ./files/* $(PKG_BUILD_DIR) + find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf +endef + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/template +define Package/uboot-omap4-$(1)/install + $(INSTALL_DIR) $$(1) + $(CP) $(PKG_BUILD_DIR)/MLO $(BIN_DIR)/MLO-$(BOARD) + $(CP) $(PKG_BUILD_DIR)/u-boot.img $(BIN_DIR)/$(2) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.img)) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUbootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-omap4-$(u))) \ +) diff --git a/package/boot/uboot-pxa/.svn/entries b/package/boot/uboot-pxa/.svn/entries new file mode 100644 index 0000000..cd230d0 --- /dev/null +++ b/package/boot/uboot-pxa/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-pxa +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +0fadf5838e09edaec577b298d7e9c4eb +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +1980 + diff --git a/package/boot/uboot-pxa/.svn/text-base/Makefile.svn-base b/package/boot/uboot-pxa/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..7fe747c --- /dev/null +++ b/package/boot/uboot-pxa/.svn/text-base/Makefile.svn-base @@ -0,0 +1,89 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2011.08.25 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=git://github.com/ashcharles/verdex-uboot.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=ca6bf3ef6ac5f5132a359b43dfa31e07076b74b7 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/gumstix + TITLE:=U-Boot for the Gumstix Verdex +endef + +UBOOTS:=gumstix + +define Package/uboot/template +define Package/uboot-pxa-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_pxa + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Florian Fainelli <florian@openwrt.org> +endef +endef + +define BuildUBootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + u-boot.bin \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/default + $(INSTALL_DIR) $(BIN_DIR) + $(CP) $(PKG_BUILD_DIR)/u-boot.bin \ + $(BIN_DIR)/openwrt-$(BOARD)-$(1)-u-boot.bin +endef + +define Package/uboot/install/template +define Package/uboot-pxa-$(1)/install + $(call Package/uboot/install/default,$(2)) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),$(u))) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUBootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-pxa-$(u))) \ +) diff --git a/package/boot/uboot-pxa/Makefile b/package/boot/uboot-pxa/Makefile new file mode 100644 index 0000000..7fe747c --- /dev/null +++ b/package/boot/uboot-pxa/Makefile @@ -0,0 +1,89 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2011.08.25 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=git://github.com/ashcharles/verdex-uboot.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=ca6bf3ef6ac5f5132a359b43dfa31e07076b74b7 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/gumstix + TITLE:=U-Boot for the Gumstix Verdex +endef + +UBOOTS:=gumstix + +define Package/uboot/template +define Package/uboot-pxa-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_pxa + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Florian Fainelli <florian@openwrt.org> +endef +endef + +define BuildUBootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + u-boot.bin \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/default + $(INSTALL_DIR) $(BIN_DIR) + $(CP) $(PKG_BUILD_DIR)/u-boot.bin \ + $(BIN_DIR)/openwrt-$(BOARD)-$(1)-u-boot.bin +endef + +define Package/uboot/install/template +define Package/uboot-pxa-$(1)/install + $(call Package/uboot/install/default,$(2)) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),$(u))) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUBootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-pxa-$(u))) \ +) diff --git a/package/boot/uboot-pxa/patches/.svn/entries b/package/boot/uboot-pxa/patches/.svn/entries new file mode 100644 index 0000000..be5d3b6 --- /dev/null +++ b/package/boot/uboot-pxa/patches/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-pxa/patches +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +001-squashfs_rootfstype_cmdline.patch +file + + + + +2013-03-17T12:13:21.000000Z +cb4baee4e5cf315fe29485e6f3c4d943 +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +1105 + diff --git a/package/boot/uboot-pxa/patches/.svn/text-base/001-squashfs_rootfstype_cmdline.patch.svn-base b/package/boot/uboot-pxa/patches/.svn/text-base/001-squashfs_rootfstype_cmdline.patch.svn-base new file mode 100644 index 0000000..cfef66b --- /dev/null +++ b/package/boot/uboot-pxa/patches/.svn/text-base/001-squashfs_rootfstype_cmdline.patch.svn-base @@ -0,0 +1,13 @@ +diff --git a/include/configs/gumstix.h b/include/configs/gumstix.h +index 319da63..5483993 100644 +--- a/include/configs/gumstix.h ++++ b/include/configs/gumstix.h +@@ -136,7 +136,7 @@ + #define CONFIG_MISC_INIT_R /* misc_init_r function in gumstix sets board serial number */ + + #define CONFIG_BOOTFILE boot/uImage +-#define CONFIG_BOOTARGS "console=ttyS0,115200n8 root=1f01 rootfstype=jffs2 reboot=cold,hard" ++#define CONFIG_BOOTARGS "console=ttyS0,115200n8 root=1f01 rootfstype=squashfs,jffs2 reboot=cold,hard" + #define CONFIG_BOOTCOMMAND "icache on; setenv stderr nulldev; setenv stdout nulldev; if pinit on && fatload ide 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on CF...; autoscr; else if mmcinit && fatload mmc 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on MMC...; autoscr; else setenv stdout serial; setenv stderr serial; katload 100000 && bootm; fi; fi" + #define CONFIG_BOOTDELAY 2 /* in seconds */ + #define CONFIG_EXTRA_ENV_SETTINGS "verify=no" diff --git a/package/boot/uboot-pxa/patches/001-squashfs_rootfstype_cmdline.patch b/package/boot/uboot-pxa/patches/001-squashfs_rootfstype_cmdline.patch new file mode 100644 index 0000000..cfef66b --- /dev/null +++ b/package/boot/uboot-pxa/patches/001-squashfs_rootfstype_cmdline.patch @@ -0,0 +1,13 @@ +diff --git a/include/configs/gumstix.h b/include/configs/gumstix.h +index 319da63..5483993 100644 +--- a/include/configs/gumstix.h ++++ b/include/configs/gumstix.h +@@ -136,7 +136,7 @@ + #define CONFIG_MISC_INIT_R /* misc_init_r function in gumstix sets board serial number */ + + #define CONFIG_BOOTFILE boot/uImage +-#define CONFIG_BOOTARGS "console=ttyS0,115200n8 root=1f01 rootfstype=jffs2 reboot=cold,hard" ++#define CONFIG_BOOTARGS "console=ttyS0,115200n8 root=1f01 rootfstype=squashfs,jffs2 reboot=cold,hard" + #define CONFIG_BOOTCOMMAND "icache on; setenv stderr nulldev; setenv stdout nulldev; if pinit on && fatload ide 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on CF...; autoscr; else if mmcinit && fatload mmc 0 a2000000 gumstix-factory.script; then setenv stdout serial; setenv stderr serial; echo Found gumstix-factory.script on MMC...; autoscr; else setenv stdout serial; setenv stderr serial; katload 100000 && bootm; fi; fi" + #define CONFIG_BOOTDELAY 2 /* in seconds */ + #define CONFIG_EXTRA_ENV_SETTINGS "verify=no" diff --git a/package/boot/uboot-xburst/.svn/entries b/package/boot/uboot-xburst/.svn/entries new file mode 100644 index 0000000..f21bf90 --- /dev/null +++ b/package/boot/uboot-xburst/.svn/entries @@ -0,0 +1,68 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst +svn://svn.openwrt.org/openwrt + + + +2013-01-07T17:11:15.287568Z +35042 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +e4c7934e9ef907cf8d46a731519a560c +2013-01-07T17:11:15.287568Z +35042 +mirko + + + + + + + + + + + + + + + + + + + + + +1820 + diff --git a/package/boot/uboot-xburst/.svn/text-base/Makefile.svn-base b/package/boot/uboot-xburst/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..f4c8ad9 --- /dev/null +++ b/package/boot/uboot-xburst/.svn/text-base/Makefile.svn-base @@ -0,0 +1,83 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2012.10-rc2 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=451c07271940016cec6f5ad8a155263b +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/qi_lb60 + TITLE:=U-boot for the qi_lb60 board +endef + +UBOOTS:=qi_lb60 + +define Package/uboot/template +define Package/uboot-xburst-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_xburst + TITLE:=$(2) + URL:=http://www.denx.de/wiki/UBoot/WebHome + VARIANT:=$(1) +endef +endef + +define BuildUbootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/template +define Package/uboot-xburst-$(1)/install + $(CP) $(PKG_BUILD_DIR)/u-boot-xburst.bin $(BIN_DIR)/$(2) + rmdir $$(1) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.bin)) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUbootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-xburst-$(u))) \ +) diff --git a/package/boot/uboot-xburst/Makefile b/package/boot/uboot-xburst/Makefile new file mode 100644 index 0000000..f4c8ad9 --- /dev/null +++ b/package/boot/uboot-xburst/Makefile @@ -0,0 +1,83 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2012.10-rc2 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=451c07271940016cec6f5ad8a155263b +PKG_TARGETS:=bin + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + CONFIG:= + IMAGE:= +endef + +define uboot/qi_lb60 + TITLE:=U-boot for the qi_lb60 board +endef + +UBOOTS:=qi_lb60 + +define Package/uboot/template +define Package/uboot-xburst-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=@TARGET_xburst + TITLE:=$(2) + URL:=http://www.denx.de/wiki/UBoot/WebHome + VARIANT:=$(1) +endef +endef + +define BuildUbootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + $(call Package/uboot/template,$(1),$(TITLE)) +endef + + +ifdef BUILD_VARIANT +$(eval $(call uboot/$(BUILD_VARIANT))) +UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT)) +UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin) +endif + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(UBOOT_CONFIG)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/template +define Package/uboot-xburst-$(1)/install + $(CP) $(PKG_BUILD_DIR)/u-boot-xburst.bin $(BIN_DIR)/$(2) + rmdir $$(1) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.bin)) \ +) + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUbootPackage,$(u))) \ + $(eval $(call BuildPackage,uboot-xburst-$(u))) \ +) diff --git a/package/boot/uboot-xburst/files/.svn/entries b/package/boot/uboot-xburst/files/.svn/entries new file mode 100644 index 0000000..df14e18 --- /dev/null +++ b/package/boot/uboot-xburst/files/.svn/entries @@ -0,0 +1,40 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +include +dir + +board +dir + +cpu +dir + +nand_spl +dir + diff --git a/package/boot/uboot-xburst/files/board/.svn/entries b/package/boot/uboot-xburst/files/board/.svn/entries new file mode 100644 index 0000000..9c92717 --- /dev/null +++ b/package/boot/uboot-xburst/files/board/.svn/entries @@ -0,0 +1,37 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/board +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +nanonote +dir + +sakc +dir + +n516 +dir + diff --git a/package/boot/uboot-xburst/files/board/n516/.svn/entries b/package/boot/uboot-xburst/files/board/n516/.svn/entries new file mode 100644 index 0000000..7556702 --- /dev/null +++ b/package/boot/uboot-xburst/files/board/n516/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/board/n516 +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-xburst/files/board/nanonote/.svn/entries b/package/boot/uboot-xburst/files/board/nanonote/.svn/entries new file mode 100644 index 0000000..cd3d211 --- /dev/null +++ b/package/boot/uboot-xburst/files/board/nanonote/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/board/nanonote +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-xburst/files/board/sakc/.svn/entries b/package/boot/uboot-xburst/files/board/sakc/.svn/entries new file mode 100644 index 0000000..e22ec07 --- /dev/null +++ b/package/boot/uboot-xburst/files/board/sakc/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/board/sakc +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-xburst/files/cpu/.svn/entries b/package/boot/uboot-xburst/files/cpu/.svn/entries new file mode 100644 index 0000000..d6e3dc5 --- /dev/null +++ b/package/boot/uboot-xburst/files/cpu/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/cpu +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +mips +dir + diff --git a/package/boot/uboot-xburst/files/cpu/mips/.svn/entries b/package/boot/uboot-xburst/files/cpu/mips/.svn/entries new file mode 100644 index 0000000..05c73eb --- /dev/null +++ b/package/boot/uboot-xburst/files/cpu/mips/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/cpu/mips +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-xburst/files/include/.svn/entries b/package/boot/uboot-xburst/files/include/.svn/entries new file mode 100644 index 0000000..8288f2b --- /dev/null +++ b/package/boot/uboot-xburst/files/include/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/include +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +asm-mips +dir + +configs +dir + diff --git a/package/boot/uboot-xburst/files/include/asm-mips/.svn/entries b/package/boot/uboot-xburst/files/include/asm-mips/.svn/entries new file mode 100644 index 0000000..2a61466 --- /dev/null +++ b/package/boot/uboot-xburst/files/include/asm-mips/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/include/asm-mips +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-xburst/files/include/configs/.svn/entries b/package/boot/uboot-xburst/files/include/configs/.svn/entries new file mode 100644 index 0000000..52a7f07 --- /dev/null +++ b/package/boot/uboot-xburst/files/include/configs/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/include/configs +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-xburst/files/nand_spl/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/.svn/entries new file mode 100644 index 0000000..b02ad1e --- /dev/null +++ b/package/boot/uboot-xburst/files/nand_spl/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +board +dir + diff --git a/package/boot/uboot-xburst/files/nand_spl/board/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/board/.svn/entries new file mode 100644 index 0000000..3aae273 --- /dev/null +++ b/package/boot/uboot-xburst/files/nand_spl/board/.svn/entries @@ -0,0 +1,37 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl/board +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +nanonote +dir + +sakc +dir + +n516 +dir + diff --git a/package/boot/uboot-xburst/files/nand_spl/board/n516/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/board/n516/.svn/entries new file mode 100644 index 0000000..081f719 --- /dev/null +++ b/package/boot/uboot-xburst/files/nand_spl/board/n516/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl/board/n516 +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-xburst/files/nand_spl/board/nanonote/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/board/nanonote/.svn/entries new file mode 100644 index 0000000..5e23a35 --- /dev/null +++ b/package/boot/uboot-xburst/files/nand_spl/board/nanonote/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl/board/nanonote +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-xburst/files/nand_spl/board/sakc/.svn/entries b/package/boot/uboot-xburst/files/nand_spl/board/sakc/.svn/entries new file mode 100644 index 0000000..d7a0ad0 --- /dev/null +++ b/package/boot/uboot-xburst/files/nand_spl/board/sakc/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/files/nand_spl/board/sakc +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + diff --git a/package/boot/uboot-xburst/patches/.svn/entries b/package/boot/uboot-xburst/patches/.svn/entries new file mode 100644 index 0000000..352f1b4 --- /dev/null +++ b/package/boot/uboot-xburst/patches/.svn/entries @@ -0,0 +1,232 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/uboot-xburst/patches +svn://svn.openwrt.org/openwrt + + + +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch +file + + + + +2013-03-17T12:13:21.000000Z +318bc9342da0200c534c0b1552a9c2d5 +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + + + + + + + + +6931 + +0005-add-nanonote-lcd-support.patch +file + + + + +2013-03-17T12:13:21.000000Z +9e8ff8de93294556ae1855c647aa3b20 +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + + + + + + + + +27030 + +0001-qi_lb60-add-nand-spl-support.patch +file + + + + +2013-03-17T12:13:21.000000Z +d3a431d733f776288d3a555a25581e94 +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + + + + + + + + +27630 + +0006-enable-silent-console.patch +file + + + + +2013-03-17T12:13:21.000000Z +cda7306fbff5de64b84db2e0f5420c5e +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + + + + + + + + +1788 + +0003-add-mmc-support.patch +file + + + + +2013-03-17T12:13:21.000000Z +c509ed47f09ab80e5ca3be62e6733000 +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + + + + + + + + +47318 + +0002-qi_lb60-add-software-usbboot-support.patch +file + + + + +2013-03-17T12:13:21.000000Z +d400befeef1d1a82fe35fc586fa32061 +2013-01-07T14:10:01.049177Z +35034 +mirko + + + + + + + + + + + + + + + + + + + + + +22384 + diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0001-qi_lb60-add-nand-spl-support.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0001-qi_lb60-add-nand-spl-support.patch.svn-base new file mode 100644 index 0000000..e770243 --- /dev/null +++ b/package/boot/uboot-xburst/patches/.svn/text-base/0001-qi_lb60-add-nand-spl-support.patch.svn-base @@ -0,0 +1,894 @@ +From 0329cf7965956a5a7044827e0ce88ae8d5150e54 Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Fri, 12 Oct 2012 09:46:58 +0800 +Subject: [PATCH 1/6] qi_lb60: add nand spl support + + The JZ4740 CPU can load 8KB from two different addresses: + 1. the normal area up to 8KB starting from NAND flash address 0x00000000 + 2. the backup area up to 8KB starting from NAND flash address 0x00002000 + +Signed-off-by: Xiangfu <xiangfu@openmobilefree.net> +--- + Makefile | 12 +++ + arch/mips/cpu/xburst/Makefile | 7 +- + arch/mips/cpu/xburst/cpu.c | 4 + + arch/mips/cpu/xburst/jz4740.c | 82 +++++++---------- + arch/mips/cpu/xburst/spl/Makefile | 47 ++++++++++ + arch/mips/cpu/xburst/spl/start.S | 63 +++++++++++++ + board/qi/qi_lb60/Makefile | 4 + + board/qi/qi_lb60/qi_lb60-spl.c | 30 +++++++ + board/qi/qi_lb60/qi_lb60.c | 8 +- + board/qi/qi_lb60/u-boot-spl.lds | 61 +++++++++++++ + drivers/mtd/nand/jz4740_nand.c | 39 ++++++++- + include/configs/qi_lb60.h | 175 ++++++++++++++++++------------------- + 12 files changed, 386 insertions(+), 146 deletions(-) + create mode 100644 arch/mips/cpu/xburst/spl/Makefile + create mode 100644 arch/mips/cpu/xburst/spl/start.S + create mode 100644 board/qi/qi_lb60/qi_lb60-spl.c + create mode 100644 board/qi/qi_lb60/u-boot-spl.lds + +diff --git a/Makefile b/Makefile +index 34d9075..a22778e 100644 +--- a/Makefile ++++ b/Makefile +@@ -393,6 +393,10 @@ ALL-y += $(obj)u-boot-nodtb-tegra.bin + endif + endif + ++ifeq ($(CPU),xburst) ++ALL-y += $(obj)u-boot-xburst.bin ++endif ++ + all: $(ALL-y) $(SUBDIR_EXAMPLES) + + $(obj)u-boot.dtb: $(obj)u-boot +@@ -506,6 +510,14 @@ $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin + endif + endif + ++ifeq ($(CPU),xburst) ++$(obj)u-boot-xburst.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin ++ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync bs=8192 count=1 ++ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=8192 count=1 ++ tr '\0' '\377' < /dev/zero | dd of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=16384 count=1 ++ cat $(obj)spl/u-boot-pad.bin u-boot.bin > $@ ++endif ++ + ifeq ($(CONFIG_SANDBOX),y) + GEN_UBOOT = \ + cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \ +diff --git a/arch/mips/cpu/xburst/Makefile b/arch/mips/cpu/xburst/Makefile +index b1f2ae4..ec35e55 100644 +--- a/arch/mips/cpu/xburst/Makefile ++++ b/arch/mips/cpu/xburst/Makefile +@@ -24,9 +24,12 @@ include $(TOPDIR)/config.mk + + LIB = $(obj)lib$(CPU).o + ++COBJS-y = cpu.o jz_serial.o ++ ++ifneq ($(CONFIG_SPL_BUILD),y) + START = start.o +-SOBJS-y = +-COBJS-y = cpu.o timer.o jz_serial.o ++COBJS-y += timer.o ++endif + + COBJS-$(CONFIG_JZ4740) += jz4740.o + +diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c +index ddcbfaa..1432838 100644 +--- a/arch/mips/cpu/xburst/cpu.c ++++ b/arch/mips/cpu/xburst/cpu.c +@@ -42,6 +42,8 @@ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + ++#ifndef CONFIG_SPL_BUILD ++ + void __attribute__((weak)) _machine_restart(void) + { + struct jz4740_wdt *wdt = (struct jz4740_wdt *)JZ4740_WDT_BASE; +@@ -109,6 +111,8 @@ void invalidate_dcache_range(ulong start_addr, ulong stop) + cache_op(Hit_Invalidate_D, addr); + } + ++#endif ++ + void flush_icache_all(void) + { + u32 addr, t = 0; +diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c +index c0b9817..8816aa3 100644 +--- a/arch/mips/cpu/xburst/jz4740.c ++++ b/arch/mips/cpu/xburst/jz4740.c +@@ -32,31 +32,19 @@ int disable_interrupts(void) + return 0; + } + +-/* +- * PLL output clock = EXTAL * NF / (NR * NO) +- * NF = FD + 2, NR = RD + 2 +- * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3) +- */ + void pll_init(void) + { + struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE; + +- register unsigned int cfcr, plcr1; +- int n2FR[33] = { +- 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, +- 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, +- 9 +- }; +- int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ +- int nf, pllout2; ++ register unsigned int cfcr, plcr; ++ unsigned int nf, pllout2; + + cfcr = CPM_CPCCR_CLKOEN | +- CPM_CPCCR_PCS | +- (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | +- (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | +- (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | +- (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) | +- (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT); ++ (0 << CPM_CPCCR_CDIV_BIT) | ++ (2 << CPM_CPCCR_HDIV_BIT) | ++ (2 << CPM_CPCCR_PDIV_BIT) | ++ (2 << CPM_CPCCR_MDIV_BIT) | ++ (2 << CPM_CPCCR_LDIV_BIT); + + pllout2 = (cfcr & CPM_CPCCR_PCS) ? + CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2); +@@ -65,15 +53,18 @@ void pll_init(void) + writel(pllout2 / 48000000 - 1, &cpm->uhccdr); + + nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL; +- plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ ++ plcr = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ + (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ + (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ +- (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ ++ (0x32 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ + CPM_CPPCR_PLLEN; /* enable PLL */ + + /* init PLL */ + writel(cfcr, &cpm->cpccr); +- writel(plcr1, &cpm->cppcr); ++ writel(plcr, &cpm->cppcr); ++ ++ while (!(readl(&cpm->cppcr) & CPM_CPPCR_PLLS)) ++ ; + } + + void sdram_init(void) +@@ -92,26 +83,12 @@ void sdram_init(void) + 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */ + }; + +- int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; +- + cpu_clk = CONFIG_SYS_CPU_SPEED; +- mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()]; ++ mem_clk = 84000000; + + writel(0, &emc->bcr); /* Disable bus release */ + writew(0, &emc->rtcsr); /* Disable clock for counting */ + +- /* Fault DMCR value for mode register setting*/ +-#define SDRAM_ROW0 11 +-#define SDRAM_COL0 8 +-#define SDRAM_BANK40 0 +- +- dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) | +- ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) | +- (SDRAM_BANK40 << EMC_DMCR_BA_BIT) | +- (SDRAM_BW16 << EMC_DMCR_BW_BIT) | +- EMC_DMCR_EPIN | +- cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; +- + /* Basic DMCR value */ + dmcr = ((SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) | + ((SDRAM_COL - 8) << EMC_DMCR_CA_BIT) | +@@ -128,31 +105,31 @@ void sdram_init(void) + if (tmp > 11) + tmp = 11; + dmcr |= (tmp - 4) << EMC_DMCR_TRAS_BIT; +- tmp = SDRAM_RCD / ns; + ++ tmp = SDRAM_RCD / ns; + if (tmp > 3) + tmp = 3; + dmcr |= tmp << EMC_DMCR_RCD_BIT; +- tmp = SDRAM_TPC / ns; + ++ tmp = SDRAM_TPC / ns; + if (tmp > 7) + tmp = 7; + dmcr |= tmp << EMC_DMCR_TPC_BIT; +- tmp = SDRAM_TRWL / ns; + ++ tmp = SDRAM_TRWL / ns; + if (tmp > 3) + tmp = 3; + dmcr |= tmp << EMC_DMCR_TRWL_BIT; +- tmp = (SDRAM_TRAS + SDRAM_TPC) / ns; + ++ tmp = (SDRAM_TRAS + SDRAM_TPC) / ns; + if (tmp > 14) + tmp = 14; + dmcr |= ((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT; + + /* SDRAM mode value */ +- sdmode = EMC_SDMR_BT_SEQ | +- EMC_SDMR_OM_NORMAL | +- EMC_SDMR_BL_4 | ++ sdmode = EMC_SDMR_BT_SEQ | ++ EMC_SDMR_OM_NORMAL | ++ EMC_SDMR_BL_4 | + cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)]; + + /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */ +@@ -172,8 +149,8 @@ void sdram_init(void) + if (tmp > 0xff) + tmp = 0xff; + writew(tmp, &emc->rtcor); ++ + writew(0, &emc->rtcnt); +- /* Divisor is 64, CKO/64 */ + writew(EMC_RTCSR_CKS_64, &emc->rtcsr); + + /* Wait for number of auto-refresh cycles */ +@@ -182,13 +159,17 @@ void sdram_init(void) + ; + + /* Stage 3. Mode Register Set */ ++ dmcr0 = (11 << EMC_DMCR_RA_BIT) | ++ (8 << EMC_DMCR_CA_BIT) | ++ (0 << EMC_DMCR_BA_BIT) | ++ EMC_DMCR_EPIN | ++ (SDRAM_BW16 << EMC_DMCR_BW_BIT) | ++ cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; + writel(dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr); + writeb(0, JZ4740_EMC_SDMR0 | sdmode); + + /* Set back to basic DMCR value */ + writel(dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr); +- +- /* everything is ok now */ + } + + DECLARE_GLOBAL_DATA_PTR; +@@ -232,9 +213,10 @@ void rtc_init(void) + phys_size_t initdram(int board_type) + { + struct jz4740_emc *emc = (struct jz4740_emc *)JZ4740_EMC_BASE; +- u32 dmcr; +- u32 rows, cols, dw, banks; +- ulong size; ++ ++ unsigned int dmcr; ++ unsigned int rows, cols, dw, banks; ++ unsigned long size; + + dmcr = readl(&emc->dmcr); + rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT); +diff --git a/arch/mips/cpu/xburst/spl/Makefile b/arch/mips/cpu/xburst/spl/Makefile +new file mode 100644 +index 0000000..f45e8c8 +--- /dev/null ++++ b/arch/mips/cpu/xburst/spl/Makefile +@@ -0,0 +1,47 @@ ++# ++# Copyright (C) 2011 Xiangfu Liu <xiangfu@openmobilefree.net> ++# ++# See file CREDITS for list of people who contributed to this ++# project. ++# ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License as ++# published by the Free Software Foundation; either version 2 of ++# the License, or (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++# MA 02111-1307 USA ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(CPU).o ++ ++START = start.o ++SOBJS-y = ++COBJS-y = ++ ++SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) ++OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) ++START := $(addprefix $(obj),$(START)) ++ ++all: $(obj).depend $(START) $(LIB) ++ ++$(LIB): $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +diff --git a/arch/mips/cpu/xburst/spl/start.S b/arch/mips/cpu/xburst/spl/start.S +new file mode 100644 +index 0000000..e31c4c8 +--- /dev/null ++++ b/arch/mips/cpu/xburst/spl/start.S +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (c) 2010 Xiangfu Liu <xiangfu@openmobilefree.net> ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 3 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#include <config.h> ++#include <version.h> ++#include <asm/regdef.h> ++#include <asm/mipsregs.h> ++#include <asm/addrspace.h> ++#include <asm/cacheops.h> ++ ++#include <asm/jz4740.h> ++ ++ .set noreorder ++ ++ .globl _start ++ .text ++_start: ++ .word JZ4740_NANDBOOT_CFG /* fetched during NAND Boot */ ++reset: ++ /* ++ * STATUS register ++ * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1 ++ */ ++ li t0, 0x0040FC04 ++ mtc0 t0, CP0_STATUS ++ /* ++ * CAUSE register ++ * IV=1, use the specical interrupt vector (0x200) ++ */ ++ li t1, 0x00800000 ++ mtc0 t1, CP0_CAUSE ++ ++ bal 1f ++ nop ++ .word _GLOBAL_OFFSET_TABLE_ ++1: ++ move gp, ra ++ lw t1, 0(ra) ++ move gp, t1 ++ ++ la sp, 0x80004000 ++ la t9, nand_spl_boot ++ j t9 ++ nop +diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile +index 5dae11b..e399246 100644 +--- a/board/qi/qi_lb60/Makefile ++++ b/board/qi/qi_lb60/Makefile +@@ -22,7 +22,11 @@ include $(TOPDIR)/config.mk + + LIB = $(obj)lib$(BOARD).o + ++ifeq ($(CONFIG_SPL_BUILD),y) ++COBJS := $(BOARD)-spl.o ++else + COBJS := $(BOARD).o ++endif + + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) + OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c +new file mode 100644 +index 0000000..3fe3fa3 +--- /dev/null ++++ b/board/qi/qi_lb60/qi_lb60-spl.c +@@ -0,0 +1,30 @@ ++/* ++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.cc> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 3 of the License, or (at your option) any later version. ++ */ ++ ++#include <common.h> ++#include <nand.h> ++#include <asm/io.h> ++#include <asm/jz4740.h> ++ ++void nand_spl_boot(void) ++{ ++ __gpio_as_sdram_16bit_4720(); ++ __gpio_as_uart0(); ++ __gpio_jtag_to_uart0(); ++ ++ serial_init(); ++ ++ pll_init(); ++ sdram_init(); ++ ++ nand_init(); ++ ++ puts("\nQi LB60 SPL: Starting U-Boot ...\n"); ++ nand_boot(); ++} +diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c +index d975209..3bd4e2f 100644 +--- a/board/qi/qi_lb60/qi_lb60.c ++++ b/board/qi/qi_lb60/qi_lb60.c +@@ -1,5 +1,5 @@ + /* +- * Authors: Xiangfu Liu <xiangfu@sharism.cc> ++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -97,8 +97,10 @@ int board_early_init_f(void) + /* U-Boot common routines */ + int checkboard(void) + { +- printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC, Speed %ld MHz)\n", +- gd->cpu_clk / 1000000); ++ printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC)\n"); ++ printf(" CPU: %ld\n", gd->cpu_clk); ++ printf(" MEM: %ld\n", gd->mem_clk); ++ printf(" DEV: %ld\n", gd->dev_clk); + + return 0; + } +diff --git a/board/qi/qi_lb60/u-boot-spl.lds b/board/qi/qi_lb60/u-boot-spl.lds +new file mode 100644 +index 0000000..930537f +--- /dev/null ++++ b/board/qi/qi_lb60/u-boot-spl.lds +@@ -0,0 +1,61 @@ ++/* ++ * (C) Copyright 2012 Xiangfu Liu <xiangfu@openmobilefree.net> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips") ++ ++OUTPUT_ARCH(mips) ++ENTRY(_start) ++SECTIONS ++{ ++ . = 0x80000000; ++ . = ALIGN(4); ++ .text : ++ { ++ *(.text) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } ++ ++ . = ALIGN(4); ++ .data : { *(.data) } ++ ++ . = ALIGN(4); ++ .sdata : { *(.sdata) } ++ ++ _gp = ALIGN(16); ++ ++ __got_start = .; ++ .got : { *(.got) } ++ __got_end = .; ++ ++ . = .; ++ __u_boot_cmd_start = .; ++ .u_boot_cmd : { *(.u_boot_cmd) } ++ __u_boot_cmd_end = .; ++ ++ uboot_end_data = .; ++ num_got_entries = (__got_end - __got_start) >> 2; ++ ++ . = ALIGN(4); ++ .sbss : { *(.sbss) } ++ .bss : { *(.bss) } ++ uboot_end = .; ++} ++ASSERT(uboot_end <= 0x80002000, "NAND bootstrap too big"); +diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c +index 3ec34f3..24a4921 100644 +--- a/drivers/mtd/nand/jz4740_nand.c ++++ b/drivers/mtd/nand/jz4740_nand.c +@@ -15,6 +15,9 @@ + #include <asm/io.h> + #include <asm/jz4740.h> + ++#ifdef CONFIG_SPL_BUILD ++#define printf(s) puts(s) ++#endif + #define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000) + #define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000) + #define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000) +@@ -176,7 +179,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat, + for (k = 0; k < 9; k++) + writeb(read_ecc[k], &emc->nfpar[k]); + } +- /* Set PRDY */ ++ + writel(readl(&emc->nfecr) | EMC_NFECR_PRDY, &emc->nfecr); + + /* Wait for completion */ +@@ -184,7 +187,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat, + status = readl(&emc->nfints); + } while (!(status & EMC_NFINTS_DECF)); + +- /* disable ecc */ ++ /* Disable ECC */ + writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr); + + /* Check decoding */ +@@ -192,7 +195,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat, + return 0; + + if (status & EMC_NFINTS_UNCOR) { +- printf("uncorrectable ecc\n"); ++ printf("JZ4740 uncorrectable ECC\n"); + return -1; + } + +@@ -230,6 +233,32 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat, + return errcnt; + } + ++#ifdef CONFIG_SPL_BUILD ++static void jz_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++#if (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R3) || \ ++ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R2) ++ for (i = 0; i < len; i += 2) ++ buf[i] = readw(this->IO_ADDR_R); ++#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R3) || \ ++ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R2) ++ for (i = 0; i < len; i++) ++ buf[i] = readb(this->IO_ADDR_R); ++#else ++ #error JZ4740_NANDBOOT_CFG not defined or wrong ++#endif ++} ++ ++static uint8_t jz_nand_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ return readb(this->IO_ADDR_R); ++} ++#endif ++ + /* + * Main initialization routine + */ +@@ -254,6 +283,10 @@ int board_nand_init(struct nand_chip *nand) + nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; + nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; + nand->ecc.layout = &qi_lb60_ecclayout_2gb; ++#ifdef CONFIG_SPL_BUILD ++ nand->read_byte = jz_nand_read_byte; ++ nand->read_buf = jz_nand_read_buf; ++#endif + nand->chip_delay = 50; + nand->options = NAND_USE_FLASH_BBT; + +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index 4bb5bbc..7bff444 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -1,5 +1,5 @@ + /* +- * Authors: Xiangfu Liu <xiangfu.z@gmail.com> ++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -14,7 +14,6 @@ + #define CONFIG_SYS_LITTLE_ENDIAN + #define CONFIG_JZSOC /* Jz SoC */ + #define CONFIG_JZ4740 /* Jz4740 SoC */ +-#define CONFIG_NAND_JZ4740 + + #define CONFIG_SYS_CPU_SPEED 336000000 /* CPU clock: 336 MHz */ + #define CONFIG_SYS_EXTAL 12000000 /* EXTAL freq: 12 MHz */ +@@ -24,24 +23,43 @@ + #define CONFIG_SYS_UART_BASE JZ4740_UART0_BASE /* Base of the UART channel */ + #define CONFIG_BAUDRATE 57600 + ++#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL) ++#define CONFIG_BOOTDELAY 0 ++#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait" ++#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x280000;bootm" ++ ++/* ++ * Miscellaneous configurable options ++ */ ++#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ ++#define CONFIG_SYS_INIT_SP_OFFSET 0x400000 ++#define CONFIG_SYS_LOAD_ADDR 0x80600000 ++#define CONFIG_SYS_MEMTEST_START 0x80100000 ++#define CONFIG_SYS_MEMTEST_END 0x80A00000 ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE ++ ++#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) ++#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024) ++ ++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) ++ ++#define CONFIG_SYS_LONGHELP ++#define CONFIG_SYS_MAXARGS 16 ++#define CONFIG_SYS_PROMPT "NanoNote# " ++ + #define CONFIG_SKIP_LOWLEVEL_INIT + #define CONFIG_BOARD_EARLY_INIT_F + #define CONFIG_SYS_NO_FLASH + #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */ +-#define CONFIG_ENV_OVERWRITE +- +-#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL) +-#define CONFIG_BOOTDELAY 0 +-#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait" +-#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x200000;bootm" + + /* +- * Command line configuration. ++ * Command line configuration + */ + #define CONFIG_CMD_BOOTD /* bootd */ + #define CONFIG_CMD_CONSOLE /* coninfo */ + #define CONFIG_CMD_ECHO /* echo arguments */ +- + #define CONFIG_CMD_LOADB /* loadb */ + #define CONFIG_CMD_LOADS /* loads */ + #define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop mtest */ +@@ -58,45 +76,16 @@ + #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ + + /* +- * Miscellaneous configurable options +- */ +-#define CONFIG_SYS_MAXARGS 16 +-#define CONFIG_SYS_LONGHELP +-#define CONFIG_SYS_PROMPT "NanoNote# " +-#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +- +-#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) +-#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024) +- +-#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ +-#define CONFIG_SYS_INIT_SP_OFFSET 0x400000 +-#define CONFIG_SYS_LOAD_ADDR 0x80600000 +-#define CONFIG_SYS_MEMTEST_START 0x80100000 +-#define CONFIG_SYS_MEMTEST_END 0x80800000 +- +-/* +- * Environment ++ * NAND driver configuration + */ +-#define CONFIG_ENV_IS_IN_NAND /* use NAND for environment vars */ +- +-#define CONFIG_SYS_NAND_5_ADDR_CYCLE +-/* +- * if board nand flash is 1GB, set to 1 +- * if board nand flash is 2GB, set to 2 +- * for change the PAGE_SIZE and BLOCK_SIZE +- * will delete when there is no 1GB flash +- */ +-#define NANONOTE_NAND_SIZE 2 +- +-#define CONFIG_SYS_NAND_PAGE_SIZE (2048 * NANONOTE_NAND_SIZE) +-#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * NANONOTE_NAND_SIZE << 10) +-/* nand bad block was marked at this page in a block, start from 0 */ ++#define CONFIG_NAND_JZ4740 ++#define CONFIG_SYS_NAND_PAGE_SIZE 4096 ++#define CONFIG_SYS_NAND_BLOCK_SIZE (512 << 10) ++/* NAND bad block was marked at this page in a block, start from 0 */ + #define CONFIG_SYS_NAND_BADBLOCK_PAGE 127 + #define CONFIG_SYS_NAND_PAGE_COUNT 128 + #define CONFIG_SYS_NAND_BAD_BLOCK_POS 0 +-/* ECC offset position in oob area, default value is 6 if it isn't defined */ +-#define CONFIG_SYS_NAND_ECC_POS (6 * NANONOTE_NAND_SIZE) ++#define CONFIG_SYS_NAND_ECC_POS 12 + #define CONFIG_SYS_NAND_ECCSIZE 512 + #define CONFIG_SYS_NAND_ECCBYTES 9 + #define CONFIG_SYS_NAND_ECCPOS \ +@@ -115,10 +104,9 @@ + #define CONFIG_SYS_ONENAND_BASE CONFIG_SYS_NAND_BASE + #define CONFIG_SYS_MAX_NAND_DEVICE 1 + #define CONFIG_SYS_NAND_SELECT_DEVICE 1 /* nand driver supports mutipl.*/ +-#define CONFIG_NAND_SPL_TEXT_BASE 0x80000000 + + /* +- * IPL (Initial Program Loader, integrated inside CPU) ++ * IPL (Initial Program Loader, integrated inside Ingenic Xburst JZ4740 CPU) + * Will load first 8k from NAND (SPL) into cache and execute it from there. + * + * SPL (Secondary Program Loader) +@@ -130,77 +118,88 @@ + * NUB (NAND U-Boot) + * This NAND U-Boot (NUB) is a special U-Boot version which can be started + * from RAM. Therefore it mustn't (re-)configure the SDRAM controller. +- * + */ ++ ++/* ++ * NAND SPL configuration ++ */ ++#define CONFIG_SPL ++#define CONFIG_SPL_LIBGENERIC_SUPPORT ++#define CONFIG_SPL_LIBCOMMON_SUPPORT ++#define CONFIG_SPL_NAND_LOAD ++#define CONFIG_SPL_NAND_SIMPLE ++#define CONFIG_SPL_NAND_SUPPORT ++#define CONFIG_SPL_TEXT_BASE 0x80000000 ++#define CONFIG_SPL_START_S_PATH "arch/mips/cpu/xburst/spl" ++ ++#define CONFIG_SYS_NAND_5_ADDR_CYCLE ++#define CONFIG_SYS_NAND_HW_ECC_OOBFIRST ++#define JZ4740_NANDBOOT_CFG JZ4740_NANDBOOT_B8R3 ++ + #define CONFIG_SYS_NAND_U_BOOT_DST 0x80100000 /* Load NUB to this addr */ + #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST +-/* Start NUB from this addr*/ ++ /* Start NUB from this addr */ ++#define CONFIG_SYS_NAND_U_BOOT_OFFS (32 << 10) /* Offset of NUB */ ++#define CONFIG_SYS_NAND_U_BOOT_SIZE (256 << 10) /* Size of NUB */ + + /* +- * Define the partitioning of the NAND chip (only RAM U-Boot is needed here) ++ * Environment configuration + */ +-#define CONFIG_SYS_NAND_U_BOOT_OFFS (256 << 10) /* Offset to RAM U-Boot image */ +-#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 << 10) /* Size of RAM U-Boot image */ +- ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_IS_IN_NAND + #define CONFIG_ENV_SIZE (4 << 10) + #define CONFIG_ENV_OFFSET \ + (CONFIG_SYS_NAND_BLOCK_SIZE + CONFIG_SYS_NAND_U_BOOT_SIZE) + #define CONFIG_ENV_OFFSET_REDUND \ + (CONFIG_ENV_OFFSET + CONFIG_SYS_NAND_BLOCK_SIZE) + +-#define CONFIG_SYS_TEXT_BASE 0x80100000 +-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE +- + /* +- * SDRAM Info. ++ * CPU cache configuration + */ +-#define CONFIG_NR_DRAM_BANKS 1 ++#define CONFIG_SYS_DCACHE_SIZE 16384 ++#define CONFIG_SYS_ICACHE_SIZE 16384 ++#define CONFIG_SYS_CACHELINE_SIZE 32 + + /* +- * Cache Configuration ++ * SDRAM configuration + */ +-#define CONFIG_SYS_DCACHE_SIZE 16384 +-#define CONFIG_SYS_ICACHE_SIZE 16384 +-#define CONFIG_SYS_CACHELINE_SIZE 32 ++#define CONFIG_NR_DRAM_BANKS 1 ++ ++#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */ ++#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */ ++#define SDRAM_ROW 13 /* Row address: 11 to 13 */ ++#define SDRAM_COL 9 /* Column address: 8 to 12 */ ++#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */ ++#define SDRAM_TRAS 45 /* RAS# Active Time */ ++#define SDRAM_RCD 20 /* RAS# to CAS# Delay */ ++#define SDRAM_TPC 20 /* RAS# Precharge Time */ ++#define SDRAM_TRWL 7 /* Write Latency Time */ ++#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */ + + /* +- * GPIO definition ++ * GPIO configuration + */ +-#define GPIO_LCD_CS (2 * 32 + 21) +-#define GPIO_AMP_EN (3 * 32 + 4) ++#define GPIO_LCD_CS (2 * 32 + 21) ++#define GPIO_AMP_EN (3 * 32 + 4) + +-#define GPIO_SDPW_EN (3 * 32 + 2) +-#define GPIO_SD_DETECT (3 * 32 + 0) ++#define GPIO_SDPW_EN (3 * 32 + 2) ++#define GPIO_SD_DETECT (3 * 32 + 0) + +-#define GPIO_BUZZ_PWM (3 * 32 + 27) +-#define GPIO_USB_DETECT (3 * 32 + 28) ++#define GPIO_BUZZ_PWM (3 * 32 + 27) ++#define GPIO_USB_DETECT (3 * 32 + 28) + +-#define GPIO_AUDIO_POP (1 * 32 + 29) +-#define GPIO_COB_TEST (1 * 32 + 30) ++#define GPIO_AUDIO_POP (1 * 32 + 29) ++#define GPIO_COB_TEST (1 * 32 + 30) + + #define GPIO_KEYOUT_BASE (2 * 32 + 10) +-#define GPIO_KEYIN_BASE (3 * 32 + 18) +-#define GPIO_KEYIN_8 (3 * 32 + 26) ++#define GPIO_KEYIN_BASE (3 * 32 + 18) ++#define GPIO_KEYIN_8 (3 * 32 + 26) + +-#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */ ++#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */ + #define GPIO_SD_VCC_EN_N GPIO_SDPW_EN /* SD Card Power Enable */ + + #define SPEN GPIO_LCD_CS /* LCDCS :Serial command enable */ + #define SPDA (2 * 32 + 22) /* LCDSCL:Serial command clock input */ + #define SPCK (2 * 32 + 23) /* LCDSDA:Serial command data input */ + +-/* SDRAM paramters */ +-#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */ +-#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */ +-#define SDRAM_ROW 13 /* Row address: 11 to 13 */ +-#define SDRAM_COL 9 /* Column address: 8 to 12 */ +-#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */ +- +-/* SDRAM Timings, unit: ns */ +-#define SDRAM_TRAS 45 /* RAS# Active Time */ +-#define SDRAM_RCD 20 /* RAS# to CAS# Delay */ +-#define SDRAM_TPC 20 /* RAS# Precharge Time */ +-#define SDRAM_TRWL 7 /* Write Latency Time */ +-#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */ +- + #endif +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0002-qi_lb60-add-software-usbboot-support.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0002-qi_lb60-add-software-usbboot-support.patch.svn-base new file mode 100644 index 0000000..feaf297 --- /dev/null +++ b/package/boot/uboot-xburst/patches/.svn/text-base/0002-qi_lb60-add-software-usbboot-support.patch.svn-base @@ -0,0 +1,916 @@ +From fa51192b912d296b8eec10f7d44c6c17eb1dd368 Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Fri, 12 Oct 2012 09:47:39 +0800 +Subject: [PATCH 2/6] qi_lb60: add software usbboot support + + JZ4740 CPU have a internal ROM have such kind of code, that make + JZ4740 can boot from USB + + usbboot.S can downloads user program from the USB port to internal + SRAM and branches to the internal SRAM to execute the program + +Signed-off-by: Xiangfu <xiangfu@openmobilefree.net> +--- + board/qi/qi_lb60/Makefile | 1 + + board/qi/qi_lb60/qi_lb60-spl.c | 20 + + board/qi/qi_lb60/usbboot.S | 838 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 859 insertions(+) + create mode 100644 board/qi/qi_lb60/usbboot.S + +diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile +index e399246..6dd8c6f 100644 +--- a/board/qi/qi_lb60/Makefile ++++ b/board/qi/qi_lb60/Makefile +@@ -23,6 +23,7 @@ include $(TOPDIR)/config.mk + LIB = $(obj)lib$(BOARD).o + + ifeq ($(CONFIG_SPL_BUILD),y) ++SOBJS := usbboot.o + COBJS := $(BOARD)-spl.o + else + COBJS := $(BOARD).o +diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c +index 3fe3fa3..aea459c 100644 +--- a/board/qi/qi_lb60/qi_lb60-spl.c ++++ b/board/qi/qi_lb60/qi_lb60-spl.c +@@ -12,6 +12,24 @@ + #include <asm/io.h> + #include <asm/jz4740.h> + ++#define KEY_U_OUT (32 * 2 + 16) ++#define KEY_U_IN (32 * 3 + 19) ++ ++extern void usb_boot(void); ++ ++static void check_usb_boot(void) ++{ ++ __gpio_as_input(KEY_U_IN); ++ __gpio_enable_pull(KEY_U_IN); ++ __gpio_as_output(KEY_U_OUT); ++ __gpio_clear_pin(KEY_U_OUT); ++ ++ if (!__gpio_get_pin(KEY_U_IN)) { ++ puts("[U] pressed, goto USBBOOT mode\n"); ++ usb_boot(); ++ } ++} ++ + void nand_spl_boot(void) + { + __gpio_as_sdram_16bit_4720(); +@@ -23,6 +41,8 @@ void nand_spl_boot(void) + pll_init(); + sdram_init(); + ++ check_usb_boot(); ++ + nand_init(); + + puts("\nQi LB60 SPL: Starting U-Boot ...\n"); +diff --git a/board/qi/qi_lb60/usbboot.S b/board/qi/qi_lb60/usbboot.S +new file mode 100644 +index 0000000..c872266 +--- /dev/null ++++ b/board/qi/qi_lb60/usbboot.S +@@ -0,0 +1,838 @@ ++/* ++ * for jz4740 usb boot ++ * ++ * Copyright (c) 2009 Author: <jlwei@ingenic.cn> ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ .set noreorder ++ .globl usb_boot ++ .text ++ ++/* ++ * Both NAND and USB boot load data to D-Cache first, then transfer ++ * data from D-Cache to I-Cache, and jump to execute the code in I-Cache. ++ * So init caches first and then dispatch to a proper boot routine. ++ */ ++ ++.macro load_addr reg addr ++ li \reg, 0x80000000 ++ addiu \reg, \reg, \addr ++ la $2, usbboot_begin ++ subu \reg, \reg, $2 ++.endm ++ ++usb_boot: ++ /* Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. */ ++ la $9, 0xB0000000 /* CPCCR: Clock Control Register */ ++ la $8, 0x42041110 /* I:S:M:P=1:2:2:2 */ ++ sw $8, 0($9) ++ ++ la $9, 0xB0000010 /* CPPCR: PLL Control Register */ ++ la $8, 0x06000120 /* M=12 N=0 D=0 CLK=12*(M+2)/(N+2) */ ++ sw $8, 0($9) ++ ++ mtc0 $0, $26 /* CP0_ERRCTL, restore WST reset state */ ++ nop ++ ++ mtc0 $0, $16 /* CP0_CONFIG */ ++ nop ++ ++ /* Relocate code to beginning of the ram */ ++ ++ la $2, usbboot_begin ++ la $3, usbboot_end ++ li $4, 0x80000000 ++ ++1: ++ lw $5, 0($2) ++ sw $5, 0($4) ++ addiu $2, $2, 4 ++ bne $2, $3, 1b ++ addiu $4, $4, 4 ++ ++ li $2, 0x80000000 ++ ori $3, $2, 0 ++ addiu $3, $3, usbboot_end ++ la $4, usbboot_begin ++ subu $3, $3, $4 ++ ++ ++2: ++ cache 0x0, 0($2) /* Index_Invalidate_I */ ++ cache 0x1, 0($2) /* Index_Writeback_Inv_D */ ++ addiu $2, $2, 32 ++ subu $4, $3, $2 ++ bgtz $4, 2b ++ nop ++ ++ load_addr $3, usb_boot_return ++ ++ jr $3 ++ ++usbboot_begin: ++ ++init_caches: ++ li $2, 3 /* cacheable for kseg0 access */ ++ mtc0 $2, $16 /* CP0_CONFIG */ ++ nop ++ ++ li $2, 0x20000000 /* enable idx-store-data cache insn */ ++ mtc0 $2, $26 /* CP0_ERRCTL */ ++ ++ ori $2, $28, 0 /* start address */ ++ ori $3, $2, 0x3fe0 /* end address, total 16KB */ ++ mtc0 $0, $28, 0 /* CP0_TAGLO */ ++ mtc0 $0, $28, 1 /* CP0_DATALO */ ++cache_clear_a_line: ++ cache 0x8, 0($2) /* Index_Store_Tag_I */ ++ cache 0x9, 0($2) /* Index_Store_Tag_D */ ++ bne $2, $3, cache_clear_a_line ++ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */ ++ ++ ori $2, $28, 0 /* start address */ ++ ori $3, $2, 0x3fe0 /* end address, total 16KB */ ++ la $4, 0x1ffff000 /* physical address and 4KB page mask */ ++cache_alloc_a_line: ++ and $5, $2, $4 ++ ori $5, $5, 1 /* V bit of the physical tag */ ++ mtc0 $5, $28, 0 /* CP0_TAGLO */ ++ cache 0x8, 0($2) /* Index_Store_Tag_I */ ++ cache 0x9, 0($2) /* Index_Store_Tag_D */ ++ bne $2, $3, cache_alloc_a_line ++ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */ ++ ++ nop ++ nop ++ nop ++ /* ++ * Transfer data from dcache to icache, then jump to icache. ++ * Input parameters: ++ * $19: data length in bytes ++ * $20: jump target address ++ */ ++xfer_d2i: ++ ++ ori $8, $20, 0 ++ addu $9, $8, $19 /* total 16KB */ ++ ++1: ++ cache 0x0, 0($8) /* Index_Invalidate_I */ ++ cache 0x1, 0($8) /* Index_Writeback_Inv_D */ ++ bne $8, $9, 1b ++ addiu $8, $8, 32 ++ ++ /* flush write-buffer */ ++ sync ++ ++ /* Invalidate BTB */ ++ mfc0 $8, $16, 7 /* CP0_CONFIG */ ++ nop ++ ori $8, 2 ++ mtc0 $8, $16, 7 ++ nop ++ ++ /* Overwrite config to disable ram initalisation */ ++ li $2, 0xff ++ sb $2, 20($20) ++ ++ jalr $20 ++ nop ++ ++icache_return: ++ /* User code can return to here after executing itself in ++ icache, by jumping to $31. */ ++ b usb_boot_return ++ nop ++ ++ ++usb_boot_return: ++ /* Enable the USB PHY */ ++ la $9, 0xB0000024 /* CPM_SCR */ ++ lw $8, 0($9) ++ ori $8, 0x40 /* USBPHY_ENABLE */ ++ sw $8, 0($9) ++ ++ /* Initialize USB registers */ ++ la $27, 0xb3040000 /* USB registers base address */ ++ ++ sb $0, 0x0b($27) /* INTRUSBE: disable common USB interrupts */ ++ sh $0, 0x06($27) /* INTRINE: disable EPIN interrutps */ ++ sh $0, 0x08($27) /* INTROUTE: disable EPOUT interrutps */ ++ ++ li $9, 0x61 ++ sb $9, 0x01($27) /* POWER: HSENAB | SUSPENDM | SOFTCONN */ ++ ++ /* Initialize USB states */ ++ li $22, 0 /* set EP0 to IDLE state */ ++ li $23, 1 /* no data stage */ ++ ++ /* Main loop of polling the usb commands */ ++usb_command_loop: ++ lbu $9, 0x0a($27) /* read INTRUSB */ ++ andi $9, 0x04 /* check USB_INTR_RESET */ ++ beqz $9, check_intr_ep0in ++ nop ++ ++ /* 1. Handle USB reset interrupt */ ++handle_reset_intr: ++ lbu $9, 0x01($27) /* read POWER */ ++ andi $9, 0x10 /* test HS_MODE */ ++ bnez $9, _usb_set_maxpktsize ++ li $9, 512 /* max packet size of HS mode */ ++ li $9, 64 /* max packet size of FS mode */ ++ ++_usb_set_maxpktsize: ++ li $8, 1 ++ sb $8, 0x0e($27) /* set INDEX 1 */ ++ ++ sh $9, 0x10($27) /* INMAXP */ ++ sb $0, 0x13($27) /* INCSRH */ ++ sh $9, 0x14($27) /* OUTMAXP */ ++ sb $0, 0x17($27) /* OUTCSRH */ ++ ++_usb_flush_fifo: ++ li $8, 0x48 /* INCSR_CDT && INCSR_FF */ ++ sb $8, 0x12($27) /* INCSR */ ++ li $8, 0x90 /* OUTCSR_CDT && OUTCSR_FF */ ++ sb $8, 0x16($27) /* OUTCSR */ ++ ++ li $22, 0 /* set EP0 to IDLE state */ ++ li $23, 1 /* no data stage */ ++ ++ /* 2. Check and handle EP0 interrupt */ ++check_intr_ep0in: ++ lhu $10, 0x02($27) /* read INTRIN */ ++ andi $9, $10, 0x1 /* check EP0 interrupt */ ++ beqz $9, check_intr_ep1in ++ nop ++ ++handle_ep0_intr: ++ sb $0, 0x0e($27) /* set INDEX 0 */ ++ lbu $11, 0x12($27) /* read CSR0 */ ++ ++ andi $9, $11, 0x04 /* check SENTSTALL */ ++ beqz $9, _ep0_setupend ++ nop ++ ++_ep0_sentstall: ++ andi $9, $11, 0xdb ++ sb $9, 0x12($27) /* clear SENDSTALL and SENTSTALL */ ++ li $22, 0 /* set EP0 to IDLE state */ ++ ++_ep0_setupend: ++ andi $9, $11, 0x10 /* check SETUPEND */ ++ beqz $9, ep0_idle_state ++ nop ++ ++ ori $9, $11, 0x80 ++ sb $9, 0x12($27) /* set SVDSETUPEND */ ++ li $22, 0 /* set EP0 to IDLE state */ ++ ++ep0_idle_state: ++ bnez $22, ep0_tx_state ++ nop ++ ++ /* 2.1 Handle EP0 IDLE state interrupt */ ++ andi $9, $11, 0x01 /* check OUTPKTRDY */ ++ beqz $9, check_intr_ep1in ++ nop ++ ++ /* Read 8-bytes setup packet from the FIFO */ ++ lw $25, 0x20($27) /* first word of setup packet */ ++ lw $26, 0x20($27) /* second word of setup packet */ ++ ++ andi $9, $25, 0x60 /* bRequestType & USB_TYPE_MASK */ ++ beqz $9, _ep0_std_req ++ nop ++ ++ /* 2.1.1 Vendor-specific setup request */ ++_ep0_vend_req: ++ li $22, 0 /* set EP0 to IDLE state */ ++ li $23, 1 /* NoData = 1 */ ++ ++ andi $9, $25, 0xff00 /* check bRequest */ ++ srl $9, $9, 8 ++ beqz $9, __ep0_get_cpu_info ++ sub $8, $9, 0x1 ++ beqz $8, __ep0_set_data_address ++ sub $8, $9, 0x2 ++ beqz $8, __ep0_set_data_length ++ sub $8, $9, 0x3 ++ beqz $8, __ep0_flush_caches ++ sub $8, $9, 0x4 ++ beqz $8, __ep0_prog_start1 ++ sub $8, $9, 0x5 ++ beqz $8, __ep0_prog_start2 ++ nop ++ b _ep0_idle_state_fini /* invalid request */ ++ nop ++ ++__ep0_get_cpu_info: ++ load_addr $20, cpu_info_data /* data pointer to transfer */ ++ li $21, 8 /* bytes left to transfer */ ++ li $22, 1 /* set EP0 to TX state */ ++ li $23, 0 /* NoData = 0 */ ++ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_set_data_address: ++ li $9, 0xffff0000 ++ and $9, $25, $9 ++ andi $8, $26, 0xffff ++ or $20, $9, $8 /* data address of next transfer */ ++ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_set_data_length: ++ li $9, 0xffff0000 ++ and $9, $25, $9 ++ andi $8, $26, 0xffff ++ or $21, $9, $8 /* data length of next transfer */ ++ ++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */ ++ sb $9, 0x12($27) /* CSR0 */ ++ ++ /* We must write packet to FIFO before EP1-IN interrupt here. */ ++ b handle_epin1_intr ++ nop ++ ++__ep0_flush_caches: ++ /* Flush dcache and invalidate icache. */ ++ li $8, 0x80000000 ++ addi $9, $8, 0x3fe0 /* total 16KB */ ++ ++1: ++ cache 0x0, 0($8) /* Index_Invalidate_I */ ++ cache 0x1, 0($8) /* Index_Writeback_Inv_D */ ++ bne $8, $9, 1b ++ addiu $8, $8, 32 ++ ++ /* flush write-buffer */ ++ sync ++ ++ /* Invalidate BTB */ ++ mfc0 $8, $16, 7 /* CP0_CONFIG */ ++ nop ++ ori $8, 2 ++ mtc0 $8, $16, 7 ++ nop ++ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_prog_start1: ++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */ ++ sb $9, 0x12($27) /* CSR0 */ ++ ++ li $9, 0xffff0000 ++ and $9, $25, $9 ++ andi $8, $26, 0xffff ++ or $20, $9, $8 /* target address */ ++ ++ b xfer_d2i ++ li $19, 0x2000 /* 16KB data length */ ++ ++__ep0_prog_start2: ++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */ ++ sb $9, 0x12($27) /* CSR0 */ ++ ++ li $9, 0xffff0000 ++ and $9, $25, $9 ++ andi $8, $26, 0xffff ++ or $20, $9, $8 /* target address */ ++ ++ jalr $20 /* jump, and place the return address in $31 */ ++ nop ++ ++__ep0_prog_start2_return: ++/* User code can return to here after executing itself, by jumping to $31 */ ++ b usb_boot_return ++ nop ++ ++ /* 2.1.2 Standard setup request */ ++_ep0_std_req: ++ andi $12, $25, 0xff00 /* check bRequest */ ++ srl $12, $12, 8 ++ sub $9, $12, 0x05 /* check USB_REQ_SET_ADDRESS */ ++ bnez $9, __ep0_req_set_config ++ nop ++ ++ /* Handle USB_REQ_SET_ADDRESS */ ++__ep0_req_set_addr: ++ srl $9, $25, 16 /* get wValue */ ++ sb $9, 0x0($27) /* set FADDR */ ++ li $23, 1 /* NoData = 1 */ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_req_set_config: ++ sub $9, $12, 0x09 /* check USB_REQ_SET_CONFIGURATION */ ++ bnez $9, __ep0_req_get_desc ++ nop ++ ++ /* Handle USB_REQ_SET_CONFIGURATION */ ++ li $23, 1 /* NoData = 1 */ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_req_get_desc: ++ sub $9, $12, 0x06 /* check USB_REQ_GET_DESCRIPTOR */ ++ bnez $9, _ep0_idle_state_fini ++ li $23, 1 /* NoData = 1 */ ++ ++ /* Handle USB_REQ_GET_DESCRIPTOR */ ++ li $23, 0 /* NoData = 0 */ ++ ++ srl $9, $25, 24 /* wValue >> 8 */ ++ sub $8, $9, 0x01 /* check USB_DT_DEVICE */ ++ beqz $8, ___ep0_get_dev_desc ++ srl $21, $26, 16 /* get wLength */ ++ sub $8, $9, 0x02 /* check USB_DT_CONFIG */ ++ beqz $8, ___ep0_get_conf_desc ++ sub $8, $9, 0x03 /* check USB_DT_STRING */ ++ beqz $8, ___ep0_get_string_desc ++ sub $8, $9, 0x06 /* check USB_DT_DEVICE_QUALIFIER */ ++ beqz $8, ___ep0_get_dev_qualifier ++ nop ++ b _ep0_idle_state_fini ++ nop ++ ++___ep0_get_dev_desc: ++ load_addr $20, device_desc /* data pointer */ ++ li $22, 1 /* set EP0 to TX state */ ++ sub $8, $21, 18 ++ blez $8, _ep0_idle_state_fini /* wLength <= 18 */ ++ nop ++ li $21, 18 /* max length of device_desc */ ++ b _ep0_idle_state_fini ++ nop ++ ++___ep0_get_dev_qualifier: ++ load_addr $20, dev_qualifier /* data pointer */ ++ li $22, 1 /* set EP0 to TX state */ ++ sub $8, $21, 10 ++ blez $8, _ep0_idle_state_fini /* wLength <= 10 */ ++ nop ++ li $21, 10 /* max length of dev_qualifier */ ++ b _ep0_idle_state_fini ++ nop ++ ++___ep0_get_conf_desc: ++ load_addr $20, config_desc_fs /* data pointer of FS mode */ ++ lbu $8, 0x01($27) /* read POWER */ ++ andi $8, 0x10 /* test HS_MODE */ ++ beqz $8, ___ep0_get_conf_desc2 ++ nop ++ load_addr $20, config_desc_hs /* data pointer of HS mode */ ++ ++___ep0_get_conf_desc2: ++ li $22, 1 /* set EP0 to TX state */ ++ sub $8, $21, 32 ++ blez $8, _ep0_idle_state_fini /* wLength <= 32 */ ++ nop ++ li $21, 32 /* max length of config_desc */ ++ b _ep0_idle_state_fini ++ nop ++ ++___ep0_get_string_desc: ++ li $22, 1 /* set EP0 to TX state */ ++ ++ srl $9, $25, 16 /* wValue & 0xff */ ++ andi $9, 0xff ++ ++ sub $8, $9, 1 ++ beqz $8, ___ep0_get_string_manufacture ++ sub $8, $9, 2 ++ beqz $8, ___ep0_get_string_product ++ nop ++ ++___ep0_get_string_lang_ids: ++ load_addr $20, string_lang_ids /* data pointer */ ++ b _ep0_idle_state_fini ++ li $21, 4 /* data length */ ++ ++___ep0_get_string_manufacture: ++ load_addr $20, string_manufacture /* data pointer */ ++ b _ep0_idle_state_fini ++ li $21, 16 /* data length */ ++ ++___ep0_get_string_product: ++ load_addr $20, string_product /* data pointer */ ++ b _ep0_idle_state_fini ++ li $21, 46 /* data length */ ++ ++_ep0_idle_state_fini: ++ li $9, 0x40 /* SVDOUTPKTRDY */ ++ beqz $23, _ep0_idle_state_fini2 ++ nop ++ ori $9, $9, 0x08 /* DATAEND */ ++_ep0_idle_state_fini2: ++ sb $9, 0x12($27) /* CSR0 */ ++ beqz $22, check_intr_ep1in ++ nop ++ ++ /* 2.2 Handle EP0 TX state interrupt */ ++ep0_tx_state: ++ sub $9, $22, 1 ++ bnez $9, check_intr_ep1in ++ nop ++ ++ sub $9, $21, 64 /* max packetsize */ ++ blez $9, _ep0_tx_state2 /* data count <= 64 */ ++ ori $19, $21, 0 ++ li $19, 64 ++ ++_ep0_tx_state2: ++ beqz $19, _ep0_tx_state3 /* send ZLP */ ++ ori $18, $19, 0 /* record bytes to be transferred */ ++ sub $21, $21, $19 /* decrement data count */ ++ ++_ep0_fifo_write_loop: ++ lbu $9, 0($20) /* read data */ ++ sb $9, 0x20($27) /* load FIFO */ ++ sub $19, $19, 1 /* decrement counter */ ++ bnez $19, _ep0_fifo_write_loop ++ addi $20, $20, 1 /* increment data pointer */ ++ ++ sub $9, $18, 64 /* max packetsize */ ++ beqz $9, _ep0_tx_state4 ++ nop ++ ++_ep0_tx_state3: ++ /* transferred bytes < max packetsize */ ++ li $9, 0x0a /* set INPKTRDY and DATAEND */ ++ sb $9, 0x12($27) /* CSR0 */ ++ li $22, 0 /* set EP0 to IDLE state */ ++ b check_intr_ep1in ++ nop ++ ++_ep0_tx_state4: ++ /* transferred bytes == max packetsize */ ++ li $9, 0x02 /* set INPKTRDY */ ++ sb $9, 0x12($27) /* CSR0 */ ++ b check_intr_ep1in ++ nop ++ ++ /* 3. Check and handle EP1 BULK-IN interrupt */ ++check_intr_ep1in: ++ andi $9, $10, 0x2 /* check EP1 IN interrupt */ ++ beqz $9, check_intr_ep1out ++ nop ++ ++handle_epin1_intr: ++ li $9, 1 ++ sb $9, 0x0e($27) /* set INDEX 1 */ ++ lbu $9, 0x12($27) /* read INCSR */ ++ ++ andi $8, $9, 0x2 /* check INCSR_FFNOTEMPT */ ++ bnez $8, _epin1_tx_state4 ++ nop ++ ++_epin1_write_fifo: ++ lhu $9, 0x10($27) /* get INMAXP */ ++ sub $8, $21, $9 ++ blez $8, _epin1_tx_state1 /* bytes left <= INMAXP */ ++ ori $19, $21, 0 ++ ori $19, $9, 0 ++ ++_epin1_tx_state1: ++ beqz $19, _epin1_tx_state4 /* No data */ ++ nop ++ ++ sub $21, $21, $19 /* decrement data count */ ++ ++ srl $5, $19, 2 /* # of word */ ++ andi $6, $19, 0x3 /* # of byte */ ++ beqz $5, _epin1_tx_state2 ++ nop ++ ++_epin1_fifo_write_word: ++ lw $9, 0($20) /* read data from source address */ ++ sw $9, 0x24($27) /* write FIFO */ ++ sub $5, $5, 1 /* decrement counter */ ++ bnez $5, _epin1_fifo_write_word ++ addiu $20, $20, 4 /* increment dest address */ ++ ++_epin1_tx_state2: ++ beqz $6, _epin1_tx_state3 ++ nop ++ ++_epin1_fifo_write_byte: ++ lbu $9, 0($20) /* read data from source address */ ++ sb $9, 0x24($27) /* write FIFO */ ++ sub $6, $6, 1 /* decrement counter */ ++ bnez $6, _epin1_fifo_write_byte ++ addiu $20, $20, 1 /* increment dest address */ ++ ++_epin1_tx_state3: ++ li $9, 0x1 ++ sb $9, 0x12($27) /* INCSR, set INPKTRDY */ ++ ++_epin1_tx_state4: ++ /* 4. Check and handle EP1 BULK-OUT interrupt */ ++check_intr_ep1out: ++ lhu $9, 0x04($27) /* read INTROUT */ ++ andi $9, 0x2 ++ beqz $9, check_status_next ++ nop ++ ++handle_epout1_intr: ++ li $9, 1 ++ sb $9, 0x0e($27) /* set INDEX 1 */ ++ ++ lbu $9, 0x16($27) /* read OUTCSR */ ++ andi $9, 0x1 /* check OUTPKTRDY */ ++ beqz $9, check_status_next ++ nop ++ ++_epout1_read_fifo: ++ lhu $19, 0x18($27) /* read OUTCOUNT */ ++ srl $5, $19, 2 /* # of word */ ++ andi $6, $19, 0x3 /* # of byte */ ++ beqz $5, _epout1_rx_state1 ++ nop ++ ++_epout1_fifo_read_word: ++ lw $9, 0x24($27) /* read FIFO */ ++ sw $9, 0($20) /* store to dest address */ ++ sub $5, $5, 1 /* decrement counter */ ++ bnez $5, _epout1_fifo_read_word ++ addiu $20, $20, 4 /* increment dest address */ ++ ++_epout1_rx_state1: ++ beqz $6, _epout1_rx_state2 ++ nop ++ ++_epout1_fifo_read_byte: ++ lbu $9, 0x24($27) /* read FIFO */ ++ sb $9, 0($20) /* store to dest address */ ++ sub $6, $6, 1 /* decrement counter */ ++ bnez $6, _epout1_fifo_read_byte ++ addiu $20, $20, 1 /* increment dest address */ ++ ++_epout1_rx_state2: ++ sb $0, 0x16($27) /* clear OUTPKTRDY */ ++ ++check_status_next: ++ b usb_command_loop ++ nop ++ ++/* Device/Configuration/Interface/Endpoint/String Descriptors */ ++ ++ .align 2 ++device_desc: ++ .byte 0x12 /* bLength */ ++ .byte 0x01 /* bDescriptorType */ ++ .byte 0x00 /* bcdUSB */ ++ .byte 0x02 /* bcdUSB */ ++ .byte 0x00 /* bDeviceClass */ ++ .byte 0x00 /* bDeviceSubClass */ ++ .byte 0x00 /* bDeviceProtocol */ ++ .byte 0x40 /* bMaxPacketSize0 */ ++ .byte 0x1a /* idVendor */ ++ .byte 0x60 /* idVendor */ ++ .byte 0x40 /* idProduct */ ++ .byte 0x47 /* idProduct */ ++ .byte 0x00 /* bcdDevice */ ++ .byte 0x01 /* bcdDevice */ ++ .byte 0x01 /* iManufacturer */ ++ .byte 0x02 /* iProduct */ ++ .byte 0x00 /* iSerialNumber */ ++ .byte 0x01 /* bNumConfigurations */ ++ ++ .align 2 ++dev_qualifier: ++ .byte 0x0a /* bLength */ ++ .byte 0x06 /* bDescriptorType */ ++ .byte 0x00 /* bcdUSB */ ++ .byte 0x02 /* bcdUSB */ ++ .byte 0x00 /* bDeviceClass */ ++ .byte 0x00 /* bDeviceSubClass */ ++ .byte 0x00 /* bDeviceProtocol */ ++ .byte 0x40 /* bMaxPacketSize0 */ ++ .byte 0x01 /* bNumConfigurations */ ++ .byte 0x00 /* bRESERVED */ ++ ++ .align 2 ++config_desc_hs: ++ .byte 0x09 /* bLength */ ++ .byte 0x02 /* bDescriptorType */ ++ .byte 0x20 /* wTotalLength */ ++ .byte 0x00 /* wTotalLength */ ++ .byte 0x01 /* bNumInterfaces */ ++ .byte 0x01 /* bConfigurationValue */ ++ .byte 0x00 /* iConfiguration */ ++ .byte 0xc0 /* bmAttributes */ ++ .byte 0x01 /* MaxPower */ ++intf_desc_hs: ++ .byte 0x09 /* bLength */ ++ .byte 0x04 /* bDescriptorType */ ++ .byte 0x00 /* bInterfaceNumber */ ++ .byte 0x00 /* bAlternateSetting */ ++ .byte 0x02 /* bNumEndpoints */ ++ .byte 0xff /* bInterfaceClass */ ++ .byte 0x00 /* bInterfaceSubClass */ ++ .byte 0x50 /* bInterfaceProtocol */ ++ .byte 0x00 /* iInterface */ ++ep1_desc_hs: ++ .byte 0x07 /* bLength */ ++ .byte 0x05 /* bDescriptorType */ ++ .byte 0x01 /* bEndpointAddress */ ++ .byte 0x02 /* bmAttributes */ ++ .byte 0x00 /* wMaxPacketSize */ ++ .byte 0x02 /* wMaxPacketSize */ ++ .byte 0x00 /* bInterval */ ++ep2_desc_hs: ++ .byte 0x07 /* bLength */ ++ .byte 0x05 /* bDescriptorType */ ++ .byte 0x81 /* bEndpointAddress */ ++ .byte 0x02 /* bmAttributes */ ++ .byte 0x00 /* wMaxPacketSize */ ++ .byte 0x02 /* wMaxPacketSize */ ++ .byte 0x00 /* bInterval */ ++ ++ .align 2 ++config_desc_fs: ++ .byte 0x09 /* bLength */ ++ .byte 0x02 /* bDescriptorType */ ++ .byte 0x20 /* wTotalLength */ ++ .byte 0x00 /* wTotalLength */ ++ .byte 0x01 /* bNumInterfaces */ ++ .byte 0x01 /* bConfigurationValue */ ++ .byte 0x00 /* iConfiguration */ ++ .byte 0xc0 /* bmAttributes */ ++ .byte 0x01 /* MaxPower */ ++intf_desc_fs: ++ .byte 0x09 /* bLength */ ++ .byte 0x04 /* bDescriptorType */ ++ .byte 0x00 /* bInterfaceNumber */ ++ .byte 0x00 /* bAlternateSetting */ ++ .byte 0x02 /* bNumEndpoints */ ++ .byte 0xff /* bInterfaceClass */ ++ .byte 0x00 /* bInterfaceSubClass */ ++ .byte 0x50 /* bInterfaceProtocol */ ++ .byte 0x00 /* iInterface */ ++ep1_desc_fs: ++ .byte 0x07 /* bLength */ ++ .byte 0x05 /* bDescriptorType */ ++ .byte 0x01 /* bEndpointAddress */ ++ .byte 0x02 /* bmAttributes */ ++ .byte 0x40 /* wMaxPacketSize */ ++ .byte 0x00 /* wMaxPacketSize */ ++ .byte 0x00 /* bInterval */ ++ep2_desc_fs: ++ .byte 0x07 /* bLength */ ++ .byte 0x05 /* bDescriptorType */ ++ .byte 0x81 /* bEndpointAddress */ ++ .byte 0x02 /* bmAttributes */ ++ .byte 0x40 /* wMaxPacketSize */ ++ .byte 0x00 /* wMaxPacketSize */ ++ .byte 0x00 /* bInterval */ ++ ++ .align 2 ++string_lang_ids: ++ .byte 0x04 ++ .byte 0x03 ++ .byte 0x09 ++ .byte 0x04 ++ ++ .align 2 ++string_manufacture: ++ .byte 0x10 ++ .byte 0x03 ++ .byte 0x49 ++ .byte 0x00 ++ .byte 0x6e ++ .byte 0x00 ++ .byte 0x67 ++ .byte 0x00 ++ .byte 0x65 ++ .byte 0x00 ++ .byte 0x6e ++ .byte 0x00 ++ .byte 0x69 ++ .byte 0x00 ++ .byte 0x63 ++ .byte 0x00 ++ ++ .align 2 ++string_product: ++ .byte 0x2e ++ .byte 0x03 ++ .byte 0x4a ++ .byte 0x00 ++ .byte 0x5a ++ .byte 0x00 ++ .byte 0x34 ++ .byte 0x00 ++ .byte 0x37 ++ .byte 0x00 ++ .byte 0x34 ++ .byte 0x00 ++ .byte 0x30 ++ .byte 0x00 ++ .byte 0x20 ++ .byte 0x00 ++ .byte 0x55 ++ .byte 0x00 ++ .byte 0x53 ++ .byte 0x00 ++ .byte 0x42 ++ .byte 0x00 ++ .byte 0x20 ++ .byte 0x00 ++ .byte 0x42 ++ .byte 0x00 ++ .byte 0x6f ++ .byte 0x00 ++ .byte 0x6f ++ .byte 0x00 ++ .byte 0x74 ++ .byte 0x00 ++ .byte 0x20 ++ .byte 0x00 ++ .byte 0x44 ++ .byte 0x00 ++ .byte 0x65 ++ .byte 0x00 ++ .byte 0x76 ++ .byte 0x00 ++ .byte 0x69 ++ .byte 0x00 ++ .byte 0x63 ++ .byte 0x00 ++ .byte 0x65 ++ .byte 0x00 ++ ++ .align 2 ++cpu_info_data: ++ .byte 0x4a ++ .byte 0x5a ++ .byte 0x34 ++ .byte 0x37 ++ .byte 0x34 ++ .byte 0x30 ++ .byte 0x56 ++ .byte 0x31 ++usbboot_end: ++ ++ .set reorder +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0003-add-mmc-support.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0003-add-mmc-support.patch.svn-base new file mode 100644 index 0000000..e9baa7c --- /dev/null +++ b/package/boot/uboot-xburst/patches/.svn/text-base/0003-add-mmc-support.patch.svn-base @@ -0,0 +1,1664 @@ +From bd36739e77669e8df45c38f6acfe2cea511534d9 Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Wed, 10 Oct 2012 18:19:41 +0800 +Subject: [PATCH 3/6] add mmc support + +--- + arch/mips/include/asm/jz4740.h | 166 ++++++ + board/qi/qi_lb60/qi_lb60.c | 9 +- + drivers/mmc/Makefile | 1 + + drivers/mmc/jz_mmc.c | 1179 ++++++++++++++++++++++++++++++++++++++++ + drivers/mmc/jz_mmc.h | 176 ++++++ + include/configs/qi_lb60.h | 9 + + include/mmc.h | 40 ++ + 7 files changed, 1578 insertions(+), 2 deletions(-) + create mode 100644 drivers/mmc/jz_mmc.c + create mode 100644 drivers/mmc/jz_mmc.h + +diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h +index 7a7cfff..68287fb 100644 +--- a/arch/mips/include/asm/jz4740.h ++++ b/arch/mips/include/asm/jz4740.h +@@ -1146,5 +1146,171 @@ extern void sdram_init(void); + extern void calc_clocks(void); + extern void rtc_init(void); + ++/************************************************************************* ++ * MSC ++ *************************************************************************/ ++#define REG8(addr) *((volatile u8 *)(addr)) ++#define REG16(addr) *((volatile u16 *)(addr)) ++#define REG32(addr) *((volatile u32 *)(addr)) ++ ++#define CPM_BASE 0xB0000000 ++#define CPM_CPCCR (CPM_BASE+0x00) ++#define CPM_MSCCDR (CPM_BASE+0x68) ++#define REG_CPM_MSCCDR REG32(CPM_MSCCDR) ++#define REG_CPM_CPCCR REG32(CPM_CPCCR) ++ ++#define MSC_BASE 0xB0021000 ++ ++#define MSC_STRPCL (MSC_BASE + 0x000) ++#define MSC_STAT (MSC_BASE + 0x004) ++#define MSC_CLKRT (MSC_BASE + 0x008) ++#define MSC_CMDAT (MSC_BASE + 0x00C) ++#define MSC_RESTO (MSC_BASE + 0x010) ++#define MSC_RDTO (MSC_BASE + 0x014) ++#define MSC_BLKLEN (MSC_BASE + 0x018) ++#define MSC_NOB (MSC_BASE + 0x01C) ++#define MSC_SNOB (MSC_BASE + 0x020) ++#define MSC_IMASK (MSC_BASE + 0x024) ++#define MSC_IREG (MSC_BASE + 0x028) ++#define MSC_CMD (MSC_BASE + 0x02C) ++#define MSC_ARG (MSC_BASE + 0x030) ++#define MSC_RES (MSC_BASE + 0x034) ++#define MSC_RXFIFO (MSC_BASE + 0x038) ++#define MSC_TXFIFO (MSC_BASE + 0x03C) ++ ++#define REG_MSC_STRPCL REG16(MSC_STRPCL) ++#define REG_MSC_STAT REG32(MSC_STAT) ++#define REG_MSC_CLKRT REG16(MSC_CLKRT) ++#define REG_MSC_CMDAT REG32(MSC_CMDAT) ++#define REG_MSC_RESTO REG16(MSC_RESTO) ++#define REG_MSC_RDTO REG16(MSC_RDTO) ++#define REG_MSC_BLKLEN REG16(MSC_BLKLEN) ++#define REG_MSC_NOB REG16(MSC_NOB) ++#define REG_MSC_SNOB REG16(MSC_SNOB) ++#define REG_MSC_IMASK REG16(MSC_IMASK) ++#define REG_MSC_IREG REG16(MSC_IREG) ++#define REG_MSC_CMD REG8(MSC_CMD) ++#define REG_MSC_ARG REG32(MSC_ARG) ++#define REG_MSC_RES REG16(MSC_RES) ++#define REG_MSC_RXFIFO REG32(MSC_RXFIFO) ++#define REG_MSC_TXFIFO REG32(MSC_TXFIFO) ++ ++/* MSC Clock and Control Register (MSC_STRPCL) */ ++ ++#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7) ++#define MSC_STRPCL_EXIT_TRANSFER (1 << 6) ++#define MSC_STRPCL_START_READWAIT (1 << 5) ++#define MSC_STRPCL_STOP_READWAIT (1 << 4) ++#define MSC_STRPCL_RESET (1 << 3) ++#define MSC_STRPCL_START_OP (1 << 2) ++#define MSC_STRPCL_CLOCK_CONTROL_BIT 0 ++#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT) ++ #define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */ ++ #define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */ ++ ++/* MSC Status Register (MSC_STAT) */ ++ ++#define MSC_STAT_IS_RESETTING (1 << 15) ++#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14) ++#define MSC_STAT_PRG_DONE (1 << 13) ++#define MSC_STAT_DATA_TRAN_DONE (1 << 12) ++#define MSC_STAT_END_CMD_RES (1 << 11) ++#define MSC_STAT_DATA_FIFO_AFULL (1 << 10) ++#define MSC_STAT_IS_READWAIT (1 << 9) ++#define MSC_STAT_CLK_EN (1 << 8) ++#define MSC_STAT_DATA_FIFO_FULL (1 << 7) ++#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6) ++#define MSC_STAT_CRC_RES_ERR (1 << 5) ++#define MSC_STAT_CRC_READ_ERROR (1 << 4) ++#define MSC_STAT_CRC_WRITE_ERROR_BIT 2 ++#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT) ++ #define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */ ++ #define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */ ++ #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */ ++#define MSC_STAT_TIME_OUT_RES (1 << 1) ++#define MSC_STAT_TIME_OUT_READ (1 << 0) ++ ++/* MSC Bus Clock Control Register (MSC_CLKRT) */ ++ ++#define MSC_CLKRT_CLK_RATE_BIT 0 ++#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT) ++ #define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */ ++ ++/* MSC Command Sequence Control Register (MSC_CMDAT) */ ++ ++#define MSC_CMDAT_IO_ABORT (1 << 11) ++#define MSC_CMDAT_BUS_WIDTH_BIT 9 ++#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT) ++#define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT) ++#define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT) ++#define MSC_CMDAT_DMA_EN (1 << 8) ++#define MSC_CMDAT_INIT (1 << 7) ++#define MSC_CMDAT_BUSY (1 << 6) ++#define MSC_CMDAT_STREAM_BLOCK (1 << 5) ++#define MSC_CMDAT_WRITE (1 << 4) ++#define MSC_CMDAT_READ (0 << 4) ++#define MSC_CMDAT_DATA_EN (1 << 3) ++#define MSC_CMDAT_RESPONSE_BIT 0 ++#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT) ++ ++/* MSC Interrupts Mask Register (MSC_IMASK) */ ++#define MSC_IMASK_SDIO (1 << 7) ++#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6) ++#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5) ++#define MSC_IMASK_END_CMD_RES (1 << 2) ++#define MSC_IMASK_PRG_DONE (1 << 1) ++#define MSC_IMASK_DATA_TRAN_DONE (1 << 0) ++ ++ ++/* MSC Interrupts Status Register (MSC_IREG) */ ++#define MSC_IREG_SDIO (1 << 7) ++#define MSC_IREG_TXFIFO_WR_REQ (1 << 6) ++#define MSC_IREG_RXFIFO_RD_REQ (1 << 5) ++#define MSC_IREG_END_CMD_RES (1 << 2) ++#define MSC_IREG_PRG_DONE (1 << 1) ++#define MSC_IREG_DATA_TRAN_DONE (1 << 0) ++ ++static __inline__ unsigned int __cpm_get_pllout2(void) ++{ ++ if (REG_CPM_CPCCR & CPM_CPCCR_PCS) ++ return __cpm_get_pllout(); ++ else ++ return __cpm_get_pllout()/2; ++} ++ ++static inline void __cpm_select_msc_clk(int sd) ++{ ++ unsigned int pllout2 = __cpm_get_pllout2(); ++ unsigned int div = 0; ++ ++ if (sd) { ++ div = pllout2 / 24000000; ++ } ++ else { ++ div = pllout2 / 16000000; ++ } ++ ++ REG_CPM_MSCCDR = div - 1; ++} ++#define __msc_reset() \ ++do { \ ++ REG_MSC_STRPCL = MSC_STRPCL_RESET; \ ++ while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \ ++} while (0) ++ + #endif /* !__ASSEMBLY__ */ + #endif /* __JZ4740_H__ */ +diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c +index 3bd4e2f..a2ba648 100644 +--- a/board/qi/qi_lb60/qi_lb60.c ++++ b/board/qi/qi_lb60/qi_lb60.c +@@ -40,8 +40,13 @@ static void gpio_init(void) + __gpio_clear_pin(GPIO_KEYOUT_BASE + i); + } + +- __gpio_as_input(GPIO_KEYIN_8); +- __gpio_enable_pull(GPIO_KEYIN_8); ++ if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){ ++ printf("[S] pressed, enable UART0\n"); ++ __gpio_as_uart0(); ++ } else { ++ __gpio_as_input(GPIO_KEYIN_8); ++ __gpio_enable_pull(GPIO_KEYIN_8); ++ } + + /* enable the TP4, TP5 as UART0 */ + __gpio_jtag_to_uart0(); +diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile +index 565ba6a..3c717b1 100644 +--- a/drivers/mmc/Makefile ++++ b/drivers/mmc/Makefile +@@ -47,6 +47,7 @@ COBJS-$(CONFIG_SDHCI) += sdhci.o + COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o + COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o + COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o ++COBJS-$(CONFIG_JZ4740_MMC) += jz_mmc.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c +new file mode 100644 +index 0000000..642cecc +--- /dev/null ++++ b/drivers/mmc/jz_mmc.c +@@ -0,0 +1,1179 @@ ++/* ++ * (C) Copyright 2003 ++ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#include <config.h> ++#include <common.h> ++#include <part.h> ++#include <mmc.h> ++ ++#include <asm/io.h> ++#include <asm/jz4740.h> ++#include "jz_mmc.h" ++ ++static int sd2_0 = 0; ++static int mmc_ready = 0; ++static int use_4bit; /* Use 4-bit data bus */ ++/* ++ * MMC Events ++ */ ++#define MMC_EVENT_NONE 0x00 /* No events */ ++#define MMC_EVENT_RX_DATA_DONE 0x01 /* Rx data done */ ++#define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */ ++#define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */ ++ ++ ++#define MMC_IRQ_MASK() \ ++do { \ ++ REG_MSC_IMASK = 0xffff; \ ++ REG_MSC_IREG = 0xffff; \ ++} while (0) ++ ++/* ++ * GPIO definition ++ */ ++#if defined(CONFIG_SAKC) ++ ++#define __msc_init_io() \ ++do { \ ++ __gpio_as_input(GPIO_SD_CD_N); \ ++} while (0) ++ ++#else ++#define __msc_init_io() \ ++do { \ ++ __gpio_as_output(GPIO_SD_VCC_EN_N); \ ++ __gpio_as_input(GPIO_SD_CD_N); \ ++} while (0) ++ ++#define __msc_enable_power() \ ++do { \ ++ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \ ++} while (0) ++ ++#define __msc_disable_power() \ ++do { \ ++ __gpio_set_pin(GPIO_SD_VCC_EN_N); \ ++} while (0) ++ ++#endif /* CONFIG_SAKE */ ++ ++#define __msc_card_detected() \ ++({ \ ++ int detected = 1; \ ++ __gpio_as_input(GPIO_SD_CD_N); \ ++ __gpio_disable_pull(GPIO_SD_CD_N); \ ++ if (!__gpio_get_pin(GPIO_SD_CD_N)) \ ++ detected = 0; \ ++ detected; \ ++}) ++ ++/* ++ * Local functions ++ */ ++ ++extern int ++fat_register_device(block_dev_desc_t *dev_desc, int part_no); ++ ++static block_dev_desc_t mmc_dev; ++ ++block_dev_desc_t * mmc_get_dev(int dev) ++{ ++ return ((block_dev_desc_t *)&mmc_dev); ++} ++ ++/* Stop the MMC clock and wait while it happens */ ++static inline int jz_mmc_stop_clock(void) ++{ ++ int timeout = 1000; ++ ++ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP; ++ ++ while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) { ++ timeout--; ++ if (timeout == 0) ++ return MMC_ERROR_TIMEOUT; ++ udelay(1); ++ } ++ return MMC_NO_ERROR; ++} ++ ++/* Start the MMC clock and operation */ ++static inline int jz_mmc_start_clock(void) ++{ ++ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP; ++ return MMC_NO_ERROR; ++} ++ ++static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate) ++{ ++ u32 clkrt = 0; ++ u32 clk_src = is_sd ? 24000000 : 16000000; ++ ++ while (rate < clk_src) { ++ clkrt ++; ++ clk_src >>= 1; ++ } ++ ++ return clkrt; ++} ++ ++/* Set the MMC clock frequency */ ++void jz_mmc_set_clock(int sd, u32 rate) ++{ ++ jz_mmc_stop_clock(); ++ ++ /* Select clock source of MSC */ ++ __cpm_select_msc_clk(sd); ++ ++ /* Set clock dividor of MSC */ ++ REG_MSC_CLKRT = jz_mmc_calc_clkrt(sd, rate); ++} ++ ++static int jz_mmc_check_status(struct mmc_request *request) ++{ ++ u32 status = REG_MSC_STAT; ++ ++ /* Checking for response or data timeout */ ++ if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) { ++ printf("MMC/SD timeout, MMC_STAT 0x%x CMD %d\n", status, request->cmd); ++ return MMC_ERROR_TIMEOUT; ++ } ++ ++ /* Checking for CRC error */ ++ if (status & (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_RES_ERR)) { ++ printf("MMC/CD CRC error, MMC_STAT 0x%x\n", status); ++ return MMC_ERROR_CRC; ++ } ++ ++ return MMC_NO_ERROR; ++} ++ ++/* Obtain response to the command and store it to response buffer */ ++static void jz_mmc_get_response(struct mmc_request *request) ++{ ++ int i; ++ u8 *buf; ++ u32 data; ++ ++ debug("fetch response for request %d, cmd %d\n", ++ request->rtype, request->cmd); ++ ++ buf = request->response; ++ request->result = MMC_NO_ERROR; ++ ++ switch (request->rtype) { ++ case RESPONSE_R1: case RESPONSE_R1B: case RESPONSE_R6: ++ case RESPONSE_R3: case RESPONSE_R4: case RESPONSE_R5: ++ { ++ data = REG_MSC_RES; ++ buf[0] = (data >> 8) & 0xff; ++ buf[1] = data & 0xff; ++ data = REG_MSC_RES; ++ buf[2] = (data >> 8) & 0xff; ++ buf[3] = data & 0xff; ++ data = REG_MSC_RES; ++ buf[4] = data & 0xff; ++ ++ debug("request %d, response [%02x %02x %02x %02x %02x]\n", ++ request->rtype, buf[0], buf[1], buf[2], buf[3], buf[4]); ++ break; ++ } ++ case RESPONSE_R2_CID: case RESPONSE_R2_CSD: ++ { ++ for (i = 0; i < 16; i += 2) { ++ data = REG_MSC_RES; ++ buf[i] = (data >> 8) & 0xff; ++ buf[i+1] = data & 0xff; ++ } ++ debug("request %d, response [", request->rtype); ++#if CONFIG_MMC_DEBUG_VERBOSE > 2 ++ if (g_mmc_debug >= 3) { ++ int n; ++ for (n = 0; n < 17; n++) ++ printk("%02x ", buf[n]); ++ printk("]\n"); ++ } ++#endif ++ break; ++ } ++ case RESPONSE_NONE: ++ debug("No response\n"); ++ break; ++ ++ default: ++ debug("unhandled response type for request %d\n", request->rtype); ++ break; ++ } ++} ++ ++static int jz_mmc_receive_data(struct mmc_request *req) ++{ ++ u32 stat, timeout, data, cnt; ++ u8 *buf = req->buffer; ++ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */ ++ ++ timeout = 0x3ffffff; ++ ++ while (timeout) { ++ timeout--; ++ stat = REG_MSC_STAT; ++ ++ if (stat & MSC_STAT_TIME_OUT_READ) ++ return MMC_ERROR_TIMEOUT; ++ else if (stat & MSC_STAT_CRC_READ_ERROR) ++ return MMC_ERROR_CRC; ++ else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY) ++ || (stat & MSC_STAT_DATA_FIFO_AFULL)) { ++ /* Ready to read data */ ++ break; ++ } ++ udelay(1); ++ } ++ if (!timeout) ++ return MMC_ERROR_TIMEOUT; ++ ++ /* Read data from RXFIFO. It could be FULL or PARTIAL FULL */ ++ cnt = wblocklen; ++ while (cnt) { ++ data = REG_MSC_RXFIFO; ++ { ++ *buf++ = (u8)(data >> 0); ++ *buf++ = (u8)(data >> 8); ++ *buf++ = (u8)(data >> 16); ++ *buf++ = (u8)(data >> 24); ++ } ++ cnt --; ++ while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY)) ++ ; ++ } ++ return MMC_NO_ERROR; ++} ++ ++static int jz_mmc_transmit_data(struct mmc_request *req) ++{ ++#if 0 ++ u32 nob = req->nob; ++ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */ ++ u8 *buf = req->buffer; ++ u32 *wbuf = (u32 *)buf; ++ u32 waligned = (((u32)buf & 0x3) == 0); /* word aligned ? */ ++ u32 stat, timeout, data, cnt; ++ ++ for (nob; nob >= 1; nob--) { ++ timeout = 0x3FFFFFF; ++ ++ while (timeout) { ++ timeout--; ++ stat = REG_MSC_STAT; ++ ++ if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS)) ++ return MMC_ERROR_CRC; ++ else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) { ++ /* Ready to write data */ ++ break; ++ } ++ ++ udelay(1); ++ } ++ ++ if (!timeout) ++ return MMC_ERROR_TIMEOUT; ++ ++ /* Write data to TXFIFO */ ++ cnt = wblocklen; ++ while (cnt) { ++ while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL) ++ ; ++ ++ if (waligned) { ++ REG_MSC_TXFIFO = *wbuf++; ++ } ++ else { ++ data = *buf++ | (*buf++ << 8) | (*buf++ << 16) | (*buf++ << 24); ++ REG_MSC_TXFIFO = data; ++ } ++ ++ cnt--; ++ } ++ } ++#endif ++ return MMC_NO_ERROR; ++} ++ ++ ++/* ++ * Name: int jz_mmc_exec_cmd() ++ * Function: send command to the card, and get a response ++ * Input: struct mmc_request *req : MMC/SD request ++ * Output: 0: right >0: error code ++ */ ++int jz_mmc_exec_cmd(struct mmc_request *request) ++{ ++ u32 cmdat = 0, events = 0; ++ int retval, timeout = 0x3fffff; ++ ++ /* Indicate we have no result yet */ ++ request->result = MMC_NO_RESPONSE; ++ if (request->cmd == MMC_CIM_RESET) { ++ /* On reset, 1-bit bus width */ ++ use_4bit = 0; ++ ++ /* Reset MMC/SD controller */ ++ __msc_reset(); ++ ++ /* On reset, drop MMC clock down */ ++ jz_mmc_set_clock(0, MMC_CLOCK_SLOW); ++ ++ /* On reset, stop MMC clock */ ++ jz_mmc_stop_clock(); ++ } ++ if (request->cmd == MMC_CMD_SEND_OP_COND) { ++ debug("Have an MMC card\n"); ++ /* always use 1bit for MMC */ ++ use_4bit = 0; ++ } ++ if (request->cmd == SET_BUS_WIDTH) { ++ if (request->arg == 0x2) { ++ printf("Use 4-bit bus width\n"); ++ use_4bit = 1; ++ } else { ++ printf("Use 1-bit bus width\n"); ++ use_4bit = 0; ++ } ++ } ++ ++ /* stop clock */ ++ jz_mmc_stop_clock(); ++ ++ /* mask all interrupts */ ++ REG_MSC_IMASK = 0xffff; ++ ++ /* clear status */ ++ REG_MSC_IREG = 0xffff; ++ ++ /* use 4-bit bus width when possible */ ++ if (use_4bit) ++ cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT; ++ ++ /* Set command type and events */ ++ switch (request->cmd) { ++ /* MMC core extra command */ ++ case MMC_CIM_RESET: ++ cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */ ++ break; ++ ++ /* bc - broadcast - no response */ ++ case MMC_CMD_GO_IDLE_STATE: ++ case MMC_CMD_SET_DSR: ++ break; ++ ++ /* bcr - broadcast with response */ ++ case MMC_CMD_SEND_OP_COND: ++ case MMC_CMD_ALL_SEND_CID: ++ case MMC_GO_IRQ_STATE: ++ break; ++ ++ /* adtc - addressed with data transfer */ ++ case MMC_READ_DAT_UNTIL_STOP: ++ case MMC_CMD_READ_SINGLE_BLOCK: ++ case MMC_CMD_READ_MULTIPLE_BLOCK: ++ case SD_CMD_APP_SEND_SCR: ++ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_READ; ++ events = MMC_EVENT_RX_DATA_DONE; ++ break; ++ ++ case MMC_WRITE_DAT_UNTIL_STOP: ++ case MMC_CMD_WRITE_SINGLE_BLOCK: ++ case MMC_CMD_WRITE_MULTIPLE_BLOCK: ++ case MMC_PROGRAM_CID: ++ case MMC_PROGRAM_CSD: ++ case MMC_SEND_WRITE_PROT: ++ case MMC_GEN_CMD: ++ case MMC_LOCK_UNLOCK: ++ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE; ++ events = MMC_EVENT_TX_DATA_DONE | MMC_EVENT_PROG_DONE; ++ ++ break; ++ ++ case MMC_CMD_STOP_TRANSMISSION: ++ events = MMC_EVENT_PROG_DONE; ++ break; ++ ++ /* ac - no data transfer */ ++ default: ++ break; ++ } ++ ++ /* Set response type */ ++ switch (request->rtype) { ++ case RESPONSE_NONE: ++ break; ++ ++ case RESPONSE_R1B: ++ cmdat |= MSC_CMDAT_BUSY; ++ /*FALLTHRU*/ ++ case RESPONSE_R1: ++ cmdat |= MSC_CMDAT_RESPONSE_R1; ++ break; ++ case RESPONSE_R2_CID: ++ case RESPONSE_R2_CSD: ++ cmdat |= MSC_CMDAT_RESPONSE_R2; ++ break; ++ case RESPONSE_R3: ++ cmdat |= MSC_CMDAT_RESPONSE_R3; ++ break; ++ case RESPONSE_R4: ++ cmdat |= MSC_CMDAT_RESPONSE_R4; ++ break; ++ case RESPONSE_R5: ++ cmdat |= MSC_CMDAT_RESPONSE_R5; ++ break; ++ case RESPONSE_R6: ++ cmdat |= MSC_CMDAT_RESPONSE_R6; ++ break; ++ default: ++ break; ++ } ++ ++ /* Set command index */ ++ if (request->cmd == MMC_CIM_RESET) { ++ REG_MSC_CMD = MMC_CMD_GO_IDLE_STATE; ++ } else { ++ REG_MSC_CMD = request->cmd; ++ } ++ ++ /* Set argument */ ++ REG_MSC_ARG = request->arg; ++ ++ /* Set block length and nob */ ++ if (request->cmd == SD_CMD_APP_SEND_SCR) { /* get SCR from DataFIFO */ ++ REG_MSC_BLKLEN = 8; ++ REG_MSC_NOB = 1; ++ } else { ++ REG_MSC_BLKLEN = request->block_len; ++ REG_MSC_NOB = request->nob; ++ } ++ ++ /* Set command */ ++ REG_MSC_CMDAT = cmdat; ++ ++ debug("Send cmd %d cmdat: %x arg: %x resp %d\n", request->cmd, ++ cmdat, request->arg, request->rtype); ++ ++ /* Start MMC/SD clock and send command to card */ ++ jz_mmc_start_clock(); ++ ++ /* Wait for command completion */ ++ while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES)) ++ ; ++ ++ if (timeout == 0) ++ return MMC_ERROR_TIMEOUT; ++ ++ REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear flag */ ++ ++ /* Check for status */ ++ retval = jz_mmc_check_status(request); ++ if (retval) { ++ return retval; ++ } ++ ++ /* Complete command with no response */ ++ if (request->rtype == RESPONSE_NONE) { ++ return MMC_NO_ERROR; ++ } ++ ++ /* Get response */ ++ jz_mmc_get_response(request); ++ ++ /* Start data operation */ ++ if (events & (MMC_EVENT_RX_DATA_DONE | MMC_EVENT_TX_DATA_DONE)) { ++ if (events & MMC_EVENT_RX_DATA_DONE) { ++ if (request->cmd == SD_CMD_APP_SEND_SCR) { ++ /* SD card returns SCR register as data. ++ MMC core expect it in the response buffer, ++ after normal response. */ ++ request->buffer = (u8 *)((u32)request->response + 5); ++ } ++ jz_mmc_receive_data(request); ++ } ++ ++ if (events & MMC_EVENT_TX_DATA_DONE) { ++ jz_mmc_transmit_data(request); ++ } ++ ++ /* Wait for Data Done */ ++ while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE)) ++ ; ++ REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */ ++ } ++ ++ /* Wait for Prog Done event */ ++ if (events & MMC_EVENT_PROG_DONE) { ++ while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE)) ++ ; ++ REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */ ++ } ++ ++ /* Command completed */ ++ ++ return MMC_NO_ERROR; /* return successfully */ ++} ++ ++int mmc_block_read(u8 *dst, ulong src, ulong len) ++{ ++ ++ struct mmc_request request; ++ struct mmc_response_r1 r1; ++ int retval = 0; ++ ++ if (len == 0) ++ goto exit; ++ ++ mmc_simple_cmd(&request, MMC_CMD_SEND_STATUS, mmcinfo.rca, RESPONSE_R1); ++ retval = mmc_unpack_r1(&request, &r1, 0); ++ if (retval && (retval != MMC_ERROR_STATE_MISMATCH)) ++ goto exit; ++ ++ mmc_simple_cmd(&request, MMC_CMD_SET_BLOCKLEN, len, RESPONSE_R1); ++ if (retval = mmc_unpack_r1(&request, &r1, 0)) ++ goto exit; ++ ++ if (!sd2_0) ++ src *= mmcinfo.block_len; ++ ++ mmc_send_cmd(&request, MMC_CMD_READ_SINGLE_BLOCK, src, 1, len, RESPONSE_R1, dst); ++ if (retval = mmc_unpack_r1(&request, &r1, 0)) ++ goto exit; ++ ++exit: ++ return retval; ++} ++ ++ulong mmc_bread(int dev_num, ulong blkstart, ulong blkcnt, ulong *dst) ++{ ++ if (!mmc_ready) { ++ printf("Please initial the MMC first\n"); ++ return -1; ++ } ++ ++ int i = 0; ++ ulong dst_tmp = dst; ++ ++ for (i = 0; i < blkcnt; i++) { ++ if ((mmc_block_read((uchar *)(dst_tmp), blkstart, mmcinfo.block_len)) < 0) ++ return -1; ++ ++ dst_tmp += mmcinfo.block_len; ++ blkstart++; ++ } ++ ++ return i; ++} ++ ++int mmc_select_card(void) ++{ ++ struct mmc_request request; ++ struct mmc_response_r1 r1; ++ int retval; ++ ++ mmc_simple_cmd(&request, MMC_CMD_SELECT_CARD, mmcinfo.rca, RESPONSE_R1B); ++ retval = mmc_unpack_r1(&request, &r1, 0); ++ if (retval) { ++ return retval; ++ } ++ ++ if (mmcinfo.sd) { ++ mmc_simple_cmd(&request, MMC_CMD_APP_CMD, mmcinfo.rca, RESPONSE_R1); ++ retval = mmc_unpack_r1(&request,&r1,0); ++ if (retval) { ++ return retval; ++ } ++#if defined(MMC_BUS_WIDTH_1BIT) ++ mmc_simple_cmd(&request, SET_BUS_WIDTH, 1, RESPONSE_R1); ++#else ++ mmc_simple_cmd(&request, SET_BUS_WIDTH, 2, RESPONSE_R1); ++#endif ++ retval = mmc_unpack_r1(&request,&r1,0); ++ if (retval) { ++ return retval; ++ } ++ } ++ return 0; ++} ++ ++/* ++ * Configure card ++ */ ++static void mmc_configure_card(void) ++{ ++ u32 rate; ++ ++ /* Get card info */ ++ if (sd2_0) ++ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) << 10; ++ else ++ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) * (1 << (mmcinfo.csd.c_size_mult + 2)); ++ ++ mmcinfo.block_len = 1 << mmcinfo.csd.read_bl_len; ++ ++ mmc_dev.if_type = IF_TYPE_SD; ++ mmc_dev.part_type = PART_TYPE_DOS; ++ mmc_dev.dev = 0; ++ mmc_dev.lun = 0; ++ mmc_dev.type = 0; ++ mmc_dev.blksz = mmcinfo.block_len; ++ mmc_dev.lba = mmcinfo.block_num; ++ mmc_dev.removable = 0; ++ ++ printf("%s Detected: %lu blocks of %lu bytes\n", ++ sd2_0 == 1 ? "SDHC" : "SD", ++ mmc_dev.lba, ++ mmc_dev.blksz); ++ ++ /* Fix the clock rate */ ++ rate = mmc_tran_speed(mmcinfo.csd.tran_speed); ++ if (rate < MMC_CLOCK_SLOW) ++ rate = MMC_CLOCK_SLOW; ++ if ((mmcinfo.sd == 0) && (rate > MMC_CLOCK_FAST)) ++ rate = MMC_CLOCK_FAST; ++ if ((mmcinfo.sd) && (rate > SD_CLOCK_FAST)) ++ rate = SD_CLOCK_FAST; ++ ++ debug("%s: block_len=%d block_num=%d rate=%d\n", ++ __func__, mmcinfo.block_len, mmcinfo.block_num, rate); ++ ++ jz_mmc_set_clock(mmcinfo.sd, rate); ++} ++ ++/* ++ * State machine routines to initialize card(s) ++ */ ++ ++/* ++ CIM_SINGLE_CARD_ACQ (frequency at 400 kHz) ++ --- Must enter from GO_IDLE_STATE --- ++ 1. SD_SEND_OP_COND (SD Card) [CMD55] + [CMD41] ++ 2. SEND_OP_COND (Full Range) [CMD1] {optional} ++ 3. SEND_OP_COND (Set Range ) [CMD1] ++ If busy, delay and repeat step 2 ++ 4. ALL_SEND_CID [CMD2] ++ If timeout, set an error (no cards found) ++ 5. SET_RELATIVE_ADDR [CMD3] ++ 6. SEND_CSD [CMD9] ++ 7. SET_DSR [CMD4] Only call this if (csd.dsr_imp). ++ 8. Set clock frequency (check available in csd.tran_speed) ++ */ ++ ++#define MMC_INIT_DOING 0 ++#define MMC_INIT_PASSED 1 ++#define MMC_INIT_FAILED 2 ++ ++static int mmc_init_card_state(struct mmc_request *request) ++{ ++ struct mmc_response_r1 r1; ++ struct mmc_response_r3 r3; ++ int retval; ++ int ocr = 0x40300000; ++ int limit_41 = 0; ++ ++ switch (request->cmd) { ++ case MMC_CMD_GO_IDLE_STATE: /* No response to parse */ ++ if (mmcinfo.sd) ++ mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1); ++ else ++ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); ++ break; ++ ++ case 8: ++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state); ++ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1); ++ break; ++ ++ case MMC_CMD_APP_CMD: ++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state); ++ if (retval & (limit_41 < 100)) { ++ debug("%s: unable to MMC_APP_CMD error=%d (%s)\n", ++ __func__, retval, mmc_result_to_string(retval)); ++ limit_41++; ++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3); ++ } else if (limit_41 < 100) { ++ limit_41++; ++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3); ++ } else{ ++ /* reset the card to idle*/ ++ mmc_simple_cmd(request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE); ++ mmcinfo.sd = 0; ++ } ++ break; ++ ++ case SD_CMD_APP_SEND_OP_COND: ++ retval = mmc_unpack_r3(request, &r3); ++ if (retval) { ++ debug("%s: try MMC card\n", __func__); ++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); ++ break; ++ } ++ ++ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr); ++ ++ if(!(r3.ocr & MMC_CARD_BUSY || ocr == 0)){ ++ udelay(50000); ++ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1); ++ } else { ++ mmcinfo.sd = 1; /* SD Card ready */ ++ mmcinfo.state = CARD_STATE_READY; ++ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID); ++ } ++ break; ++ ++ case MMC_CMD_SEND_OP_COND: ++ retval = mmc_unpack_r3(request, &r3); ++ if (retval) { ++ debug("%s: failed SEND_OP_COND error=%d (%s)\n", ++ __func__, retval, mmc_result_to_string(retval)); ++ return MMC_INIT_FAILED; ++ } ++ ++ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr); ++ if (!(r3.ocr & MMC_CARD_BUSY)) { ++ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); ++ } else { ++ mmcinfo.sd = 0; /* MMC Card ready */ ++ mmcinfo.state = CARD_STATE_READY; ++ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID); ++ } ++ break; ++ ++ case MMC_CMD_ALL_SEND_CID: ++ retval = mmc_unpack_cid( request, &mmcinfo.cid ); ++ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */ ++ if ( retval && (retval != MMC_ERROR_CRC)) { ++ debug("mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n", ++ retval, mmc_result_to_string(retval)); ++ return MMC_INIT_FAILED; ++ } ++ mmcinfo.state = CARD_STATE_IDENT; ++ if(mmcinfo.sd) ++ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, 0, RESPONSE_R6); ++ else ++ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, ID_TO_RCA(mmcinfo.id) << 16, RESPONSE_R1); ++ break; ++ ++ case MMC_CMD_SET_RELATIVE_ADDR: ++ if (mmcinfo.sd) { ++ retval = mmc_unpack_r6(request, &r1, mmcinfo.state, &mmcinfo.rca); ++ mmcinfo.rca = mmcinfo.rca << 16; ++ debug("%s: Get RCA from SD: 0x%04x Status: %x\n", ++ __func__, mmcinfo.rca, r1.status); ++ } else { ++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state); ++ mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16; ++ } ++ if (retval) { ++ debug("%s: unable to SET_RELATIVE_ADDR error=%d (%s)\n", ++ __func__, retval, mmc_result_to_string(retval)); ++ return MMC_INIT_FAILED; ++ } ++ ++ mmcinfo.state = CARD_STATE_STBY; ++ mmc_simple_cmd(request, MMC_CMD_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD); ++ ++ break; ++ ++ case MMC_CMD_SEND_CSD: ++ retval = mmc_unpack_csd(request, &mmcinfo.csd); ++ mmc_ready = 1; ++ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */ ++ if (retval && (retval != MMC_ERROR_CRC)) { ++ debug("%s: unable to SEND_CSD error=%d (%s)\n", ++ __func__, retval, mmc_result_to_string(retval)); ++ return MMC_INIT_FAILED; ++ } ++ if (mmcinfo.csd.dsr_imp) { ++ debug("%s: driver doesn't support setting DSR\n", __func__); ++ } ++ mmc_configure_card(); ++ return MMC_INIT_PASSED; ++ ++ default: ++ debug("%s: error! Illegal last cmd %d\n", __func__, request->cmd); ++ return MMC_INIT_FAILED; ++ } ++ ++ return MMC_INIT_DOING; ++} ++ ++int mmc_init_card(void) ++{ ++ struct mmc_request request; ++ int retval; ++ ++ mmc_simple_cmd(&request, MMC_CIM_RESET, 0, RESPONSE_NONE); /* reset card */ ++ mmc_simple_cmd(&request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE); ++ mmcinfo.sd = 1; /* assuming a SD card */ ++ ++ while ((retval = mmc_init_card_state(&request)) == MMC_INIT_DOING) ++ ; ++ ++ if (retval == MMC_INIT_PASSED) ++ return MMC_NO_ERROR; ++ else ++ return MMC_NO_RESPONSE; ++} ++ ++int mmc_legacy_init(int verbose) ++{ ++ if (!__msc_card_detected()) ++ return 1; ++ ++ /* Step-1: init GPIO */ ++ __gpio_as_msc(); ++ __msc_init_io(); ++ ++ /* Step-2: turn on power of card */ ++#if !defined(CONFIG_SAKC) ++ __msc_enable_power(); ++#endif ++ ++ /* Step-3: Reset MSC Controller. */ ++ __msc_reset(); ++ ++ /* Step-3: mask all IRQs. */ ++ MMC_IRQ_MASK(); ++ ++ /* Step-4: stop MMC/SD clock */ ++ jz_mmc_stop_clock(); ++ mmc_init_card(); ++ mmc_select_card(); ++ ++ mmc_dev.block_read = mmc_bread; ++ fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */ ++ ++ return 0; ++} ++ ++/* ++ * Debugging functions ++ */ ++static char * mmc_result_strings[] = { ++ "NO_RESPONSE", ++ "NO_ERROR", ++ "ERROR_OUT_OF_RANGE", ++ "ERROR_ADDRESS", ++ "ERROR_BLOCK_LEN", ++ "ERROR_ERASE_SEQ", ++ "ERROR_ERASE_PARAM", ++ "ERROR_WP_VIOLATION", ++ "ERROR_CARD_IS_LOCKED", ++ "ERROR_LOCK_UNLOCK_FAILED", ++ "ERROR_COM_CRC", ++ "ERROR_ILLEGAL_COMMAND", ++ "ERROR_CARD_ECC_FAILED", ++ "ERROR_CC", ++ "ERROR_GENERAL", ++ "ERROR_UNDERRUN", ++ "ERROR_OVERRUN", ++ "ERROR_CID_CSD_OVERWRITE", ++ "ERROR_STATE_MISMATCH", ++ "ERROR_HEADER_MISMATCH", ++ "ERROR_TIMEOUT", ++ "ERROR_CRC", ++ "ERROR_DRIVER_FAILURE", ++}; ++ ++char * mmc_result_to_string(int i) ++{ ++ return mmc_result_strings[i+1]; ++} ++ ++static char * card_state_strings[] = { ++ "empty", ++ "idle", ++ "ready", ++ "ident", ++ "stby", ++ "tran", ++ "data", ++ "rcv", ++ "prg", ++ "dis", ++}; ++ ++static inline char * card_state_to_string(int i) ++{ ++ return card_state_strings[i+1]; ++} ++ ++/* ++ * Utility functions ++ */ ++ ++#define PARSE_U32(_buf,_index) \ ++ (((u32)_buf[_index]) << 24) | (((u32)_buf[_index+1]) << 16) | \ ++ (((u32)_buf[_index+2]) << 8) | ((u32)_buf[_index+3]); ++ ++#define PARSE_U16(_buf,_index) \ ++ (((u16)_buf[_index]) << 8) | ((u16)_buf[_index+1]); ++ ++int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd) ++{ ++ u8 *buf = request->response; ++ int num = 0; ++ ++ if (request->result) ++ return request->result; ++ ++ if (buf[0] != 0x3f) ++ return MMC_ERROR_HEADER_MISMATCH; ++ ++ csd->csd_structure = (buf[1] & 0xc0) >> 6; ++ if (csd->csd_structure) ++ sd2_0 = 1; ++ else ++ sd2_0 = 0; ++ ++ switch (csd->csd_structure) { ++ case 0 :/* Version 1.01-1.10 ++ * Version 2.00/Standard Capacity */ ++ csd->taac = buf[2]; ++ csd->nsac = buf[3]; ++ csd->tran_speed = buf[4]; ++ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4); ++ csd->read_bl_len = buf[6] & 0x0f; ++ /* for support 2GB card*/ ++ if (csd->read_bl_len >= 10) ++ { ++ num = csd->read_bl_len - 9; ++ csd->read_bl_len = 9; ++ } ++ ++ csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0; ++ csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0; ++ csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0; ++ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0; ++ csd->c_size = ((((u16)buf[7]) & 0x03) << 10) | (((u16)buf[8]) << 2) | (((u16)buf[9]) & 0xc0) >> 6; ++ ++ if (num) ++ csd->c_size = csd->c_size << num; ++ ++ ++ csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3; ++ csd->vdd_r_curr_max = buf[9] & 0x07; ++ csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5; ++ csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2; ++ csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7); ++ csd->sector_size = (buf[11] & 0x7c) >> 2; ++ csd->erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5); ++ csd->wp_grp_size = buf[12] & 0x1f; ++ csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0; ++ csd->default_ecc = (buf[13] & 0x60) >> 5; ++ csd->r2w_factor = (buf[13] & 0x1c) >> 2; ++ csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6); ++ if (csd->write_bl_len >= 10) ++ csd->write_bl_len = 9; ++ ++ csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0; ++ csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0; ++ csd->copy = (buf[15] & 0x40) ? 1 : 0; ++ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0; ++ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0; ++ csd->file_format = (buf[15] & 0x0c) >> 2; ++ csd->ecc = buf[15] & 0x03; ++ break; ++ case 1 : /* Version 2.00/High Capacity */ ++ csd->taac = 0; ++ csd->nsac = 0; ++ csd->tran_speed = buf[4]; ++ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4); ++ ++ csd->read_bl_len = 9; ++ csd->read_bl_partial = 0; ++ csd->write_blk_misalign = 0; ++ csd->read_blk_misalign = 0; ++ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0; ++ csd->c_size = ((((u16)buf[8]) & 0x3f) << 16) | (((u16)buf[9]) << 8) | ((u16)buf[10]) ; ++ csd->sector_size = 0x7f; ++ csd->erase_grp_size = 0; ++ csd->wp_grp_size = 0; ++ csd->wp_grp_enable = 0; ++ csd->default_ecc = (buf[13] & 0x60) >> 5; ++ csd->r2w_factor = 4;/* Unused */ ++ csd->write_bl_len = 9; ++ ++ csd->write_bl_partial = 0; ++ csd->file_format_grp = 0; ++ csd->copy = (buf[15] & 0x40) ? 1 : 0; ++ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0; ++ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0; ++ csd->file_format = 0; ++ csd->ecc = buf[15] & 0x03; ++ } ++ ++ return 0; ++} ++ ++int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state) ++{ ++ u8 *buf = request->response; ++ ++ if (request->result) ++ return request->result; ++ ++ r1->cmd = buf[0]; ++ r1->status = PARSE_U32(buf,1); ++ ++ debug("mmc_unpack_r1: cmd=%d status=%08x\n", r1->cmd, r1->status); ++ ++ if (R1_STATUS(r1->status)) { ++ if (r1->status & R1_OUT_OF_RANGE) return MMC_ERROR_OUT_OF_RANGE; ++ if (r1->status & R1_ADDRESS_ERROR) return MMC_ERROR_ADDRESS; ++ if (r1->status & R1_BLOCK_LEN_ERROR) return MMC_ERROR_BLOCK_LEN; ++ if (r1->status & R1_ERASE_SEQ_ERROR) return MMC_ERROR_ERASE_SEQ; ++ if (r1->status & R1_ERASE_PARAM) return MMC_ERROR_ERASE_PARAM; ++ if (r1->status & R1_WP_VIOLATION) return MMC_ERROR_WP_VIOLATION; ++ /*if (r1->status & R1_CARD_IS_LOCKED) return MMC_ERROR_CARD_IS_LOCKED; */ ++ if (r1->status & R1_LOCK_UNLOCK_FAILED) return MMC_ERROR_LOCK_UNLOCK_FAILED; ++ if (r1->status & R1_COM_CRC_ERROR) return MMC_ERROR_COM_CRC; ++ if (r1->status & R1_ILLEGAL_COMMAND) return MMC_ERROR_ILLEGAL_COMMAND; ++ if (r1->status & R1_CARD_ECC_FAILED) return MMC_ERROR_CARD_ECC_FAILED; ++ if (r1->status & R1_CC_ERROR) return MMC_ERROR_CC; ++ if (r1->status & R1_ERROR) return MMC_ERROR_GENERAL; ++ if (r1->status & R1_UNDERRUN) return MMC_ERROR_UNDERRUN; ++ if (r1->status & R1_OVERRUN) return MMC_ERROR_OVERRUN; ++ if (r1->status & R1_CID_CSD_OVERWRITE) return MMC_ERROR_CID_CSD_OVERWRITE; ++ } ++ ++ if (buf[0] != request->cmd) ++ return MMC_ERROR_HEADER_MISMATCH; ++ ++ /* This should be last - it's the least dangerous error */ ++ ++ return 0; ++} ++ ++int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr) ++{ ++ u8 *buf = request->response; ++ if (request->result) ++ return request->result; ++ ++ *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */ ++ return mmc_unpack_r1(request, r1, state); ++ ++} ++ ++int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca) ++{ ++ u8 *buf = request->response; ++ ++ if (request->result) ++ return request->result; ++ ++ *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */ ++ ++ *(buf+1) = 0; ++ *(buf+2) = 0; ++ ++ return mmc_unpack_r1(request, r1, state); ++} ++ ++int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid) ++{ ++ int i; ++ u8 *buf = request->response; ++ ++ if (request->result) ++ return request->result; ++ ++ cid->mid = buf[1]; ++ cid->oid = PARSE_U16(buf,2); ++ for (i = 0 ; i < 5 ; i++) ++ cid->pnm[i] = buf[4+i]; ++ cid->pnm[6] = 0; ++ cid->prv = buf[10]; ++ cid->psn = PARSE_U32(buf,10); ++ cid->mdt = buf[15]; ++ ++ printf("Man %02x OEM 0x%04x \"%s\" %d.%d 0x%08x " ++ "Date %02u/%04u\n", ++ cid->mid, ++ cid->oid, ++ cid->pnm, ++ cid->prv >> 4, ++ cid->prv & 0xf, ++ cid->psn, ++ cid->mdt & 0xf, ++ (cid->mdt >> 4) + 2000); ++ ++ if (buf[0] != 0x3f) ++ return MMC_ERROR_HEADER_MISMATCH; ++ return 0; ++} ++ ++int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3) ++{ ++ u8 *buf = request->response; ++ ++ if (request->result) ++ return request->result; ++ ++ r3->ocr = PARSE_U32(buf,1); ++ debug("mmc_unpack_r3: ocr=%08x\n", r3->ocr); ++ ++ if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH; ++ return 0; ++} ++ ++#define KBPS 1 ++#define MBPS 1000 ++ ++static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; ++static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, ++ 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; ++ ++u32 mmc_tran_speed(u8 ts) ++{ ++ u32 rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; ++ ++ if (rate <= 0) { ++ debug("%s: error - unrecognized speed 0x%02x\n", __func__, ts); ++ return 1; ++ } ++ ++ return rate; ++} ++ ++void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg, ++ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer) ++{ ++ request->cmd = cmd; ++ request->arg = arg; ++ request->rtype = rtype; ++ request->nob = nob; ++ request->block_len = block_len; ++ request->buffer = buffer; ++ request->cnt = nob * block_len; ++ ++ jz_mmc_exec_cmd(request); ++} +diff --git a/drivers/mmc/jz_mmc.h b/drivers/mmc/jz_mmc.h +new file mode 100644 +index 0000000..936c514 +--- /dev/null ++++ b/drivers/mmc/jz_mmc.h +@@ -0,0 +1,176 @@ ++/* ++ * linux/drivers/mmc/jz_mmc.h ++ * ++ * Author: Vladimir Shebordaev, Igor Oblakov ++ * Copyright: MontaVista Software Inc. ++ * ++ * $Id: jz_mmc.h,v 1.3 2007-06-15 08:04:20 jlwei Exp $ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __MMC_JZMMC_H__ ++#define __MMC_JZMMC_H__ ++ ++#define ID_TO_RCA(x) ((x)+1) ++#define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */ ++ ++/* Standard MMC/SD clock speeds */ ++#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */ ++#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */ ++#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ ++ ++/* Use negative numbers to disambiguate */ ++#define MMC_CIM_RESET -1 ++#define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ ++ ++#define R1_OUT_OF_RANGE (1 << 31) /* er, c */ ++#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ ++#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */ ++#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */ ++#define R1_ERASE_PARAM (1 << 27) /* ex, c */ ++#define R1_WP_VIOLATION (1 << 26) /* erx, c */ ++#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */ ++#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */ ++#define R1_COM_CRC_ERROR (1 << 23) /* er, b */ ++#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */ ++#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */ ++#define R1_CC_ERROR (1 << 20) /* erx, c */ ++#define R1_ERROR (1 << 19) /* erx, c */ ++#define R1_UNDERRUN (1 << 18) /* ex, c */ ++#define R1_OVERRUN (1 << 17) /* ex, c */ ++#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */ ++#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ ++#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ ++#define R1_ERASE_RESET (1 << 13) /* sr, c */ ++#define R1_STATUS(x) (x & 0xFFFFE000) ++ ++#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ ++ ++#define MMC_PROGRAM_CID 26 /* adtc R1 */ ++#define MMC_PROGRAM_CSD 27 /* adtc R1 */ ++ ++#define MMC_GO_IRQ_STATE 40 /* bcr R5 */ ++#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */ ++#define MMC_LOCK_UNLOCK 42 /* adtc R1b */ ++#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ ++#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ ++#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ ++ ++ ++enum mmc_result_t { ++ MMC_NO_RESPONSE = -1, ++ MMC_NO_ERROR = 0, ++ MMC_ERROR_OUT_OF_RANGE, ++ MMC_ERROR_ADDRESS, ++ MMC_ERROR_BLOCK_LEN, ++ MMC_ERROR_ERASE_SEQ, ++ MMC_ERROR_ERASE_PARAM, ++ MMC_ERROR_WP_VIOLATION, ++ MMC_ERROR_CARD_IS_LOCKED, ++ MMC_ERROR_LOCK_UNLOCK_FAILED, ++ MMC_ERROR_COM_CRC, ++ MMC_ERROR_ILLEGAL_COMMAND, ++ MMC_ERROR_CARD_ECC_FAILED, ++ MMC_ERROR_CC, ++ MMC_ERROR_GENERAL, ++ MMC_ERROR_UNDERRUN, ++ MMC_ERROR_OVERRUN, ++ MMC_ERROR_CID_CSD_OVERWRITE, ++ MMC_ERROR_STATE_MISMATCH, ++ MMC_ERROR_HEADER_MISMATCH, ++ MMC_ERROR_TIMEOUT, ++ MMC_ERROR_CRC, ++ MMC_ERROR_DRIVER_FAILURE, ++}; ++ ++enum card_state { ++ CARD_STATE_EMPTY = -1, ++ CARD_STATE_IDLE = 0, ++ CARD_STATE_READY = 1, ++ CARD_STATE_IDENT = 2, ++ CARD_STATE_STBY = 3, ++ CARD_STATE_TRAN = 4, ++ CARD_STATE_DATA = 5, ++ CARD_STATE_RCV = 6, ++ CARD_STATE_PRG = 7, ++ CARD_STATE_DIS = 8, ++}; ++ ++enum mmc_rsp_t { ++ RESPONSE_NONE = 0, ++ RESPONSE_R1 = 1, ++ RESPONSE_R1B = 2, ++ RESPONSE_R2_CID = 3, ++ RESPONSE_R2_CSD = 4, ++ RESPONSE_R3 = 5, ++ RESPONSE_R4 = 6, ++ RESPONSE_R5 = 7, ++ RESPONSE_R6 = 8, ++}; ++ ++struct mmc_response_r1 { ++ u8 cmd; ++ u32 status; ++}; ++ ++struct mmc_response_r3 { ++ u32 ocr; ++}; ++ ++/* the information structure of MMC/SD Card */ ++struct mmc_info { ++ int id; /* Card index */ ++ int sd; /* MMC or SD card */ ++ int rca; /* RCA */ ++ u32 scr; /* SCR 63:32*/ ++ int flags; /* Ejected, inserted */ ++ enum card_state state; /* empty, ident, ready, whatever */ ++ ++ /* Card specific information */ ++ struct mmc_cid cid; ++ struct mmc_csd csd; ++ u32 block_num; ++ u32 block_len; ++ u32 erase_unit; ++}; ++ ++struct mmc_info mmcinfo; ++ ++struct mmc_request { ++ int index; /* Slot index - used for CS lines */ ++ int cmd; /* Command to send */ ++ u32 arg; /* Argument to send */ ++ enum mmc_rsp_t rtype; /* Response type expected */ ++ ++ /* Data transfer (these may be modified at the low level) */ ++ u16 nob; /* Number of blocks to transfer*/ ++ u16 block_len; /* Block length */ ++ u8 *buffer; /* Data buffer */ ++ u32 cnt; /* Data length, for PIO */ ++ ++ /* Results */ ++ u8 response[18]; /* Buffer to store response - CRC is optional */ ++ enum mmc_result_t result; ++}; ++ ++char * mmc_result_to_string(int); ++int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd); ++int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state); ++int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca); ++int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr); ++int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid); ++int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3); ++ ++void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg, ++ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer); ++u32 mmc_tran_speed(u8 ts); ++void jz_mmc_set_clock(int sd, u32 rate); ++ ++static inline void mmc_simple_cmd(struct mmc_request *request, int cmd, u32 arg, enum mmc_rsp_t rtype) ++{ ++ mmc_send_cmd( request, cmd, arg, 0, 0, rtype, 0); ++} ++ ++#endif /* __MMC_JZMMC_H__ */ +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index 7bff444..7b33be0 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -31,6 +31,15 @@ + /* + * Miscellaneous configurable options + */ ++#define CONFIG_JZ4740_MMC ++#define CONFIG_MMC 1 ++#define CONFIG_FAT 1 ++#define CONFIG_DOS_PARTITION 1 ++#define CONFIG_CMD_MMC ++#define CONFIG_CMD_FAT ++#define CONFIG_CMD_EXT2 ++ ++ + #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ + #define CONFIG_SYS_INIT_SP_OFFSET 0x400000 + #define CONFIG_SYS_LOAD_ADDR 0x80600000 +diff --git a/include/mmc.h b/include/mmc.h +index a13e2bd..3c4761c 100644 +--- a/include/mmc.h ++++ b/include/mmc.h +@@ -283,4 +283,44 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode); + int mmc_legacy_init(int verbose); + #endif + ++struct mmc_csd ++{ ++ u8 csd_structure:2, ++ spec_vers:4, ++ rsvd1:2; ++ u8 taac; ++ u8 nsac; ++ u8 tran_speed; ++ u16 ccc:12, ++ read_bl_len:4; ++ u32 c_size:22; ++ u64 read_bl_partial:1, ++ write_blk_misalign:1, ++ read_blk_misalign:1, ++ dsr_imp:1, ++ rsvd2:2, ++ vdd_r_curr_min:3, ++ vdd_r_curr_max:3, ++ vdd_w_curr_min:3, ++ vdd_w_curr_max:3, ++ c_size_mult:3, ++ sector_size:5, ++ erase_grp_size:5, ++ wp_grp_size:5, ++ wp_grp_enable:1, ++ default_ecc:2, ++ r2w_factor:3, ++ write_bl_len:4, ++ write_bl_partial:1, ++ rsvd3:5; ++ u8 file_format_grp:1, ++ copy:1, ++ perm_write_protect:1, ++ tmp_write_protect:1, ++ file_format:2, ++ ecc:2; ++ u8 crc:7; ++ u8 one:1; ++}; ++ + #endif /* _MMC_H_ */ +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch.svn-base new file mode 100644 index 0000000..73e0324 --- /dev/null +++ b/package/boot/uboot-xburst/patches/.svn/text-base/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch.svn-base @@ -0,0 +1,200 @@ +From c52b6168979d03fc31205444c3278c537787472a Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Wed, 10 Oct 2012 18:39:55 +0800 +Subject: [PATCH 4/6] add more boot options(F1/F2/F3/F4/M/S) + +--- + arch/mips/include/asm/global_data.h | 3 +++ + arch/mips/lib/bootm.c | 17 ++++++++++++++++- + board/qi/qi_lb60/qi_lb60.c | 26 +++++++++++++++++++++++--- + common/main.c | 21 +++++++++++++++++++-- + include/configs/qi_lb60.h | 32 ++++++++++++++++++++++++++++++++ + 5 files changed, 93 insertions(+), 6 deletions(-) + +diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h +index 6e2cdc7..cd03d7e 100644 +--- a/arch/mips/include/asm/global_data.h ++++ b/arch/mips/include/asm/global_data.h +@@ -59,6 +59,9 @@ typedef struct global_data { + unsigned long env_valid; /* Checksum of Environment valid? */ + void **jt; /* jump table */ + char env_buf[32]; /* buffer for getenv() before reloc. */ ++#if defined(CONFIG_NANONOTE) ++ unsigned long boot_option; ++#endif + } gd_t; + + #include <asm-generic/global_data_flags.h> +diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c +index 608c1a7..e00416b 100644 +--- a/arch/mips/lib/bootm.c ++++ b/arch/mips/lib/bootm.c +@@ -47,10 +47,25 @@ int do_bootm_linux(int flag, int argc, char * const argv[], + bootm_headers_t *images) + { + void (*theKernel) (int, char **, char **, int *); +- char *commandline = getenv("bootargs"); ++ char *commandline; + char env_buf[12]; + char *cp; + ++#if defined(CONFIG_NANONOTE) ++ if (gd->boot_option & BOOT_FROM_MEMCARD) ++ commandline = getenv ("bootargsfromsd"); ++ else if (gd->boot_option & BOOT_WITH_F1) ++ commandline = getenv ("bootargsf1"); ++ else if (gd->boot_option & BOOT_WITH_F2) ++ commandline = getenv ("bootargsf2"); ++ else if (gd->boot_option & BOOT_WITH_F3) ++ commandline = getenv ("bootargsf3"); ++ else if (gd->boot_option & BOOT_WITH_F4) ++ commandline = getenv ("bootargsf4"); ++ else ++#endif ++ commandline = getenv ("bootargs"); ++ + if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) + return 1; + +diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c +index a2ba648..d622219 100644 +--- a/board/qi/qi_lb60/qi_lb60.c ++++ b/board/qi/qi_lb60/qi_lb60.c +@@ -15,7 +15,7 @@ DECLARE_GLOBAL_DATA_PTR; + + static void gpio_init(void) + { +- unsigned int i; ++ unsigned int i, j; + + /* Initialize NAND Flash Pins */ + __gpio_as_nand(); +@@ -42,14 +42,34 @@ static void gpio_init(void) + + if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){ + printf("[S] pressed, enable UART0\n"); ++ gd->boot_option |= BOOT_WITH_ENABLE_UART; + __gpio_as_uart0(); + } else { + __gpio_as_input(GPIO_KEYIN_8); + __gpio_enable_pull(GPIO_KEYIN_8); + } + +- /* enable the TP4, TP5 as UART0 */ +- __gpio_jtag_to_uart0(); ++ if (__gpio_get_pin(GPIO_KEYIN_BASE + 3) == 0) { ++ printf("[M] pressed, boot from memory card\n"); ++ gd->boot_option |= BOOT_FROM_MEMCARD; ++ __gpio_jtag_to_uart0(); ++ } ++ ++ for (j = 0; j < 4; j++) { ++ for (i = 0; i < 4; i++) ++ __gpio_set_pin(GPIO_KEYOUT_BASE + i); ++ ++ __gpio_clear_pin(GPIO_KEYOUT_BASE + j); ++ ++ if (__gpio_get_pin(GPIO_KEYIN_BASE) == 0) { ++ printf("[F%d] pressed", (j + 1)); ++ gd->boot_option |= (1 << (j + 2)); ++ /* BOOT_WITH_F1 (1 << 2) */ ++ /* BOOT_WITH_F2 (1 << 3) */ ++ /* BOOT_WITH_F3 (1 << 4) */ ++ /* BOOT_WITH_F4 (1 << 5) */ ++ } ++ } + + __gpio_as_output(GPIO_AUDIO_POP); + __gpio_set_pin(GPIO_AUDIO_POP); +diff --git a/common/main.c b/common/main.c +index 9507cec..dbfb7ca 100644 +--- a/common/main.c ++++ b/common/main.c +@@ -355,7 +355,11 @@ void main_loop (void) + #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) + s = getenv ("bootdelay"); + bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; +- ++#if defined(CONFIG_NANONOTE) ++ DECLARE_GLOBAL_DATA_PTR; ++ if (gd->boot_option & BOOT_WITH_ENABLE_UART) ++ bootdelay = 3; ++# endif + debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay); + + #if defined(CONFIG_MENU_SHOW) +@@ -379,7 +383,20 @@ void main_loop (void) + } + else + #endif /* CONFIG_BOOTCOUNT_LIMIT */ +- s = getenv ("bootcmd"); ++#if defined(CONFIG_NANONOTE) ++ if (gd->boot_option & BOOT_FROM_MEMCARD) ++ s = getenv ("bootcmdfromsd"); ++ else if (gd->boot_option & BOOT_WITH_F1) ++ s = getenv ("bootcmdf1"); ++ else if (gd->boot_option & BOOT_WITH_F2) ++ s = getenv ("bootcmdf2"); ++ else if (gd->boot_option & BOOT_WITH_F3) ++ s = getenv ("bootcmdf3"); ++ else if (gd->boot_option & BOOT_WITH_F4) ++ s = getenv ("bootcmdf4"); ++ else ++#endif ++ s = getenv ("bootcmd"); + + debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>"); + +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index 7b33be0..52b370c 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -31,6 +31,7 @@ + /* + * Miscellaneous configurable options + */ ++#define CONFIG_NANONOTE + #define CONFIG_JZ4740_MMC + #define CONFIG_MMC 1 + #define CONFIG_FAT 1 +@@ -39,6 +40,37 @@ + #define CONFIG_CMD_FAT + #define CONFIG_CMD_EXT2 + ++#define CONFIG_CMD_UBIFS ++#define CONFIG_CMD_UBI ++#define CONFIG_MTD_PARTITIONS ++#define CONFIG_MTD_DEVICE ++#define CONFIG_CMD_MTDPARTS ++#define CONFIG_CMD_UBI ++#define CONFIG_CMD_UBIFS ++#define CONFIG_LZO ++#define CONFIG_RBTREE ++ ++#define MTDIDS_DEFAULT "nand0=jz4740-nand" ++#define MTDPARTS_DEFAULT "mtdparts=jz4740-nand:4M@0(uboot)ro,4M@4M(kernel)ro,512M@8M(rootfs)ro,-(data)ro" ++ ++#define BOOT_FROM_MEMCARD 1 ++#define BOOT_WITH_ENABLE_UART (1 << 1) /* Vaule for global_data.h gd->boot_option */ ++#define BOOT_WITH_F1 (1 << 2) ++#define BOOT_WITH_F2 (1 << 3) ++#define BOOT_WITH_F3 (1 << 4) ++#define BOOT_WITH_F4 (1 << 5) ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ "bootcmdfromsd=mmc init; ext2load mmc 0 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsfromsd=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \ ++ "bootcmdf1=mmc init; ext2load mmc 0:1 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsf1=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \ ++ "bootcmdf2=mmc init; ext2load mmc 0:2 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsf2=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p2 rw rootwait\0" \ ++ "bootcmdf3=mmc init; ext2load mmc 0:3 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsf3=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p3 rw rootwait\0" \ ++ "bootcmdf4=mtdparts default;ubi part rootfs;ubifsmount rootfs;ubifsload 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsf4=mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait" + + #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ + #define CONFIG_SYS_INIT_SP_OFFSET 0x400000 +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0005-add-nanonote-lcd-support.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0005-add-nanonote-lcd-support.patch.svn-base new file mode 100644 index 0000000..2c550f7 --- /dev/null +++ b/package/boot/uboot-xburst/patches/.svn/text-base/0005-add-nanonote-lcd-support.patch.svn-base @@ -0,0 +1,847 @@ +From ca8c5216cfd3ad3fda9867ed2d157ae5a209834b Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Wed, 10 Oct 2012 22:05:27 +0800 +Subject: [PATCH 5/6] add nanonote lcd support + +--- + arch/mips/include/asm/global_data.h | 1 + + arch/mips/include/asm/jz4740.h | 90 ++++++++ + arch/mips/lib/board.c | 6 + + common/lcd.c | 9 +- + drivers/video/Makefile | 1 + + drivers/video/nanonote_gpm940b0.c | 400 +++++++++++++++++++++++++++++++++++ + drivers/video/nanonote_gpm940b0.h | 135 ++++++++++++ + include/configs/qi_lb60.h | 7 + + include/lcd.h | 52 ++++- + 9 files changed, 697 insertions(+), 4 deletions(-) + create mode 100644 drivers/video/nanonote_gpm940b0.c + create mode 100644 drivers/video/nanonote_gpm940b0.h + +diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h +index cd03d7e..7cec2de 100644 +--- a/arch/mips/include/asm/global_data.h ++++ b/arch/mips/include/asm/global_data.h +@@ -44,6 +44,7 @@ typedef struct global_data { + unsigned long per_clk; /* Peripheral bus clock */ + unsigned long mem_clk; /* Memory bus clock */ + unsigned long dev_clk; /* Device clock */ ++ unsigned long fb_base; /* base address of framebuffer */ + /* "static data" needed by most of timer.c */ + unsigned long tbl; + unsigned long lastinc; +diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h +index 68287fb..13724a2 100644 +--- a/arch/mips/include/asm/jz4740.h ++++ b/arch/mips/include/asm/jz4740.h +@@ -1312,5 +1312,95 @@ do { \ + while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \ + } while (0) + ++/************************************************************************* ++ * LCD (LCD Controller) ++ *************************************************************************/ ++#define REG32(addr) *((volatile u32 *)(addr)) ++ ++#define CPM_BASE 0xB0000000 ++#define CPM_CPCCR (CPM_BASE+0x00) ++#define REG_CPM_CPCCR REG32(CPM_CPCCR) ++ ++#define LCD_BASE 0xB3050000 ++#define LCD_CFG (LCD_BASE + 0x00) /* LCD Configure Register */ ++#define LCD_VSYNC (LCD_BASE + 0x04) /* Vertical Synchronize Register */ ++#define LCD_HSYNC (LCD_BASE + 0x08) /* Horizontal Synchronize Register */ ++#define LCD_VAT (LCD_BASE + 0x0c) /* Virtual Area Setting Register */ ++#define LCD_DAH (LCD_BASE + 0x10) /* Display Area Horizontal Start/End Point */ ++#define LCD_DAV (LCD_BASE + 0x14) /* Display Area Vertical Start/End Point */ ++#define LCD_PS (LCD_BASE + 0x18) /* PS Signal Setting */ ++#define LCD_CLS (LCD_BASE + 0x1c) /* CLS Signal Setting */ ++#define LCD_SPL (LCD_BASE + 0x20) /* SPL Signal Setting */ ++#define LCD_REV (LCD_BASE + 0x24) /* REV Signal Setting */ ++#define LCD_CTRL (LCD_BASE + 0x30) /* LCD Control Register */ ++#define LCD_STATE (LCD_BASE + 0x34) /* LCD Status Register */ ++#define LCD_IID (LCD_BASE + 0x38) /* Interrupt ID Register */ ++#define LCD_DA0 (LCD_BASE + 0x40) /* Descriptor Address Register 0 */ ++#define LCD_SA0 (LCD_BASE + 0x44) /* Source Address Register 0 */ ++#define LCD_FID0 (LCD_BASE + 0x48) /* Frame ID Register 0 */ ++#define LCD_CMD0 (LCD_BASE + 0x4c) /* DMA Command Register 0 */ ++#define LCD_DA1 (LCD_BASE + 0x50) /* Descriptor Address Register 1 */ ++#define LCD_SA1 (LCD_BASE + 0x54) /* Source Address Register 1 */ ++#define LCD_FID1 (LCD_BASE + 0x58) /* Frame ID Register 1 */ ++#define LCD_CMD1 (LCD_BASE + 0x5c) /* DMA Command Register 1 */ ++ ++#define REG_LCD_CFG REG32(LCD_CFG) ++#define REG_LCD_VSYNC REG32(LCD_VSYNC) ++#define REG_LCD_HSYNC REG32(LCD_HSYNC) ++#define REG_LCD_VAT REG32(LCD_VAT) ++#define REG_LCD_DAH REG32(LCD_DAH) ++#define REG_LCD_DAV REG32(LCD_DAV) ++#define REG_LCD_PS REG32(LCD_PS) ++#define REG_LCD_CLS REG32(LCD_CLS) ++#define REG_LCD_SPL REG32(LCD_SPL) ++#define REG_LCD_REV REG32(LCD_REV) ++#define REG_LCD_CTRL REG32(LCD_CTRL) ++#define REG_LCD_STATE REG32(LCD_STATE) ++#define REG_LCD_IID REG32(LCD_IID) ++#define REG_LCD_DA0 REG32(LCD_DA0) ++#define REG_LCD_SA0 REG32(LCD_SA0) ++#define REG_LCD_FID0 REG32(LCD_FID0) ++#define REG_LCD_CMD0 REG32(LCD_CMD0) ++#define REG_LCD_DA1 REG32(LCD_DA1) ++#define REG_LCD_SA1 REG32(LCD_SA1) ++#define REG_LCD_FID1 REG32(LCD_FID1) ++#define REG_LCD_CMD1 REG32(LCD_CMD1) ++ ++#define LCD_CTRL_BPP_BIT 0 /* Bits Per Pixel */ ++#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT) ++ #define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT) /* 1 bpp */ ++ #define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT) /* 2 bpp */ ++ #define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT) /* 4 bpp */ ++ #define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT) /* 8 bpp */ ++ #define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT) /* 15/16 bpp */ ++ #define LCD_CTRL_BPP_18_24 (5 << LCD_CTRL_BPP_BIT) /* 18/24/32 bpp */ ++ ++#define LCD_CTRL_BST_BIT 28 /* Burst Length Selection */ ++#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT) ++ #define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT) /* 4-word */ ++ #define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT) /* 8-word */ ++ #define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT) /* 16-word */ ++#define LCD_CTRL_RGB565 (0 << 27) /* RGB565 mode */ ++#define LCD_CTRL_RGB555 (1 << 27) /* RGB555 mode */ ++#define LCD_CTRL_OFUP (1 << 26) /* Output FIFO underrun protection enable */ ++#define LCD_CTRL_FRC_BIT 24 /* STN FRC Algorithm Selection */ ++#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT) ++ #define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT) /* 16 grayscale */ ++ #define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT) /* 4 grayscale */ ++ #define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT) /* 2 grayscale */ ++ ++#define CPM_LPCDR (CPM_BASE+0x64) ++#define CPM_CLKGR (CPM_BASE+0x20) ++#define REG_CPM_LPCDR REG32(CPM_LPCDR) ++#define REG_CPM_CLKGR REG32(CPM_CLKGR) ++ ++#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU) ++#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD) ++#define __cpm_set_pixdiv(v) \ ++ (REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT))) ++#define __cpm_set_ldiv(v) \ ++ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT))) ++#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD) ++ + #endif /* !__ASSEMBLY__ */ + #endif /* __JZ4740_H__ */ +diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c +index b14b33e..c2e64d9 100644 +--- a/arch/mips/lib/board.c ++++ b/arch/mips/lib/board.c +@@ -172,6 +172,12 @@ void board_init_f(ulong bootflag) + addr &= ~(4096 - 1); + debug("Top of RAM usable for U-Boot at: %08lx\n", addr); + ++#ifdef CONFIG_LCD ++ /* reserve memory for LCD display (always full pages) */ ++ addr = lcd_setmem (addr); ++ gd->fb_base = addr; ++#endif /* CONFIG_LCD */ ++ + /* Reserve memory for U-Boot code, data & bss + * round down to next 16 kB limit + */ +diff --git a/common/lcd.c b/common/lcd.c +index b6be800..af1281a 100644 +--- a/common/lcd.c ++++ b/common/lcd.c +@@ -263,6 +263,13 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count) + lcd_color_fg : lcd_color_bg; + bits <<= 1; + } ++#elif LCD_BPP == LCD_COLOR32 ++ uint *m = (uint *)d; ++ for (c=0; c<32; ++c) { ++ *m++ = (bits & 0x80) ? ++ lcd_color_fg : lcd_color_bg; ++ bits <<= 1; ++ } + #endif + } + #if LCD_BPP == LCD_MONOCHROME +@@ -509,7 +516,7 @@ static inline ushort *configuration_get_cmap(void) + return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); + #elif defined(CONFIG_ATMEL_LCD) + return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); +-#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) ++#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) && !defined(CONFIG_VIDEO_GPM940B0) + return panel_info.cmap; + #else + #if defined(CONFIG_LCD_LOGO) +diff --git a/drivers/video/Makefile b/drivers/video/Makefile +index ebb6da8..03625bc 100644 +--- a/drivers/video/Makefile ++++ b/drivers/video/Makefile +@@ -50,6 +50,7 @@ COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o + COBJS-$(CONFIG_VIDEO_SM501) += sm501.o + COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o + COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o ++COBJS-$(CONFIG_VIDEO_GPM940B0) += nanonote_gpm940b0.o + + COBJS := $(sort $(COBJS-y)) + SRCS := $(COBJS:.o=.c) +diff --git a/drivers/video/nanonote_gpm940b0.c b/drivers/video/nanonote_gpm940b0.c +new file mode 100644 +index 0000000..11efb72 +--- /dev/null ++++ b/drivers/video/nanonote_gpm940b0.c +@@ -0,0 +1,400 @@ ++/* ++ * JzRISC lcd controller ++ * ++ * Xiangfu Liu <xiangfu@sharism.cc> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#include <config.h> ++#include <common.h> ++#include <lcd.h> ++ ++#include <asm/io.h> /* virt_to_phys() */ ++#include <asm/jz4740.h> ++ ++#include "nanonote_gpm940b0.h" ++ ++#define align2(n) (n)=((((n)+1)>>1)<<1) ++#define align4(n) (n)=((((n)+3)>>2)<<2) ++#define align8(n) (n)=((((n)+7)>>3)<<3) ++ ++struct jzfb_info { ++ unsigned int cfg; /* panel mode and pin usage etc. */ ++ unsigned int w; ++ unsigned int h; ++ unsigned int bpp; /* bit per pixel */ ++ unsigned int fclk; /* frame clk */ ++ unsigned int hsw; /* hsync width, in pclk */ ++ unsigned int vsw; /* vsync width, in line count */ ++ unsigned int elw; /* end of line, in pclk */ ++ unsigned int blw; /* begin of line, in pclk */ ++ unsigned int efw; /* end of frame, in line count */ ++ unsigned int bfw; /* begin of frame, in line count */ ++}; ++ ++static struct jzfb_info jzfb = { ++ MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N, ++ 320, 240, 32, 70, 1, 1, 273, 140, 1, 20 ++}; ++ ++vidinfo_t panel_info = { ++ 320, 240, LCD_BPP, ++}; ++ ++void *lcd_base; ++void *lcd_console_address; ++int lcd_line_length; ++int lcd_color_fg; ++int lcd_color_bg; ++short console_col; ++short console_row; ++ ++static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid) ++{ ++ u_long palette_mem_size; ++ struct jz_fb_info *fbi = &vid->jz_fb; ++ int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8; ++ ++ fbi->screen = (u_long)lcdbase; ++ fbi->palette_size = 256; ++ palette_mem_size = fbi->palette_size * sizeof(u16); ++ ++ debug("jz_lcd.c palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); ++ /* locate palette and descs at end of page following fb */ ++ fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size; ++ ++ return 0; ++} ++ ++static void jz_lcd_desc_init(vidinfo_t *vid) ++{ ++ struct jz_fb_info * fbi; ++ fbi = &vid->jz_fb; ++ fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 3*16); ++ fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 2*16); ++ fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 1*16); ++ ++ #define BYTES_PER_PANEL (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8) ++ ++ /* populate descriptors */ ++ fbi->dmadesc_fblow->fdadr = virt_to_phys(fbi->dmadesc_fblow); ++ fbi->dmadesc_fblow->fsadr = virt_to_phys((void *)(fbi->screen + BYTES_PER_PANEL)); ++ fbi->dmadesc_fblow->fidr = 0; ++ fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL / 4 ; ++ ++ fbi->fdadr1 = virt_to_phys(fbi->dmadesc_fblow); /* only used in dual-panel mode */ ++ ++ fbi->dmadesc_fbhigh->fsadr = virt_to_phys((void *)fbi->screen); ++ fbi->dmadesc_fbhigh->fidr = 0; ++ fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL / 4; /* length in word */ ++ ++ fbi->dmadesc_palette->fsadr = virt_to_phys((void *)fbi->palette); ++ fbi->dmadesc_palette->fidr = 0; ++ fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2)/4 | (1<<28); ++ ++ if(NBITS(vid->vl_bpix) < 12) { ++ /* assume any mode with <12 bpp is palette driven */ ++ fbi->dmadesc_palette->fdadr = virt_to_phys(fbi->dmadesc_fbhigh); ++ fbi->dmadesc_fbhigh->fdadr = virt_to_phys(fbi->dmadesc_palette); ++ /* flips back and forth between pal and fbhigh */ ++ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_palette); ++ } else { ++ /* palette shouldn't be loaded in true-color mode */ ++ fbi->dmadesc_fbhigh->fdadr = virt_to_phys((void *)fbi->dmadesc_fbhigh); ++ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_fbhigh); /* no pal just fbhigh */ ++ } ++} ++ ++static int jz_lcd_hw_init(vidinfo_t *vid) ++{ ++ struct jz_fb_info *fbi = &vid->jz_fb; ++ unsigned int val = 0; ++ unsigned int pclk; ++ unsigned int stnH; ++ int pll_div; ++ ++ /* Setting Control register */ ++ switch (jzfb.bpp) { ++ case 1: ++ val |= LCD_CTRL_BPP_1; ++ break; ++ case 2: ++ val |= LCD_CTRL_BPP_2; ++ break; ++ case 4: ++ val |= LCD_CTRL_BPP_4; ++ break; ++ case 8: ++ val |= LCD_CTRL_BPP_8; ++ break; ++ case 15: ++ val |= LCD_CTRL_RGB555; ++ case 16: ++ val |= LCD_CTRL_BPP_16; ++ break; ++ case 17 ... 32: ++ val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */ ++ break; ++ ++ default: ++ printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp); ++ val |= LCD_CTRL_BPP_16; ++ break; ++ } ++ ++ switch (jzfb.cfg & MODE_MASK) { ++ case MODE_STN_MONO_DUAL: ++ case MODE_STN_COLOR_DUAL: ++ case MODE_STN_MONO_SINGLE: ++ case MODE_STN_COLOR_SINGLE: ++ switch (jzfb.bpp) { ++ case 1: ++ /* val |= LCD_CTRL_PEDN; */ ++ case 2: ++ val |= LCD_CTRL_FRC_2; ++ break; ++ case 4: ++ val |= LCD_CTRL_FRC_4; ++ break; ++ case 8: ++ default: ++ val |= LCD_CTRL_FRC_16; ++ break; ++ } ++ break; ++ } ++ ++ val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */ ++ val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */ ++ ++ switch (jzfb.cfg & MODE_MASK) { ++ case MODE_STN_MONO_DUAL: ++ case MODE_STN_COLOR_DUAL: ++ case MODE_STN_MONO_SINGLE: ++ case MODE_STN_COLOR_SINGLE: ++ switch (jzfb.cfg & STN_DAT_PINMASK) { ++ case STN_DAT_PIN1: ++ /* Do not adjust the hori-param value. */ ++ break; ++ case STN_DAT_PIN2: ++ align2(jzfb.hsw); ++ align2(jzfb.elw); ++ align2(jzfb.blw); ++ break; ++ case STN_DAT_PIN4: ++ align4(jzfb.hsw); ++ align4(jzfb.elw); ++ align4(jzfb.blw); ++ break; ++ case STN_DAT_PIN8: ++ align8(jzfb.hsw); ++ align8(jzfb.elw); ++ align8(jzfb.blw); ++ break; ++ } ++ break; ++ } ++ ++ REG_LCD_CTRL = val; ++ ++ switch (jzfb.cfg & MODE_MASK) { ++ case MODE_STN_MONO_DUAL: ++ case MODE_STN_COLOR_DUAL: ++ case MODE_STN_MONO_SINGLE: ++ case MODE_STN_COLOR_SINGLE: ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL)) ++ stnH = jzfb.h >> 1; ++ else ++ stnH = jzfb.h; ++ ++ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw; ++ REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw); ++ ++ /* Screen setting */ ++ REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw); ++ REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w); ++ REG_LCD_DAV = (0 << 16) | (stnH); ++ ++ /* AC BIAs signal */ ++ REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw); ++ ++ break; ++ ++ case MODE_TFT_GEN: ++ case MODE_TFT_SHARP: ++ case MODE_TFT_CASIO: ++ case MODE_TFT_SAMSUNG: ++ case MODE_8BIT_SERIAL_TFT: ++ case MODE_TFT_18BIT: ++ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw; ++ REG_LCD_HSYNC = (0 << 16) | jzfb.hsw; ++ REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h); ++ REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w ); ++ REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \ ++ | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw); ++ break; ++ } ++ ++ switch (jzfb.cfg & MODE_MASK) { ++ case MODE_TFT_SAMSUNG: ++ { ++ unsigned int total, tp_s, tp_e, ckv_s, ckv_e; ++ unsigned int rev_s, rev_e, inv_s, inv_e; ++ ++ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) * ++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */ ++ ++ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw; ++ tp_s = jzfb.blw + jzfb.w + 1; ++ tp_e = tp_s + 1; ++ ckv_s = tp_s - pclk/(1000000000/4100); ++ ckv_e = tp_s + total; ++ rev_s = tp_s - 11; /* -11.5 clk */ ++ rev_e = rev_s + total; ++ inv_s = tp_s; ++ inv_e = inv_s + total; ++ REG_LCD_CLS = (tp_s << 16) | tp_e; ++ REG_LCD_PS = (ckv_s << 16) | ckv_e; ++ REG_LCD_SPL = (rev_s << 16) | rev_e; ++ REG_LCD_REV = (inv_s << 16) | inv_e; ++ jzfb.cfg |= STFT_REVHI | STFT_SPLHI; ++ break; ++ } ++ case MODE_TFT_SHARP: ++ { ++ unsigned int total, cls_s, cls_e, ps_s, ps_e; ++ unsigned int spl_s, spl_e, rev_s, rev_e; ++ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw; ++ spl_s = 1; ++ spl_e = spl_s + 1; ++ cls_s = 0; ++ cls_e = total - 60; /* > 4us (pclk = 80ns) */ ++ ps_s = cls_s; ++ ps_e = cls_e; ++ rev_s = total - 40; /* > 3us (pclk = 80ns) */ ++ rev_e = rev_s + total; ++ jzfb.cfg |= STFT_PSHI; ++ REG_LCD_SPL = (spl_s << 16) | spl_e; ++ REG_LCD_CLS = (cls_s << 16) | cls_e; ++ REG_LCD_PS = (ps_s << 16) | ps_e; ++ REG_LCD_REV = (rev_s << 16) | rev_e; ++ break; ++ } ++ case MODE_TFT_CASIO: ++ break; ++ } ++ ++ /* Configure the LCD panel */ ++ REG_LCD_CFG = jzfb.cfg; ++ ++ /* Timing setting */ ++ __cpm_stop_lcd(); ++ ++ val = jzfb.fclk; /* frame clk */ ++ if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) { ++ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) * ++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */ ++ } else { ++ /* serial mode: Hsync period = 3*Width_Pixel */ ++ pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) * ++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */ ++ } ++ ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL)) ++ pclk = (pclk * 3); ++ ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL)) ++ pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4); ++ ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL)) ++ pclk >>= 1; ++ ++ pll_div = (REG_CPM_CPCCR & CPM_CPCCR_PCS); /* clock source,0:pllout/2 1: pllout */ ++ pll_div = pll_div ? 1 : 2; ++ val = (__cpm_get_pllout() / pll_div) / pclk; ++ val--; ++ if (val > 0x1ff) { ++ printf("CPM_LPCDR too large, set it to 0x1ff\n"); ++ val = 0x1ff; ++ } ++ __cpm_set_pixdiv(val); ++ ++ val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */ ++ if (val > 150000000) { ++ printf("Warning: LCDClock=%d\n, LCDClock must less or equal to 150MHz.\n", val); ++ printf("Change LCDClock to 150MHz\n"); ++ val = 150000000; ++ } ++ val = (__cpm_get_pllout() / pll_div) / val; ++ val--; ++ if (val > 0x1f) { ++ printf("CPM_CPCCR.LDIV too large, set it to 0x1f\n"); ++ val = 0x1f; ++ } ++ __cpm_set_ldiv( val ); ++ REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */ ++ ++ __cpm_start_lcd(); ++ udelay(1000); ++ ++ REG_LCD_DA0 = fbi->fdadr0; /* frame descripter*/ ++ ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL)) ++ REG_LCD_DA1 = fbi->fdadr1; /* frame descripter*/ ++ ++ return 0; ++} ++ ++void lcd_ctrl_init (void *lcdbase) ++{ ++ __lcd_display_pin_init(); ++ __lcd_display_on() ; ++ ++ jz_lcd_init_mem(lcdbase, &panel_info); ++ jz_lcd_desc_init(&panel_info); ++ jz_lcd_hw_init(&panel_info); ++ ++} ++ ++/* ++ * Before enabled lcd controller, lcd registers should be configured correctly. ++ */ ++void lcd_enable (void) ++{ ++ REG_LCD_CTRL &= ~(1<<4); /* LCDCTRL.DIS */ ++ REG_LCD_CTRL |= 1<<3; /* LCDCTRL.ENA*/ ++} ++ ++void lcd_disable (void) ++{ ++ REG_LCD_CTRL |= (1<<4); ++} ++ ++void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue) ++{ ++} ++ ++void lcd_initcolregs (void) ++{ ++} +diff --git a/drivers/video/nanonote_gpm940b0.h b/drivers/video/nanonote_gpm940b0.h +new file mode 100644 +index 0000000..efe491e +--- /dev/null ++++ b/drivers/video/nanonote_gpm940b0.h +@@ -0,0 +1,135 @@ ++/* ++ * JzRISC lcd controller ++ * ++ * Xiangfu Liu <xiangfu@sharism.cc> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#ifndef __QI_LB60_GPM940B0_H__ ++#define __QI_LB60_GPM940B0_H__ ++ ++struct lcd_desc{ ++ unsigned int next_desc; /* LCDDAx */ ++ unsigned int databuf; /* LCDSAx */ ++ unsigned int frame_id; /* LCDFIDx */ ++ unsigned int cmd; /* LCDCMDx */ ++}; ++ ++#define MODE_MASK 0x0f ++#define MODE_TFT_GEN 0x00 ++#define MODE_TFT_SHARP 0x01 ++#define MODE_TFT_CASIO 0x02 ++#define MODE_TFT_SAMSUNG 0x03 ++#define MODE_CCIR656_NONINT 0x04 ++#define MODE_CCIR656_INT 0x05 ++#define MODE_STN_COLOR_SINGLE 0x08 ++#define MODE_STN_MONO_SINGLE 0x09 ++#define MODE_STN_COLOR_DUAL 0x0a ++#define MODE_STN_MONO_DUAL 0x0b ++#define MODE_8BIT_SERIAL_TFT 0x0c ++ ++#define MODE_TFT_18BIT (1<<7) ++ ++#define STN_DAT_PIN1 (0x00 << 4) ++#define STN_DAT_PIN2 (0x01 << 4) ++#define STN_DAT_PIN4 (0x02 << 4) ++#define STN_DAT_PIN8 (0x03 << 4) ++#define STN_DAT_PINMASK STN_DAT_PIN8 ++ ++#define STFT_PSHI (1 << 15) ++#define STFT_CLSHI (1 << 14) ++#define STFT_SPLHI (1 << 13) ++#define STFT_REVHI (1 << 12) ++ ++#define SYNC_MASTER (0 << 16) ++#define SYNC_SLAVE (1 << 16) ++ ++#define DE_P (0 << 9) ++#define DE_N (1 << 9) ++ ++#define PCLK_P (0 << 10) ++#define PCLK_N (1 << 10) ++ ++#define HSYNC_P (0 << 11) ++#define HSYNC_N (1 << 11) ++ ++#define VSYNC_P (0 << 8) ++#define VSYNC_N (1 << 8) ++ ++#define DATA_NORMAL (0 << 17) ++#define DATA_INVERSE (1 << 17) ++ ++ ++/* Jz LCDFB supported I/O controls. */ ++#define FBIOSETBACKLIGHT 0x4688 ++#define FBIODISPON 0x4689 ++#define FBIODISPOFF 0x468a ++#define FBIORESET 0x468b ++#define FBIOPRINT_REG 0x468c ++ ++/* ++ * LCD panel specific definition ++ */ ++#define MODE (0xc9) /* 8bit serial RGB */ ++ ++#define __spi_write_reg1(reg, val) \ ++do { \ ++ unsigned char no; \ ++ unsigned short value; \ ++ unsigned char a=reg; \ ++ unsigned char b=val; \ ++ __gpio_set_pin(SPEN); \ ++ __gpio_set_pin(SPCK); \ ++ __gpio_clear_pin(SPDA); \ ++ __gpio_clear_pin(SPEN); \ ++ value=((a<<8)|(b&0xFF)); \ ++ for(no=0;no<16;no++) \ ++ { \ ++ __gpio_clear_pin(SPCK); \ ++ if((value&0x8000)==0x8000) \ ++ __gpio_set_pin(SPDA); \ ++ else \ ++ __gpio_clear_pin(SPDA); \ ++ __gpio_set_pin(SPCK); \ ++ value=(value<<1); \ ++ } \ ++ __gpio_set_pin(SPEN); \ ++} while (0) ++ ++#define __lcd_display_pin_init() \ ++do { \ ++ __cpm_start_tcu(); \ ++ __gpio_as_output(SPEN); /* use SPDA */ \ ++ __gpio_as_output(SPCK); /* use SPCK */ \ ++ __gpio_as_output(SPDA); /* use SPDA */ \ ++} while (0) ++ ++#define __lcd_display_on() \ ++do { \ ++ __spi_write_reg1(0x05, 0x1e); \ ++ __spi_write_reg1(0x05, 0x5e); \ ++ __spi_write_reg1(0x07, 0x8d); \ ++ __spi_write_reg1(0x13, 0x01); \ ++ __spi_write_reg1(0x05, 0x5f); \ ++} while (0) ++ ++#define __lcd_display_off() \ ++do { \ ++ __spi_write_reg1(0x05, 0x5e); \ ++} while (0) ++ ++#endif /* __QI_LB60_GPM940B0_H__ */ +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index 52b370c..d3e78ad 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -32,6 +32,13 @@ + * Miscellaneous configurable options + */ + #define CONFIG_NANONOTE ++ ++#define CONFIG_LCD ++#define CONFIG_SYS_WHITE_ON_BLACK ++#define LCD_BPP LCD_COLOR32 ++#define CONFIG_VIDEO_GPM940B0 ++ ++ + #define CONFIG_JZ4740_MMC + #define CONFIG_MMC 1 + #define CONFIG_FAT 1 +diff --git a/include/lcd.h b/include/lcd.h +index 42070d7..6de5482 100644 +--- a/include/lcd.h ++++ b/include/lcd.h +@@ -263,8 +263,44 @@ typedef struct vidinfo { + + void init_panel_info(vidinfo_t *vid); + +-#else ++#elif defined(CONFIG_JZSOC) ++/* ++ * LCD controller stucture for JZSOC: JZ4740 ++ */ ++struct jz_fb_dma_descriptor { ++ u_long fdadr; /* Frame descriptor address register */ ++ u_long fsadr; /* Frame source address register */ ++ u_long fidr; /* Frame ID register */ ++ u_long ldcmd; /* Command register */ ++}; ++ ++/* ++ * Jz LCD info ++ */ ++struct jz_fb_info { ++ ++ u_long fdadr0; /* physical address of frame/palette descriptor */ ++ u_long fdadr1; /* physical address of frame descriptor */ ++ ++ /* DMA descriptors */ ++ struct jz_fb_dma_descriptor * dmadesc_fblow; ++ struct jz_fb_dma_descriptor * dmadesc_fbhigh; ++ struct jz_fb_dma_descriptor * dmadesc_palette; ++ u_long screen; /* address of frame buffer */ ++ u_long palette; /* address of palette memory */ ++ u_int palette_size; ++}; ++typedef struct vidinfo { ++ ushort vl_col; /* Number of columns (i.e. 640) */ ++ ushort vl_row; /* Number of rows (i.e. 480) */ ++ u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8 */ ++ ++ struct jz_fb_info jz_fb; ++} vidinfo_t; ++ ++extern vidinfo_t panel_info; + ++#else + typedef struct vidinfo { + ushort vl_col; /* Number of columns (i.e. 160) */ + ushort vl_row; /* Number of rows (i.e. 100) */ +@@ -318,6 +354,7 @@ void lcd_show_board_info(void); + #define LCD_COLOR4 2 + #define LCD_COLOR8 3 + #define LCD_COLOR16 4 ++#define LCD_COLOR32 5 + + /*----------------------------------------------------------------------*/ + #if defined(CONFIG_LCD_INFO_BELOW_LOGO) +@@ -369,7 +406,7 @@ void lcd_show_board_info(void); + # define CONSOLE_COLOR_GREY 14 + # define CONSOLE_COLOR_WHITE 15 /* Must remain last / highest */ + +-#else ++#elif LCD_BPP == LCD_COLOR16 + + /* + * 16bpp color definitions +@@ -377,6 +414,15 @@ void lcd_show_board_info(void); + # define CONSOLE_COLOR_BLACK 0x0000 + # define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */ + ++#elif LCD_BPP == LCD_COLOR32 ++/* ++ * 18,24,32 bpp color definitions ++ */ ++# define CONSOLE_COLOR_BLACK 0x00000000 ++# define CONSOLE_COLOR_WHITE 0xffffffff /* Must remain last / highest */ ++ ++#else ++ + #endif /* color definitions */ + + /************************************************************************/ +@@ -406,7 +452,7 @@ void lcd_show_board_info(void); + #if LCD_BPP == LCD_MONOCHROME + # define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \ + (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7) +-#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) ++#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || (LCD_BPP == LCD_COLOR32) + # define COLOR_MASK(c) (c) + #else + # error Unsupported LCD BPP. +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/.svn/text-base/0006-enable-silent-console.patch.svn-base b/package/boot/uboot-xburst/patches/.svn/text-base/0006-enable-silent-console.patch.svn-base new file mode 100644 index 0000000..ebd6a6a --- /dev/null +++ b/package/boot/uboot-xburst/patches/.svn/text-base/0006-enable-silent-console.patch.svn-base @@ -0,0 +1,60 @@ +From 5eb4d4c598f2806bd1b3d1140e917bfead7851ad Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Wed, 10 Oct 2012 23:51:26 +0800 +Subject: [PATCH 6/6] enable silent console + +--- + common/console.c | 16 ++++++++++++++++ + include/configs/qi_lb60.h | 2 ++ + 2 files changed, 18 insertions(+) + +diff --git a/common/console.c b/common/console.c +index 1177f7d..e8a2078 100644 +--- a/common/console.c ++++ b/common/console.c +@@ -685,6 +685,14 @@ done: + + gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ + ++#ifdef CONFIG_SILENT_CONSOLE ++ /* Check one more time the contents of the silent environment ++ * variable, because if the environment is loaded from NAND it was ++ * not available when console_init_f() was called */ ++ if (getenv("silent") != NULL) ++ gd->flags |= GD_FLG_SILENT; ++#endif ++ + stdio_print_current_devices(); + + #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE +@@ -760,6 +768,14 @@ int console_init_r(void) + + gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ + ++#ifdef CONFIG_SILENT_CONSOLE ++ /* Check one more time the contents of the silent environment ++ * variable, because if the environment is loaded from NAND it was ++ * not available when console_init_f() was called */ ++ if (getenv("silent") != NULL) ++ gd->flags |= GD_FLG_SILENT; ++#endif ++ + stdio_print_current_devices(); + + /* Setting environment variables */ +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index d3e78ad..a3534ff 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -102,6 +102,8 @@ + #define CONFIG_SYS_NO_FLASH + #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */ + ++#define CONFIG_SILENT_CONSOLE 1 /* Enable silent console */ ++ + /* + * Command line configuration + */ +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch b/package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch new file mode 100644 index 0000000..e770243 --- /dev/null +++ b/package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch @@ -0,0 +1,894 @@ +From 0329cf7965956a5a7044827e0ce88ae8d5150e54 Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Fri, 12 Oct 2012 09:46:58 +0800 +Subject: [PATCH 1/6] qi_lb60: add nand spl support + + The JZ4740 CPU can load 8KB from two different addresses: + 1. the normal area up to 8KB starting from NAND flash address 0x00000000 + 2. the backup area up to 8KB starting from NAND flash address 0x00002000 + +Signed-off-by: Xiangfu <xiangfu@openmobilefree.net> +--- + Makefile | 12 +++ + arch/mips/cpu/xburst/Makefile | 7 +- + arch/mips/cpu/xburst/cpu.c | 4 + + arch/mips/cpu/xburst/jz4740.c | 82 +++++++---------- + arch/mips/cpu/xburst/spl/Makefile | 47 ++++++++++ + arch/mips/cpu/xburst/spl/start.S | 63 +++++++++++++ + board/qi/qi_lb60/Makefile | 4 + + board/qi/qi_lb60/qi_lb60-spl.c | 30 +++++++ + board/qi/qi_lb60/qi_lb60.c | 8 +- + board/qi/qi_lb60/u-boot-spl.lds | 61 +++++++++++++ + drivers/mtd/nand/jz4740_nand.c | 39 ++++++++- + include/configs/qi_lb60.h | 175 ++++++++++++++++++------------------- + 12 files changed, 386 insertions(+), 146 deletions(-) + create mode 100644 arch/mips/cpu/xburst/spl/Makefile + create mode 100644 arch/mips/cpu/xburst/spl/start.S + create mode 100644 board/qi/qi_lb60/qi_lb60-spl.c + create mode 100644 board/qi/qi_lb60/u-boot-spl.lds + +diff --git a/Makefile b/Makefile +index 34d9075..a22778e 100644 +--- a/Makefile ++++ b/Makefile +@@ -393,6 +393,10 @@ ALL-y += $(obj)u-boot-nodtb-tegra.bin + endif + endif + ++ifeq ($(CPU),xburst) ++ALL-y += $(obj)u-boot-xburst.bin ++endif ++ + all: $(ALL-y) $(SUBDIR_EXAMPLES) + + $(obj)u-boot.dtb: $(obj)u-boot +@@ -506,6 +510,14 @@ $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin + endif + endif + ++ifeq ($(CPU),xburst) ++$(obj)u-boot-xburst.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin ++ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync bs=8192 count=1 ++ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=8192 count=1 ++ tr '\0' '\377' < /dev/zero | dd of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=16384 count=1 ++ cat $(obj)spl/u-boot-pad.bin u-boot.bin > $@ ++endif ++ + ifeq ($(CONFIG_SANDBOX),y) + GEN_UBOOT = \ + cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \ +diff --git a/arch/mips/cpu/xburst/Makefile b/arch/mips/cpu/xburst/Makefile +index b1f2ae4..ec35e55 100644 +--- a/arch/mips/cpu/xburst/Makefile ++++ b/arch/mips/cpu/xburst/Makefile +@@ -24,9 +24,12 @@ include $(TOPDIR)/config.mk + + LIB = $(obj)lib$(CPU).o + ++COBJS-y = cpu.o jz_serial.o ++ ++ifneq ($(CONFIG_SPL_BUILD),y) + START = start.o +-SOBJS-y = +-COBJS-y = cpu.o timer.o jz_serial.o ++COBJS-y += timer.o ++endif + + COBJS-$(CONFIG_JZ4740) += jz4740.o + +diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c +index ddcbfaa..1432838 100644 +--- a/arch/mips/cpu/xburst/cpu.c ++++ b/arch/mips/cpu/xburst/cpu.c +@@ -42,6 +42,8 @@ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + ++#ifndef CONFIG_SPL_BUILD ++ + void __attribute__((weak)) _machine_restart(void) + { + struct jz4740_wdt *wdt = (struct jz4740_wdt *)JZ4740_WDT_BASE; +@@ -109,6 +111,8 @@ void invalidate_dcache_range(ulong start_addr, ulong stop) + cache_op(Hit_Invalidate_D, addr); + } + ++#endif ++ + void flush_icache_all(void) + { + u32 addr, t = 0; +diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c +index c0b9817..8816aa3 100644 +--- a/arch/mips/cpu/xburst/jz4740.c ++++ b/arch/mips/cpu/xburst/jz4740.c +@@ -32,31 +32,19 @@ int disable_interrupts(void) + return 0; + } + +-/* +- * PLL output clock = EXTAL * NF / (NR * NO) +- * NF = FD + 2, NR = RD + 2 +- * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3) +- */ + void pll_init(void) + { + struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE; + +- register unsigned int cfcr, plcr1; +- int n2FR[33] = { +- 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0, +- 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, +- 9 +- }; +- int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ +- int nf, pllout2; ++ register unsigned int cfcr, plcr; ++ unsigned int nf, pllout2; + + cfcr = CPM_CPCCR_CLKOEN | +- CPM_CPCCR_PCS | +- (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | +- (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | +- (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) | +- (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) | +- (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT); ++ (0 << CPM_CPCCR_CDIV_BIT) | ++ (2 << CPM_CPCCR_HDIV_BIT) | ++ (2 << CPM_CPCCR_PDIV_BIT) | ++ (2 << CPM_CPCCR_MDIV_BIT) | ++ (2 << CPM_CPCCR_LDIV_BIT); + + pllout2 = (cfcr & CPM_CPCCR_PCS) ? + CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2); +@@ -65,15 +53,18 @@ void pll_init(void) + writel(pllout2 / 48000000 - 1, &cpm->uhccdr); + + nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL; +- plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ ++ plcr = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ + (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ + (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ +- (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ ++ (0x32 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */ + CPM_CPPCR_PLLEN; /* enable PLL */ + + /* init PLL */ + writel(cfcr, &cpm->cpccr); +- writel(plcr1, &cpm->cppcr); ++ writel(plcr, &cpm->cppcr); ++ ++ while (!(readl(&cpm->cppcr) & CPM_CPPCR_PLLS)) ++ ; + } + + void sdram_init(void) +@@ -92,26 +83,12 @@ void sdram_init(void) + 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */ + }; + +- int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; +- + cpu_clk = CONFIG_SYS_CPU_SPEED; +- mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()]; ++ mem_clk = 84000000; + + writel(0, &emc->bcr); /* Disable bus release */ + writew(0, &emc->rtcsr); /* Disable clock for counting */ + +- /* Fault DMCR value for mode register setting*/ +-#define SDRAM_ROW0 11 +-#define SDRAM_COL0 8 +-#define SDRAM_BANK40 0 +- +- dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) | +- ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) | +- (SDRAM_BANK40 << EMC_DMCR_BA_BIT) | +- (SDRAM_BW16 << EMC_DMCR_BW_BIT) | +- EMC_DMCR_EPIN | +- cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; +- + /* Basic DMCR value */ + dmcr = ((SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) | + ((SDRAM_COL - 8) << EMC_DMCR_CA_BIT) | +@@ -128,31 +105,31 @@ void sdram_init(void) + if (tmp > 11) + tmp = 11; + dmcr |= (tmp - 4) << EMC_DMCR_TRAS_BIT; +- tmp = SDRAM_RCD / ns; + ++ tmp = SDRAM_RCD / ns; + if (tmp > 3) + tmp = 3; + dmcr |= tmp << EMC_DMCR_RCD_BIT; +- tmp = SDRAM_TPC / ns; + ++ tmp = SDRAM_TPC / ns; + if (tmp > 7) + tmp = 7; + dmcr |= tmp << EMC_DMCR_TPC_BIT; +- tmp = SDRAM_TRWL / ns; + ++ tmp = SDRAM_TRWL / ns; + if (tmp > 3) + tmp = 3; + dmcr |= tmp << EMC_DMCR_TRWL_BIT; +- tmp = (SDRAM_TRAS + SDRAM_TPC) / ns; + ++ tmp = (SDRAM_TRAS + SDRAM_TPC) / ns; + if (tmp > 14) + tmp = 14; + dmcr |= ((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT; + + /* SDRAM mode value */ +- sdmode = EMC_SDMR_BT_SEQ | +- EMC_SDMR_OM_NORMAL | +- EMC_SDMR_BL_4 | ++ sdmode = EMC_SDMR_BT_SEQ | ++ EMC_SDMR_OM_NORMAL | ++ EMC_SDMR_BL_4 | + cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)]; + + /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */ +@@ -172,8 +149,8 @@ void sdram_init(void) + if (tmp > 0xff) + tmp = 0xff; + writew(tmp, &emc->rtcor); ++ + writew(0, &emc->rtcnt); +- /* Divisor is 64, CKO/64 */ + writew(EMC_RTCSR_CKS_64, &emc->rtcsr); + + /* Wait for number of auto-refresh cycles */ +@@ -182,13 +159,17 @@ void sdram_init(void) + ; + + /* Stage 3. Mode Register Set */ ++ dmcr0 = (11 << EMC_DMCR_RA_BIT) | ++ (8 << EMC_DMCR_CA_BIT) | ++ (0 << EMC_DMCR_BA_BIT) | ++ EMC_DMCR_EPIN | ++ (SDRAM_BW16 << EMC_DMCR_BW_BIT) | ++ cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; + writel(dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr); + writeb(0, JZ4740_EMC_SDMR0 | sdmode); + + /* Set back to basic DMCR value */ + writel(dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr); +- +- /* everything is ok now */ + } + + DECLARE_GLOBAL_DATA_PTR; +@@ -232,9 +213,10 @@ void rtc_init(void) + phys_size_t initdram(int board_type) + { + struct jz4740_emc *emc = (struct jz4740_emc *)JZ4740_EMC_BASE; +- u32 dmcr; +- u32 rows, cols, dw, banks; +- ulong size; ++ ++ unsigned int dmcr; ++ unsigned int rows, cols, dw, banks; ++ unsigned long size; + + dmcr = readl(&emc->dmcr); + rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT); +diff --git a/arch/mips/cpu/xburst/spl/Makefile b/arch/mips/cpu/xburst/spl/Makefile +new file mode 100644 +index 0000000..f45e8c8 +--- /dev/null ++++ b/arch/mips/cpu/xburst/spl/Makefile +@@ -0,0 +1,47 @@ ++# ++# Copyright (C) 2011 Xiangfu Liu <xiangfu@openmobilefree.net> ++# ++# See file CREDITS for list of people who contributed to this ++# project. ++# ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License as ++# published by the Free Software Foundation; either version 2 of ++# the License, or (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++# MA 02111-1307 USA ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(CPU).o ++ ++START = start.o ++SOBJS-y = ++COBJS-y = ++ ++SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) ++OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) ++START := $(addprefix $(obj),$(START)) ++ ++all: $(obj).depend $(START) $(LIB) ++ ++$(LIB): $(OBJS) ++ $(call cmd_link_o_target, $(OBJS)) ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend ++ ++######################################################################### +diff --git a/arch/mips/cpu/xburst/spl/start.S b/arch/mips/cpu/xburst/spl/start.S +new file mode 100644 +index 0000000..e31c4c8 +--- /dev/null ++++ b/arch/mips/cpu/xburst/spl/start.S +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (c) 2010 Xiangfu Liu <xiangfu@openmobilefree.net> ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 3 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#include <config.h> ++#include <version.h> ++#include <asm/regdef.h> ++#include <asm/mipsregs.h> ++#include <asm/addrspace.h> ++#include <asm/cacheops.h> ++ ++#include <asm/jz4740.h> ++ ++ .set noreorder ++ ++ .globl _start ++ .text ++_start: ++ .word JZ4740_NANDBOOT_CFG /* fetched during NAND Boot */ ++reset: ++ /* ++ * STATUS register ++ * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1 ++ */ ++ li t0, 0x0040FC04 ++ mtc0 t0, CP0_STATUS ++ /* ++ * CAUSE register ++ * IV=1, use the specical interrupt vector (0x200) ++ */ ++ li t1, 0x00800000 ++ mtc0 t1, CP0_CAUSE ++ ++ bal 1f ++ nop ++ .word _GLOBAL_OFFSET_TABLE_ ++1: ++ move gp, ra ++ lw t1, 0(ra) ++ move gp, t1 ++ ++ la sp, 0x80004000 ++ la t9, nand_spl_boot ++ j t9 ++ nop +diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile +index 5dae11b..e399246 100644 +--- a/board/qi/qi_lb60/Makefile ++++ b/board/qi/qi_lb60/Makefile +@@ -22,7 +22,11 @@ include $(TOPDIR)/config.mk + + LIB = $(obj)lib$(BOARD).o + ++ifeq ($(CONFIG_SPL_BUILD),y) ++COBJS := $(BOARD)-spl.o ++else + COBJS := $(BOARD).o ++endif + + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) + OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c +new file mode 100644 +index 0000000..3fe3fa3 +--- /dev/null ++++ b/board/qi/qi_lb60/qi_lb60-spl.c +@@ -0,0 +1,30 @@ ++/* ++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.cc> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 3 of the License, or (at your option) any later version. ++ */ ++ ++#include <common.h> ++#include <nand.h> ++#include <asm/io.h> ++#include <asm/jz4740.h> ++ ++void nand_spl_boot(void) ++{ ++ __gpio_as_sdram_16bit_4720(); ++ __gpio_as_uart0(); ++ __gpio_jtag_to_uart0(); ++ ++ serial_init(); ++ ++ pll_init(); ++ sdram_init(); ++ ++ nand_init(); ++ ++ puts("\nQi LB60 SPL: Starting U-Boot ...\n"); ++ nand_boot(); ++} +diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c +index d975209..3bd4e2f 100644 +--- a/board/qi/qi_lb60/qi_lb60.c ++++ b/board/qi/qi_lb60/qi_lb60.c +@@ -1,5 +1,5 @@ + /* +- * Authors: Xiangfu Liu <xiangfu@sharism.cc> ++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -97,8 +97,10 @@ int board_early_init_f(void) + /* U-Boot common routines */ + int checkboard(void) + { +- printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC, Speed %ld MHz)\n", +- gd->cpu_clk / 1000000); ++ printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC)\n"); ++ printf(" CPU: %ld\n", gd->cpu_clk); ++ printf(" MEM: %ld\n", gd->mem_clk); ++ printf(" DEV: %ld\n", gd->dev_clk); + + return 0; + } +diff --git a/board/qi/qi_lb60/u-boot-spl.lds b/board/qi/qi_lb60/u-boot-spl.lds +new file mode 100644 +index 0000000..930537f +--- /dev/null ++++ b/board/qi/qi_lb60/u-boot-spl.lds +@@ -0,0 +1,61 @@ ++/* ++ * (C) Copyright 2012 Xiangfu Liu <xiangfu@openmobilefree.net> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips") ++ ++OUTPUT_ARCH(mips) ++ENTRY(_start) ++SECTIONS ++{ ++ . = 0x80000000; ++ . = ALIGN(4); ++ .text : ++ { ++ *(.text) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } ++ ++ . = ALIGN(4); ++ .data : { *(.data) } ++ ++ . = ALIGN(4); ++ .sdata : { *(.sdata) } ++ ++ _gp = ALIGN(16); ++ ++ __got_start = .; ++ .got : { *(.got) } ++ __got_end = .; ++ ++ . = .; ++ __u_boot_cmd_start = .; ++ .u_boot_cmd : { *(.u_boot_cmd) } ++ __u_boot_cmd_end = .; ++ ++ uboot_end_data = .; ++ num_got_entries = (__got_end - __got_start) >> 2; ++ ++ . = ALIGN(4); ++ .sbss : { *(.sbss) } ++ .bss : { *(.bss) } ++ uboot_end = .; ++} ++ASSERT(uboot_end <= 0x80002000, "NAND bootstrap too big"); +diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c +index 3ec34f3..24a4921 100644 +--- a/drivers/mtd/nand/jz4740_nand.c ++++ b/drivers/mtd/nand/jz4740_nand.c +@@ -15,6 +15,9 @@ + #include <asm/io.h> + #include <asm/jz4740.h> + ++#ifdef CONFIG_SPL_BUILD ++#define printf(s) puts(s) ++#endif + #define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000) + #define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000) + #define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000) +@@ -176,7 +179,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat, + for (k = 0; k < 9; k++) + writeb(read_ecc[k], &emc->nfpar[k]); + } +- /* Set PRDY */ ++ + writel(readl(&emc->nfecr) | EMC_NFECR_PRDY, &emc->nfecr); + + /* Wait for completion */ +@@ -184,7 +187,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat, + status = readl(&emc->nfints); + } while (!(status & EMC_NFINTS_DECF)); + +- /* disable ecc */ ++ /* Disable ECC */ + writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr); + + /* Check decoding */ +@@ -192,7 +195,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat, + return 0; + + if (status & EMC_NFINTS_UNCOR) { +- printf("uncorrectable ecc\n"); ++ printf("JZ4740 uncorrectable ECC\n"); + return -1; + } + +@@ -230,6 +233,32 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat, + return errcnt; + } + ++#ifdef CONFIG_SPL_BUILD ++static void jz_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++#if (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R3) || \ ++ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R2) ++ for (i = 0; i < len; i += 2) ++ buf[i] = readw(this->IO_ADDR_R); ++#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R3) || \ ++ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R2) ++ for (i = 0; i < len; i++) ++ buf[i] = readb(this->IO_ADDR_R); ++#else ++ #error JZ4740_NANDBOOT_CFG not defined or wrong ++#endif ++} ++ ++static uint8_t jz_nand_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ return readb(this->IO_ADDR_R); ++} ++#endif ++ + /* + * Main initialization routine + */ +@@ -254,6 +283,10 @@ int board_nand_init(struct nand_chip *nand) + nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; + nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; + nand->ecc.layout = &qi_lb60_ecclayout_2gb; ++#ifdef CONFIG_SPL_BUILD ++ nand->read_byte = jz_nand_read_byte; ++ nand->read_buf = jz_nand_read_buf; ++#endif + nand->chip_delay = 50; + nand->options = NAND_USE_FLASH_BBT; + +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index 4bb5bbc..7bff444 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -1,5 +1,5 @@ + /* +- * Authors: Xiangfu Liu <xiangfu.z@gmail.com> ++ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -14,7 +14,6 @@ + #define CONFIG_SYS_LITTLE_ENDIAN + #define CONFIG_JZSOC /* Jz SoC */ + #define CONFIG_JZ4740 /* Jz4740 SoC */ +-#define CONFIG_NAND_JZ4740 + + #define CONFIG_SYS_CPU_SPEED 336000000 /* CPU clock: 336 MHz */ + #define CONFIG_SYS_EXTAL 12000000 /* EXTAL freq: 12 MHz */ +@@ -24,24 +23,43 @@ + #define CONFIG_SYS_UART_BASE JZ4740_UART0_BASE /* Base of the UART channel */ + #define CONFIG_BAUDRATE 57600 + ++#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL) ++#define CONFIG_BOOTDELAY 0 ++#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait" ++#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x280000;bootm" ++ ++/* ++ * Miscellaneous configurable options ++ */ ++#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ ++#define CONFIG_SYS_INIT_SP_OFFSET 0x400000 ++#define CONFIG_SYS_LOAD_ADDR 0x80600000 ++#define CONFIG_SYS_MEMTEST_START 0x80100000 ++#define CONFIG_SYS_MEMTEST_END 0x80A00000 ++#define CONFIG_SYS_TEXT_BASE 0x80100000 ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE ++ ++#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) ++#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024) ++ ++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) ++ ++#define CONFIG_SYS_LONGHELP ++#define CONFIG_SYS_MAXARGS 16 ++#define CONFIG_SYS_PROMPT "NanoNote# " ++ + #define CONFIG_SKIP_LOWLEVEL_INIT + #define CONFIG_BOARD_EARLY_INIT_F + #define CONFIG_SYS_NO_FLASH + #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */ +-#define CONFIG_ENV_OVERWRITE +- +-#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL) +-#define CONFIG_BOOTDELAY 0 +-#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait" +-#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x200000;bootm" + + /* +- * Command line configuration. ++ * Command line configuration + */ + #define CONFIG_CMD_BOOTD /* bootd */ + #define CONFIG_CMD_CONSOLE /* coninfo */ + #define CONFIG_CMD_ECHO /* echo arguments */ +- + #define CONFIG_CMD_LOADB /* loadb */ + #define CONFIG_CMD_LOADS /* loads */ + #define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop mtest */ +@@ -58,45 +76,16 @@ + #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ + + /* +- * Miscellaneous configurable options +- */ +-#define CONFIG_SYS_MAXARGS 16 +-#define CONFIG_SYS_LONGHELP +-#define CONFIG_SYS_PROMPT "NanoNote# " +-#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +- +-#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) +-#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024) +- +-#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ +-#define CONFIG_SYS_INIT_SP_OFFSET 0x400000 +-#define CONFIG_SYS_LOAD_ADDR 0x80600000 +-#define CONFIG_SYS_MEMTEST_START 0x80100000 +-#define CONFIG_SYS_MEMTEST_END 0x80800000 +- +-/* +- * Environment ++ * NAND driver configuration + */ +-#define CONFIG_ENV_IS_IN_NAND /* use NAND for environment vars */ +- +-#define CONFIG_SYS_NAND_5_ADDR_CYCLE +-/* +- * if board nand flash is 1GB, set to 1 +- * if board nand flash is 2GB, set to 2 +- * for change the PAGE_SIZE and BLOCK_SIZE +- * will delete when there is no 1GB flash +- */ +-#define NANONOTE_NAND_SIZE 2 +- +-#define CONFIG_SYS_NAND_PAGE_SIZE (2048 * NANONOTE_NAND_SIZE) +-#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * NANONOTE_NAND_SIZE << 10) +-/* nand bad block was marked at this page in a block, start from 0 */ ++#define CONFIG_NAND_JZ4740 ++#define CONFIG_SYS_NAND_PAGE_SIZE 4096 ++#define CONFIG_SYS_NAND_BLOCK_SIZE (512 << 10) ++/* NAND bad block was marked at this page in a block, start from 0 */ + #define CONFIG_SYS_NAND_BADBLOCK_PAGE 127 + #define CONFIG_SYS_NAND_PAGE_COUNT 128 + #define CONFIG_SYS_NAND_BAD_BLOCK_POS 0 +-/* ECC offset position in oob area, default value is 6 if it isn't defined */ +-#define CONFIG_SYS_NAND_ECC_POS (6 * NANONOTE_NAND_SIZE) ++#define CONFIG_SYS_NAND_ECC_POS 12 + #define CONFIG_SYS_NAND_ECCSIZE 512 + #define CONFIG_SYS_NAND_ECCBYTES 9 + #define CONFIG_SYS_NAND_ECCPOS \ +@@ -115,10 +104,9 @@ + #define CONFIG_SYS_ONENAND_BASE CONFIG_SYS_NAND_BASE + #define CONFIG_SYS_MAX_NAND_DEVICE 1 + #define CONFIG_SYS_NAND_SELECT_DEVICE 1 /* nand driver supports mutipl.*/ +-#define CONFIG_NAND_SPL_TEXT_BASE 0x80000000 + + /* +- * IPL (Initial Program Loader, integrated inside CPU) ++ * IPL (Initial Program Loader, integrated inside Ingenic Xburst JZ4740 CPU) + * Will load first 8k from NAND (SPL) into cache and execute it from there. + * + * SPL (Secondary Program Loader) +@@ -130,77 +118,88 @@ + * NUB (NAND U-Boot) + * This NAND U-Boot (NUB) is a special U-Boot version which can be started + * from RAM. Therefore it mustn't (re-)configure the SDRAM controller. +- * + */ ++ ++/* ++ * NAND SPL configuration ++ */ ++#define CONFIG_SPL ++#define CONFIG_SPL_LIBGENERIC_SUPPORT ++#define CONFIG_SPL_LIBCOMMON_SUPPORT ++#define CONFIG_SPL_NAND_LOAD ++#define CONFIG_SPL_NAND_SIMPLE ++#define CONFIG_SPL_NAND_SUPPORT ++#define CONFIG_SPL_TEXT_BASE 0x80000000 ++#define CONFIG_SPL_START_S_PATH "arch/mips/cpu/xburst/spl" ++ ++#define CONFIG_SYS_NAND_5_ADDR_CYCLE ++#define CONFIG_SYS_NAND_HW_ECC_OOBFIRST ++#define JZ4740_NANDBOOT_CFG JZ4740_NANDBOOT_B8R3 ++ + #define CONFIG_SYS_NAND_U_BOOT_DST 0x80100000 /* Load NUB to this addr */ + #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST +-/* Start NUB from this addr*/ ++ /* Start NUB from this addr */ ++#define CONFIG_SYS_NAND_U_BOOT_OFFS (32 << 10) /* Offset of NUB */ ++#define CONFIG_SYS_NAND_U_BOOT_SIZE (256 << 10) /* Size of NUB */ + + /* +- * Define the partitioning of the NAND chip (only RAM U-Boot is needed here) ++ * Environment configuration + */ +-#define CONFIG_SYS_NAND_U_BOOT_OFFS (256 << 10) /* Offset to RAM U-Boot image */ +-#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 << 10) /* Size of RAM U-Boot image */ +- ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_ENV_IS_IN_NAND + #define CONFIG_ENV_SIZE (4 << 10) + #define CONFIG_ENV_OFFSET \ + (CONFIG_SYS_NAND_BLOCK_SIZE + CONFIG_SYS_NAND_U_BOOT_SIZE) + #define CONFIG_ENV_OFFSET_REDUND \ + (CONFIG_ENV_OFFSET + CONFIG_SYS_NAND_BLOCK_SIZE) + +-#define CONFIG_SYS_TEXT_BASE 0x80100000 +-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE +- + /* +- * SDRAM Info. ++ * CPU cache configuration + */ +-#define CONFIG_NR_DRAM_BANKS 1 ++#define CONFIG_SYS_DCACHE_SIZE 16384 ++#define CONFIG_SYS_ICACHE_SIZE 16384 ++#define CONFIG_SYS_CACHELINE_SIZE 32 + + /* +- * Cache Configuration ++ * SDRAM configuration + */ +-#define CONFIG_SYS_DCACHE_SIZE 16384 +-#define CONFIG_SYS_ICACHE_SIZE 16384 +-#define CONFIG_SYS_CACHELINE_SIZE 32 ++#define CONFIG_NR_DRAM_BANKS 1 ++ ++#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */ ++#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */ ++#define SDRAM_ROW 13 /* Row address: 11 to 13 */ ++#define SDRAM_COL 9 /* Column address: 8 to 12 */ ++#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */ ++#define SDRAM_TRAS 45 /* RAS# Active Time */ ++#define SDRAM_RCD 20 /* RAS# to CAS# Delay */ ++#define SDRAM_TPC 20 /* RAS# Precharge Time */ ++#define SDRAM_TRWL 7 /* Write Latency Time */ ++#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */ + + /* +- * GPIO definition ++ * GPIO configuration + */ +-#define GPIO_LCD_CS (2 * 32 + 21) +-#define GPIO_AMP_EN (3 * 32 + 4) ++#define GPIO_LCD_CS (2 * 32 + 21) ++#define GPIO_AMP_EN (3 * 32 + 4) + +-#define GPIO_SDPW_EN (3 * 32 + 2) +-#define GPIO_SD_DETECT (3 * 32 + 0) ++#define GPIO_SDPW_EN (3 * 32 + 2) ++#define GPIO_SD_DETECT (3 * 32 + 0) + +-#define GPIO_BUZZ_PWM (3 * 32 + 27) +-#define GPIO_USB_DETECT (3 * 32 + 28) ++#define GPIO_BUZZ_PWM (3 * 32 + 27) ++#define GPIO_USB_DETECT (3 * 32 + 28) + +-#define GPIO_AUDIO_POP (1 * 32 + 29) +-#define GPIO_COB_TEST (1 * 32 + 30) ++#define GPIO_AUDIO_POP (1 * 32 + 29) ++#define GPIO_COB_TEST (1 * 32 + 30) + + #define GPIO_KEYOUT_BASE (2 * 32 + 10) +-#define GPIO_KEYIN_BASE (3 * 32 + 18) +-#define GPIO_KEYIN_8 (3 * 32 + 26) ++#define GPIO_KEYIN_BASE (3 * 32 + 18) ++#define GPIO_KEYIN_8 (3 * 32 + 26) + +-#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */ ++#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */ + #define GPIO_SD_VCC_EN_N GPIO_SDPW_EN /* SD Card Power Enable */ + + #define SPEN GPIO_LCD_CS /* LCDCS :Serial command enable */ + #define SPDA (2 * 32 + 22) /* LCDSCL:Serial command clock input */ + #define SPCK (2 * 32 + 23) /* LCDSDA:Serial command data input */ + +-/* SDRAM paramters */ +-#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */ +-#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */ +-#define SDRAM_ROW 13 /* Row address: 11 to 13 */ +-#define SDRAM_COL 9 /* Column address: 8 to 12 */ +-#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */ +- +-/* SDRAM Timings, unit: ns */ +-#define SDRAM_TRAS 45 /* RAS# Active Time */ +-#define SDRAM_RCD 20 /* RAS# to CAS# Delay */ +-#define SDRAM_TPC 20 /* RAS# Precharge Time */ +-#define SDRAM_TRWL 7 /* Write Latency Time */ +-#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */ +- + #endif +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch b/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch new file mode 100644 index 0000000..feaf297 --- /dev/null +++ b/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch @@ -0,0 +1,916 @@ +From fa51192b912d296b8eec10f7d44c6c17eb1dd368 Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Fri, 12 Oct 2012 09:47:39 +0800 +Subject: [PATCH 2/6] qi_lb60: add software usbboot support + + JZ4740 CPU have a internal ROM have such kind of code, that make + JZ4740 can boot from USB + + usbboot.S can downloads user program from the USB port to internal + SRAM and branches to the internal SRAM to execute the program + +Signed-off-by: Xiangfu <xiangfu@openmobilefree.net> +--- + board/qi/qi_lb60/Makefile | 1 + + board/qi/qi_lb60/qi_lb60-spl.c | 20 + + board/qi/qi_lb60/usbboot.S | 838 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 859 insertions(+) + create mode 100644 board/qi/qi_lb60/usbboot.S + +diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile +index e399246..6dd8c6f 100644 +--- a/board/qi/qi_lb60/Makefile ++++ b/board/qi/qi_lb60/Makefile +@@ -23,6 +23,7 @@ include $(TOPDIR)/config.mk + LIB = $(obj)lib$(BOARD).o + + ifeq ($(CONFIG_SPL_BUILD),y) ++SOBJS := usbboot.o + COBJS := $(BOARD)-spl.o + else + COBJS := $(BOARD).o +diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c +index 3fe3fa3..aea459c 100644 +--- a/board/qi/qi_lb60/qi_lb60-spl.c ++++ b/board/qi/qi_lb60/qi_lb60-spl.c +@@ -12,6 +12,24 @@ + #include <asm/io.h> + #include <asm/jz4740.h> + ++#define KEY_U_OUT (32 * 2 + 16) ++#define KEY_U_IN (32 * 3 + 19) ++ ++extern void usb_boot(void); ++ ++static void check_usb_boot(void) ++{ ++ __gpio_as_input(KEY_U_IN); ++ __gpio_enable_pull(KEY_U_IN); ++ __gpio_as_output(KEY_U_OUT); ++ __gpio_clear_pin(KEY_U_OUT); ++ ++ if (!__gpio_get_pin(KEY_U_IN)) { ++ puts("[U] pressed, goto USBBOOT mode\n"); ++ usb_boot(); ++ } ++} ++ + void nand_spl_boot(void) + { + __gpio_as_sdram_16bit_4720(); +@@ -23,6 +41,8 @@ void nand_spl_boot(void) + pll_init(); + sdram_init(); + ++ check_usb_boot(); ++ + nand_init(); + + puts("\nQi LB60 SPL: Starting U-Boot ...\n"); +diff --git a/board/qi/qi_lb60/usbboot.S b/board/qi/qi_lb60/usbboot.S +new file mode 100644 +index 0000000..c872266 +--- /dev/null ++++ b/board/qi/qi_lb60/usbboot.S +@@ -0,0 +1,838 @@ ++/* ++ * for jz4740 usb boot ++ * ++ * Copyright (c) 2009 Author: <jlwei@ingenic.cn> ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ .set noreorder ++ .globl usb_boot ++ .text ++ ++/* ++ * Both NAND and USB boot load data to D-Cache first, then transfer ++ * data from D-Cache to I-Cache, and jump to execute the code in I-Cache. ++ * So init caches first and then dispatch to a proper boot routine. ++ */ ++ ++.macro load_addr reg addr ++ li \reg, 0x80000000 ++ addiu \reg, \reg, \addr ++ la $2, usbboot_begin ++ subu \reg, \reg, $2 ++.endm ++ ++usb_boot: ++ /* Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. */ ++ la $9, 0xB0000000 /* CPCCR: Clock Control Register */ ++ la $8, 0x42041110 /* I:S:M:P=1:2:2:2 */ ++ sw $8, 0($9) ++ ++ la $9, 0xB0000010 /* CPPCR: PLL Control Register */ ++ la $8, 0x06000120 /* M=12 N=0 D=0 CLK=12*(M+2)/(N+2) */ ++ sw $8, 0($9) ++ ++ mtc0 $0, $26 /* CP0_ERRCTL, restore WST reset state */ ++ nop ++ ++ mtc0 $0, $16 /* CP0_CONFIG */ ++ nop ++ ++ /* Relocate code to beginning of the ram */ ++ ++ la $2, usbboot_begin ++ la $3, usbboot_end ++ li $4, 0x80000000 ++ ++1: ++ lw $5, 0($2) ++ sw $5, 0($4) ++ addiu $2, $2, 4 ++ bne $2, $3, 1b ++ addiu $4, $4, 4 ++ ++ li $2, 0x80000000 ++ ori $3, $2, 0 ++ addiu $3, $3, usbboot_end ++ la $4, usbboot_begin ++ subu $3, $3, $4 ++ ++ ++2: ++ cache 0x0, 0($2) /* Index_Invalidate_I */ ++ cache 0x1, 0($2) /* Index_Writeback_Inv_D */ ++ addiu $2, $2, 32 ++ subu $4, $3, $2 ++ bgtz $4, 2b ++ nop ++ ++ load_addr $3, usb_boot_return ++ ++ jr $3 ++ ++usbboot_begin: ++ ++init_caches: ++ li $2, 3 /* cacheable for kseg0 access */ ++ mtc0 $2, $16 /* CP0_CONFIG */ ++ nop ++ ++ li $2, 0x20000000 /* enable idx-store-data cache insn */ ++ mtc0 $2, $26 /* CP0_ERRCTL */ ++ ++ ori $2, $28, 0 /* start address */ ++ ori $3, $2, 0x3fe0 /* end address, total 16KB */ ++ mtc0 $0, $28, 0 /* CP0_TAGLO */ ++ mtc0 $0, $28, 1 /* CP0_DATALO */ ++cache_clear_a_line: ++ cache 0x8, 0($2) /* Index_Store_Tag_I */ ++ cache 0x9, 0($2) /* Index_Store_Tag_D */ ++ bne $2, $3, cache_clear_a_line ++ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */ ++ ++ ori $2, $28, 0 /* start address */ ++ ori $3, $2, 0x3fe0 /* end address, total 16KB */ ++ la $4, 0x1ffff000 /* physical address and 4KB page mask */ ++cache_alloc_a_line: ++ and $5, $2, $4 ++ ori $5, $5, 1 /* V bit of the physical tag */ ++ mtc0 $5, $28, 0 /* CP0_TAGLO */ ++ cache 0x8, 0($2) /* Index_Store_Tag_I */ ++ cache 0x9, 0($2) /* Index_Store_Tag_D */ ++ bne $2, $3, cache_alloc_a_line ++ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */ ++ ++ nop ++ nop ++ nop ++ /* ++ * Transfer data from dcache to icache, then jump to icache. ++ * Input parameters: ++ * $19: data length in bytes ++ * $20: jump target address ++ */ ++xfer_d2i: ++ ++ ori $8, $20, 0 ++ addu $9, $8, $19 /* total 16KB */ ++ ++1: ++ cache 0x0, 0($8) /* Index_Invalidate_I */ ++ cache 0x1, 0($8) /* Index_Writeback_Inv_D */ ++ bne $8, $9, 1b ++ addiu $8, $8, 32 ++ ++ /* flush write-buffer */ ++ sync ++ ++ /* Invalidate BTB */ ++ mfc0 $8, $16, 7 /* CP0_CONFIG */ ++ nop ++ ori $8, 2 ++ mtc0 $8, $16, 7 ++ nop ++ ++ /* Overwrite config to disable ram initalisation */ ++ li $2, 0xff ++ sb $2, 20($20) ++ ++ jalr $20 ++ nop ++ ++icache_return: ++ /* User code can return to here after executing itself in ++ icache, by jumping to $31. */ ++ b usb_boot_return ++ nop ++ ++ ++usb_boot_return: ++ /* Enable the USB PHY */ ++ la $9, 0xB0000024 /* CPM_SCR */ ++ lw $8, 0($9) ++ ori $8, 0x40 /* USBPHY_ENABLE */ ++ sw $8, 0($9) ++ ++ /* Initialize USB registers */ ++ la $27, 0xb3040000 /* USB registers base address */ ++ ++ sb $0, 0x0b($27) /* INTRUSBE: disable common USB interrupts */ ++ sh $0, 0x06($27) /* INTRINE: disable EPIN interrutps */ ++ sh $0, 0x08($27) /* INTROUTE: disable EPOUT interrutps */ ++ ++ li $9, 0x61 ++ sb $9, 0x01($27) /* POWER: HSENAB | SUSPENDM | SOFTCONN */ ++ ++ /* Initialize USB states */ ++ li $22, 0 /* set EP0 to IDLE state */ ++ li $23, 1 /* no data stage */ ++ ++ /* Main loop of polling the usb commands */ ++usb_command_loop: ++ lbu $9, 0x0a($27) /* read INTRUSB */ ++ andi $9, 0x04 /* check USB_INTR_RESET */ ++ beqz $9, check_intr_ep0in ++ nop ++ ++ /* 1. Handle USB reset interrupt */ ++handle_reset_intr: ++ lbu $9, 0x01($27) /* read POWER */ ++ andi $9, 0x10 /* test HS_MODE */ ++ bnez $9, _usb_set_maxpktsize ++ li $9, 512 /* max packet size of HS mode */ ++ li $9, 64 /* max packet size of FS mode */ ++ ++_usb_set_maxpktsize: ++ li $8, 1 ++ sb $8, 0x0e($27) /* set INDEX 1 */ ++ ++ sh $9, 0x10($27) /* INMAXP */ ++ sb $0, 0x13($27) /* INCSRH */ ++ sh $9, 0x14($27) /* OUTMAXP */ ++ sb $0, 0x17($27) /* OUTCSRH */ ++ ++_usb_flush_fifo: ++ li $8, 0x48 /* INCSR_CDT && INCSR_FF */ ++ sb $8, 0x12($27) /* INCSR */ ++ li $8, 0x90 /* OUTCSR_CDT && OUTCSR_FF */ ++ sb $8, 0x16($27) /* OUTCSR */ ++ ++ li $22, 0 /* set EP0 to IDLE state */ ++ li $23, 1 /* no data stage */ ++ ++ /* 2. Check and handle EP0 interrupt */ ++check_intr_ep0in: ++ lhu $10, 0x02($27) /* read INTRIN */ ++ andi $9, $10, 0x1 /* check EP0 interrupt */ ++ beqz $9, check_intr_ep1in ++ nop ++ ++handle_ep0_intr: ++ sb $0, 0x0e($27) /* set INDEX 0 */ ++ lbu $11, 0x12($27) /* read CSR0 */ ++ ++ andi $9, $11, 0x04 /* check SENTSTALL */ ++ beqz $9, _ep0_setupend ++ nop ++ ++_ep0_sentstall: ++ andi $9, $11, 0xdb ++ sb $9, 0x12($27) /* clear SENDSTALL and SENTSTALL */ ++ li $22, 0 /* set EP0 to IDLE state */ ++ ++_ep0_setupend: ++ andi $9, $11, 0x10 /* check SETUPEND */ ++ beqz $9, ep0_idle_state ++ nop ++ ++ ori $9, $11, 0x80 ++ sb $9, 0x12($27) /* set SVDSETUPEND */ ++ li $22, 0 /* set EP0 to IDLE state */ ++ ++ep0_idle_state: ++ bnez $22, ep0_tx_state ++ nop ++ ++ /* 2.1 Handle EP0 IDLE state interrupt */ ++ andi $9, $11, 0x01 /* check OUTPKTRDY */ ++ beqz $9, check_intr_ep1in ++ nop ++ ++ /* Read 8-bytes setup packet from the FIFO */ ++ lw $25, 0x20($27) /* first word of setup packet */ ++ lw $26, 0x20($27) /* second word of setup packet */ ++ ++ andi $9, $25, 0x60 /* bRequestType & USB_TYPE_MASK */ ++ beqz $9, _ep0_std_req ++ nop ++ ++ /* 2.1.1 Vendor-specific setup request */ ++_ep0_vend_req: ++ li $22, 0 /* set EP0 to IDLE state */ ++ li $23, 1 /* NoData = 1 */ ++ ++ andi $9, $25, 0xff00 /* check bRequest */ ++ srl $9, $9, 8 ++ beqz $9, __ep0_get_cpu_info ++ sub $8, $9, 0x1 ++ beqz $8, __ep0_set_data_address ++ sub $8, $9, 0x2 ++ beqz $8, __ep0_set_data_length ++ sub $8, $9, 0x3 ++ beqz $8, __ep0_flush_caches ++ sub $8, $9, 0x4 ++ beqz $8, __ep0_prog_start1 ++ sub $8, $9, 0x5 ++ beqz $8, __ep0_prog_start2 ++ nop ++ b _ep0_idle_state_fini /* invalid request */ ++ nop ++ ++__ep0_get_cpu_info: ++ load_addr $20, cpu_info_data /* data pointer to transfer */ ++ li $21, 8 /* bytes left to transfer */ ++ li $22, 1 /* set EP0 to TX state */ ++ li $23, 0 /* NoData = 0 */ ++ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_set_data_address: ++ li $9, 0xffff0000 ++ and $9, $25, $9 ++ andi $8, $26, 0xffff ++ or $20, $9, $8 /* data address of next transfer */ ++ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_set_data_length: ++ li $9, 0xffff0000 ++ and $9, $25, $9 ++ andi $8, $26, 0xffff ++ or $21, $9, $8 /* data length of next transfer */ ++ ++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */ ++ sb $9, 0x12($27) /* CSR0 */ ++ ++ /* We must write packet to FIFO before EP1-IN interrupt here. */ ++ b handle_epin1_intr ++ nop ++ ++__ep0_flush_caches: ++ /* Flush dcache and invalidate icache. */ ++ li $8, 0x80000000 ++ addi $9, $8, 0x3fe0 /* total 16KB */ ++ ++1: ++ cache 0x0, 0($8) /* Index_Invalidate_I */ ++ cache 0x1, 0($8) /* Index_Writeback_Inv_D */ ++ bne $8, $9, 1b ++ addiu $8, $8, 32 ++ ++ /* flush write-buffer */ ++ sync ++ ++ /* Invalidate BTB */ ++ mfc0 $8, $16, 7 /* CP0_CONFIG */ ++ nop ++ ori $8, 2 ++ mtc0 $8, $16, 7 ++ nop ++ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_prog_start1: ++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */ ++ sb $9, 0x12($27) /* CSR0 */ ++ ++ li $9, 0xffff0000 ++ and $9, $25, $9 ++ andi $8, $26, 0xffff ++ or $20, $9, $8 /* target address */ ++ ++ b xfer_d2i ++ li $19, 0x2000 /* 16KB data length */ ++ ++__ep0_prog_start2: ++ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */ ++ sb $9, 0x12($27) /* CSR0 */ ++ ++ li $9, 0xffff0000 ++ and $9, $25, $9 ++ andi $8, $26, 0xffff ++ or $20, $9, $8 /* target address */ ++ ++ jalr $20 /* jump, and place the return address in $31 */ ++ nop ++ ++__ep0_prog_start2_return: ++/* User code can return to here after executing itself, by jumping to $31 */ ++ b usb_boot_return ++ nop ++ ++ /* 2.1.2 Standard setup request */ ++_ep0_std_req: ++ andi $12, $25, 0xff00 /* check bRequest */ ++ srl $12, $12, 8 ++ sub $9, $12, 0x05 /* check USB_REQ_SET_ADDRESS */ ++ bnez $9, __ep0_req_set_config ++ nop ++ ++ /* Handle USB_REQ_SET_ADDRESS */ ++__ep0_req_set_addr: ++ srl $9, $25, 16 /* get wValue */ ++ sb $9, 0x0($27) /* set FADDR */ ++ li $23, 1 /* NoData = 1 */ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_req_set_config: ++ sub $9, $12, 0x09 /* check USB_REQ_SET_CONFIGURATION */ ++ bnez $9, __ep0_req_get_desc ++ nop ++ ++ /* Handle USB_REQ_SET_CONFIGURATION */ ++ li $23, 1 /* NoData = 1 */ ++ b _ep0_idle_state_fini ++ nop ++ ++__ep0_req_get_desc: ++ sub $9, $12, 0x06 /* check USB_REQ_GET_DESCRIPTOR */ ++ bnez $9, _ep0_idle_state_fini ++ li $23, 1 /* NoData = 1 */ ++ ++ /* Handle USB_REQ_GET_DESCRIPTOR */ ++ li $23, 0 /* NoData = 0 */ ++ ++ srl $9, $25, 24 /* wValue >> 8 */ ++ sub $8, $9, 0x01 /* check USB_DT_DEVICE */ ++ beqz $8, ___ep0_get_dev_desc ++ srl $21, $26, 16 /* get wLength */ ++ sub $8, $9, 0x02 /* check USB_DT_CONFIG */ ++ beqz $8, ___ep0_get_conf_desc ++ sub $8, $9, 0x03 /* check USB_DT_STRING */ ++ beqz $8, ___ep0_get_string_desc ++ sub $8, $9, 0x06 /* check USB_DT_DEVICE_QUALIFIER */ ++ beqz $8, ___ep0_get_dev_qualifier ++ nop ++ b _ep0_idle_state_fini ++ nop ++ ++___ep0_get_dev_desc: ++ load_addr $20, device_desc /* data pointer */ ++ li $22, 1 /* set EP0 to TX state */ ++ sub $8, $21, 18 ++ blez $8, _ep0_idle_state_fini /* wLength <= 18 */ ++ nop ++ li $21, 18 /* max length of device_desc */ ++ b _ep0_idle_state_fini ++ nop ++ ++___ep0_get_dev_qualifier: ++ load_addr $20, dev_qualifier /* data pointer */ ++ li $22, 1 /* set EP0 to TX state */ ++ sub $8, $21, 10 ++ blez $8, _ep0_idle_state_fini /* wLength <= 10 */ ++ nop ++ li $21, 10 /* max length of dev_qualifier */ ++ b _ep0_idle_state_fini ++ nop ++ ++___ep0_get_conf_desc: ++ load_addr $20, config_desc_fs /* data pointer of FS mode */ ++ lbu $8, 0x01($27) /* read POWER */ ++ andi $8, 0x10 /* test HS_MODE */ ++ beqz $8, ___ep0_get_conf_desc2 ++ nop ++ load_addr $20, config_desc_hs /* data pointer of HS mode */ ++ ++___ep0_get_conf_desc2: ++ li $22, 1 /* set EP0 to TX state */ ++ sub $8, $21, 32 ++ blez $8, _ep0_idle_state_fini /* wLength <= 32 */ ++ nop ++ li $21, 32 /* max length of config_desc */ ++ b _ep0_idle_state_fini ++ nop ++ ++___ep0_get_string_desc: ++ li $22, 1 /* set EP0 to TX state */ ++ ++ srl $9, $25, 16 /* wValue & 0xff */ ++ andi $9, 0xff ++ ++ sub $8, $9, 1 ++ beqz $8, ___ep0_get_string_manufacture ++ sub $8, $9, 2 ++ beqz $8, ___ep0_get_string_product ++ nop ++ ++___ep0_get_string_lang_ids: ++ load_addr $20, string_lang_ids /* data pointer */ ++ b _ep0_idle_state_fini ++ li $21, 4 /* data length */ ++ ++___ep0_get_string_manufacture: ++ load_addr $20, string_manufacture /* data pointer */ ++ b _ep0_idle_state_fini ++ li $21, 16 /* data length */ ++ ++___ep0_get_string_product: ++ load_addr $20, string_product /* data pointer */ ++ b _ep0_idle_state_fini ++ li $21, 46 /* data length */ ++ ++_ep0_idle_state_fini: ++ li $9, 0x40 /* SVDOUTPKTRDY */ ++ beqz $23, _ep0_idle_state_fini2 ++ nop ++ ori $9, $9, 0x08 /* DATAEND */ ++_ep0_idle_state_fini2: ++ sb $9, 0x12($27) /* CSR0 */ ++ beqz $22, check_intr_ep1in ++ nop ++ ++ /* 2.2 Handle EP0 TX state interrupt */ ++ep0_tx_state: ++ sub $9, $22, 1 ++ bnez $9, check_intr_ep1in ++ nop ++ ++ sub $9, $21, 64 /* max packetsize */ ++ blez $9, _ep0_tx_state2 /* data count <= 64 */ ++ ori $19, $21, 0 ++ li $19, 64 ++ ++_ep0_tx_state2: ++ beqz $19, _ep0_tx_state3 /* send ZLP */ ++ ori $18, $19, 0 /* record bytes to be transferred */ ++ sub $21, $21, $19 /* decrement data count */ ++ ++_ep0_fifo_write_loop: ++ lbu $9, 0($20) /* read data */ ++ sb $9, 0x20($27) /* load FIFO */ ++ sub $19, $19, 1 /* decrement counter */ ++ bnez $19, _ep0_fifo_write_loop ++ addi $20, $20, 1 /* increment data pointer */ ++ ++ sub $9, $18, 64 /* max packetsize */ ++ beqz $9, _ep0_tx_state4 ++ nop ++ ++_ep0_tx_state3: ++ /* transferred bytes < max packetsize */ ++ li $9, 0x0a /* set INPKTRDY and DATAEND */ ++ sb $9, 0x12($27) /* CSR0 */ ++ li $22, 0 /* set EP0 to IDLE state */ ++ b check_intr_ep1in ++ nop ++ ++_ep0_tx_state4: ++ /* transferred bytes == max packetsize */ ++ li $9, 0x02 /* set INPKTRDY */ ++ sb $9, 0x12($27) /* CSR0 */ ++ b check_intr_ep1in ++ nop ++ ++ /* 3. Check and handle EP1 BULK-IN interrupt */ ++check_intr_ep1in: ++ andi $9, $10, 0x2 /* check EP1 IN interrupt */ ++ beqz $9, check_intr_ep1out ++ nop ++ ++handle_epin1_intr: ++ li $9, 1 ++ sb $9, 0x0e($27) /* set INDEX 1 */ ++ lbu $9, 0x12($27) /* read INCSR */ ++ ++ andi $8, $9, 0x2 /* check INCSR_FFNOTEMPT */ ++ bnez $8, _epin1_tx_state4 ++ nop ++ ++_epin1_write_fifo: ++ lhu $9, 0x10($27) /* get INMAXP */ ++ sub $8, $21, $9 ++ blez $8, _epin1_tx_state1 /* bytes left <= INMAXP */ ++ ori $19, $21, 0 ++ ori $19, $9, 0 ++ ++_epin1_tx_state1: ++ beqz $19, _epin1_tx_state4 /* No data */ ++ nop ++ ++ sub $21, $21, $19 /* decrement data count */ ++ ++ srl $5, $19, 2 /* # of word */ ++ andi $6, $19, 0x3 /* # of byte */ ++ beqz $5, _epin1_tx_state2 ++ nop ++ ++_epin1_fifo_write_word: ++ lw $9, 0($20) /* read data from source address */ ++ sw $9, 0x24($27) /* write FIFO */ ++ sub $5, $5, 1 /* decrement counter */ ++ bnez $5, _epin1_fifo_write_word ++ addiu $20, $20, 4 /* increment dest address */ ++ ++_epin1_tx_state2: ++ beqz $6, _epin1_tx_state3 ++ nop ++ ++_epin1_fifo_write_byte: ++ lbu $9, 0($20) /* read data from source address */ ++ sb $9, 0x24($27) /* write FIFO */ ++ sub $6, $6, 1 /* decrement counter */ ++ bnez $6, _epin1_fifo_write_byte ++ addiu $20, $20, 1 /* increment dest address */ ++ ++_epin1_tx_state3: ++ li $9, 0x1 ++ sb $9, 0x12($27) /* INCSR, set INPKTRDY */ ++ ++_epin1_tx_state4: ++ /* 4. Check and handle EP1 BULK-OUT interrupt */ ++check_intr_ep1out: ++ lhu $9, 0x04($27) /* read INTROUT */ ++ andi $9, 0x2 ++ beqz $9, check_status_next ++ nop ++ ++handle_epout1_intr: ++ li $9, 1 ++ sb $9, 0x0e($27) /* set INDEX 1 */ ++ ++ lbu $9, 0x16($27) /* read OUTCSR */ ++ andi $9, 0x1 /* check OUTPKTRDY */ ++ beqz $9, check_status_next ++ nop ++ ++_epout1_read_fifo: ++ lhu $19, 0x18($27) /* read OUTCOUNT */ ++ srl $5, $19, 2 /* # of word */ ++ andi $6, $19, 0x3 /* # of byte */ ++ beqz $5, _epout1_rx_state1 ++ nop ++ ++_epout1_fifo_read_word: ++ lw $9, 0x24($27) /* read FIFO */ ++ sw $9, 0($20) /* store to dest address */ ++ sub $5, $5, 1 /* decrement counter */ ++ bnez $5, _epout1_fifo_read_word ++ addiu $20, $20, 4 /* increment dest address */ ++ ++_epout1_rx_state1: ++ beqz $6, _epout1_rx_state2 ++ nop ++ ++_epout1_fifo_read_byte: ++ lbu $9, 0x24($27) /* read FIFO */ ++ sb $9, 0($20) /* store to dest address */ ++ sub $6, $6, 1 /* decrement counter */ ++ bnez $6, _epout1_fifo_read_byte ++ addiu $20, $20, 1 /* increment dest address */ ++ ++_epout1_rx_state2: ++ sb $0, 0x16($27) /* clear OUTPKTRDY */ ++ ++check_status_next: ++ b usb_command_loop ++ nop ++ ++/* Device/Configuration/Interface/Endpoint/String Descriptors */ ++ ++ .align 2 ++device_desc: ++ .byte 0x12 /* bLength */ ++ .byte 0x01 /* bDescriptorType */ ++ .byte 0x00 /* bcdUSB */ ++ .byte 0x02 /* bcdUSB */ ++ .byte 0x00 /* bDeviceClass */ ++ .byte 0x00 /* bDeviceSubClass */ ++ .byte 0x00 /* bDeviceProtocol */ ++ .byte 0x40 /* bMaxPacketSize0 */ ++ .byte 0x1a /* idVendor */ ++ .byte 0x60 /* idVendor */ ++ .byte 0x40 /* idProduct */ ++ .byte 0x47 /* idProduct */ ++ .byte 0x00 /* bcdDevice */ ++ .byte 0x01 /* bcdDevice */ ++ .byte 0x01 /* iManufacturer */ ++ .byte 0x02 /* iProduct */ ++ .byte 0x00 /* iSerialNumber */ ++ .byte 0x01 /* bNumConfigurations */ ++ ++ .align 2 ++dev_qualifier: ++ .byte 0x0a /* bLength */ ++ .byte 0x06 /* bDescriptorType */ ++ .byte 0x00 /* bcdUSB */ ++ .byte 0x02 /* bcdUSB */ ++ .byte 0x00 /* bDeviceClass */ ++ .byte 0x00 /* bDeviceSubClass */ ++ .byte 0x00 /* bDeviceProtocol */ ++ .byte 0x40 /* bMaxPacketSize0 */ ++ .byte 0x01 /* bNumConfigurations */ ++ .byte 0x00 /* bRESERVED */ ++ ++ .align 2 ++config_desc_hs: ++ .byte 0x09 /* bLength */ ++ .byte 0x02 /* bDescriptorType */ ++ .byte 0x20 /* wTotalLength */ ++ .byte 0x00 /* wTotalLength */ ++ .byte 0x01 /* bNumInterfaces */ ++ .byte 0x01 /* bConfigurationValue */ ++ .byte 0x00 /* iConfiguration */ ++ .byte 0xc0 /* bmAttributes */ ++ .byte 0x01 /* MaxPower */ ++intf_desc_hs: ++ .byte 0x09 /* bLength */ ++ .byte 0x04 /* bDescriptorType */ ++ .byte 0x00 /* bInterfaceNumber */ ++ .byte 0x00 /* bAlternateSetting */ ++ .byte 0x02 /* bNumEndpoints */ ++ .byte 0xff /* bInterfaceClass */ ++ .byte 0x00 /* bInterfaceSubClass */ ++ .byte 0x50 /* bInterfaceProtocol */ ++ .byte 0x00 /* iInterface */ ++ep1_desc_hs: ++ .byte 0x07 /* bLength */ ++ .byte 0x05 /* bDescriptorType */ ++ .byte 0x01 /* bEndpointAddress */ ++ .byte 0x02 /* bmAttributes */ ++ .byte 0x00 /* wMaxPacketSize */ ++ .byte 0x02 /* wMaxPacketSize */ ++ .byte 0x00 /* bInterval */ ++ep2_desc_hs: ++ .byte 0x07 /* bLength */ ++ .byte 0x05 /* bDescriptorType */ ++ .byte 0x81 /* bEndpointAddress */ ++ .byte 0x02 /* bmAttributes */ ++ .byte 0x00 /* wMaxPacketSize */ ++ .byte 0x02 /* wMaxPacketSize */ ++ .byte 0x00 /* bInterval */ ++ ++ .align 2 ++config_desc_fs: ++ .byte 0x09 /* bLength */ ++ .byte 0x02 /* bDescriptorType */ ++ .byte 0x20 /* wTotalLength */ ++ .byte 0x00 /* wTotalLength */ ++ .byte 0x01 /* bNumInterfaces */ ++ .byte 0x01 /* bConfigurationValue */ ++ .byte 0x00 /* iConfiguration */ ++ .byte 0xc0 /* bmAttributes */ ++ .byte 0x01 /* MaxPower */ ++intf_desc_fs: ++ .byte 0x09 /* bLength */ ++ .byte 0x04 /* bDescriptorType */ ++ .byte 0x00 /* bInterfaceNumber */ ++ .byte 0x00 /* bAlternateSetting */ ++ .byte 0x02 /* bNumEndpoints */ ++ .byte 0xff /* bInterfaceClass */ ++ .byte 0x00 /* bInterfaceSubClass */ ++ .byte 0x50 /* bInterfaceProtocol */ ++ .byte 0x00 /* iInterface */ ++ep1_desc_fs: ++ .byte 0x07 /* bLength */ ++ .byte 0x05 /* bDescriptorType */ ++ .byte 0x01 /* bEndpointAddress */ ++ .byte 0x02 /* bmAttributes */ ++ .byte 0x40 /* wMaxPacketSize */ ++ .byte 0x00 /* wMaxPacketSize */ ++ .byte 0x00 /* bInterval */ ++ep2_desc_fs: ++ .byte 0x07 /* bLength */ ++ .byte 0x05 /* bDescriptorType */ ++ .byte 0x81 /* bEndpointAddress */ ++ .byte 0x02 /* bmAttributes */ ++ .byte 0x40 /* wMaxPacketSize */ ++ .byte 0x00 /* wMaxPacketSize */ ++ .byte 0x00 /* bInterval */ ++ ++ .align 2 ++string_lang_ids: ++ .byte 0x04 ++ .byte 0x03 ++ .byte 0x09 ++ .byte 0x04 ++ ++ .align 2 ++string_manufacture: ++ .byte 0x10 ++ .byte 0x03 ++ .byte 0x49 ++ .byte 0x00 ++ .byte 0x6e ++ .byte 0x00 ++ .byte 0x67 ++ .byte 0x00 ++ .byte 0x65 ++ .byte 0x00 ++ .byte 0x6e ++ .byte 0x00 ++ .byte 0x69 ++ .byte 0x00 ++ .byte 0x63 ++ .byte 0x00 ++ ++ .align 2 ++string_product: ++ .byte 0x2e ++ .byte 0x03 ++ .byte 0x4a ++ .byte 0x00 ++ .byte 0x5a ++ .byte 0x00 ++ .byte 0x34 ++ .byte 0x00 ++ .byte 0x37 ++ .byte 0x00 ++ .byte 0x34 ++ .byte 0x00 ++ .byte 0x30 ++ .byte 0x00 ++ .byte 0x20 ++ .byte 0x00 ++ .byte 0x55 ++ .byte 0x00 ++ .byte 0x53 ++ .byte 0x00 ++ .byte 0x42 ++ .byte 0x00 ++ .byte 0x20 ++ .byte 0x00 ++ .byte 0x42 ++ .byte 0x00 ++ .byte 0x6f ++ .byte 0x00 ++ .byte 0x6f ++ .byte 0x00 ++ .byte 0x74 ++ .byte 0x00 ++ .byte 0x20 ++ .byte 0x00 ++ .byte 0x44 ++ .byte 0x00 ++ .byte 0x65 ++ .byte 0x00 ++ .byte 0x76 ++ .byte 0x00 ++ .byte 0x69 ++ .byte 0x00 ++ .byte 0x63 ++ .byte 0x00 ++ .byte 0x65 ++ .byte 0x00 ++ ++ .align 2 ++cpu_info_data: ++ .byte 0x4a ++ .byte 0x5a ++ .byte 0x34 ++ .byte 0x37 ++ .byte 0x34 ++ .byte 0x30 ++ .byte 0x56 ++ .byte 0x31 ++usbboot_end: ++ ++ .set reorder +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/0003-add-mmc-support.patch b/package/boot/uboot-xburst/patches/0003-add-mmc-support.patch new file mode 100644 index 0000000..e9baa7c --- /dev/null +++ b/package/boot/uboot-xburst/patches/0003-add-mmc-support.patch @@ -0,0 +1,1664 @@ +From bd36739e77669e8df45c38f6acfe2cea511534d9 Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Wed, 10 Oct 2012 18:19:41 +0800 +Subject: [PATCH 3/6] add mmc support + +--- + arch/mips/include/asm/jz4740.h | 166 ++++++ + board/qi/qi_lb60/qi_lb60.c | 9 +- + drivers/mmc/Makefile | 1 + + drivers/mmc/jz_mmc.c | 1179 ++++++++++++++++++++++++++++++++++++++++ + drivers/mmc/jz_mmc.h | 176 ++++++ + include/configs/qi_lb60.h | 9 + + include/mmc.h | 40 ++ + 7 files changed, 1578 insertions(+), 2 deletions(-) + create mode 100644 drivers/mmc/jz_mmc.c + create mode 100644 drivers/mmc/jz_mmc.h + +diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h +index 7a7cfff..68287fb 100644 +--- a/arch/mips/include/asm/jz4740.h ++++ b/arch/mips/include/asm/jz4740.h +@@ -1146,5 +1146,171 @@ extern void sdram_init(void); + extern void calc_clocks(void); + extern void rtc_init(void); + ++/************************************************************************* ++ * MSC ++ *************************************************************************/ ++#define REG8(addr) *((volatile u8 *)(addr)) ++#define REG16(addr) *((volatile u16 *)(addr)) ++#define REG32(addr) *((volatile u32 *)(addr)) ++ ++#define CPM_BASE 0xB0000000 ++#define CPM_CPCCR (CPM_BASE+0x00) ++#define CPM_MSCCDR (CPM_BASE+0x68) ++#define REG_CPM_MSCCDR REG32(CPM_MSCCDR) ++#define REG_CPM_CPCCR REG32(CPM_CPCCR) ++ ++#define MSC_BASE 0xB0021000 ++ ++#define MSC_STRPCL (MSC_BASE + 0x000) ++#define MSC_STAT (MSC_BASE + 0x004) ++#define MSC_CLKRT (MSC_BASE + 0x008) ++#define MSC_CMDAT (MSC_BASE + 0x00C) ++#define MSC_RESTO (MSC_BASE + 0x010) ++#define MSC_RDTO (MSC_BASE + 0x014) ++#define MSC_BLKLEN (MSC_BASE + 0x018) ++#define MSC_NOB (MSC_BASE + 0x01C) ++#define MSC_SNOB (MSC_BASE + 0x020) ++#define MSC_IMASK (MSC_BASE + 0x024) ++#define MSC_IREG (MSC_BASE + 0x028) ++#define MSC_CMD (MSC_BASE + 0x02C) ++#define MSC_ARG (MSC_BASE + 0x030) ++#define MSC_RES (MSC_BASE + 0x034) ++#define MSC_RXFIFO (MSC_BASE + 0x038) ++#define MSC_TXFIFO (MSC_BASE + 0x03C) ++ ++#define REG_MSC_STRPCL REG16(MSC_STRPCL) ++#define REG_MSC_STAT REG32(MSC_STAT) ++#define REG_MSC_CLKRT REG16(MSC_CLKRT) ++#define REG_MSC_CMDAT REG32(MSC_CMDAT) ++#define REG_MSC_RESTO REG16(MSC_RESTO) ++#define REG_MSC_RDTO REG16(MSC_RDTO) ++#define REG_MSC_BLKLEN REG16(MSC_BLKLEN) ++#define REG_MSC_NOB REG16(MSC_NOB) ++#define REG_MSC_SNOB REG16(MSC_SNOB) ++#define REG_MSC_IMASK REG16(MSC_IMASK) ++#define REG_MSC_IREG REG16(MSC_IREG) ++#define REG_MSC_CMD REG8(MSC_CMD) ++#define REG_MSC_ARG REG32(MSC_ARG) ++#define REG_MSC_RES REG16(MSC_RES) ++#define REG_MSC_RXFIFO REG32(MSC_RXFIFO) ++#define REG_MSC_TXFIFO REG32(MSC_TXFIFO) ++ ++/* MSC Clock and Control Register (MSC_STRPCL) */ ++ ++#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7) ++#define MSC_STRPCL_EXIT_TRANSFER (1 << 6) ++#define MSC_STRPCL_START_READWAIT (1 << 5) ++#define MSC_STRPCL_STOP_READWAIT (1 << 4) ++#define MSC_STRPCL_RESET (1 << 3) ++#define MSC_STRPCL_START_OP (1 << 2) ++#define MSC_STRPCL_CLOCK_CONTROL_BIT 0 ++#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT) ++ #define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */ ++ #define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */ ++ ++/* MSC Status Register (MSC_STAT) */ ++ ++#define MSC_STAT_IS_RESETTING (1 << 15) ++#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14) ++#define MSC_STAT_PRG_DONE (1 << 13) ++#define MSC_STAT_DATA_TRAN_DONE (1 << 12) ++#define MSC_STAT_END_CMD_RES (1 << 11) ++#define MSC_STAT_DATA_FIFO_AFULL (1 << 10) ++#define MSC_STAT_IS_READWAIT (1 << 9) ++#define MSC_STAT_CLK_EN (1 << 8) ++#define MSC_STAT_DATA_FIFO_FULL (1 << 7) ++#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6) ++#define MSC_STAT_CRC_RES_ERR (1 << 5) ++#define MSC_STAT_CRC_READ_ERROR (1 << 4) ++#define MSC_STAT_CRC_WRITE_ERROR_BIT 2 ++#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT) ++ #define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */ ++ #define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */ ++ #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */ ++#define MSC_STAT_TIME_OUT_RES (1 << 1) ++#define MSC_STAT_TIME_OUT_READ (1 << 0) ++ ++/* MSC Bus Clock Control Register (MSC_CLKRT) */ ++ ++#define MSC_CLKRT_CLK_RATE_BIT 0 ++#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT) ++ #define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */ ++ #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */ ++ ++/* MSC Command Sequence Control Register (MSC_CMDAT) */ ++ ++#define MSC_CMDAT_IO_ABORT (1 << 11) ++#define MSC_CMDAT_BUS_WIDTH_BIT 9 ++#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT) ++#define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT) ++#define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT) ++#define MSC_CMDAT_DMA_EN (1 << 8) ++#define MSC_CMDAT_INIT (1 << 7) ++#define MSC_CMDAT_BUSY (1 << 6) ++#define MSC_CMDAT_STREAM_BLOCK (1 << 5) ++#define MSC_CMDAT_WRITE (1 << 4) ++#define MSC_CMDAT_READ (0 << 4) ++#define MSC_CMDAT_DATA_EN (1 << 3) ++#define MSC_CMDAT_RESPONSE_BIT 0 ++#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT) ++#define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT) ++ ++/* MSC Interrupts Mask Register (MSC_IMASK) */ ++#define MSC_IMASK_SDIO (1 << 7) ++#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6) ++#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5) ++#define MSC_IMASK_END_CMD_RES (1 << 2) ++#define MSC_IMASK_PRG_DONE (1 << 1) ++#define MSC_IMASK_DATA_TRAN_DONE (1 << 0) ++ ++ ++/* MSC Interrupts Status Register (MSC_IREG) */ ++#define MSC_IREG_SDIO (1 << 7) ++#define MSC_IREG_TXFIFO_WR_REQ (1 << 6) ++#define MSC_IREG_RXFIFO_RD_REQ (1 << 5) ++#define MSC_IREG_END_CMD_RES (1 << 2) ++#define MSC_IREG_PRG_DONE (1 << 1) ++#define MSC_IREG_DATA_TRAN_DONE (1 << 0) ++ ++static __inline__ unsigned int __cpm_get_pllout2(void) ++{ ++ if (REG_CPM_CPCCR & CPM_CPCCR_PCS) ++ return __cpm_get_pllout(); ++ else ++ return __cpm_get_pllout()/2; ++} ++ ++static inline void __cpm_select_msc_clk(int sd) ++{ ++ unsigned int pllout2 = __cpm_get_pllout2(); ++ unsigned int div = 0; ++ ++ if (sd) { ++ div = pllout2 / 24000000; ++ } ++ else { ++ div = pllout2 / 16000000; ++ } ++ ++ REG_CPM_MSCCDR = div - 1; ++} ++#define __msc_reset() \ ++do { \ ++ REG_MSC_STRPCL = MSC_STRPCL_RESET; \ ++ while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \ ++} while (0) ++ + #endif /* !__ASSEMBLY__ */ + #endif /* __JZ4740_H__ */ +diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c +index 3bd4e2f..a2ba648 100644 +--- a/board/qi/qi_lb60/qi_lb60.c ++++ b/board/qi/qi_lb60/qi_lb60.c +@@ -40,8 +40,13 @@ static void gpio_init(void) + __gpio_clear_pin(GPIO_KEYOUT_BASE + i); + } + +- __gpio_as_input(GPIO_KEYIN_8); +- __gpio_enable_pull(GPIO_KEYIN_8); ++ if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){ ++ printf("[S] pressed, enable UART0\n"); ++ __gpio_as_uart0(); ++ } else { ++ __gpio_as_input(GPIO_KEYIN_8); ++ __gpio_enable_pull(GPIO_KEYIN_8); ++ } + + /* enable the TP4, TP5 as UART0 */ + __gpio_jtag_to_uart0(); +diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile +index 565ba6a..3c717b1 100644 +--- a/drivers/mmc/Makefile ++++ b/drivers/mmc/Makefile +@@ -47,6 +47,7 @@ COBJS-$(CONFIG_SDHCI) += sdhci.o + COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o + COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o + COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o ++COBJS-$(CONFIG_JZ4740_MMC) += jz_mmc.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c +new file mode 100644 +index 0000000..642cecc +--- /dev/null ++++ b/drivers/mmc/jz_mmc.c +@@ -0,0 +1,1179 @@ ++/* ++ * (C) Copyright 2003 ++ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#include <config.h> ++#include <common.h> ++#include <part.h> ++#include <mmc.h> ++ ++#include <asm/io.h> ++#include <asm/jz4740.h> ++#include "jz_mmc.h" ++ ++static int sd2_0 = 0; ++static int mmc_ready = 0; ++static int use_4bit; /* Use 4-bit data bus */ ++/* ++ * MMC Events ++ */ ++#define MMC_EVENT_NONE 0x00 /* No events */ ++#define MMC_EVENT_RX_DATA_DONE 0x01 /* Rx data done */ ++#define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */ ++#define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */ ++ ++ ++#define MMC_IRQ_MASK() \ ++do { \ ++ REG_MSC_IMASK = 0xffff; \ ++ REG_MSC_IREG = 0xffff; \ ++} while (0) ++ ++/* ++ * GPIO definition ++ */ ++#if defined(CONFIG_SAKC) ++ ++#define __msc_init_io() \ ++do { \ ++ __gpio_as_input(GPIO_SD_CD_N); \ ++} while (0) ++ ++#else ++#define __msc_init_io() \ ++do { \ ++ __gpio_as_output(GPIO_SD_VCC_EN_N); \ ++ __gpio_as_input(GPIO_SD_CD_N); \ ++} while (0) ++ ++#define __msc_enable_power() \ ++do { \ ++ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \ ++} while (0) ++ ++#define __msc_disable_power() \ ++do { \ ++ __gpio_set_pin(GPIO_SD_VCC_EN_N); \ ++} while (0) ++ ++#endif /* CONFIG_SAKE */ ++ ++#define __msc_card_detected() \ ++({ \ ++ int detected = 1; \ ++ __gpio_as_input(GPIO_SD_CD_N); \ ++ __gpio_disable_pull(GPIO_SD_CD_N); \ ++ if (!__gpio_get_pin(GPIO_SD_CD_N)) \ ++ detected = 0; \ ++ detected; \ ++}) ++ ++/* ++ * Local functions ++ */ ++ ++extern int ++fat_register_device(block_dev_desc_t *dev_desc, int part_no); ++ ++static block_dev_desc_t mmc_dev; ++ ++block_dev_desc_t * mmc_get_dev(int dev) ++{ ++ return ((block_dev_desc_t *)&mmc_dev); ++} ++ ++/* Stop the MMC clock and wait while it happens */ ++static inline int jz_mmc_stop_clock(void) ++{ ++ int timeout = 1000; ++ ++ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP; ++ ++ while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) { ++ timeout--; ++ if (timeout == 0) ++ return MMC_ERROR_TIMEOUT; ++ udelay(1); ++ } ++ return MMC_NO_ERROR; ++} ++ ++/* Start the MMC clock and operation */ ++static inline int jz_mmc_start_clock(void) ++{ ++ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP; ++ return MMC_NO_ERROR; ++} ++ ++static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate) ++{ ++ u32 clkrt = 0; ++ u32 clk_src = is_sd ? 24000000 : 16000000; ++ ++ while (rate < clk_src) { ++ clkrt ++; ++ clk_src >>= 1; ++ } ++ ++ return clkrt; ++} ++ ++/* Set the MMC clock frequency */ ++void jz_mmc_set_clock(int sd, u32 rate) ++{ ++ jz_mmc_stop_clock(); ++ ++ /* Select clock source of MSC */ ++ __cpm_select_msc_clk(sd); ++ ++ /* Set clock dividor of MSC */ ++ REG_MSC_CLKRT = jz_mmc_calc_clkrt(sd, rate); ++} ++ ++static int jz_mmc_check_status(struct mmc_request *request) ++{ ++ u32 status = REG_MSC_STAT; ++ ++ /* Checking for response or data timeout */ ++ if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) { ++ printf("MMC/SD timeout, MMC_STAT 0x%x CMD %d\n", status, request->cmd); ++ return MMC_ERROR_TIMEOUT; ++ } ++ ++ /* Checking for CRC error */ ++ if (status & (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_RES_ERR)) { ++ printf("MMC/CD CRC error, MMC_STAT 0x%x\n", status); ++ return MMC_ERROR_CRC; ++ } ++ ++ return MMC_NO_ERROR; ++} ++ ++/* Obtain response to the command and store it to response buffer */ ++static void jz_mmc_get_response(struct mmc_request *request) ++{ ++ int i; ++ u8 *buf; ++ u32 data; ++ ++ debug("fetch response for request %d, cmd %d\n", ++ request->rtype, request->cmd); ++ ++ buf = request->response; ++ request->result = MMC_NO_ERROR; ++ ++ switch (request->rtype) { ++ case RESPONSE_R1: case RESPONSE_R1B: case RESPONSE_R6: ++ case RESPONSE_R3: case RESPONSE_R4: case RESPONSE_R5: ++ { ++ data = REG_MSC_RES; ++ buf[0] = (data >> 8) & 0xff; ++ buf[1] = data & 0xff; ++ data = REG_MSC_RES; ++ buf[2] = (data >> 8) & 0xff; ++ buf[3] = data & 0xff; ++ data = REG_MSC_RES; ++ buf[4] = data & 0xff; ++ ++ debug("request %d, response [%02x %02x %02x %02x %02x]\n", ++ request->rtype, buf[0], buf[1], buf[2], buf[3], buf[4]); ++ break; ++ } ++ case RESPONSE_R2_CID: case RESPONSE_R2_CSD: ++ { ++ for (i = 0; i < 16; i += 2) { ++ data = REG_MSC_RES; ++ buf[i] = (data >> 8) & 0xff; ++ buf[i+1] = data & 0xff; ++ } ++ debug("request %d, response [", request->rtype); ++#if CONFIG_MMC_DEBUG_VERBOSE > 2 ++ if (g_mmc_debug >= 3) { ++ int n; ++ for (n = 0; n < 17; n++) ++ printk("%02x ", buf[n]); ++ printk("]\n"); ++ } ++#endif ++ break; ++ } ++ case RESPONSE_NONE: ++ debug("No response\n"); ++ break; ++ ++ default: ++ debug("unhandled response type for request %d\n", request->rtype); ++ break; ++ } ++} ++ ++static int jz_mmc_receive_data(struct mmc_request *req) ++{ ++ u32 stat, timeout, data, cnt; ++ u8 *buf = req->buffer; ++ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */ ++ ++ timeout = 0x3ffffff; ++ ++ while (timeout) { ++ timeout--; ++ stat = REG_MSC_STAT; ++ ++ if (stat & MSC_STAT_TIME_OUT_READ) ++ return MMC_ERROR_TIMEOUT; ++ else if (stat & MSC_STAT_CRC_READ_ERROR) ++ return MMC_ERROR_CRC; ++ else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY) ++ || (stat & MSC_STAT_DATA_FIFO_AFULL)) { ++ /* Ready to read data */ ++ break; ++ } ++ udelay(1); ++ } ++ if (!timeout) ++ return MMC_ERROR_TIMEOUT; ++ ++ /* Read data from RXFIFO. It could be FULL or PARTIAL FULL */ ++ cnt = wblocklen; ++ while (cnt) { ++ data = REG_MSC_RXFIFO; ++ { ++ *buf++ = (u8)(data >> 0); ++ *buf++ = (u8)(data >> 8); ++ *buf++ = (u8)(data >> 16); ++ *buf++ = (u8)(data >> 24); ++ } ++ cnt --; ++ while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY)) ++ ; ++ } ++ return MMC_NO_ERROR; ++} ++ ++static int jz_mmc_transmit_data(struct mmc_request *req) ++{ ++#if 0 ++ u32 nob = req->nob; ++ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */ ++ u8 *buf = req->buffer; ++ u32 *wbuf = (u32 *)buf; ++ u32 waligned = (((u32)buf & 0x3) == 0); /* word aligned ? */ ++ u32 stat, timeout, data, cnt; ++ ++ for (nob; nob >= 1; nob--) { ++ timeout = 0x3FFFFFF; ++ ++ while (timeout) { ++ timeout--; ++ stat = REG_MSC_STAT; ++ ++ if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS)) ++ return MMC_ERROR_CRC; ++ else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) { ++ /* Ready to write data */ ++ break; ++ } ++ ++ udelay(1); ++ } ++ ++ if (!timeout) ++ return MMC_ERROR_TIMEOUT; ++ ++ /* Write data to TXFIFO */ ++ cnt = wblocklen; ++ while (cnt) { ++ while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL) ++ ; ++ ++ if (waligned) { ++ REG_MSC_TXFIFO = *wbuf++; ++ } ++ else { ++ data = *buf++ | (*buf++ << 8) | (*buf++ << 16) | (*buf++ << 24); ++ REG_MSC_TXFIFO = data; ++ } ++ ++ cnt--; ++ } ++ } ++#endif ++ return MMC_NO_ERROR; ++} ++ ++ ++/* ++ * Name: int jz_mmc_exec_cmd() ++ * Function: send command to the card, and get a response ++ * Input: struct mmc_request *req : MMC/SD request ++ * Output: 0: right >0: error code ++ */ ++int jz_mmc_exec_cmd(struct mmc_request *request) ++{ ++ u32 cmdat = 0, events = 0; ++ int retval, timeout = 0x3fffff; ++ ++ /* Indicate we have no result yet */ ++ request->result = MMC_NO_RESPONSE; ++ if (request->cmd == MMC_CIM_RESET) { ++ /* On reset, 1-bit bus width */ ++ use_4bit = 0; ++ ++ /* Reset MMC/SD controller */ ++ __msc_reset(); ++ ++ /* On reset, drop MMC clock down */ ++ jz_mmc_set_clock(0, MMC_CLOCK_SLOW); ++ ++ /* On reset, stop MMC clock */ ++ jz_mmc_stop_clock(); ++ } ++ if (request->cmd == MMC_CMD_SEND_OP_COND) { ++ debug("Have an MMC card\n"); ++ /* always use 1bit for MMC */ ++ use_4bit = 0; ++ } ++ if (request->cmd == SET_BUS_WIDTH) { ++ if (request->arg == 0x2) { ++ printf("Use 4-bit bus width\n"); ++ use_4bit = 1; ++ } else { ++ printf("Use 1-bit bus width\n"); ++ use_4bit = 0; ++ } ++ } ++ ++ /* stop clock */ ++ jz_mmc_stop_clock(); ++ ++ /* mask all interrupts */ ++ REG_MSC_IMASK = 0xffff; ++ ++ /* clear status */ ++ REG_MSC_IREG = 0xffff; ++ ++ /* use 4-bit bus width when possible */ ++ if (use_4bit) ++ cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT; ++ ++ /* Set command type and events */ ++ switch (request->cmd) { ++ /* MMC core extra command */ ++ case MMC_CIM_RESET: ++ cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */ ++ break; ++ ++ /* bc - broadcast - no response */ ++ case MMC_CMD_GO_IDLE_STATE: ++ case MMC_CMD_SET_DSR: ++ break; ++ ++ /* bcr - broadcast with response */ ++ case MMC_CMD_SEND_OP_COND: ++ case MMC_CMD_ALL_SEND_CID: ++ case MMC_GO_IRQ_STATE: ++ break; ++ ++ /* adtc - addressed with data transfer */ ++ case MMC_READ_DAT_UNTIL_STOP: ++ case MMC_CMD_READ_SINGLE_BLOCK: ++ case MMC_CMD_READ_MULTIPLE_BLOCK: ++ case SD_CMD_APP_SEND_SCR: ++ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_READ; ++ events = MMC_EVENT_RX_DATA_DONE; ++ break; ++ ++ case MMC_WRITE_DAT_UNTIL_STOP: ++ case MMC_CMD_WRITE_SINGLE_BLOCK: ++ case MMC_CMD_WRITE_MULTIPLE_BLOCK: ++ case MMC_PROGRAM_CID: ++ case MMC_PROGRAM_CSD: ++ case MMC_SEND_WRITE_PROT: ++ case MMC_GEN_CMD: ++ case MMC_LOCK_UNLOCK: ++ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE; ++ events = MMC_EVENT_TX_DATA_DONE | MMC_EVENT_PROG_DONE; ++ ++ break; ++ ++ case MMC_CMD_STOP_TRANSMISSION: ++ events = MMC_EVENT_PROG_DONE; ++ break; ++ ++ /* ac - no data transfer */ ++ default: ++ break; ++ } ++ ++ /* Set response type */ ++ switch (request->rtype) { ++ case RESPONSE_NONE: ++ break; ++ ++ case RESPONSE_R1B: ++ cmdat |= MSC_CMDAT_BUSY; ++ /*FALLTHRU*/ ++ case RESPONSE_R1: ++ cmdat |= MSC_CMDAT_RESPONSE_R1; ++ break; ++ case RESPONSE_R2_CID: ++ case RESPONSE_R2_CSD: ++ cmdat |= MSC_CMDAT_RESPONSE_R2; ++ break; ++ case RESPONSE_R3: ++ cmdat |= MSC_CMDAT_RESPONSE_R3; ++ break; ++ case RESPONSE_R4: ++ cmdat |= MSC_CMDAT_RESPONSE_R4; ++ break; ++ case RESPONSE_R5: ++ cmdat |= MSC_CMDAT_RESPONSE_R5; ++ break; ++ case RESPONSE_R6: ++ cmdat |= MSC_CMDAT_RESPONSE_R6; ++ break; ++ default: ++ break; ++ } ++ ++ /* Set command index */ ++ if (request->cmd == MMC_CIM_RESET) { ++ REG_MSC_CMD = MMC_CMD_GO_IDLE_STATE; ++ } else { ++ REG_MSC_CMD = request->cmd; ++ } ++ ++ /* Set argument */ ++ REG_MSC_ARG = request->arg; ++ ++ /* Set block length and nob */ ++ if (request->cmd == SD_CMD_APP_SEND_SCR) { /* get SCR from DataFIFO */ ++ REG_MSC_BLKLEN = 8; ++ REG_MSC_NOB = 1; ++ } else { ++ REG_MSC_BLKLEN = request->block_len; ++ REG_MSC_NOB = request->nob; ++ } ++ ++ /* Set command */ ++ REG_MSC_CMDAT = cmdat; ++ ++ debug("Send cmd %d cmdat: %x arg: %x resp %d\n", request->cmd, ++ cmdat, request->arg, request->rtype); ++ ++ /* Start MMC/SD clock and send command to card */ ++ jz_mmc_start_clock(); ++ ++ /* Wait for command completion */ ++ while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES)) ++ ; ++ ++ if (timeout == 0) ++ return MMC_ERROR_TIMEOUT; ++ ++ REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear flag */ ++ ++ /* Check for status */ ++ retval = jz_mmc_check_status(request); ++ if (retval) { ++ return retval; ++ } ++ ++ /* Complete command with no response */ ++ if (request->rtype == RESPONSE_NONE) { ++ return MMC_NO_ERROR; ++ } ++ ++ /* Get response */ ++ jz_mmc_get_response(request); ++ ++ /* Start data operation */ ++ if (events & (MMC_EVENT_RX_DATA_DONE | MMC_EVENT_TX_DATA_DONE)) { ++ if (events & MMC_EVENT_RX_DATA_DONE) { ++ if (request->cmd == SD_CMD_APP_SEND_SCR) { ++ /* SD card returns SCR register as data. ++ MMC core expect it in the response buffer, ++ after normal response. */ ++ request->buffer = (u8 *)((u32)request->response + 5); ++ } ++ jz_mmc_receive_data(request); ++ } ++ ++ if (events & MMC_EVENT_TX_DATA_DONE) { ++ jz_mmc_transmit_data(request); ++ } ++ ++ /* Wait for Data Done */ ++ while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE)) ++ ; ++ REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */ ++ } ++ ++ /* Wait for Prog Done event */ ++ if (events & MMC_EVENT_PROG_DONE) { ++ while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE)) ++ ; ++ REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */ ++ } ++ ++ /* Command completed */ ++ ++ return MMC_NO_ERROR; /* return successfully */ ++} ++ ++int mmc_block_read(u8 *dst, ulong src, ulong len) ++{ ++ ++ struct mmc_request request; ++ struct mmc_response_r1 r1; ++ int retval = 0; ++ ++ if (len == 0) ++ goto exit; ++ ++ mmc_simple_cmd(&request, MMC_CMD_SEND_STATUS, mmcinfo.rca, RESPONSE_R1); ++ retval = mmc_unpack_r1(&request, &r1, 0); ++ if (retval && (retval != MMC_ERROR_STATE_MISMATCH)) ++ goto exit; ++ ++ mmc_simple_cmd(&request, MMC_CMD_SET_BLOCKLEN, len, RESPONSE_R1); ++ if (retval = mmc_unpack_r1(&request, &r1, 0)) ++ goto exit; ++ ++ if (!sd2_0) ++ src *= mmcinfo.block_len; ++ ++ mmc_send_cmd(&request, MMC_CMD_READ_SINGLE_BLOCK, src, 1, len, RESPONSE_R1, dst); ++ if (retval = mmc_unpack_r1(&request, &r1, 0)) ++ goto exit; ++ ++exit: ++ return retval; ++} ++ ++ulong mmc_bread(int dev_num, ulong blkstart, ulong blkcnt, ulong *dst) ++{ ++ if (!mmc_ready) { ++ printf("Please initial the MMC first\n"); ++ return -1; ++ } ++ ++ int i = 0; ++ ulong dst_tmp = dst; ++ ++ for (i = 0; i < blkcnt; i++) { ++ if ((mmc_block_read((uchar *)(dst_tmp), blkstart, mmcinfo.block_len)) < 0) ++ return -1; ++ ++ dst_tmp += mmcinfo.block_len; ++ blkstart++; ++ } ++ ++ return i; ++} ++ ++int mmc_select_card(void) ++{ ++ struct mmc_request request; ++ struct mmc_response_r1 r1; ++ int retval; ++ ++ mmc_simple_cmd(&request, MMC_CMD_SELECT_CARD, mmcinfo.rca, RESPONSE_R1B); ++ retval = mmc_unpack_r1(&request, &r1, 0); ++ if (retval) { ++ return retval; ++ } ++ ++ if (mmcinfo.sd) { ++ mmc_simple_cmd(&request, MMC_CMD_APP_CMD, mmcinfo.rca, RESPONSE_R1); ++ retval = mmc_unpack_r1(&request,&r1,0); ++ if (retval) { ++ return retval; ++ } ++#if defined(MMC_BUS_WIDTH_1BIT) ++ mmc_simple_cmd(&request, SET_BUS_WIDTH, 1, RESPONSE_R1); ++#else ++ mmc_simple_cmd(&request, SET_BUS_WIDTH, 2, RESPONSE_R1); ++#endif ++ retval = mmc_unpack_r1(&request,&r1,0); ++ if (retval) { ++ return retval; ++ } ++ } ++ return 0; ++} ++ ++/* ++ * Configure card ++ */ ++static void mmc_configure_card(void) ++{ ++ u32 rate; ++ ++ /* Get card info */ ++ if (sd2_0) ++ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) << 10; ++ else ++ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) * (1 << (mmcinfo.csd.c_size_mult + 2)); ++ ++ mmcinfo.block_len = 1 << mmcinfo.csd.read_bl_len; ++ ++ mmc_dev.if_type = IF_TYPE_SD; ++ mmc_dev.part_type = PART_TYPE_DOS; ++ mmc_dev.dev = 0; ++ mmc_dev.lun = 0; ++ mmc_dev.type = 0; ++ mmc_dev.blksz = mmcinfo.block_len; ++ mmc_dev.lba = mmcinfo.block_num; ++ mmc_dev.removable = 0; ++ ++ printf("%s Detected: %lu blocks of %lu bytes\n", ++ sd2_0 == 1 ? "SDHC" : "SD", ++ mmc_dev.lba, ++ mmc_dev.blksz); ++ ++ /* Fix the clock rate */ ++ rate = mmc_tran_speed(mmcinfo.csd.tran_speed); ++ if (rate < MMC_CLOCK_SLOW) ++ rate = MMC_CLOCK_SLOW; ++ if ((mmcinfo.sd == 0) && (rate > MMC_CLOCK_FAST)) ++ rate = MMC_CLOCK_FAST; ++ if ((mmcinfo.sd) && (rate > SD_CLOCK_FAST)) ++ rate = SD_CLOCK_FAST; ++ ++ debug("%s: block_len=%d block_num=%d rate=%d\n", ++ __func__, mmcinfo.block_len, mmcinfo.block_num, rate); ++ ++ jz_mmc_set_clock(mmcinfo.sd, rate); ++} ++ ++/* ++ * State machine routines to initialize card(s) ++ */ ++ ++/* ++ CIM_SINGLE_CARD_ACQ (frequency at 400 kHz) ++ --- Must enter from GO_IDLE_STATE --- ++ 1. SD_SEND_OP_COND (SD Card) [CMD55] + [CMD41] ++ 2. SEND_OP_COND (Full Range) [CMD1] {optional} ++ 3. SEND_OP_COND (Set Range ) [CMD1] ++ If busy, delay and repeat step 2 ++ 4. ALL_SEND_CID [CMD2] ++ If timeout, set an error (no cards found) ++ 5. SET_RELATIVE_ADDR [CMD3] ++ 6. SEND_CSD [CMD9] ++ 7. SET_DSR [CMD4] Only call this if (csd.dsr_imp). ++ 8. Set clock frequency (check available in csd.tran_speed) ++ */ ++ ++#define MMC_INIT_DOING 0 ++#define MMC_INIT_PASSED 1 ++#define MMC_INIT_FAILED 2 ++ ++static int mmc_init_card_state(struct mmc_request *request) ++{ ++ struct mmc_response_r1 r1; ++ struct mmc_response_r3 r3; ++ int retval; ++ int ocr = 0x40300000; ++ int limit_41 = 0; ++ ++ switch (request->cmd) { ++ case MMC_CMD_GO_IDLE_STATE: /* No response to parse */ ++ if (mmcinfo.sd) ++ mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1); ++ else ++ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); ++ break; ++ ++ case 8: ++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state); ++ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1); ++ break; ++ ++ case MMC_CMD_APP_CMD: ++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state); ++ if (retval & (limit_41 < 100)) { ++ debug("%s: unable to MMC_APP_CMD error=%d (%s)\n", ++ __func__, retval, mmc_result_to_string(retval)); ++ limit_41++; ++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3); ++ } else if (limit_41 < 100) { ++ limit_41++; ++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3); ++ } else{ ++ /* reset the card to idle*/ ++ mmc_simple_cmd(request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE); ++ mmcinfo.sd = 0; ++ } ++ break; ++ ++ case SD_CMD_APP_SEND_OP_COND: ++ retval = mmc_unpack_r3(request, &r3); ++ if (retval) { ++ debug("%s: try MMC card\n", __func__); ++ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); ++ break; ++ } ++ ++ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr); ++ ++ if(!(r3.ocr & MMC_CARD_BUSY || ocr == 0)){ ++ udelay(50000); ++ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1); ++ } else { ++ mmcinfo.sd = 1; /* SD Card ready */ ++ mmcinfo.state = CARD_STATE_READY; ++ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID); ++ } ++ break; ++ ++ case MMC_CMD_SEND_OP_COND: ++ retval = mmc_unpack_r3(request, &r3); ++ if (retval) { ++ debug("%s: failed SEND_OP_COND error=%d (%s)\n", ++ __func__, retval, mmc_result_to_string(retval)); ++ return MMC_INIT_FAILED; ++ } ++ ++ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr); ++ if (!(r3.ocr & MMC_CARD_BUSY)) { ++ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3); ++ } else { ++ mmcinfo.sd = 0; /* MMC Card ready */ ++ mmcinfo.state = CARD_STATE_READY; ++ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID); ++ } ++ break; ++ ++ case MMC_CMD_ALL_SEND_CID: ++ retval = mmc_unpack_cid( request, &mmcinfo.cid ); ++ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */ ++ if ( retval && (retval != MMC_ERROR_CRC)) { ++ debug("mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n", ++ retval, mmc_result_to_string(retval)); ++ return MMC_INIT_FAILED; ++ } ++ mmcinfo.state = CARD_STATE_IDENT; ++ if(mmcinfo.sd) ++ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, 0, RESPONSE_R6); ++ else ++ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, ID_TO_RCA(mmcinfo.id) << 16, RESPONSE_R1); ++ break; ++ ++ case MMC_CMD_SET_RELATIVE_ADDR: ++ if (mmcinfo.sd) { ++ retval = mmc_unpack_r6(request, &r1, mmcinfo.state, &mmcinfo.rca); ++ mmcinfo.rca = mmcinfo.rca << 16; ++ debug("%s: Get RCA from SD: 0x%04x Status: %x\n", ++ __func__, mmcinfo.rca, r1.status); ++ } else { ++ retval = mmc_unpack_r1(request,&r1,mmcinfo.state); ++ mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16; ++ } ++ if (retval) { ++ debug("%s: unable to SET_RELATIVE_ADDR error=%d (%s)\n", ++ __func__, retval, mmc_result_to_string(retval)); ++ return MMC_INIT_FAILED; ++ } ++ ++ mmcinfo.state = CARD_STATE_STBY; ++ mmc_simple_cmd(request, MMC_CMD_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD); ++ ++ break; ++ ++ case MMC_CMD_SEND_CSD: ++ retval = mmc_unpack_csd(request, &mmcinfo.csd); ++ mmc_ready = 1; ++ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */ ++ if (retval && (retval != MMC_ERROR_CRC)) { ++ debug("%s: unable to SEND_CSD error=%d (%s)\n", ++ __func__, retval, mmc_result_to_string(retval)); ++ return MMC_INIT_FAILED; ++ } ++ if (mmcinfo.csd.dsr_imp) { ++ debug("%s: driver doesn't support setting DSR\n", __func__); ++ } ++ mmc_configure_card(); ++ return MMC_INIT_PASSED; ++ ++ default: ++ debug("%s: error! Illegal last cmd %d\n", __func__, request->cmd); ++ return MMC_INIT_FAILED; ++ } ++ ++ return MMC_INIT_DOING; ++} ++ ++int mmc_init_card(void) ++{ ++ struct mmc_request request; ++ int retval; ++ ++ mmc_simple_cmd(&request, MMC_CIM_RESET, 0, RESPONSE_NONE); /* reset card */ ++ mmc_simple_cmd(&request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE); ++ mmcinfo.sd = 1; /* assuming a SD card */ ++ ++ while ((retval = mmc_init_card_state(&request)) == MMC_INIT_DOING) ++ ; ++ ++ if (retval == MMC_INIT_PASSED) ++ return MMC_NO_ERROR; ++ else ++ return MMC_NO_RESPONSE; ++} ++ ++int mmc_legacy_init(int verbose) ++{ ++ if (!__msc_card_detected()) ++ return 1; ++ ++ /* Step-1: init GPIO */ ++ __gpio_as_msc(); ++ __msc_init_io(); ++ ++ /* Step-2: turn on power of card */ ++#if !defined(CONFIG_SAKC) ++ __msc_enable_power(); ++#endif ++ ++ /* Step-3: Reset MSC Controller. */ ++ __msc_reset(); ++ ++ /* Step-3: mask all IRQs. */ ++ MMC_IRQ_MASK(); ++ ++ /* Step-4: stop MMC/SD clock */ ++ jz_mmc_stop_clock(); ++ mmc_init_card(); ++ mmc_select_card(); ++ ++ mmc_dev.block_read = mmc_bread; ++ fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */ ++ ++ return 0; ++} ++ ++/* ++ * Debugging functions ++ */ ++static char * mmc_result_strings[] = { ++ "NO_RESPONSE", ++ "NO_ERROR", ++ "ERROR_OUT_OF_RANGE", ++ "ERROR_ADDRESS", ++ "ERROR_BLOCK_LEN", ++ "ERROR_ERASE_SEQ", ++ "ERROR_ERASE_PARAM", ++ "ERROR_WP_VIOLATION", ++ "ERROR_CARD_IS_LOCKED", ++ "ERROR_LOCK_UNLOCK_FAILED", ++ "ERROR_COM_CRC", ++ "ERROR_ILLEGAL_COMMAND", ++ "ERROR_CARD_ECC_FAILED", ++ "ERROR_CC", ++ "ERROR_GENERAL", ++ "ERROR_UNDERRUN", ++ "ERROR_OVERRUN", ++ "ERROR_CID_CSD_OVERWRITE", ++ "ERROR_STATE_MISMATCH", ++ "ERROR_HEADER_MISMATCH", ++ "ERROR_TIMEOUT", ++ "ERROR_CRC", ++ "ERROR_DRIVER_FAILURE", ++}; ++ ++char * mmc_result_to_string(int i) ++{ ++ return mmc_result_strings[i+1]; ++} ++ ++static char * card_state_strings[] = { ++ "empty", ++ "idle", ++ "ready", ++ "ident", ++ "stby", ++ "tran", ++ "data", ++ "rcv", ++ "prg", ++ "dis", ++}; ++ ++static inline char * card_state_to_string(int i) ++{ ++ return card_state_strings[i+1]; ++} ++ ++/* ++ * Utility functions ++ */ ++ ++#define PARSE_U32(_buf,_index) \ ++ (((u32)_buf[_index]) << 24) | (((u32)_buf[_index+1]) << 16) | \ ++ (((u32)_buf[_index+2]) << 8) | ((u32)_buf[_index+3]); ++ ++#define PARSE_U16(_buf,_index) \ ++ (((u16)_buf[_index]) << 8) | ((u16)_buf[_index+1]); ++ ++int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd) ++{ ++ u8 *buf = request->response; ++ int num = 0; ++ ++ if (request->result) ++ return request->result; ++ ++ if (buf[0] != 0x3f) ++ return MMC_ERROR_HEADER_MISMATCH; ++ ++ csd->csd_structure = (buf[1] & 0xc0) >> 6; ++ if (csd->csd_structure) ++ sd2_0 = 1; ++ else ++ sd2_0 = 0; ++ ++ switch (csd->csd_structure) { ++ case 0 :/* Version 1.01-1.10 ++ * Version 2.00/Standard Capacity */ ++ csd->taac = buf[2]; ++ csd->nsac = buf[3]; ++ csd->tran_speed = buf[4]; ++ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4); ++ csd->read_bl_len = buf[6] & 0x0f; ++ /* for support 2GB card*/ ++ if (csd->read_bl_len >= 10) ++ { ++ num = csd->read_bl_len - 9; ++ csd->read_bl_len = 9; ++ } ++ ++ csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0; ++ csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0; ++ csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0; ++ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0; ++ csd->c_size = ((((u16)buf[7]) & 0x03) << 10) | (((u16)buf[8]) << 2) | (((u16)buf[9]) & 0xc0) >> 6; ++ ++ if (num) ++ csd->c_size = csd->c_size << num; ++ ++ ++ csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3; ++ csd->vdd_r_curr_max = buf[9] & 0x07; ++ csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5; ++ csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2; ++ csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7); ++ csd->sector_size = (buf[11] & 0x7c) >> 2; ++ csd->erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5); ++ csd->wp_grp_size = buf[12] & 0x1f; ++ csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0; ++ csd->default_ecc = (buf[13] & 0x60) >> 5; ++ csd->r2w_factor = (buf[13] & 0x1c) >> 2; ++ csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6); ++ if (csd->write_bl_len >= 10) ++ csd->write_bl_len = 9; ++ ++ csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0; ++ csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0; ++ csd->copy = (buf[15] & 0x40) ? 1 : 0; ++ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0; ++ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0; ++ csd->file_format = (buf[15] & 0x0c) >> 2; ++ csd->ecc = buf[15] & 0x03; ++ break; ++ case 1 : /* Version 2.00/High Capacity */ ++ csd->taac = 0; ++ csd->nsac = 0; ++ csd->tran_speed = buf[4]; ++ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4); ++ ++ csd->read_bl_len = 9; ++ csd->read_bl_partial = 0; ++ csd->write_blk_misalign = 0; ++ csd->read_blk_misalign = 0; ++ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0; ++ csd->c_size = ((((u16)buf[8]) & 0x3f) << 16) | (((u16)buf[9]) << 8) | ((u16)buf[10]) ; ++ csd->sector_size = 0x7f; ++ csd->erase_grp_size = 0; ++ csd->wp_grp_size = 0; ++ csd->wp_grp_enable = 0; ++ csd->default_ecc = (buf[13] & 0x60) >> 5; ++ csd->r2w_factor = 4;/* Unused */ ++ csd->write_bl_len = 9; ++ ++ csd->write_bl_partial = 0; ++ csd->file_format_grp = 0; ++ csd->copy = (buf[15] & 0x40) ? 1 : 0; ++ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0; ++ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0; ++ csd->file_format = 0; ++ csd->ecc = buf[15] & 0x03; ++ } ++ ++ return 0; ++} ++ ++int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state) ++{ ++ u8 *buf = request->response; ++ ++ if (request->result) ++ return request->result; ++ ++ r1->cmd = buf[0]; ++ r1->status = PARSE_U32(buf,1); ++ ++ debug("mmc_unpack_r1: cmd=%d status=%08x\n", r1->cmd, r1->status); ++ ++ if (R1_STATUS(r1->status)) { ++ if (r1->status & R1_OUT_OF_RANGE) return MMC_ERROR_OUT_OF_RANGE; ++ if (r1->status & R1_ADDRESS_ERROR) return MMC_ERROR_ADDRESS; ++ if (r1->status & R1_BLOCK_LEN_ERROR) return MMC_ERROR_BLOCK_LEN; ++ if (r1->status & R1_ERASE_SEQ_ERROR) return MMC_ERROR_ERASE_SEQ; ++ if (r1->status & R1_ERASE_PARAM) return MMC_ERROR_ERASE_PARAM; ++ if (r1->status & R1_WP_VIOLATION) return MMC_ERROR_WP_VIOLATION; ++ /*if (r1->status & R1_CARD_IS_LOCKED) return MMC_ERROR_CARD_IS_LOCKED; */ ++ if (r1->status & R1_LOCK_UNLOCK_FAILED) return MMC_ERROR_LOCK_UNLOCK_FAILED; ++ if (r1->status & R1_COM_CRC_ERROR) return MMC_ERROR_COM_CRC; ++ if (r1->status & R1_ILLEGAL_COMMAND) return MMC_ERROR_ILLEGAL_COMMAND; ++ if (r1->status & R1_CARD_ECC_FAILED) return MMC_ERROR_CARD_ECC_FAILED; ++ if (r1->status & R1_CC_ERROR) return MMC_ERROR_CC; ++ if (r1->status & R1_ERROR) return MMC_ERROR_GENERAL; ++ if (r1->status & R1_UNDERRUN) return MMC_ERROR_UNDERRUN; ++ if (r1->status & R1_OVERRUN) return MMC_ERROR_OVERRUN; ++ if (r1->status & R1_CID_CSD_OVERWRITE) return MMC_ERROR_CID_CSD_OVERWRITE; ++ } ++ ++ if (buf[0] != request->cmd) ++ return MMC_ERROR_HEADER_MISMATCH; ++ ++ /* This should be last - it's the least dangerous error */ ++ ++ return 0; ++} ++ ++int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr) ++{ ++ u8 *buf = request->response; ++ if (request->result) ++ return request->result; ++ ++ *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */ ++ return mmc_unpack_r1(request, r1, state); ++ ++} ++ ++int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca) ++{ ++ u8 *buf = request->response; ++ ++ if (request->result) ++ return request->result; ++ ++ *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */ ++ ++ *(buf+1) = 0; ++ *(buf+2) = 0; ++ ++ return mmc_unpack_r1(request, r1, state); ++} ++ ++int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid) ++{ ++ int i; ++ u8 *buf = request->response; ++ ++ if (request->result) ++ return request->result; ++ ++ cid->mid = buf[1]; ++ cid->oid = PARSE_U16(buf,2); ++ for (i = 0 ; i < 5 ; i++) ++ cid->pnm[i] = buf[4+i]; ++ cid->pnm[6] = 0; ++ cid->prv = buf[10]; ++ cid->psn = PARSE_U32(buf,10); ++ cid->mdt = buf[15]; ++ ++ printf("Man %02x OEM 0x%04x \"%s\" %d.%d 0x%08x " ++ "Date %02u/%04u\n", ++ cid->mid, ++ cid->oid, ++ cid->pnm, ++ cid->prv >> 4, ++ cid->prv & 0xf, ++ cid->psn, ++ cid->mdt & 0xf, ++ (cid->mdt >> 4) + 2000); ++ ++ if (buf[0] != 0x3f) ++ return MMC_ERROR_HEADER_MISMATCH; ++ return 0; ++} ++ ++int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3) ++{ ++ u8 *buf = request->response; ++ ++ if (request->result) ++ return request->result; ++ ++ r3->ocr = PARSE_U32(buf,1); ++ debug("mmc_unpack_r3: ocr=%08x\n", r3->ocr); ++ ++ if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH; ++ return 0; ++} ++ ++#define KBPS 1 ++#define MBPS 1000 ++ ++static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; ++static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, ++ 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; ++ ++u32 mmc_tran_speed(u8 ts) ++{ ++ u32 rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; ++ ++ if (rate <= 0) { ++ debug("%s: error - unrecognized speed 0x%02x\n", __func__, ts); ++ return 1; ++ } ++ ++ return rate; ++} ++ ++void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg, ++ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer) ++{ ++ request->cmd = cmd; ++ request->arg = arg; ++ request->rtype = rtype; ++ request->nob = nob; ++ request->block_len = block_len; ++ request->buffer = buffer; ++ request->cnt = nob * block_len; ++ ++ jz_mmc_exec_cmd(request); ++} +diff --git a/drivers/mmc/jz_mmc.h b/drivers/mmc/jz_mmc.h +new file mode 100644 +index 0000000..936c514 +--- /dev/null ++++ b/drivers/mmc/jz_mmc.h +@@ -0,0 +1,176 @@ ++/* ++ * linux/drivers/mmc/jz_mmc.h ++ * ++ * Author: Vladimir Shebordaev, Igor Oblakov ++ * Copyright: MontaVista Software Inc. ++ * ++ * $Id: jz_mmc.h,v 1.3 2007-06-15 08:04:20 jlwei Exp $ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __MMC_JZMMC_H__ ++#define __MMC_JZMMC_H__ ++ ++#define ID_TO_RCA(x) ((x)+1) ++#define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */ ++ ++/* Standard MMC/SD clock speeds */ ++#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */ ++#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */ ++#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ ++ ++/* Use negative numbers to disambiguate */ ++#define MMC_CIM_RESET -1 ++#define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ ++ ++#define R1_OUT_OF_RANGE (1 << 31) /* er, c */ ++#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ ++#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */ ++#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */ ++#define R1_ERASE_PARAM (1 << 27) /* ex, c */ ++#define R1_WP_VIOLATION (1 << 26) /* erx, c */ ++#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */ ++#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */ ++#define R1_COM_CRC_ERROR (1 << 23) /* er, b */ ++#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */ ++#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */ ++#define R1_CC_ERROR (1 << 20) /* erx, c */ ++#define R1_ERROR (1 << 19) /* erx, c */ ++#define R1_UNDERRUN (1 << 18) /* ex, c */ ++#define R1_OVERRUN (1 << 17) /* ex, c */ ++#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */ ++#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ ++#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ ++#define R1_ERASE_RESET (1 << 13) /* sr, c */ ++#define R1_STATUS(x) (x & 0xFFFFE000) ++ ++#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ ++ ++#define MMC_PROGRAM_CID 26 /* adtc R1 */ ++#define MMC_PROGRAM_CSD 27 /* adtc R1 */ ++ ++#define MMC_GO_IRQ_STATE 40 /* bcr R5 */ ++#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */ ++#define MMC_LOCK_UNLOCK 42 /* adtc R1b */ ++#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ ++#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ ++#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ ++ ++ ++enum mmc_result_t { ++ MMC_NO_RESPONSE = -1, ++ MMC_NO_ERROR = 0, ++ MMC_ERROR_OUT_OF_RANGE, ++ MMC_ERROR_ADDRESS, ++ MMC_ERROR_BLOCK_LEN, ++ MMC_ERROR_ERASE_SEQ, ++ MMC_ERROR_ERASE_PARAM, ++ MMC_ERROR_WP_VIOLATION, ++ MMC_ERROR_CARD_IS_LOCKED, ++ MMC_ERROR_LOCK_UNLOCK_FAILED, ++ MMC_ERROR_COM_CRC, ++ MMC_ERROR_ILLEGAL_COMMAND, ++ MMC_ERROR_CARD_ECC_FAILED, ++ MMC_ERROR_CC, ++ MMC_ERROR_GENERAL, ++ MMC_ERROR_UNDERRUN, ++ MMC_ERROR_OVERRUN, ++ MMC_ERROR_CID_CSD_OVERWRITE, ++ MMC_ERROR_STATE_MISMATCH, ++ MMC_ERROR_HEADER_MISMATCH, ++ MMC_ERROR_TIMEOUT, ++ MMC_ERROR_CRC, ++ MMC_ERROR_DRIVER_FAILURE, ++}; ++ ++enum card_state { ++ CARD_STATE_EMPTY = -1, ++ CARD_STATE_IDLE = 0, ++ CARD_STATE_READY = 1, ++ CARD_STATE_IDENT = 2, ++ CARD_STATE_STBY = 3, ++ CARD_STATE_TRAN = 4, ++ CARD_STATE_DATA = 5, ++ CARD_STATE_RCV = 6, ++ CARD_STATE_PRG = 7, ++ CARD_STATE_DIS = 8, ++}; ++ ++enum mmc_rsp_t { ++ RESPONSE_NONE = 0, ++ RESPONSE_R1 = 1, ++ RESPONSE_R1B = 2, ++ RESPONSE_R2_CID = 3, ++ RESPONSE_R2_CSD = 4, ++ RESPONSE_R3 = 5, ++ RESPONSE_R4 = 6, ++ RESPONSE_R5 = 7, ++ RESPONSE_R6 = 8, ++}; ++ ++struct mmc_response_r1 { ++ u8 cmd; ++ u32 status; ++}; ++ ++struct mmc_response_r3 { ++ u32 ocr; ++}; ++ ++/* the information structure of MMC/SD Card */ ++struct mmc_info { ++ int id; /* Card index */ ++ int sd; /* MMC or SD card */ ++ int rca; /* RCA */ ++ u32 scr; /* SCR 63:32*/ ++ int flags; /* Ejected, inserted */ ++ enum card_state state; /* empty, ident, ready, whatever */ ++ ++ /* Card specific information */ ++ struct mmc_cid cid; ++ struct mmc_csd csd; ++ u32 block_num; ++ u32 block_len; ++ u32 erase_unit; ++}; ++ ++struct mmc_info mmcinfo; ++ ++struct mmc_request { ++ int index; /* Slot index - used for CS lines */ ++ int cmd; /* Command to send */ ++ u32 arg; /* Argument to send */ ++ enum mmc_rsp_t rtype; /* Response type expected */ ++ ++ /* Data transfer (these may be modified at the low level) */ ++ u16 nob; /* Number of blocks to transfer*/ ++ u16 block_len; /* Block length */ ++ u8 *buffer; /* Data buffer */ ++ u32 cnt; /* Data length, for PIO */ ++ ++ /* Results */ ++ u8 response[18]; /* Buffer to store response - CRC is optional */ ++ enum mmc_result_t result; ++}; ++ ++char * mmc_result_to_string(int); ++int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd); ++int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state); ++int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca); ++int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr); ++int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid); ++int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3); ++ ++void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg, ++ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer); ++u32 mmc_tran_speed(u8 ts); ++void jz_mmc_set_clock(int sd, u32 rate); ++ ++static inline void mmc_simple_cmd(struct mmc_request *request, int cmd, u32 arg, enum mmc_rsp_t rtype) ++{ ++ mmc_send_cmd( request, cmd, arg, 0, 0, rtype, 0); ++} ++ ++#endif /* __MMC_JZMMC_H__ */ +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index 7bff444..7b33be0 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -31,6 +31,15 @@ + /* + * Miscellaneous configurable options + */ ++#define CONFIG_JZ4740_MMC ++#define CONFIG_MMC 1 ++#define CONFIG_FAT 1 ++#define CONFIG_DOS_PARTITION 1 ++#define CONFIG_CMD_MMC ++#define CONFIG_CMD_FAT ++#define CONFIG_CMD_EXT2 ++ ++ + #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ + #define CONFIG_SYS_INIT_SP_OFFSET 0x400000 + #define CONFIG_SYS_LOAD_ADDR 0x80600000 +diff --git a/include/mmc.h b/include/mmc.h +index a13e2bd..3c4761c 100644 +--- a/include/mmc.h ++++ b/include/mmc.h +@@ -283,4 +283,44 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode); + int mmc_legacy_init(int verbose); + #endif + ++struct mmc_csd ++{ ++ u8 csd_structure:2, ++ spec_vers:4, ++ rsvd1:2; ++ u8 taac; ++ u8 nsac; ++ u8 tran_speed; ++ u16 ccc:12, ++ read_bl_len:4; ++ u32 c_size:22; ++ u64 read_bl_partial:1, ++ write_blk_misalign:1, ++ read_blk_misalign:1, ++ dsr_imp:1, ++ rsvd2:2, ++ vdd_r_curr_min:3, ++ vdd_r_curr_max:3, ++ vdd_w_curr_min:3, ++ vdd_w_curr_max:3, ++ c_size_mult:3, ++ sector_size:5, ++ erase_grp_size:5, ++ wp_grp_size:5, ++ wp_grp_enable:1, ++ default_ecc:2, ++ r2w_factor:3, ++ write_bl_len:4, ++ write_bl_partial:1, ++ rsvd3:5; ++ u8 file_format_grp:1, ++ copy:1, ++ perm_write_protect:1, ++ tmp_write_protect:1, ++ file_format:2, ++ ecc:2; ++ u8 crc:7; ++ u8 one:1; ++}; ++ + #endif /* _MMC_H_ */ +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch b/package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch new file mode 100644 index 0000000..73e0324 --- /dev/null +++ b/package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch @@ -0,0 +1,200 @@ +From c52b6168979d03fc31205444c3278c537787472a Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Wed, 10 Oct 2012 18:39:55 +0800 +Subject: [PATCH 4/6] add more boot options(F1/F2/F3/F4/M/S) + +--- + arch/mips/include/asm/global_data.h | 3 +++ + arch/mips/lib/bootm.c | 17 ++++++++++++++++- + board/qi/qi_lb60/qi_lb60.c | 26 +++++++++++++++++++++++--- + common/main.c | 21 +++++++++++++++++++-- + include/configs/qi_lb60.h | 32 ++++++++++++++++++++++++++++++++ + 5 files changed, 93 insertions(+), 6 deletions(-) + +diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h +index 6e2cdc7..cd03d7e 100644 +--- a/arch/mips/include/asm/global_data.h ++++ b/arch/mips/include/asm/global_data.h +@@ -59,6 +59,9 @@ typedef struct global_data { + unsigned long env_valid; /* Checksum of Environment valid? */ + void **jt; /* jump table */ + char env_buf[32]; /* buffer for getenv() before reloc. */ ++#if defined(CONFIG_NANONOTE) ++ unsigned long boot_option; ++#endif + } gd_t; + + #include <asm-generic/global_data_flags.h> +diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c +index 608c1a7..e00416b 100644 +--- a/arch/mips/lib/bootm.c ++++ b/arch/mips/lib/bootm.c +@@ -47,10 +47,25 @@ int do_bootm_linux(int flag, int argc, char * const argv[], + bootm_headers_t *images) + { + void (*theKernel) (int, char **, char **, int *); +- char *commandline = getenv("bootargs"); ++ char *commandline; + char env_buf[12]; + char *cp; + ++#if defined(CONFIG_NANONOTE) ++ if (gd->boot_option & BOOT_FROM_MEMCARD) ++ commandline = getenv ("bootargsfromsd"); ++ else if (gd->boot_option & BOOT_WITH_F1) ++ commandline = getenv ("bootargsf1"); ++ else if (gd->boot_option & BOOT_WITH_F2) ++ commandline = getenv ("bootargsf2"); ++ else if (gd->boot_option & BOOT_WITH_F3) ++ commandline = getenv ("bootargsf3"); ++ else if (gd->boot_option & BOOT_WITH_F4) ++ commandline = getenv ("bootargsf4"); ++ else ++#endif ++ commandline = getenv ("bootargs"); ++ + if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) + return 1; + +diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c +index a2ba648..d622219 100644 +--- a/board/qi/qi_lb60/qi_lb60.c ++++ b/board/qi/qi_lb60/qi_lb60.c +@@ -15,7 +15,7 @@ DECLARE_GLOBAL_DATA_PTR; + + static void gpio_init(void) + { +- unsigned int i; ++ unsigned int i, j; + + /* Initialize NAND Flash Pins */ + __gpio_as_nand(); +@@ -42,14 +42,34 @@ static void gpio_init(void) + + if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){ + printf("[S] pressed, enable UART0\n"); ++ gd->boot_option |= BOOT_WITH_ENABLE_UART; + __gpio_as_uart0(); + } else { + __gpio_as_input(GPIO_KEYIN_8); + __gpio_enable_pull(GPIO_KEYIN_8); + } + +- /* enable the TP4, TP5 as UART0 */ +- __gpio_jtag_to_uart0(); ++ if (__gpio_get_pin(GPIO_KEYIN_BASE + 3) == 0) { ++ printf("[M] pressed, boot from memory card\n"); ++ gd->boot_option |= BOOT_FROM_MEMCARD; ++ __gpio_jtag_to_uart0(); ++ } ++ ++ for (j = 0; j < 4; j++) { ++ for (i = 0; i < 4; i++) ++ __gpio_set_pin(GPIO_KEYOUT_BASE + i); ++ ++ __gpio_clear_pin(GPIO_KEYOUT_BASE + j); ++ ++ if (__gpio_get_pin(GPIO_KEYIN_BASE) == 0) { ++ printf("[F%d] pressed", (j + 1)); ++ gd->boot_option |= (1 << (j + 2)); ++ /* BOOT_WITH_F1 (1 << 2) */ ++ /* BOOT_WITH_F2 (1 << 3) */ ++ /* BOOT_WITH_F3 (1 << 4) */ ++ /* BOOT_WITH_F4 (1 << 5) */ ++ } ++ } + + __gpio_as_output(GPIO_AUDIO_POP); + __gpio_set_pin(GPIO_AUDIO_POP); +diff --git a/common/main.c b/common/main.c +index 9507cec..dbfb7ca 100644 +--- a/common/main.c ++++ b/common/main.c +@@ -355,7 +355,11 @@ void main_loop (void) + #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) + s = getenv ("bootdelay"); + bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; +- ++#if defined(CONFIG_NANONOTE) ++ DECLARE_GLOBAL_DATA_PTR; ++ if (gd->boot_option & BOOT_WITH_ENABLE_UART) ++ bootdelay = 3; ++# endif + debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay); + + #if defined(CONFIG_MENU_SHOW) +@@ -379,7 +383,20 @@ void main_loop (void) + } + else + #endif /* CONFIG_BOOTCOUNT_LIMIT */ +- s = getenv ("bootcmd"); ++#if defined(CONFIG_NANONOTE) ++ if (gd->boot_option & BOOT_FROM_MEMCARD) ++ s = getenv ("bootcmdfromsd"); ++ else if (gd->boot_option & BOOT_WITH_F1) ++ s = getenv ("bootcmdf1"); ++ else if (gd->boot_option & BOOT_WITH_F2) ++ s = getenv ("bootcmdf2"); ++ else if (gd->boot_option & BOOT_WITH_F3) ++ s = getenv ("bootcmdf3"); ++ else if (gd->boot_option & BOOT_WITH_F4) ++ s = getenv ("bootcmdf4"); ++ else ++#endif ++ s = getenv ("bootcmd"); + + debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>"); + +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index 7b33be0..52b370c 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -31,6 +31,7 @@ + /* + * Miscellaneous configurable options + */ ++#define CONFIG_NANONOTE + #define CONFIG_JZ4740_MMC + #define CONFIG_MMC 1 + #define CONFIG_FAT 1 +@@ -39,6 +40,37 @@ + #define CONFIG_CMD_FAT + #define CONFIG_CMD_EXT2 + ++#define CONFIG_CMD_UBIFS ++#define CONFIG_CMD_UBI ++#define CONFIG_MTD_PARTITIONS ++#define CONFIG_MTD_DEVICE ++#define CONFIG_CMD_MTDPARTS ++#define CONFIG_CMD_UBI ++#define CONFIG_CMD_UBIFS ++#define CONFIG_LZO ++#define CONFIG_RBTREE ++ ++#define MTDIDS_DEFAULT "nand0=jz4740-nand" ++#define MTDPARTS_DEFAULT "mtdparts=jz4740-nand:4M@0(uboot)ro,4M@4M(kernel)ro,512M@8M(rootfs)ro,-(data)ro" ++ ++#define BOOT_FROM_MEMCARD 1 ++#define BOOT_WITH_ENABLE_UART (1 << 1) /* Vaule for global_data.h gd->boot_option */ ++#define BOOT_WITH_F1 (1 << 2) ++#define BOOT_WITH_F2 (1 << 3) ++#define BOOT_WITH_F3 (1 << 4) ++#define BOOT_WITH_F4 (1 << 5) ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ "bootcmdfromsd=mmc init; ext2load mmc 0 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsfromsd=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \ ++ "bootcmdf1=mmc init; ext2load mmc 0:1 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsf1=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \ ++ "bootcmdf2=mmc init; ext2load mmc 0:2 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsf2=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p2 rw rootwait\0" \ ++ "bootcmdf3=mmc init; ext2load mmc 0:3 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsf3=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p3 rw rootwait\0" \ ++ "bootcmdf4=mtdparts default;ubi part rootfs;ubifsmount rootfs;ubifsload 0x80600000 /boot/uImage; bootm;\0" \ ++ "bootargsf4=mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait" + + #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */ + #define CONFIG_SYS_INIT_SP_OFFSET 0x400000 +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch b/package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch new file mode 100644 index 0000000..2c550f7 --- /dev/null +++ b/package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch @@ -0,0 +1,847 @@ +From ca8c5216cfd3ad3fda9867ed2d157ae5a209834b Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Wed, 10 Oct 2012 22:05:27 +0800 +Subject: [PATCH 5/6] add nanonote lcd support + +--- + arch/mips/include/asm/global_data.h | 1 + + arch/mips/include/asm/jz4740.h | 90 ++++++++ + arch/mips/lib/board.c | 6 + + common/lcd.c | 9 +- + drivers/video/Makefile | 1 + + drivers/video/nanonote_gpm940b0.c | 400 +++++++++++++++++++++++++++++++++++ + drivers/video/nanonote_gpm940b0.h | 135 ++++++++++++ + include/configs/qi_lb60.h | 7 + + include/lcd.h | 52 ++++- + 9 files changed, 697 insertions(+), 4 deletions(-) + create mode 100644 drivers/video/nanonote_gpm940b0.c + create mode 100644 drivers/video/nanonote_gpm940b0.h + +diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h +index cd03d7e..7cec2de 100644 +--- a/arch/mips/include/asm/global_data.h ++++ b/arch/mips/include/asm/global_data.h +@@ -44,6 +44,7 @@ typedef struct global_data { + unsigned long per_clk; /* Peripheral bus clock */ + unsigned long mem_clk; /* Memory bus clock */ + unsigned long dev_clk; /* Device clock */ ++ unsigned long fb_base; /* base address of framebuffer */ + /* "static data" needed by most of timer.c */ + unsigned long tbl; + unsigned long lastinc; +diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h +index 68287fb..13724a2 100644 +--- a/arch/mips/include/asm/jz4740.h ++++ b/arch/mips/include/asm/jz4740.h +@@ -1312,5 +1312,95 @@ do { \ + while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \ + } while (0) + ++/************************************************************************* ++ * LCD (LCD Controller) ++ *************************************************************************/ ++#define REG32(addr) *((volatile u32 *)(addr)) ++ ++#define CPM_BASE 0xB0000000 ++#define CPM_CPCCR (CPM_BASE+0x00) ++#define REG_CPM_CPCCR REG32(CPM_CPCCR) ++ ++#define LCD_BASE 0xB3050000 ++#define LCD_CFG (LCD_BASE + 0x00) /* LCD Configure Register */ ++#define LCD_VSYNC (LCD_BASE + 0x04) /* Vertical Synchronize Register */ ++#define LCD_HSYNC (LCD_BASE + 0x08) /* Horizontal Synchronize Register */ ++#define LCD_VAT (LCD_BASE + 0x0c) /* Virtual Area Setting Register */ ++#define LCD_DAH (LCD_BASE + 0x10) /* Display Area Horizontal Start/End Point */ ++#define LCD_DAV (LCD_BASE + 0x14) /* Display Area Vertical Start/End Point */ ++#define LCD_PS (LCD_BASE + 0x18) /* PS Signal Setting */ ++#define LCD_CLS (LCD_BASE + 0x1c) /* CLS Signal Setting */ ++#define LCD_SPL (LCD_BASE + 0x20) /* SPL Signal Setting */ ++#define LCD_REV (LCD_BASE + 0x24) /* REV Signal Setting */ ++#define LCD_CTRL (LCD_BASE + 0x30) /* LCD Control Register */ ++#define LCD_STATE (LCD_BASE + 0x34) /* LCD Status Register */ ++#define LCD_IID (LCD_BASE + 0x38) /* Interrupt ID Register */ ++#define LCD_DA0 (LCD_BASE + 0x40) /* Descriptor Address Register 0 */ ++#define LCD_SA0 (LCD_BASE + 0x44) /* Source Address Register 0 */ ++#define LCD_FID0 (LCD_BASE + 0x48) /* Frame ID Register 0 */ ++#define LCD_CMD0 (LCD_BASE + 0x4c) /* DMA Command Register 0 */ ++#define LCD_DA1 (LCD_BASE + 0x50) /* Descriptor Address Register 1 */ ++#define LCD_SA1 (LCD_BASE + 0x54) /* Source Address Register 1 */ ++#define LCD_FID1 (LCD_BASE + 0x58) /* Frame ID Register 1 */ ++#define LCD_CMD1 (LCD_BASE + 0x5c) /* DMA Command Register 1 */ ++ ++#define REG_LCD_CFG REG32(LCD_CFG) ++#define REG_LCD_VSYNC REG32(LCD_VSYNC) ++#define REG_LCD_HSYNC REG32(LCD_HSYNC) ++#define REG_LCD_VAT REG32(LCD_VAT) ++#define REG_LCD_DAH REG32(LCD_DAH) ++#define REG_LCD_DAV REG32(LCD_DAV) ++#define REG_LCD_PS REG32(LCD_PS) ++#define REG_LCD_CLS REG32(LCD_CLS) ++#define REG_LCD_SPL REG32(LCD_SPL) ++#define REG_LCD_REV REG32(LCD_REV) ++#define REG_LCD_CTRL REG32(LCD_CTRL) ++#define REG_LCD_STATE REG32(LCD_STATE) ++#define REG_LCD_IID REG32(LCD_IID) ++#define REG_LCD_DA0 REG32(LCD_DA0) ++#define REG_LCD_SA0 REG32(LCD_SA0) ++#define REG_LCD_FID0 REG32(LCD_FID0) ++#define REG_LCD_CMD0 REG32(LCD_CMD0) ++#define REG_LCD_DA1 REG32(LCD_DA1) ++#define REG_LCD_SA1 REG32(LCD_SA1) ++#define REG_LCD_FID1 REG32(LCD_FID1) ++#define REG_LCD_CMD1 REG32(LCD_CMD1) ++ ++#define LCD_CTRL_BPP_BIT 0 /* Bits Per Pixel */ ++#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT) ++ #define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT) /* 1 bpp */ ++ #define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT) /* 2 bpp */ ++ #define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT) /* 4 bpp */ ++ #define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT) /* 8 bpp */ ++ #define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT) /* 15/16 bpp */ ++ #define LCD_CTRL_BPP_18_24 (5 << LCD_CTRL_BPP_BIT) /* 18/24/32 bpp */ ++ ++#define LCD_CTRL_BST_BIT 28 /* Burst Length Selection */ ++#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT) ++ #define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT) /* 4-word */ ++ #define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT) /* 8-word */ ++ #define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT) /* 16-word */ ++#define LCD_CTRL_RGB565 (0 << 27) /* RGB565 mode */ ++#define LCD_CTRL_RGB555 (1 << 27) /* RGB555 mode */ ++#define LCD_CTRL_OFUP (1 << 26) /* Output FIFO underrun protection enable */ ++#define LCD_CTRL_FRC_BIT 24 /* STN FRC Algorithm Selection */ ++#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT) ++ #define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT) /* 16 grayscale */ ++ #define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT) /* 4 grayscale */ ++ #define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT) /* 2 grayscale */ ++ ++#define CPM_LPCDR (CPM_BASE+0x64) ++#define CPM_CLKGR (CPM_BASE+0x20) ++#define REG_CPM_LPCDR REG32(CPM_LPCDR) ++#define REG_CPM_CLKGR REG32(CPM_CLKGR) ++ ++#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU) ++#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD) ++#define __cpm_set_pixdiv(v) \ ++ (REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT))) ++#define __cpm_set_ldiv(v) \ ++ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT))) ++#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD) ++ + #endif /* !__ASSEMBLY__ */ + #endif /* __JZ4740_H__ */ +diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c +index b14b33e..c2e64d9 100644 +--- a/arch/mips/lib/board.c ++++ b/arch/mips/lib/board.c +@@ -172,6 +172,12 @@ void board_init_f(ulong bootflag) + addr &= ~(4096 - 1); + debug("Top of RAM usable for U-Boot at: %08lx\n", addr); + ++#ifdef CONFIG_LCD ++ /* reserve memory for LCD display (always full pages) */ ++ addr = lcd_setmem (addr); ++ gd->fb_base = addr; ++#endif /* CONFIG_LCD */ ++ + /* Reserve memory for U-Boot code, data & bss + * round down to next 16 kB limit + */ +diff --git a/common/lcd.c b/common/lcd.c +index b6be800..af1281a 100644 +--- a/common/lcd.c ++++ b/common/lcd.c +@@ -263,6 +263,13 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count) + lcd_color_fg : lcd_color_bg; + bits <<= 1; + } ++#elif LCD_BPP == LCD_COLOR32 ++ uint *m = (uint *)d; ++ for (c=0; c<32; ++c) { ++ *m++ = (bits & 0x80) ? ++ lcd_color_fg : lcd_color_bg; ++ bits <<= 1; ++ } + #endif + } + #if LCD_BPP == LCD_MONOCHROME +@@ -509,7 +516,7 @@ static inline ushort *configuration_get_cmap(void) + return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); + #elif defined(CONFIG_ATMEL_LCD) + return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); +-#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) ++#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) && !defined(CONFIG_VIDEO_GPM940B0) + return panel_info.cmap; + #else + #if defined(CONFIG_LCD_LOGO) +diff --git a/drivers/video/Makefile b/drivers/video/Makefile +index ebb6da8..03625bc 100644 +--- a/drivers/video/Makefile ++++ b/drivers/video/Makefile +@@ -50,6 +50,7 @@ COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o + COBJS-$(CONFIG_VIDEO_SM501) += sm501.o + COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o + COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o ++COBJS-$(CONFIG_VIDEO_GPM940B0) += nanonote_gpm940b0.o + + COBJS := $(sort $(COBJS-y)) + SRCS := $(COBJS:.o=.c) +diff --git a/drivers/video/nanonote_gpm940b0.c b/drivers/video/nanonote_gpm940b0.c +new file mode 100644 +index 0000000..11efb72 +--- /dev/null ++++ b/drivers/video/nanonote_gpm940b0.c +@@ -0,0 +1,400 @@ ++/* ++ * JzRISC lcd controller ++ * ++ * Xiangfu Liu <xiangfu@sharism.cc> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#include <config.h> ++#include <common.h> ++#include <lcd.h> ++ ++#include <asm/io.h> /* virt_to_phys() */ ++#include <asm/jz4740.h> ++ ++#include "nanonote_gpm940b0.h" ++ ++#define align2(n) (n)=((((n)+1)>>1)<<1) ++#define align4(n) (n)=((((n)+3)>>2)<<2) ++#define align8(n) (n)=((((n)+7)>>3)<<3) ++ ++struct jzfb_info { ++ unsigned int cfg; /* panel mode and pin usage etc. */ ++ unsigned int w; ++ unsigned int h; ++ unsigned int bpp; /* bit per pixel */ ++ unsigned int fclk; /* frame clk */ ++ unsigned int hsw; /* hsync width, in pclk */ ++ unsigned int vsw; /* vsync width, in line count */ ++ unsigned int elw; /* end of line, in pclk */ ++ unsigned int blw; /* begin of line, in pclk */ ++ unsigned int efw; /* end of frame, in line count */ ++ unsigned int bfw; /* begin of frame, in line count */ ++}; ++ ++static struct jzfb_info jzfb = { ++ MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N, ++ 320, 240, 32, 70, 1, 1, 273, 140, 1, 20 ++}; ++ ++vidinfo_t panel_info = { ++ 320, 240, LCD_BPP, ++}; ++ ++void *lcd_base; ++void *lcd_console_address; ++int lcd_line_length; ++int lcd_color_fg; ++int lcd_color_bg; ++short console_col; ++short console_row; ++ ++static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid) ++{ ++ u_long palette_mem_size; ++ struct jz_fb_info *fbi = &vid->jz_fb; ++ int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8; ++ ++ fbi->screen = (u_long)lcdbase; ++ fbi->palette_size = 256; ++ palette_mem_size = fbi->palette_size * sizeof(u16); ++ ++ debug("jz_lcd.c palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); ++ /* locate palette and descs at end of page following fb */ ++ fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size; ++ ++ return 0; ++} ++ ++static void jz_lcd_desc_init(vidinfo_t *vid) ++{ ++ struct jz_fb_info * fbi; ++ fbi = &vid->jz_fb; ++ fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 3*16); ++ fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 2*16); ++ fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 1*16); ++ ++ #define BYTES_PER_PANEL (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8) ++ ++ /* populate descriptors */ ++ fbi->dmadesc_fblow->fdadr = virt_to_phys(fbi->dmadesc_fblow); ++ fbi->dmadesc_fblow->fsadr = virt_to_phys((void *)(fbi->screen + BYTES_PER_PANEL)); ++ fbi->dmadesc_fblow->fidr = 0; ++ fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL / 4 ; ++ ++ fbi->fdadr1 = virt_to_phys(fbi->dmadesc_fblow); /* only used in dual-panel mode */ ++ ++ fbi->dmadesc_fbhigh->fsadr = virt_to_phys((void *)fbi->screen); ++ fbi->dmadesc_fbhigh->fidr = 0; ++ fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL / 4; /* length in word */ ++ ++ fbi->dmadesc_palette->fsadr = virt_to_phys((void *)fbi->palette); ++ fbi->dmadesc_palette->fidr = 0; ++ fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2)/4 | (1<<28); ++ ++ if(NBITS(vid->vl_bpix) < 12) { ++ /* assume any mode with <12 bpp is palette driven */ ++ fbi->dmadesc_palette->fdadr = virt_to_phys(fbi->dmadesc_fbhigh); ++ fbi->dmadesc_fbhigh->fdadr = virt_to_phys(fbi->dmadesc_palette); ++ /* flips back and forth between pal and fbhigh */ ++ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_palette); ++ } else { ++ /* palette shouldn't be loaded in true-color mode */ ++ fbi->dmadesc_fbhigh->fdadr = virt_to_phys((void *)fbi->dmadesc_fbhigh); ++ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_fbhigh); /* no pal just fbhigh */ ++ } ++} ++ ++static int jz_lcd_hw_init(vidinfo_t *vid) ++{ ++ struct jz_fb_info *fbi = &vid->jz_fb; ++ unsigned int val = 0; ++ unsigned int pclk; ++ unsigned int stnH; ++ int pll_div; ++ ++ /* Setting Control register */ ++ switch (jzfb.bpp) { ++ case 1: ++ val |= LCD_CTRL_BPP_1; ++ break; ++ case 2: ++ val |= LCD_CTRL_BPP_2; ++ break; ++ case 4: ++ val |= LCD_CTRL_BPP_4; ++ break; ++ case 8: ++ val |= LCD_CTRL_BPP_8; ++ break; ++ case 15: ++ val |= LCD_CTRL_RGB555; ++ case 16: ++ val |= LCD_CTRL_BPP_16; ++ break; ++ case 17 ... 32: ++ val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */ ++ break; ++ ++ default: ++ printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp); ++ val |= LCD_CTRL_BPP_16; ++ break; ++ } ++ ++ switch (jzfb.cfg & MODE_MASK) { ++ case MODE_STN_MONO_DUAL: ++ case MODE_STN_COLOR_DUAL: ++ case MODE_STN_MONO_SINGLE: ++ case MODE_STN_COLOR_SINGLE: ++ switch (jzfb.bpp) { ++ case 1: ++ /* val |= LCD_CTRL_PEDN; */ ++ case 2: ++ val |= LCD_CTRL_FRC_2; ++ break; ++ case 4: ++ val |= LCD_CTRL_FRC_4; ++ break; ++ case 8: ++ default: ++ val |= LCD_CTRL_FRC_16; ++ break; ++ } ++ break; ++ } ++ ++ val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */ ++ val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */ ++ ++ switch (jzfb.cfg & MODE_MASK) { ++ case MODE_STN_MONO_DUAL: ++ case MODE_STN_COLOR_DUAL: ++ case MODE_STN_MONO_SINGLE: ++ case MODE_STN_COLOR_SINGLE: ++ switch (jzfb.cfg & STN_DAT_PINMASK) { ++ case STN_DAT_PIN1: ++ /* Do not adjust the hori-param value. */ ++ break; ++ case STN_DAT_PIN2: ++ align2(jzfb.hsw); ++ align2(jzfb.elw); ++ align2(jzfb.blw); ++ break; ++ case STN_DAT_PIN4: ++ align4(jzfb.hsw); ++ align4(jzfb.elw); ++ align4(jzfb.blw); ++ break; ++ case STN_DAT_PIN8: ++ align8(jzfb.hsw); ++ align8(jzfb.elw); ++ align8(jzfb.blw); ++ break; ++ } ++ break; ++ } ++ ++ REG_LCD_CTRL = val; ++ ++ switch (jzfb.cfg & MODE_MASK) { ++ case MODE_STN_MONO_DUAL: ++ case MODE_STN_COLOR_DUAL: ++ case MODE_STN_MONO_SINGLE: ++ case MODE_STN_COLOR_SINGLE: ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL)) ++ stnH = jzfb.h >> 1; ++ else ++ stnH = jzfb.h; ++ ++ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw; ++ REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw); ++ ++ /* Screen setting */ ++ REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw); ++ REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w); ++ REG_LCD_DAV = (0 << 16) | (stnH); ++ ++ /* AC BIAs signal */ ++ REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw); ++ ++ break; ++ ++ case MODE_TFT_GEN: ++ case MODE_TFT_SHARP: ++ case MODE_TFT_CASIO: ++ case MODE_TFT_SAMSUNG: ++ case MODE_8BIT_SERIAL_TFT: ++ case MODE_TFT_18BIT: ++ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw; ++ REG_LCD_HSYNC = (0 << 16) | jzfb.hsw; ++ REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h); ++ REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w ); ++ REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \ ++ | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw); ++ break; ++ } ++ ++ switch (jzfb.cfg & MODE_MASK) { ++ case MODE_TFT_SAMSUNG: ++ { ++ unsigned int total, tp_s, tp_e, ckv_s, ckv_e; ++ unsigned int rev_s, rev_e, inv_s, inv_e; ++ ++ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) * ++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */ ++ ++ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw; ++ tp_s = jzfb.blw + jzfb.w + 1; ++ tp_e = tp_s + 1; ++ ckv_s = tp_s - pclk/(1000000000/4100); ++ ckv_e = tp_s + total; ++ rev_s = tp_s - 11; /* -11.5 clk */ ++ rev_e = rev_s + total; ++ inv_s = tp_s; ++ inv_e = inv_s + total; ++ REG_LCD_CLS = (tp_s << 16) | tp_e; ++ REG_LCD_PS = (ckv_s << 16) | ckv_e; ++ REG_LCD_SPL = (rev_s << 16) | rev_e; ++ REG_LCD_REV = (inv_s << 16) | inv_e; ++ jzfb.cfg |= STFT_REVHI | STFT_SPLHI; ++ break; ++ } ++ case MODE_TFT_SHARP: ++ { ++ unsigned int total, cls_s, cls_e, ps_s, ps_e; ++ unsigned int spl_s, spl_e, rev_s, rev_e; ++ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw; ++ spl_s = 1; ++ spl_e = spl_s + 1; ++ cls_s = 0; ++ cls_e = total - 60; /* > 4us (pclk = 80ns) */ ++ ps_s = cls_s; ++ ps_e = cls_e; ++ rev_s = total - 40; /* > 3us (pclk = 80ns) */ ++ rev_e = rev_s + total; ++ jzfb.cfg |= STFT_PSHI; ++ REG_LCD_SPL = (spl_s << 16) | spl_e; ++ REG_LCD_CLS = (cls_s << 16) | cls_e; ++ REG_LCD_PS = (ps_s << 16) | ps_e; ++ REG_LCD_REV = (rev_s << 16) | rev_e; ++ break; ++ } ++ case MODE_TFT_CASIO: ++ break; ++ } ++ ++ /* Configure the LCD panel */ ++ REG_LCD_CFG = jzfb.cfg; ++ ++ /* Timing setting */ ++ __cpm_stop_lcd(); ++ ++ val = jzfb.fclk; /* frame clk */ ++ if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) { ++ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) * ++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */ ++ } else { ++ /* serial mode: Hsync period = 3*Width_Pixel */ ++ pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) * ++ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */ ++ } ++ ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL)) ++ pclk = (pclk * 3); ++ ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL)) ++ pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4); ++ ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL)) ++ pclk >>= 1; ++ ++ pll_div = (REG_CPM_CPCCR & CPM_CPCCR_PCS); /* clock source,0:pllout/2 1: pllout */ ++ pll_div = pll_div ? 1 : 2; ++ val = (__cpm_get_pllout() / pll_div) / pclk; ++ val--; ++ if (val > 0x1ff) { ++ printf("CPM_LPCDR too large, set it to 0x1ff\n"); ++ val = 0x1ff; ++ } ++ __cpm_set_pixdiv(val); ++ ++ val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */ ++ if (val > 150000000) { ++ printf("Warning: LCDClock=%d\n, LCDClock must less or equal to 150MHz.\n", val); ++ printf("Change LCDClock to 150MHz\n"); ++ val = 150000000; ++ } ++ val = (__cpm_get_pllout() / pll_div) / val; ++ val--; ++ if (val > 0x1f) { ++ printf("CPM_CPCCR.LDIV too large, set it to 0x1f\n"); ++ val = 0x1f; ++ } ++ __cpm_set_ldiv( val ); ++ REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */ ++ ++ __cpm_start_lcd(); ++ udelay(1000); ++ ++ REG_LCD_DA0 = fbi->fdadr0; /* frame descripter*/ ++ ++ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) || ++ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL)) ++ REG_LCD_DA1 = fbi->fdadr1; /* frame descripter*/ ++ ++ return 0; ++} ++ ++void lcd_ctrl_init (void *lcdbase) ++{ ++ __lcd_display_pin_init(); ++ __lcd_display_on() ; ++ ++ jz_lcd_init_mem(lcdbase, &panel_info); ++ jz_lcd_desc_init(&panel_info); ++ jz_lcd_hw_init(&panel_info); ++ ++} ++ ++/* ++ * Before enabled lcd controller, lcd registers should be configured correctly. ++ */ ++void lcd_enable (void) ++{ ++ REG_LCD_CTRL &= ~(1<<4); /* LCDCTRL.DIS */ ++ REG_LCD_CTRL |= 1<<3; /* LCDCTRL.ENA*/ ++} ++ ++void lcd_disable (void) ++{ ++ REG_LCD_CTRL |= (1<<4); ++} ++ ++void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue) ++{ ++} ++ ++void lcd_initcolregs (void) ++{ ++} +diff --git a/drivers/video/nanonote_gpm940b0.h b/drivers/video/nanonote_gpm940b0.h +new file mode 100644 +index 0000000..efe491e +--- /dev/null ++++ b/drivers/video/nanonote_gpm940b0.h +@@ -0,0 +1,135 @@ ++/* ++ * JzRISC lcd controller ++ * ++ * Xiangfu Liu <xiangfu@sharism.cc> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#ifndef __QI_LB60_GPM940B0_H__ ++#define __QI_LB60_GPM940B0_H__ ++ ++struct lcd_desc{ ++ unsigned int next_desc; /* LCDDAx */ ++ unsigned int databuf; /* LCDSAx */ ++ unsigned int frame_id; /* LCDFIDx */ ++ unsigned int cmd; /* LCDCMDx */ ++}; ++ ++#define MODE_MASK 0x0f ++#define MODE_TFT_GEN 0x00 ++#define MODE_TFT_SHARP 0x01 ++#define MODE_TFT_CASIO 0x02 ++#define MODE_TFT_SAMSUNG 0x03 ++#define MODE_CCIR656_NONINT 0x04 ++#define MODE_CCIR656_INT 0x05 ++#define MODE_STN_COLOR_SINGLE 0x08 ++#define MODE_STN_MONO_SINGLE 0x09 ++#define MODE_STN_COLOR_DUAL 0x0a ++#define MODE_STN_MONO_DUAL 0x0b ++#define MODE_8BIT_SERIAL_TFT 0x0c ++ ++#define MODE_TFT_18BIT (1<<7) ++ ++#define STN_DAT_PIN1 (0x00 << 4) ++#define STN_DAT_PIN2 (0x01 << 4) ++#define STN_DAT_PIN4 (0x02 << 4) ++#define STN_DAT_PIN8 (0x03 << 4) ++#define STN_DAT_PINMASK STN_DAT_PIN8 ++ ++#define STFT_PSHI (1 << 15) ++#define STFT_CLSHI (1 << 14) ++#define STFT_SPLHI (1 << 13) ++#define STFT_REVHI (1 << 12) ++ ++#define SYNC_MASTER (0 << 16) ++#define SYNC_SLAVE (1 << 16) ++ ++#define DE_P (0 << 9) ++#define DE_N (1 << 9) ++ ++#define PCLK_P (0 << 10) ++#define PCLK_N (1 << 10) ++ ++#define HSYNC_P (0 << 11) ++#define HSYNC_N (1 << 11) ++ ++#define VSYNC_P (0 << 8) ++#define VSYNC_N (1 << 8) ++ ++#define DATA_NORMAL (0 << 17) ++#define DATA_INVERSE (1 << 17) ++ ++ ++/* Jz LCDFB supported I/O controls. */ ++#define FBIOSETBACKLIGHT 0x4688 ++#define FBIODISPON 0x4689 ++#define FBIODISPOFF 0x468a ++#define FBIORESET 0x468b ++#define FBIOPRINT_REG 0x468c ++ ++/* ++ * LCD panel specific definition ++ */ ++#define MODE (0xc9) /* 8bit serial RGB */ ++ ++#define __spi_write_reg1(reg, val) \ ++do { \ ++ unsigned char no; \ ++ unsigned short value; \ ++ unsigned char a=reg; \ ++ unsigned char b=val; \ ++ __gpio_set_pin(SPEN); \ ++ __gpio_set_pin(SPCK); \ ++ __gpio_clear_pin(SPDA); \ ++ __gpio_clear_pin(SPEN); \ ++ value=((a<<8)|(b&0xFF)); \ ++ for(no=0;no<16;no++) \ ++ { \ ++ __gpio_clear_pin(SPCK); \ ++ if((value&0x8000)==0x8000) \ ++ __gpio_set_pin(SPDA); \ ++ else \ ++ __gpio_clear_pin(SPDA); \ ++ __gpio_set_pin(SPCK); \ ++ value=(value<<1); \ ++ } \ ++ __gpio_set_pin(SPEN); \ ++} while (0) ++ ++#define __lcd_display_pin_init() \ ++do { \ ++ __cpm_start_tcu(); \ ++ __gpio_as_output(SPEN); /* use SPDA */ \ ++ __gpio_as_output(SPCK); /* use SPCK */ \ ++ __gpio_as_output(SPDA); /* use SPDA */ \ ++} while (0) ++ ++#define __lcd_display_on() \ ++do { \ ++ __spi_write_reg1(0x05, 0x1e); \ ++ __spi_write_reg1(0x05, 0x5e); \ ++ __spi_write_reg1(0x07, 0x8d); \ ++ __spi_write_reg1(0x13, 0x01); \ ++ __spi_write_reg1(0x05, 0x5f); \ ++} while (0) ++ ++#define __lcd_display_off() \ ++do { \ ++ __spi_write_reg1(0x05, 0x5e); \ ++} while (0) ++ ++#endif /* __QI_LB60_GPM940B0_H__ */ +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index 52b370c..d3e78ad 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -32,6 +32,13 @@ + * Miscellaneous configurable options + */ + #define CONFIG_NANONOTE ++ ++#define CONFIG_LCD ++#define CONFIG_SYS_WHITE_ON_BLACK ++#define LCD_BPP LCD_COLOR32 ++#define CONFIG_VIDEO_GPM940B0 ++ ++ + #define CONFIG_JZ4740_MMC + #define CONFIG_MMC 1 + #define CONFIG_FAT 1 +diff --git a/include/lcd.h b/include/lcd.h +index 42070d7..6de5482 100644 +--- a/include/lcd.h ++++ b/include/lcd.h +@@ -263,8 +263,44 @@ typedef struct vidinfo { + + void init_panel_info(vidinfo_t *vid); + +-#else ++#elif defined(CONFIG_JZSOC) ++/* ++ * LCD controller stucture for JZSOC: JZ4740 ++ */ ++struct jz_fb_dma_descriptor { ++ u_long fdadr; /* Frame descriptor address register */ ++ u_long fsadr; /* Frame source address register */ ++ u_long fidr; /* Frame ID register */ ++ u_long ldcmd; /* Command register */ ++}; ++ ++/* ++ * Jz LCD info ++ */ ++struct jz_fb_info { ++ ++ u_long fdadr0; /* physical address of frame/palette descriptor */ ++ u_long fdadr1; /* physical address of frame descriptor */ ++ ++ /* DMA descriptors */ ++ struct jz_fb_dma_descriptor * dmadesc_fblow; ++ struct jz_fb_dma_descriptor * dmadesc_fbhigh; ++ struct jz_fb_dma_descriptor * dmadesc_palette; ++ u_long screen; /* address of frame buffer */ ++ u_long palette; /* address of palette memory */ ++ u_int palette_size; ++}; ++typedef struct vidinfo { ++ ushort vl_col; /* Number of columns (i.e. 640) */ ++ ushort vl_row; /* Number of rows (i.e. 480) */ ++ u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8 */ ++ ++ struct jz_fb_info jz_fb; ++} vidinfo_t; ++ ++extern vidinfo_t panel_info; + ++#else + typedef struct vidinfo { + ushort vl_col; /* Number of columns (i.e. 160) */ + ushort vl_row; /* Number of rows (i.e. 100) */ +@@ -318,6 +354,7 @@ void lcd_show_board_info(void); + #define LCD_COLOR4 2 + #define LCD_COLOR8 3 + #define LCD_COLOR16 4 ++#define LCD_COLOR32 5 + + /*----------------------------------------------------------------------*/ + #if defined(CONFIG_LCD_INFO_BELOW_LOGO) +@@ -369,7 +406,7 @@ void lcd_show_board_info(void); + # define CONSOLE_COLOR_GREY 14 + # define CONSOLE_COLOR_WHITE 15 /* Must remain last / highest */ + +-#else ++#elif LCD_BPP == LCD_COLOR16 + + /* + * 16bpp color definitions +@@ -377,6 +414,15 @@ void lcd_show_board_info(void); + # define CONSOLE_COLOR_BLACK 0x0000 + # define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */ + ++#elif LCD_BPP == LCD_COLOR32 ++/* ++ * 18,24,32 bpp color definitions ++ */ ++# define CONSOLE_COLOR_BLACK 0x00000000 ++# define CONSOLE_COLOR_WHITE 0xffffffff /* Must remain last / highest */ ++ ++#else ++ + #endif /* color definitions */ + + /************************************************************************/ +@@ -406,7 +452,7 @@ void lcd_show_board_info(void); + #if LCD_BPP == LCD_MONOCHROME + # define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \ + (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7) +-#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) ++#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || (LCD_BPP == LCD_COLOR32) + # define COLOR_MASK(c) (c) + #else + # error Unsupported LCD BPP. +-- +1.7.9.5 + diff --git a/package/boot/uboot-xburst/patches/0006-enable-silent-console.patch b/package/boot/uboot-xburst/patches/0006-enable-silent-console.patch new file mode 100644 index 0000000..ebd6a6a --- /dev/null +++ b/package/boot/uboot-xburst/patches/0006-enable-silent-console.patch @@ -0,0 +1,60 @@ +From 5eb4d4c598f2806bd1b3d1140e917bfead7851ad Mon Sep 17 00:00:00 2001 +From: Xiangfu <xiangfu@openmobilefree.net> +Date: Wed, 10 Oct 2012 23:51:26 +0800 +Subject: [PATCH 6/6] enable silent console + +--- + common/console.c | 16 ++++++++++++++++ + include/configs/qi_lb60.h | 2 ++ + 2 files changed, 18 insertions(+) + +diff --git a/common/console.c b/common/console.c +index 1177f7d..e8a2078 100644 +--- a/common/console.c ++++ b/common/console.c +@@ -685,6 +685,14 @@ done: + + gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ + ++#ifdef CONFIG_SILENT_CONSOLE ++ /* Check one more time the contents of the silent environment ++ * variable, because if the environment is loaded from NAND it was ++ * not available when console_init_f() was called */ ++ if (getenv("silent") != NULL) ++ gd->flags |= GD_FLG_SILENT; ++#endif ++ + stdio_print_current_devices(); + + #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE +@@ -760,6 +768,14 @@ int console_init_r(void) + + gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ + ++#ifdef CONFIG_SILENT_CONSOLE ++ /* Check one more time the contents of the silent environment ++ * variable, because if the environment is loaded from NAND it was ++ * not available when console_init_f() was called */ ++ if (getenv("silent") != NULL) ++ gd->flags |= GD_FLG_SILENT; ++#endif ++ + stdio_print_current_devices(); + + /* Setting environment variables */ +diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h +index d3e78ad..a3534ff 100644 +--- a/include/configs/qi_lb60.h ++++ b/include/configs/qi_lb60.h +@@ -102,6 +102,8 @@ + #define CONFIG_SYS_NO_FLASH + #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */ + ++#define CONFIG_SILENT_CONSOLE 1 /* Enable silent console */ ++ + /* + * Command line configuration + */ +-- +1.7.9.5 + diff --git a/package/boot/yamonenv/.svn/entries b/package/boot/yamonenv/.svn/entries new file mode 100644 index 0000000..3b96508 --- /dev/null +++ b/package/boot/yamonenv/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/yamonenv +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +6c2b050e03080e465cf30e3b809c68cd +2012-10-16T13:44:25.630275Z +33781 +blogic +has-props + + + + + + + + + + + + + + + + + + + + +897 + diff --git a/package/boot/yamonenv/.svn/prop-base/Makefile.svn-base b/package/boot/yamonenv/.svn/prop-base/Makefile.svn-base new file mode 100644 index 0000000..8e522ae --- /dev/null +++ b/package/boot/yamonenv/.svn/prop-base/Makefile.svn-base @@ -0,0 +1,9 @@ +K 13 +svn:copyright +V 30 +Copyright (C) 2006 OpenWrt.org +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/boot/yamonenv/.svn/text-base/Makefile.svn-base b/package/boot/yamonenv/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..e1d2a4b --- /dev/null +++ b/package/boot/yamonenv/.svn/text-base/Makefile.svn-base @@ -0,0 +1,39 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=yamonenv +PKG_VERSION:=20051022 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)_gruen.4g__$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/ +PKG_MD5SUM:=a3e4f24155aa3ba5aa502bc63fdaa6ad + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/yamonenv + SECTION:=utils + CATEGORY:=Utilities + DEPENDS:=@TARGET_au1000 + TITLE:=YAMON configuration utility + URL:=http://meshcube.org/nylon/stable/sources/ + MAINTAINER:=Florian Fainelli <florian@openwrt.org> +endef + +define Build/Configure +endef + +define Package/yamonenv/install + $(INSTALL_DIR) $(1)/usr/sbin + $(CP) $(PKG_BUILD_DIR)/src/$(PKG_NAME) $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,yamonenv)) diff --git a/package/boot/yamonenv/Makefile b/package/boot/yamonenv/Makefile new file mode 100644 index 0000000..e1d2a4b --- /dev/null +++ b/package/boot/yamonenv/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=yamonenv +PKG_VERSION:=20051022 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)_gruen.4g__$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/ +PKG_MD5SUM:=a3e4f24155aa3ba5aa502bc63fdaa6ad + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/yamonenv + SECTION:=utils + CATEGORY:=Utilities + DEPENDS:=@TARGET_au1000 + TITLE:=YAMON configuration utility + URL:=http://meshcube.org/nylon/stable/sources/ + MAINTAINER:=Florian Fainelli <florian@openwrt.org> +endef + +define Build/Configure +endef + +define Package/yamonenv/install + $(INSTALL_DIR) $(1)/usr/sbin + $(CP) $(PKG_BUILD_DIR)/src/$(PKG_NAME) $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,yamonenv)) diff --git a/package/boot/yamonenv/patches/.svn/entries b/package/boot/yamonenv/patches/.svn/entries new file mode 100644 index 0000000..fe61910 --- /dev/null +++ b/package/boot/yamonenv/patches/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/boot/yamonenv/patches +svn://svn.openwrt.org/openwrt + + + +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +001-yamonenv_mtd_partition.patch +file + + + + +2013-03-17T12:13:21.000000Z +a53d173ddfcc4d3ff0b51638431afcff +2012-10-16T13:44:25.630275Z +33781 +blogic + + + + + + + + + + + + + + + + + + + + + +230 + diff --git a/package/boot/yamonenv/patches/.svn/text-base/001-yamonenv_mtd_partition.patch.svn-base b/package/boot/yamonenv/patches/.svn/text-base/001-yamonenv_mtd_partition.patch.svn-base new file mode 100644 index 0000000..e1def28 --- /dev/null +++ b/package/boot/yamonenv/patches/.svn/text-base/001-yamonenv_mtd_partition.patch.svn-base @@ -0,0 +1,11 @@ +--- a/src/yamonenv.c ++++ b/src/yamonenv.c +@@ -12,7 +12,7 @@ + #include <fcntl.h> + #include <unistd.h> + +-#define DEFAULT_YAMON_ENV_FILE "/dev/mtd/3" ++#define DEFAULT_YAMON_ENV_FILE "/dev/mtd3" + + + // control byte definitions: diff --git a/package/boot/yamonenv/patches/001-yamonenv_mtd_partition.patch b/package/boot/yamonenv/patches/001-yamonenv_mtd_partition.patch new file mode 100644 index 0000000..e1def28 --- /dev/null +++ b/package/boot/yamonenv/patches/001-yamonenv_mtd_partition.patch @@ -0,0 +1,11 @@ +--- a/src/yamonenv.c ++++ b/src/yamonenv.c +@@ -12,7 +12,7 @@ + #include <fcntl.h> + #include <unistd.h> + +-#define DEFAULT_YAMON_ENV_FILE "/dev/mtd/3" ++#define DEFAULT_YAMON_ENV_FILE "/dev/mtd3" + + + // control byte definitions: |