diff options
Diffstat (limited to 'package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch')
-rw-r--r-- | package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch | 9496 |
1 files changed, 0 insertions, 9496 deletions
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 deleted file mode 100644 index 2582c16a94..0000000000 --- a/package/boot/uboot-lantiq/patches/0023-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch +++ /dev/null @@ -1,9496 +0,0 @@ -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; -+} |