1 From 11553b0de8992ded6240d034bd49f561d17bea53 Mon Sep 17 00:00:00 2001
2 From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
3 Date: Thu, 13 Jun 2013 01:18:02 +0200
4 Subject: MIPS: add support for Lantiq XWAY SoCs
6 Signed-off-by: Luka Perkov <luka@openwrt.org>
7 Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
9 diff --git a/.gitignore b/.gitignore
10 index a39bd54..7abdc37 100644
19 +/u-boot.ltq.lzma.norspl
20 +/u-boot.ltq.lzo.norspl
27 diff --git a/Makefile b/Makefile
28 index 6ee9a3c..73ec67d 100644
31 @@ -435,6 +435,12 @@ $(obj)u-boot.bin: $(obj)u-boot
32 $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
35 +$(obj)u-boot.bin.lzma: $(obj)u-boot.bin
36 + cat $< | lzma -9 -f - > $@
38 +$(obj)u-boot.bin.lzo: $(obj)u-boot.bin
39 + cat $< | lzop -9 -f - > $@
41 $(obj)u-boot.ldr: $(obj)u-boot
43 $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
44 @@ -454,13 +460,23 @@ ifndef CONFIG_SYS_UBOOT_START
45 CONFIG_SYS_UBOOT_START := 0
48 -$(obj)u-boot.img: $(obj)u-boot.bin
49 - $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
50 +define GEN_UBOOT_IMAGE
51 + $(obj)tools/mkimage -A $(ARCH) -T firmware -C $(1) \
52 -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \
53 -e $(CONFIG_SYS_UBOOT_START) \
54 -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
55 sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
59 +$(obj)u-boot.img: $(obj)u-boot.bin
60 + $(call GEN_UBOOT_IMAGE,none)
62 +$(obj)u-boot.lzma.img: $(obj)u-boot.bin.lzma
63 + $(call GEN_UBOOT_IMAGE,lzma)
65 +$(obj)u-boot.lzo.img: $(obj)u-boot.bin.lzo
66 + $(call GEN_UBOOT_IMAGE,lzo)
68 $(obj)u-boot.imx: $(obj)u-boot.bin depend
69 $(MAKE) -C $(SRCTREE)/arch/arm/imx-common $(OBJTREE)/u-boot.imx
70 @@ -571,6 +587,27 @@ $(obj)u-boot-img-spl-at-end.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
71 conv=notrunc 2>/dev/null
72 cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@
74 +$(obj)u-boot.ltq.sfspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
75 + $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
76 + -s $(obj)spl/u-boot-spl.bin -u $< -o $@
78 +$(obj)u-boot.ltq.lzo.sfspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
79 + $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
80 + -s $(obj)spl/u-boot-spl.bin -u $< -o $@
82 +$(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
83 + $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
84 + -s $(obj)spl/u-boot-spl.bin -u $< -o $@
86 +$(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
87 + cat $(obj)spl/u-boot-spl.bin $< > $@
89 +$(obj)u-boot.ltq.lzo.norspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
90 + cat $(obj)spl/u-boot-spl.bin $< > $@
92 +$(obj)u-boot.ltq.lzma.norspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
93 + cat $(obj)spl/u-boot-spl.bin $< > $@
95 ifeq ($(CONFIG_SANDBOX),y)
97 cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
98 diff --git a/README b/README
99 index 09662a4..1acceff 100644
102 @@ -468,6 +468,11 @@ The following options need to be configured:
104 CONF_CM_CACHABLE_ACCELERATED
106 + CONFIG_SYS_MIPS_CACHE_EXT_INIT
108 + Enable this to use extended cache initialization for recent
111 CONFIG_SYS_XWAY_EBU_BOOTCFG
113 Special option for Lantiq XWAY SoCs for booting from NOR flash.
114 diff --git a/arch/mips/config.mk b/arch/mips/config.mk
115 index c3f81b5..84b6e59 100644
116 --- a/arch/mips/config.mk
117 +++ b/arch/mips/config.mk
118 @@ -45,9 +45,13 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__
119 # On the other hand, we want PIC in the U-Boot code to relocate it from ROM
120 # to RAM. $28 is always used as gp.
122 -PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS)
123 +PF_ABICALLS ?= -mabicalls
127 +PLATFORM_CPPFLAGS += -G 0 $(PF_ABICALLS) $(PF_PIC) $(ENDIANNESS)
128 PLATFORM_CPPFLAGS += -msoft-float
129 PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS)
130 PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
131 -LDFLAGS_FINAL += --gc-sections -pie
132 +LDFLAGS_FINAL += --gc-sections $(PF_PIE)
133 OBJCFLAGS += --remove-section=.dynsym
134 diff --git a/arch/mips/cpu/mips32/cache.S b/arch/mips/cpu/mips32/cache.S
135 index 12f656c..8620a9d 100644
136 --- a/arch/mips/cpu/mips32/cache.S
137 +++ b/arch/mips/cpu/mips32/cache.S
140 #define MIPS_MAX_CACHE_SIZE 0x10000
142 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
143 +#define INDEX_BASE 0x9fc00000
145 #define INDEX_BASE CKSEG0
148 .macro cache_op op addr
152 LEAF(mips_init_icache)
154 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
155 + mtc0 zero, CP0_ITAGLO
159 /* clear tag to invalidate */
160 PTR_LI t0, INDEX_BASE
162 @@ -90,7 +98,11 @@ LEAF(mips_init_icache)
164 LEAF(mips_init_dcache)
166 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
167 + mtc0 zero, CP0_DTAGLO
172 PTR_LI t0, INDEX_BASE
174 diff --git a/arch/mips/cpu/mips32/danube/Makefile b/arch/mips/cpu/mips32/danube/Makefile
176 index 0000000..98f5f73
178 +++ b/arch/mips/cpu/mips32/danube/Makefile
181 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
183 +# SPDX-License-Identifier: GPL-2.0+
186 +include $(TOPDIR)/config.mk
188 +LIB = $(obj)lib$(SOC).o
190 +COBJS-y += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
191 +SOBJS-y += cgu_init.o mem_init.o
195 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
196 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
200 +$(LIB): $(obj).depend $(OBJS)
201 + $(call cmd_link_o_target, $(OBJS))
203 +#########################################################################
205 +# defines $(obj).depend target
206 +include $(SRCTREE)/rules.mk
208 +sinclude $(obj).depend
210 +#########################################################################
211 diff --git a/arch/mips/cpu/mips32/danube/cgu.c b/arch/mips/cpu/mips32/danube/cgu.c
213 index 0000000..4fd110a
215 +++ b/arch/mips/cpu/mips32/danube/cgu.c
218 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
219 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
221 + * SPDX-License-Identifier: GPL-2.0+
225 +#include <asm/arch/soc.h>
226 +#include <asm/lantiq/clk.h>
227 +#include <asm/lantiq/io.h>
229 +#define LTQ_CGU_SYS_DDR_MASK 0x0003
230 +#define LTQ_CGU_SYS_DDR_SHIFT 0
231 +#define LTQ_CGU_SYS_CPU0_MASK 0x000C
232 +#define LTQ_CGU_SYS_CPU0_SHIFT 2
233 +#define LTQ_CGU_SYS_FPI_MASK 0x0040
234 +#define LTQ_CGU_SYS_FPI_SHIFT 6
236 +struct ltq_cgu_regs {
238 + u32 pll0_cfg; /* PLL0 config */
239 + u32 pll1_cfg; /* PLL1 config */
240 + u32 pll2_cfg; /* PLL2 config */
241 + u32 sys; /* System clock */
242 + u32 update; /* CGU update control */
243 + u32 if_clk; /* Interface clock */
244 + u32 osc_con; /* Update OSC Control */
245 + u32 smd; /* SDRAM Memory Control */
247 + u32 pcm_cr; /* PCM control */
248 + u32 pci_cr; /* PCI clock control */
251 +static struct ltq_cgu_regs *ltq_cgu_regs =
252 + (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
254 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
256 + return (ltq_readl(<q_cgu_regs->sys) & mask) >> shift;
259 +unsigned long ltq_get_io_region_clock(void)
264 + ddr_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_DDR_MASK,
265 + LTQ_CGU_SYS_DDR_SHIFT);
269 + clk = CLOCK_166_MHZ;
272 + clk = CLOCK_133_MHZ;
275 + clk = CLOCK_111_MHZ;
278 + clk = CLOCK_83_MHZ;
288 +unsigned long ltq_get_cpu_clock(void)
293 + cpu0_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU0_MASK,
294 + LTQ_CGU_SYS_CPU0_SHIFT);
296 + switch (cpu0_sel) {
297 + /* Same as PLL0 output (333,33 MHz) */
299 + clk = CLOCK_333_MHZ;
301 + /* 1/1 fixed ratio to DDR clock */
303 + clk = ltq_get_io_region_clock();
305 + /* 1/2 fixed ratio to DDR clock */
307 + clk = ltq_get_io_region_clock() << 1;
317 +unsigned long ltq_get_bus_clock(void)
322 + fpi_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_FPI_MASK,
323 + LTQ_CGU_SYS_FPI_SHIFT);
326 + /* Half the DDR clock */
327 + clk = ltq_get_io_region_clock() >> 1;
329 + /* Same as DDR clock */
330 + clk = ltq_get_io_region_clock();
334 diff --git a/arch/mips/cpu/mips32/danube/cgu_init.S b/arch/mips/cpu/mips32/danube/cgu_init.S
336 index 0000000..e0922f1
338 +++ b/arch/mips/cpu/mips32/danube/cgu_init.S
341 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
342 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
344 + * SPDX-License-Identifier: GPL-2.0+
348 +#include <asm/asm.h>
349 +#include <asm/regdef.h>
350 +#include <asm/addrspace.h>
351 +#include <asm/arch/soc.h>
353 +/* RCU module register */
354 +#define LTQ_RCU_RST_REQ 0x0010
355 +#define LTQ_RCU_RST_STAT 0x0014
356 +#define LTQ_RCU_RST_REQ_VALUE 0x40000008
357 +#define LTQ_RCU_RST_STAT_XTAL_F 0x20000
359 +/* CGU module register */
360 +#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
361 +#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
362 +#define LTQ_CGU_PLL2_CFG 0x000C /* PLL2 config */
363 +#define LTQ_CGU_SYS 0x0010 /* System clock */
365 +/* Valid SYS.CPU0/1 values */
366 +#define LTQ_CGU_SYS_CPU0_SHIFT 2
367 +#define LTQ_CGU_SYS_CPU1_SHIFT 4
368 +#define LTQ_CGU_SYS_CPU_PLL0 0x0
369 +#define LTQ_CGU_SYS_CPU_DDR_EQUAL 0x1
370 +#define LTQ_CGU_SYS_CPU_DDR_TWICE 0x2
372 +/* Valid SYS.DDR values */
373 +#define LTQ_CGU_SYS_DDR_SHIFT 0
374 +#define LTQ_CGU_SYS_DDR_167_MHZ 0x0
375 +#define LTQ_CGU_SYS_DDR_133_MHZ 0x1
376 +#define LTQ_CGU_SYS_DDR_111_MHZ 0x2
377 +#define LTQ_CGU_SYS_DDR_83_MHZ 0x3
379 +/* Valid SYS.FPI values */
380 +#define LTQ_CGU_SYS_FPI_SHIFT 6
381 +#define LTQ_CGU_SYS_FPI_DDR_EQUAL 0x0
382 +#define LTQ_CGU_SYS_FPI_DDR_HALF 0x1
384 +/* Valid SYS.PPE values */
385 +#define LTQ_CGU_SYS_PPE_SHIFT 7
386 +#define LTQ_CGU_SYS_PPE_266_MHZ 0x0
387 +#define LTQ_CGU_SYS_PPE_240_MHZ 0x1
388 +#define LTQ_CGU_SYS_PPE_222_MHZ 0x2
389 +#define LTQ_CGU_SYS_PPE_133_MHZ 0x3
391 +#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167)
392 +#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_TWICE
393 +#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_167_MHZ
394 +#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
395 +#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_266_MHZ
396 +#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111)
397 +#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_EQUAL
398 +#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_111_MHZ
399 +#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
400 +#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_133_MHZ
402 +#error "Invalid system clock configuration!"
405 +/* Build register values */
406 +#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_PPE_CONFIG << \
407 + LTQ_CGU_SYS_PPE_SHIFT) | \
408 + (LTQ_CGU_SYS_FPI_CONFIG << \
409 + LTQ_CGU_SYS_FPI_SHIFT) | \
410 + (LTQ_CGU_SYS_CPU_CONFIG << \
411 + LTQ_CGU_SYS_CPU1_SHIFT) | \
412 + (LTQ_CGU_SYS_CPU_CONFIG << \
413 + LTQ_CGU_SYS_CPU0_SHIFT) | \
414 + LTQ_CGU_SYS_DDR_CONFIG)
416 +/* Reset values for PLL registers for usage with 35.328 MHz crystal */
417 +#define PLL0_35MHZ_CONFIG 0x9D861059
418 +#define PLL1_35MHZ_CONFIG 0x1A260CD9
419 +#define PLL2_35MHZ_CONFIG 0x8000f1e5
421 +/* Reset values for PLL registers for usage with 36 MHz crystal */
422 +#define PLL0_36MHZ_CONFIG 0x1000125D
423 +#define PLL1_36MHZ_CONFIG 0x1B1E0C99
424 +#define PLL2_36MHZ_CONFIG 0x8002f2a1
427 + /* Load current CGU register value */
428 + li t0, (LTQ_CGU_BASE | KSEG1)
429 + lw t1, LTQ_CGU_SYS(t0)
431 + /* Load target CGU register values */
432 + li t3, LTQ_CGU_SYS_VALUE
434 + /* Only update registers if values differ */
435 + beq t1, t3, finished
438 + * Check whether the XTAL_F bit in RST_STAT register is set or not.
439 + * This bit is latched in via pin strapping. If bit is set then
440 + * clock source is a 36 MHz crystal. Otherwise a 35.328 MHz crystal.
442 + li t1, (LTQ_RCU_BASE | KSEG1)
443 + lw t2, LTQ_RCU_RST_STAT(t1)
444 + and t2, t2, LTQ_RCU_RST_STAT_XTAL_F
445 + beq t2, LTQ_RCU_RST_STAT_XTAL_F, boot_36mhz
448 + /* Configure PLL for 35.328 MHz */
449 + li t2, PLL0_35MHZ_CONFIG
450 + sw t2, LTQ_CGU_PLL0_CFG(t0)
451 + li t2, PLL1_35MHZ_CONFIG
452 + sw t2, LTQ_CGU_PLL1_CFG(t0)
453 + li t2, PLL2_35MHZ_CONFIG
454 + sw t2, LTQ_CGU_PLL2_CFG(t0)
459 + /* Configure PLL for 36 MHz */
460 + li t2, PLL0_36MHZ_CONFIG
461 + sw t2, LTQ_CGU_PLL0_CFG(t0)
462 + li t2, PLL1_36MHZ_CONFIG
463 + sw t2, LTQ_CGU_PLL1_CFG(t0)
464 + li t2, PLL2_36MHZ_CONFIG
465 + sw t2, LTQ_CGU_PLL2_CFG(t0)
468 + /* Store new clock config */
469 + sw t3, LTQ_CGU_SYS(t0)
471 + /* Perform software reset to activate new clock config */
472 + li t2, LTQ_RCU_RST_REQ_VALUE
473 + sw t2, LTQ_RCU_RST_REQ(t1)
482 diff --git a/arch/mips/cpu/mips32/danube/chipid.c b/arch/mips/cpu/mips32/danube/chipid.c
484 index 0000000..02d9554
486 +++ b/arch/mips/cpu/mips32/danube/chipid.c
489 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
491 + * SPDX-License-Identifier: GPL-2.0+
495 +#include <asm/lantiq/io.h>
496 +#include <asm/lantiq/chipid.h>
497 +#include <asm/arch/soc.h>
499 +#define LTQ_CHIPID_VERSION_SHIFT 28
500 +#define LTQ_CHIPID_VERSION_MASK (0xF << LTQ_CHIPID_VERSION_SHIFT)
501 +#define LTQ_CHIPID_PNUM_SHIFT 12
502 +#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
504 +struct ltq_chipid_regs {
505 + u32 manid; /* Manufacturer identification */
506 + u32 chipid; /* Chip identification */
509 +static struct ltq_chipid_regs *ltq_chipid_regs =
510 + (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
512 +unsigned int ltq_chip_version_get(void)
516 + chipid = ltq_readl(<q_chipid_regs->chipid);
518 + return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
521 +unsigned int ltq_chip_partnum_get(void)
525 + chipid = ltq_readl(<q_chipid_regs->chipid);
527 + return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
530 +const char *ltq_chip_partnum_str(void)
532 + enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
535 + case LTQ_SOC_DANUBE:
537 + case LTQ_SOC_DANUBE_S:
539 + case LTQ_SOC_TWINPASS:
542 + printf("Unknown partnum: %x\n", partnum);
547 diff --git a/arch/mips/cpu/mips32/danube/config.mk b/arch/mips/cpu/mips32/danube/config.mk
549 index 0000000..cee376f
551 +++ b/arch/mips/cpu/mips32/danube/config.mk
554 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
556 +# SPDX-License-Identifier: GPL-2.0+
559 +PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,)
560 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE)
562 +ifdef CONFIG_SPL_BUILD
563 +PF_ABICALLS := -mno-abicalls
566 +USE_PRIVATE_LIBGCC := yes
569 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
571 +ifndef CONFIG_SPL_BUILD
572 +ifdef CONFIG_SYS_BOOT_NORSPL
573 +ALL-y += $(obj)u-boot.ltq.norspl
574 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
575 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
578 diff --git a/arch/mips/cpu/mips32/danube/ebu.c b/arch/mips/cpu/mips32/danube/ebu.c
580 index 0000000..902f6a7
582 +++ b/arch/mips/cpu/mips32/danube/ebu.c
585 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
587 + * SPDX-License-Identifier: GPL-2.0+
591 +#include <asm/arch/soc.h>
592 +#include <asm/lantiq/io.h>
594 +#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4)
595 +#define EBU_ADDRSEL_REGEN (1 << 0)
597 +#define EBU_CON_WRDIS (1 << 31)
598 +#define EBU_CON_AGEN_DEMUX (0x0 << 24)
599 +#define EBU_CON_AGEN_MUX (0x2 << 24)
600 +#define EBU_CON_SETUP (1 << 22)
601 +#define EBU_CON_WAIT_DIS (0x0 << 20)
602 +#define EBU_CON_WAIT_ASYNC (0x1 << 20)
603 +#define EBU_CON_WAIT_SYNC (0x2 << 20)
604 +#define EBU_CON_WINV (1 << 19)
605 +#define EBU_CON_PW_8BIT (0x0 << 16)
606 +#define EBU_CON_PW_16BIT (0x1 << 16)
607 +#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14)
608 +#define EBU_CON_BCGEN_CS (0x0 << 12)
609 +#define EBU_CON_BCGEN_INTEL (0x1 << 12)
610 +#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12)
611 +#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8)
612 +#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6)
613 +#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4)
614 +#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2)
615 +#define EBU_CON_CMULT_1 0x0
616 +#define EBU_CON_CMULT_4 0x1
617 +#define EBU_CON_CMULT_8 0x2
618 +#define EBU_CON_CMULT_16 0x3
620 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
621 +#define ebu_region0_enable 1
623 +#define ebu_region0_enable 0
626 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
627 +#define ebu_region1_enable 1
629 +#define ebu_region1_enable 0
632 +struct ltq_ebu_regs {
644 +static struct ltq_ebu_regs *ltq_ebu_regs =
645 + (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
647 +void ltq_ebu_init(void)
649 + if (ebu_region0_enable) {
651 + * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
652 + * region control. This supports up to 32 MiB NOR flash in
655 + ltq_writel(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
656 + EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
658 + ltq_writel(<q_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
659 + EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
660 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
661 + EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
662 + EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
665 + ltq_clrbits(<q_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
667 + if (ebu_region1_enable) {
669 + * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
670 + * region control. This supports NAND flash in bank 1.
672 + ltq_writel(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
673 + EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
675 + ltq_writel(<q_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
676 + EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
677 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
678 + EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
679 + EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
682 + ltq_clrbits(<q_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
685 +void *flash_swap_addr(unsigned long addr)
687 + return (void *)(addr ^ 2);
689 diff --git a/arch/mips/cpu/mips32/danube/mem.c b/arch/mips/cpu/mips32/danube/mem.c
691 index 0000000..be1922c
693 +++ b/arch/mips/cpu/mips32/danube/mem.c
696 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
698 + * SPDX-License-Identifier: GPL-2.0+
702 +#include <asm/arch/soc.h>
703 +#include <asm/lantiq/io.h>
705 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
707 +static inline u32 ltq_mc_dc_read(u32 index)
709 + return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
712 +phys_size_t initdram(int board_type)
714 + u32 col, row, dc04, dc19, dc20;
716 + dc04 = ltq_mc_dc_read(4);
717 + dc19 = ltq_mc_dc_read(19);
718 + dc20 = ltq_mc_dc_read(20);
720 + row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
721 + col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
723 + return (1 << (row + col)) * 4 * 2;
725 diff --git a/arch/mips/cpu/mips32/danube/mem_init.S b/arch/mips/cpu/mips32/danube/mem_init.S
727 index 0000000..47a35e1
729 +++ b/arch/mips/cpu/mips32/danube/mem_init.S
732 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
733 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
735 + * SPDX-License-Identifier: GPL-2.0+
739 +#include <asm/asm.h>
740 +#include <asm/regdef.h>
741 +#include <asm/addrspace.h>
742 +#include <asm/arch/soc.h>
744 +/* Must be configured in BOARDDIR */
745 +#include <ddr_settings.h>
747 +#define LTQ_MC_GEN_ERRCAUSE 0x0010
748 +#define LTQ_MC_GEN_ERRADDR 0x0020
749 +#define LTQ_MC_GEN_CON 0x0060
750 +#define LTQ_MC_GEN_STAT 0x0070
751 +#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE 0x5
752 +#define LTQ_MC_GEN_STAT_DLCK_PWRON 0xC
754 +#define LTQ_MC_DDR_DC03_MC_START 0x100
756 + /* Store given value in MC DDR CCRx register */
757 + .macro dc_sw num, val
759 + sw t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
763 + /* Load MC General and MC DDR module base */
764 + li t0, (LTQ_MC_GEN_BASE | KSEG1)
765 + li t1, (LTQ_MC_DDR_BASE | KSEG1)
767 + /* Clear access error log registers */
768 + sw zero, LTQ_MC_GEN_ERRCAUSE(t0)
769 + sw zero, LTQ_MC_GEN_ERRADDR(t0)
771 + /* Enable DDR and SRAM module in memory controller */
772 + li t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE
773 + sw t2, LTQ_MC_GEN_CON(t0)
775 + /* Clear start bit of DDR memory controller */
776 + sw zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
778 + /* Init memory controller registers with values ddr_settings.h */
779 + dc_sw 0, MC_DC00_VALUE
780 + dc_sw 1, MC_DC01_VALUE
781 + dc_sw 2, MC_DC02_VALUE
782 + dc_sw 4, MC_DC04_VALUE
783 + dc_sw 5, MC_DC05_VALUE
784 + dc_sw 6, MC_DC06_VALUE
785 + dc_sw 7, MC_DC07_VALUE
786 + dc_sw 8, MC_DC08_VALUE
787 + dc_sw 9, MC_DC09_VALUE
789 + dc_sw 10, MC_DC10_VALUE
790 + dc_sw 11, MC_DC11_VALUE
791 + dc_sw 12, MC_DC12_VALUE
792 + dc_sw 13, MC_DC13_VALUE
793 + dc_sw 14, MC_DC14_VALUE
794 + dc_sw 15, MC_DC15_VALUE
795 + dc_sw 16, MC_DC16_VALUE
796 + dc_sw 17, MC_DC17_VALUE
797 + dc_sw 18, MC_DC18_VALUE
798 + dc_sw 19, MC_DC19_VALUE
800 + dc_sw 20, MC_DC20_VALUE
801 + dc_sw 21, MC_DC21_VALUE
802 + dc_sw 22, MC_DC22_VALUE
803 + dc_sw 23, MC_DC23_VALUE
804 + dc_sw 24, MC_DC24_VALUE
805 + dc_sw 25, MC_DC25_VALUE
806 + dc_sw 26, MC_DC26_VALUE
807 + dc_sw 27, MC_DC27_VALUE
808 + dc_sw 28, MC_DC28_VALUE
809 + dc_sw 29, MC_DC29_VALUE
811 + dc_sw 30, MC_DC30_VALUE
812 + dc_sw 31, MC_DC31_VALUE
813 + dc_sw 32, MC_DC32_VALUE
814 + dc_sw 33, MC_DC33_VALUE
815 + dc_sw 34, MC_DC34_VALUE
816 + dc_sw 35, MC_DC35_VALUE
817 + dc_sw 36, MC_DC36_VALUE
818 + dc_sw 37, MC_DC37_VALUE
819 + dc_sw 38, MC_DC38_VALUE
820 + dc_sw 39, MC_DC39_VALUE
822 + dc_sw 40, MC_DC40_VALUE
823 + dc_sw 41, MC_DC41_VALUE
824 + dc_sw 42, MC_DC42_VALUE
825 + dc_sw 43, MC_DC43_VALUE
826 + dc_sw 44, MC_DC44_VALUE
827 + dc_sw 45, MC_DC45_VALUE
828 + dc_sw 46, MC_DC46_VALUE
830 + /* Set start bit of DDR memory controller */
831 + li t2, LTQ_MC_DDR_DC03_MC_START
832 + sw t2, LTQ_MC_DDR_DC_OFFSET(3)(t1)
834 + /* Wait until DLL has locked and core is ready for data transfers */
836 + lw t2, LTQ_MC_GEN_STAT(t0)
837 + li t3, LTQ_MC_GEN_STAT_DLCK_PWRON
839 + bne t2, t3, wait_ready
845 diff --git a/arch/mips/cpu/mips32/danube/pmu.c b/arch/mips/cpu/mips32/danube/pmu.c
847 index 0000000..7dd8aea
849 +++ b/arch/mips/cpu/mips32/danube/pmu.c
852 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
854 + * SPDX-License-Identifier: GPL-2.0+
858 +#include <asm/lantiq/io.h>
859 +#include <asm/lantiq/pm.h>
860 +#include <asm/arch/soc.h>
862 +#define LTQ_PMU_PWDCR_RESERVED 0xFD0C001C
864 +#define LTQ_PMU_PWDCR_TDM (1 << 25)
865 +#define LTQ_PMU_PWDCR_PPE_ENET0 (1 << 23)
866 +#define LTQ_PMU_PWDCR_PPE_ENET1 (1 << 22)
867 +#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
868 +#define LTQ_PMU_PWDCR_DEU (1 << 20)
869 +#define LTQ_PMU_PWDCR_UART1 (1 << 17)
870 +#define LTQ_PMU_PWDCR_SDIO (1 << 16)
871 +#define LTQ_PMU_PWDCR_AHB (1 << 15)
872 +#define LTQ_PMU_PWDCR_FPI0 (1 << 14)
873 +#define LTQ_PMU_PWDCR_PPE (1 << 13)
874 +#define LTQ_PMU_PWDCR_GPTC (1 << 12)
875 +#define LTQ_PMU_PWDCR_LEDC (1 << 11)
876 +#define LTQ_PMU_PWDCR_EBU (1 << 10)
877 +#define LTQ_PMU_PWDCR_DSL (1 << 9)
878 +#define LTQ_PMU_PWDCR_SPI (1 << 8)
879 +#define LTQ_PMU_PWDCR_UART0 (1 << 7)
880 +#define LTQ_PMU_PWDCR_USB (1 << 6)
881 +#define LTQ_PMU_PWDCR_DMA (1 << 5)
882 +#define LTQ_PMU_PWDCR_FPI1 (1 << 1)
883 +#define LTQ_PMU_PWDCR_USB_PHY (1 << 0)
885 +struct ltq_pmu_regs {
893 +static struct ltq_pmu_regs *ltq_pmu_regs =
894 + (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
896 +u32 ltq_pm_map(enum ltq_pm_modules module)
902 + val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 |
903 + LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
906 + val = LTQ_PMU_PWDCR_DMA;
909 + val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC |
913 + val = LTQ_PMU_PWDCR_SPI;
923 +int ltq_pm_enable(enum ltq_pm_modules module)
925 + const unsigned long timeout = 1000;
926 + unsigned long timebase;
929 + val = ltq_pm_map(module);
930 + if (unlikely(!val))
933 + ltq_clrbits(<q_pmu_regs->pwdcr, val);
935 + timebase = get_timer(0);
938 + sr = ltq_readl(<q_pmu_regs->sr);
941 + } while (get_timer(timebase) < timeout);
946 +int ltq_pm_disable(enum ltq_pm_modules module)
950 + val = ltq_pm_map(module);
951 + if (unlikely(!val))
954 + ltq_setbits(<q_pmu_regs->pwdcr, val);
959 +void ltq_pmu_init(void)
963 + clr = ltq_pm_map(LTQ_PM_CORE);
964 + set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
966 + ltq_clrsetbits(<q_pmu_regs->pwdcr, clr, set);
968 diff --git a/arch/mips/cpu/mips32/danube/rcu.c b/arch/mips/cpu/mips32/danube/rcu.c
970 index 0000000..906491a
972 +++ b/arch/mips/cpu/mips32/danube/rcu.c
975 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
977 + * SPDX-License-Identifier: GPL-2.0+
981 +#include <asm/lantiq/io.h>
982 +#include <asm/lantiq/reset.h>
983 +#include <asm/lantiq/cpu.h>
984 +#include <asm/arch/soc.h>
986 +#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
987 +#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
988 +#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
989 +#define LTQ_RCU_RD_DFE_AFE (1 << 12) /* Voice DFE/AFE */
990 +#define LTQ_RCU_RD_DSL_AFE (1 << 11) /* DSL AFE */
991 +#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
992 +#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
993 +#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
994 +#define LTQ_RCU_RD_ARC_DFE (1 << 7) /* ARC/DFE core */
995 +#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
996 +#define LTQ_RCU_RD_ENET_MAC1 (1 << 5) /* Ethernet MAC1 */
997 +#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
998 +#define LTQ_RCU_RD_CPU1 (1 << 3) /* CPU1 subsystem */
999 +#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
1000 +#define LTQ_RCU_RD_CPU0 (1 << 1) /* CPU0 subsystem */
1001 +#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
1003 +#define LTQ_RCU_STAT_BOOT_SHIFT 18
1004 +#define LTQ_RCU_STAT_BOOT_MASK (0x7 << LTQ_RCU_STAT_BOOT_SHIFT)
1006 +struct ltq_rcu_regs {
1008 + u32 req; /* Reset request */
1009 + u32 stat; /* Reset status */
1010 + u32 usb_cfg; /* USB configure */
1012 + u32 pci_rdy; /* PCI boot ready */
1015 +static struct ltq_rcu_regs *ltq_rcu_regs =
1016 + (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
1018 +u32 ltq_reset_map(enum ltq_reset_modules module)
1023 + case LTQ_RESET_CORE:
1024 + case LTQ_RESET_SOFT:
1025 + val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1;
1027 + case LTQ_RESET_DMA:
1028 + val = LTQ_RCU_RD_DMA;
1030 + case LTQ_RESET_ETH:
1031 + val = LTQ_RCU_RD_PPE;
1033 + case LTQ_RESET_HARD:
1034 + val = LTQ_RCU_RD_HRST;
1044 +int ltq_reset_activate(enum ltq_reset_modules module)
1048 + val = ltq_reset_map(module);
1049 + if (unlikely(!val))
1052 + ltq_setbits(<q_rcu_regs->req, val);
1057 +int ltq_reset_deactivate(enum ltq_reset_modules module)
1061 + val = ltq_reset_map(module);
1062 + if (unlikely(!val))
1065 + ltq_clrbits(<q_rcu_regs->req, val);
1070 +enum ltq_boot_select ltq_boot_select(void)
1073 + unsigned int bootstrap;
1075 + stat = ltq_readl(<q_rcu_regs->stat);
1076 + bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
1078 + switch (bootstrap) {
1080 + return BOOT_NOR_NO_BOOTROM;
1094 + return BOOT_RMII0;
1096 + return BOOT_UNKNOWN;
1099 diff --git a/arch/mips/cpu/mips32/lantiq-common/Makefile b/arch/mips/cpu/mips32/lantiq-common/Makefile
1100 new file mode 100644
1101 index 0000000..260d67c
1103 +++ b/arch/mips/cpu/mips32/lantiq-common/Makefile
1106 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1108 +# SPDX-License-Identifier: GPL-2.0+
1111 +include $(TOPDIR)/config.mk
1113 +LIB = $(obj)liblantiq-common.o
1116 +COBJS-y = cpu.o pmu.o
1117 +COBJS-$(CONFIG_SPL_BUILD) += spl.o
1118 +SOBJS-y = lowlevel_init.o
1120 +COBJS := $(COBJS-y)
1121 +SOBJS := $(SOBJS-y)
1122 +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
1123 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
1124 +START := $(addprefix $(obj),$(START))
1128 +$(LIB): $(obj).depend $(OBJS)
1129 + $(call cmd_link_o_target, $(OBJS))
1131 +#########################################################################
1133 +# defines $(obj).depend target
1134 +include $(SRCTREE)/rules.mk
1136 +sinclude $(obj).depend
1138 +#########################################################################
1139 diff --git a/arch/mips/cpu/mips32/lantiq-common/cpu.c b/arch/mips/cpu/mips32/lantiq-common/cpu.c
1140 new file mode 100644
1141 index 0000000..4a7acdf
1143 +++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
1146 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1148 + * SPDX-License-Identifier: GPL-2.0+
1151 +#include <common.h>
1152 +#include <asm/lantiq/chipid.h>
1153 +#include <asm/lantiq/clk.h>
1154 +#include <asm/lantiq/reset.h>
1155 +#include <asm/lantiq/cpu.h>
1157 +static const char ltq_bootsel_strings[][16] = {
1159 + "NOR w/o BootROM",
1161 + "UART w/o EEPROM",
1171 +const char *ltq_boot_select_str(void)
1172 +{ enum ltq_boot_select bootsel = ltq_boot_select();
1174 + if (bootsel > BOOT_UNKNOWN)
1175 + bootsel = BOOT_UNKNOWN;
1177 + return ltq_bootsel_strings[bootsel];
1180 +void ltq_chip_print_info(void)
1184 + printf("SoC: Lantiq %s v1.%u\n", ltq_chip_partnum_str(),
1185 + ltq_chip_version_get());
1186 + printf("CPU: %s MHz\n", strmhz(buf, ltq_get_cpu_clock()));
1187 + printf("IO: %s MHz\n", strmhz(buf, ltq_get_io_region_clock()));
1188 + printf("BUS: %s MHz\n", strmhz(buf, ltq_get_bus_clock()));
1189 + printf("BOOT: %s\n", ltq_boot_select_str());
1192 +int arch_cpu_init(void)
1200 +void _machine_restart(void)
1202 + ltq_reset_activate(LTQ_RESET_CORE);
1204 diff --git a/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
1205 new file mode 100644
1206 index 0000000..ad03b04
1208 +++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
1211 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1213 + * SPDX-License-Identifier: GPL-2.0+
1216 +#include <asm/asm.h>
1217 +#include <asm/regdef.h>
1219 +NESTED(lowlevel_init, 0, ra)
1222 + la t7, ltq_cgu_init
1225 + la t7, ltq_mem_init
1229 + END(lowlevel_init)
1230 diff --git a/arch/mips/cpu/mips32/lantiq-common/pmu.c b/arch/mips/cpu/mips32/lantiq-common/pmu.c
1231 new file mode 100644
1232 index 0000000..8f0dac1
1234 +++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c
1237 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1239 + * SPDX-License-Identifier: GPL-2.0+
1242 +#include <common.h>
1243 +#include <asm/lantiq/pm.h>
1245 diff --git a/arch/mips/cpu/mips32/lantiq-common/spl.c b/arch/mips/cpu/mips32/lantiq-common/spl.c
1246 new file mode 100644
1247 index 0000000..489a82b
1249 +++ b/arch/mips/cpu/mips32/lantiq-common/spl.c
1252 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1254 + * SPDX-License-Identifier: GPL-2.0+
1257 +#include <common.h>
1259 +#include <version.h>
1260 +#include <spi_flash.h>
1261 +#include <linux/compiler.h>
1262 +#include <lzma/LzmaDec.h>
1263 +#include <linux/lzo.h>
1264 +#include <asm/mipsregs.h>
1266 +#if defined(CONFIG_LTQ_SPL_CONSOLE)
1267 +#define spl_has_console 1
1269 +#if defined(CONFIG_LTQ_SPL_DEBUG)
1270 +#define spl_has_debug 1
1272 +#define spl_has_debug 0
1276 +#define spl_has_console 0
1277 +#define spl_has_debug 0
1280 +#define spl_debug(fmt, args...) \
1282 + if (spl_has_debug) \
1283 + printf(fmt, ##args); \
1286 +#define spl_puts(msg) \
1288 + if (spl_has_console) \
1292 +#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
1293 +#define spl_boot_spi_flash 1
1295 +#define spl_boot_spi_flash 0
1296 +#ifndef CONFIG_SPL_SPI_BUS
1297 +#define CONFIG_SPL_SPI_BUS 0
1299 +#ifndef CONFIG_SPL_SPI_CS
1300 +#define CONFIG_SPL_SPI_CS 0
1302 +#ifndef CONFIG_SPL_SPI_MAX_HZ
1303 +#define CONFIG_SPL_SPI_MAX_HZ 0
1305 +#ifndef CONFIG_SPL_SPI_MODE
1306 +#define CONFIG_SPL_SPI_MODE 0
1310 +#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
1311 +#define spl_boot_nor_flash 1
1313 +#define spl_boot_nor_flash 0
1316 +#define spl_sync() __asm__ __volatile__("sync");
1327 +DECLARE_GLOBAL_DATA_PTR;
1329 +/* Emulated malloc area needed for LZMA allocator in BSS */
1330 +static u8 *spl_mem_ptr __maybe_unused;
1331 +static size_t spl_mem_size __maybe_unused;
1333 +static int spl_is_comp_lzma(const struct spl_image *spl)
1335 +#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
1336 + return spl->comp == IH_COMP_LZMA;
1342 +static int spl_is_comp_lzo(const struct spl_image *spl)
1344 +#if defined(CONFIG_LTQ_SPL_COMP_LZO)
1345 + return spl->comp == IH_COMP_LZO;
1351 +static int spl_is_compressed(const struct spl_image *spl)
1353 + if (spl_is_comp_lzma(spl))
1356 + if (spl_is_comp_lzo(spl))
1362 +static void spl_console_init(void)
1364 + if (!spl_has_console)
1367 + gd->flags |= GD_FLG_RELOC;
1368 + gd->baudrate = CONFIG_BAUDRATE;
1372 + gd->have_console = 1;
1374 + spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
1375 + U_BOOT_TIME ")\n");
1378 +static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl)
1380 + spl_puts("SPL: checking U-Boot image\n");
1382 + if (!image_check_magic(hdr)) {
1383 + spl_puts("SPL: invalid magic\n");
1387 + if (!image_check_hcrc(hdr)) {
1388 + spl_puts("SPL: invalid header CRC\n");
1392 + spl->data_addr += image_get_header_size();
1393 + spl->entry_addr = image_get_load(hdr);
1394 + spl->data_size = image_get_data_size(hdr);
1395 + spl->data_crc = image_get_dcrc(hdr);
1396 + spl->comp = image_get_comp(hdr);
1398 + spl_debug("SPL: data %08lx, size %lu, entry %08lx, comp %u\n",
1399 + spl->data_addr, spl->data_size, spl->entry_addr, spl->comp);
1404 +static int spl_check_data(const struct spl_image *spl, ulong loadaddr)
1406 + ulong dcrc = crc32(0, (unsigned char *)loadaddr, spl->data_size);
1408 + if (dcrc != spl->data_crc) {
1409 + spl_puts("SPL: invalid data CRC\n");
1416 +static void *spl_lzma_alloc(void *p, size_t size)
1420 + if (size > spl_mem_size)
1423 + ret = spl_mem_ptr;
1424 + spl_mem_ptr += size;
1425 + spl_mem_size -= size;
1430 +static void spl_lzma_free(void *p, void *addr)
1434 +static int spl_copy_image(struct spl_image *spl)
1436 + spl_puts("SPL: copying U-Boot to RAM\n");
1438 + memcpy((void *) spl->entry_addr, (const void *) spl->data_addr,
1441 + spl->entry_size = spl->data_size;
1446 +static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr)
1449 + const Byte *prop = (const Byte *) loadaddr;
1450 + const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE +
1452 + Byte *dest = (Byte *) spl->entry_addr;
1453 + SizeT dest_len = 0xFFFFFFFF;
1454 + SizeT src_len = spl->data_size - LZMA_PROPS_SIZE;
1455 + ELzmaStatus status = 0;
1458 + spl_puts("SPL: decompressing U-Boot with LZMA\n");
1460 + alloc.Alloc = spl_lzma_alloc;
1461 + alloc.Free = spl_lzma_free;
1462 + spl_mem_ptr = (u8 *) CONFIG_SPL_MALLOC_BASE;
1463 + spl_mem_size = CONFIG_SPL_MALLOC_MAX_SIZE;
1465 + res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE,
1466 + LZMA_FINISH_ANY, &status, &alloc);
1470 + spl->entry_size = dest_len;
1475 +static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr)
1480 + spl_puts("SPL: decompressing U-Boot with LZO\n");
1482 + ret = lzop_decompress(
1483 + (const unsigned char*) loadaddr, spl->data_size,
1484 + (unsigned char *) spl->entry_addr, &len);
1486 + spl->entry_size = len;
1491 +static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr)
1495 + if (spl_is_comp_lzma(spl))
1496 + ret = spl_uncompress_lzma(spl, loadaddr);
1497 + else if (spl_is_comp_lzo(spl))
1498 + ret = spl_uncompress_lzo(spl, loadaddr);
1505 +static int spl_load_spi_flash(struct spl_image *spl)
1507 + struct spi_flash sf = { 0 };
1508 + image_header_t hdr;
1510 + unsigned long loadaddr;
1515 + * - 12 byte non-volatile bootstrap header
1517 + * - 12 byte non-volatile bootstrap header
1518 + * - 64 byte U-Boot mkimage header
1521 + spl->data_addr = image_copy_end() - CONFIG_SPL_TEXT_BASE + 24;
1523 + spl_puts("SPL: probing SPI flash\n");
1526 + ret = spl_spi_flash_probe(&sf);
1530 + spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr);
1532 + ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr);
1536 + spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr);
1538 + ret = spl_parse_image(&hdr, spl);
1542 + if (spl_is_compressed(spl))
1543 + loadaddr = CONFIG_LOADADDR;
1545 + loadaddr = spl->entry_addr;
1547 + spl_puts("SPL: loading U-Boot to RAM\n");
1549 + ret = spi_flash_read(&sf, spl->data_addr, spl->data_size,
1550 + (void *) loadaddr);
1552 + if (!spl_check_data(spl, loadaddr))
1555 + if (spl_is_compressed(spl))
1556 + ret = spl_uncompress(spl, loadaddr);
1561 +static int spl_load_nor_flash(struct spl_image *spl)
1563 + const image_header_t *hdr;
1570 + * - 64 byte U-Boot mkimage header
1573 + spl->data_addr = image_copy_end();
1574 + hdr = (const image_header_t *) image_copy_end();
1576 + spl_debug("SPL: checking image header at address %p\n", hdr);
1578 + ret = spl_parse_image(hdr, spl);
1582 + if (spl_is_compressed(spl))
1583 + ret = spl_uncompress(spl, spl->data_addr);
1585 + ret = spl_copy_image(spl);
1590 +static int spl_load(struct spl_image *spl)
1594 + if (spl_boot_spi_flash)
1595 + ret = spl_load_spi_flash(spl);
1596 + else if (spl_boot_nor_flash)
1597 + ret = spl_load_nor_flash(spl);
1604 +void __noreturn spl_lantiq_init(void)
1606 + void (*uboot)(void) __noreturn;
1607 + struct spl_image spl;
1613 + memset((void *)gd, 0, sizeof(gd_t));
1615 + spl_console_init();
1617 + spl_debug("SPL: initializing\n");
1620 + spl_debug("CP0_CONFIG: %08x\n", read_c0_config());
1621 + spl_debug("CP0_CONFIG1: %08x\n", read_c0_config1());
1622 + spl_debug("CP0_CONFIG2: %08x\n", read_c0_config2());
1623 + spl_debug("CP0_CONFIG3: %08x\n", read_c0_config3());
1624 + spl_debug("CP0_CONFIG6: %08x\n", read_c0_config6());
1625 + spl_debug("CP0_CONFIG7: %08x\n", read_c0_config7());
1626 + spl_debug("CP0_STATUS: %08x\n", read_c0_status());
1627 + spl_debug("CP0_PRID: %08x\n", read_c0_prid());
1630 + board_early_init_f();
1633 + memset(&spl, 0, sizeof(spl));
1635 + ret = spl_load(&spl);
1639 + spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr);
1640 + spl_puts("SPL: jumping to U-Boot\n");
1642 + flush_cache(spl.entry_addr, spl.entry_size);
1645 + uboot = (void *) spl.entry_addr;
1649 + spl_puts("SPL: cannot start U-Boot\n");
1654 diff --git a/arch/mips/cpu/mips32/lantiq-common/start.S b/arch/mips/cpu/mips32/lantiq-common/start.S
1655 new file mode 100644
1656 index 0000000..481d739
1658 +++ b/arch/mips/cpu/mips32/lantiq-common/start.S
1661 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1662 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1664 + * SPDX-License-Identifier: GPL-2.0+
1667 +#include <config.h>
1668 +#include <asm/regdef.h>
1669 +#include <asm/mipsregs.h>
1671 +#define S_PRIdCoID 16 /* Company ID (R) */
1672 +#define M_PRIdCoID (0xff << S_PRIdCoID)
1673 +#define S_PRIdImp 8 /* Implementation ID (R) */
1674 +#define M_PRIdImp (0xff << S_PRIdImp)
1676 +#define K_CacheAttrCWTnWA 0 /* Cacheable, write-thru, no write allocate */
1677 +#define K_CacheAttrCWTWA 1 /* Cacheable, write-thru, write allocate */
1678 +#define K_CacheAttrU 2 /* Uncached */
1679 +#define K_CacheAttrC 3 /* Cacheable */
1680 +#define K_CacheAttrCN 3 /* Cacheable, non-coherent */
1681 +#define K_CacheAttrCCE 4 /* Cacheable, coherent, exclusive */
1682 +#define K_CacheAttrCCS 5 /* Cacheable, coherent, shared */
1683 +#define K_CacheAttrCCU 6 /* Cacheable, coherent, update */
1684 +#define K_CacheAttrUA 7 /* Uncached accelerated */
1686 +#define S_ConfigK23 28 /* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */
1687 +#define M_ConfigK23 (0x7 << S_ConfigK23)
1688 +#define W_ConfigK23 3
1689 +#define S_ConfigKU 25 /* Kuseg coherency algorithm (FM MMU only) (R/W) */
1690 +#define M_ConfigKU (0x7 << S_ConfigKU)
1691 +#define W_ConfigKU 3
1693 +#define S_ConfigMM 18 /* Merge mode (implementation specific) */
1694 +#define M_ConfigMM (0x1 << S_ConfigMM)
1696 +#define S_StatusBEV 22 /* Enable Boot Exception Vectors (R/W) */
1697 +#define M_StatusBEV (0x1 << S_StatusBEV)
1699 +#define S_StatusFR 26 /* Enable 64-bit FPRs (R/W) */
1700 +#define M_StatusFR (0x1 << S_StatusFR)
1702 +#define S_ConfigK0 0 /* Kseg0 coherency algorithm (R/W) */
1703 +#define M_ConfigK0 (0x7 << S_ConfigK0)
1705 +#define CONFIG0_MIPS32_64_MSK 0x8000ffff
1706 +#define STATUS_MIPS32_64_MSK 0xfffcffff
1708 +#define STATUS_MIPS24K 0
1709 +#define CONFIG0_MIPS24K ((K_CacheAttrCN << S_ConfigK23) |\
1710 + (K_CacheAttrCN << S_ConfigKU) |\
1713 +#define STATUS_MIPS34K 0
1714 +#define CONFIG0_MIPS34K ((K_CacheAttrCN << S_ConfigK23) |\
1715 + (K_CacheAttrCN << S_ConfigKU) |\
1718 +#define STATUS_MIPS32_64 (M_StatusBEV | M_StatusFR)
1719 +#define CONFIG0_MIPS32_64 (K_CacheAttrCN << S_ConfigK0)
1721 +#ifdef CONFIG_SOC_XWAY_DANUBE
1722 +#define CONFIG0_LANTIQ (CONFIG0_MIPS24K | CONFIG0_MIPS32_64)
1723 +#define STATUS_LANTIQ (STATUS_MIPS24K | STATUS_MIPS32_64)
1726 +#ifdef CONFIG_SOC_XWAY_VRX200
1727 +#define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
1728 +#define STATUS_LANTIQ (STATUS_MIPS34K | STATUS_MIPS32_64)
1741 + /* Lantiq SoC Boot config word */
1743 +#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
1744 + .word CONFIG_SYS_XWAY_EBU_BOOTCFG
1754 + mtc0 zero, CP0_COUNT
1755 + mtc0 zero, CP0_COMPARE
1757 + /* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */
1758 + mfc0 t0, CP0_CONFIG
1759 + li t1, CONFIG0_MIPS32_64_MSK
1761 + li t1, CONFIG0_LANTIQ
1763 + mtc0 t0, CP0_CONFIG
1765 + mfc0 t0, CP0_STATUS
1766 + li t1, STATUS_MIPS32_64_MSK
1768 + li t1, STATUS_LANTIQ
1770 + mtc0 t0, CP0_STATUS
1772 + /* Initialize CGU */
1773 + la t9, ltq_cgu_init
1777 + /* Initialize memory controller */
1778 + la t9, ltq_mem_init
1782 + /* Initialize caches... */
1783 + la t9, mips_cache_reset
1788 + la t1, __bss_start
1796 + /* Setup stack pointer and force alignment on a 16 byte boundary */
1797 + li t0, (CONFIG_SPL_STACK_BASE & ~0xF)
1800 + la t9, spl_lantiq_init
1803 diff --git a/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
1804 new file mode 100644
1805 index 0000000..97c8fa8
1807 +++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
1810 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1812 + * SPDX-License-Identifier: GPL-2.0+
1815 +MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \
1816 + LENGTH = CONFIG_SPL_MAX_SIZE }
1817 +MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_BASE, \
1818 + LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
1820 +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
1832 + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
1837 + *(SORT_BY_ALIGNMENT(.data*))
1838 + *(SORT_BY_ALIGNMENT(.sdata*))
1842 + __image_copy_end = .;
1843 + uboot_end_data = .;
1857 diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S
1858 index 70ad198..091a4e2 100644
1859 --- a/arch/mips/cpu/mips32/start.S
1860 +++ b/arch/mips/cpu/mips32/start.S
1861 @@ -105,7 +105,7 @@ reset:
1862 mtc0 zero, CP0_COUNT
1863 mtc0 zero, CP0_COMPARE
1865 -#ifndef CONFIG_SKIP_LOWLEVEL_INIT
1866 +#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_SYS_DISABLE_CACHE)
1867 /* CONFIG0 register */
1868 li t0, CONF_CM_UNCACHED
1870 diff --git a/arch/mips/cpu/mips32/vrx200/Makefile b/arch/mips/cpu/mips32/vrx200/Makefile
1871 new file mode 100644
1872 index 0000000..714dc69
1874 +++ b/arch/mips/cpu/mips32/vrx200/Makefile
1877 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1879 +# SPDX-License-Identifier: GPL-2.0+
1882 +include $(TOPDIR)/config.mk
1884 +LIB = $(obj)lib$(SOC).o
1886 +COBJS-y += cgu.o chipid.o dcdc.o ebu.o gphy.o mem.o pmu.o rcu.o
1887 +SOBJS-y += cgu_init.o mem_init.o
1888 +SOBJS-y += gphy_fw.o
1890 +COBJS := $(COBJS-y)
1891 +SOBJS := $(SOBJS-y)
1892 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
1893 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
1897 +$(LIB): $(obj).depend $(OBJS)
1898 + $(call cmd_link_o_target, $(OBJS))
1900 +#########################################################################
1902 +# defines $(obj).depend target
1903 +include $(SRCTREE)/rules.mk
1905 +sinclude $(obj).depend
1907 +#########################################################################
1908 diff --git a/arch/mips/cpu/mips32/vrx200/cgu.c b/arch/mips/cpu/mips32/vrx200/cgu.c
1909 new file mode 100644
1910 index 0000000..799c902
1912 +++ b/arch/mips/cpu/mips32/vrx200/cgu.c
1915 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1916 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1918 + * SPDX-License-Identifier: GPL-2.0+
1921 +#include <common.h>
1922 +#include <asm/arch/soc.h>
1923 +#include <asm/arch/gphy.h>
1924 +#include <asm/lantiq/clk.h>
1925 +#include <asm/lantiq/io.h>
1927 +#define LTQ_CGU_PLL1_PLLN_SHIFT 6
1928 +#define LTQ_CGU_PLL1_PLLN_MASK (0x3F << LTQ_CGU_PLL1_PLLN_SHIFT)
1929 +#define LTQ_CGU_PLL1_PLLM_SHIFT 2
1930 +#define LTQ_CGU_PLL1_PLLM_MASK (0xF << LTQ_CGU_PLL1_PLLM_SHIFT)
1931 +#define LTQ_CGU_PLL1_PLLL (1 << 1)
1932 +#define LTQ_CGU_PLL1_PLL_EN 1
1934 +#define LTQ_CGU_SYS_OCP_SHIFT 0
1935 +#define LTQ_CGU_SYS_OCP_MASK (0x3 << LTQ_CGU_SYS_OCP_SHIFT)
1936 +#define LTQ_CGU_SYS_CPU_SHIFT 4
1937 +#define LTQ_CGU_SYS_CPU_MASK (0xF << LTQ_CGU_SYS_CPU_SHIFT)
1939 +#define LTQ_CGU_UPDATE 1
1941 +#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT 2
1942 +#define LTQ_CGU_IFCLK_GPHY_SEL_MASK (0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT)
1944 +struct ltq_cgu_regs {
1946 + u32 pll0_cfg; /* PLL0 config */
1947 + u32 pll1_cfg; /* PLL1 config */
1948 + u32 sys; /* System clock */
1949 + u32 clk_fsr; /* Clock frequency select */
1950 + u32 clk_gsr; /* Clock gating status */
1951 + u32 clk_gcr0; /* Clock gating control 0 */
1952 + u32 clk_gcr1; /* Clock gating control 1 */
1953 + u32 update; /* CGU update control */
1954 + u32 if_clk; /* Interface clock */
1955 + u32 ddr; /* DDR memory control */
1956 + u32 ct1_sr; /* CT status 1 */
1957 + u32 ct_kval; /* CT K value */
1958 + u32 pcm_cr; /* PCM control */
1959 + u32 pci_cr; /* PCI clock control */
1961 + u32 gphy1_cfg; /* GPHY1 config */
1962 + u32 gphy0_cfg; /* GPHY0 config */
1964 + u32 pll2_cfg; /* PLL2 config */
1967 +static struct ltq_cgu_regs *ltq_cgu_regs =
1968 + (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
1970 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
1972 + return (ltq_readl(<q_cgu_regs->sys) & mask) >> shift;
1975 +unsigned long ltq_get_io_region_clock(void)
1977 + unsigned int ocp_sel;
1978 + unsigned long clk, cpu_clk;
1980 + cpu_clk = ltq_get_cpu_clock();
1982 + ocp_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_OCP_MASK,
1983 + LTQ_CGU_SYS_OCP_SHIFT);
1985 + switch (ocp_sel) {
1992 + clk = cpu_clk / 2;
1995 + /* OCP ratio 2.5 */
1996 + clk = (cpu_clk * 2) / 5;
2000 + clk = cpu_clk / 3;
2010 +unsigned long ltq_get_cpu_clock(void)
2012 + unsigned int cpu_sel;
2013 + unsigned long clk;
2015 + cpu_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU_MASK,
2016 + LTQ_CGU_SYS_CPU_SHIFT);
2018 + switch (cpu_sel) {
2020 + clk = CLOCK_600_MHZ;
2023 + clk = CLOCK_500_MHZ;
2026 + clk = CLOCK_393_MHZ;
2029 + clk = CLOCK_333_MHZ;
2033 + clk = CLOCK_197_MHZ;
2036 + clk = CLOCK_166_MHZ;
2041 + clk = CLOCK_125_MHZ;
2051 +unsigned long ltq_get_bus_clock(void)
2053 + return ltq_get_io_region_clock();
2056 +void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk)
2058 + ltq_clrbits(<q_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK);
2059 + ltq_setbits(<q_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT);
2062 +static inline int ltq_cgu_pll1_locked(void)
2064 + u32 pll1_cfg = ltq_readl(<q_cgu_regs->pll1_cfg);
2066 + return pll1_cfg & LTQ_CGU_PLL1_PLLL;
2069 +static inline void ltq_cgu_pll1_restart(unsigned m, unsigned n)
2073 + ltq_clrbits(<q_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN);
2074 + ltq_setbits(<q_cgu_regs->update, LTQ_CGU_UPDATE);
2076 + pll1_cfg = ltq_readl(<q_cgu_regs->pll1_cfg);
2077 + pll1_cfg &= ~(LTQ_CGU_PLL1_PLLN_MASK | LTQ_CGU_PLL1_PLLM_MASK);
2078 + pll1_cfg |= n << LTQ_CGU_PLL1_PLLN_SHIFT;
2079 + pll1_cfg |= m << LTQ_CGU_PLL1_PLLM_SHIFT;
2080 + pll1_cfg |= LTQ_CGU_PLL1_PLL_EN;
2081 + ltq_writel(<q_cgu_regs->pll1_cfg, pll1_cfg);
2082 + ltq_setbits(<q_cgu_regs->update, LTQ_CGU_UPDATE);
2088 + * From chapter 9 in errata sheet:
2090 + * Under certain condition, the PLL1 may failed to enter into lock
2091 + * status by hardware default N, M setting.
2093 + * Since system always starts from PLL0, the system software can run
2094 + * and re-program the PLL1 settings.
2096 +static void ltq_cgu_pll1_init(void)
2099 + const unsigned pll1_m[] = { 1, 2, 3, 4 };
2100 + const unsigned pll1_n[] = { 21, 32, 43, 54 };
2102 + /* Check if PLL1 has locked with hardware default settings */
2103 + if (ltq_cgu_pll1_locked())
2106 + for (i = 0; i < 4; i++) {
2107 + ltq_cgu_pll1_restart(pll1_m[i], pll1_n[i]);
2109 + if (ltq_cgu_pll1_locked())
2114 + /* Restart with hardware default values M=5, N=64 */
2115 + ltq_cgu_pll1_restart(5, 64);
2118 +void ltq_pll_init(void)
2120 + ltq_cgu_pll1_init();
2122 diff --git a/arch/mips/cpu/mips32/vrx200/cgu_init.S b/arch/mips/cpu/mips32/vrx200/cgu_init.S
2123 new file mode 100644
2124 index 0000000..190ef89
2126 +++ b/arch/mips/cpu/mips32/vrx200/cgu_init.S
2129 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2130 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2132 + * SPDX-License-Identifier: GPL-2.0+
2135 +#include <config.h>
2136 +#include <asm/asm.h>
2137 +#include <asm/regdef.h>
2138 +#include <asm/addrspace.h>
2139 +#include <asm/arch/soc.h>
2141 +/* RCU module register */
2142 +#define LTQ_RCU_RST_REQ 0x0010 /* Reset request */
2143 +#define LTQ_RCU_RST_REQ_VALUE ((1 << 14) | (1 << 1))
2145 +/* CGU module register */
2146 +#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
2147 +#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
2148 +#define LTQ_CGU_PLL2_CFG 0x0060 /* PLL2 config */
2149 +#define LTQ_CGU_SYS 0x000C /* System clock */
2150 +#define LTQ_CGU_CLK_FSR 0x0010 /* Clock frequency select */
2151 +#define LTQ_CGU_UPDATE 0x0020 /* Clock update control */
2153 +/* Valid SYS.CPU values */
2154 +#define LTQ_CGU_SYS_CPU_SHIFT 4
2155 +#define LTQ_CGU_SYS_CPU_600_MHZ 0x0
2156 +#define LTQ_CGU_SYS_CPU_500_MHZ 0x1
2157 +#define LTQ_CGU_SYS_CPU_393_MHZ 0x2
2158 +#define LTQ_CGU_SYS_CPU_333_MHZ 0x3
2159 +#define LTQ_CGU_SYS_CPU_197_MHZ 0x5
2160 +#define LTQ_CGU_SYS_CPU_166_MHZ 0x7
2161 +#define LTQ_CGU_SYS_CPU_125_MHZ 0x9
2163 +/* Valid SYS.OCP values */
2164 +#define LTQ_CGU_SYS_OCP_SHIFT 0
2165 +#define LTQ_CGU_SYS_OCP_1 0x0
2166 +#define LTQ_CGU_SYS_OCP_2 0x2
2167 +#define LTQ_CGU_SYS_OCP_2_5 0x3
2168 +#define LTQ_CGU_SYS_OCP_3 0x4
2170 +/* Valid CLK_FSR.ETH values */
2171 +#define LTQ_CGU_CLK_FSR_ETH_SHIFT 24
2172 +#define LTQ_CGU_CLK_FSR_ETH_50_MHZ 0x0
2173 +#define LTQ_CGU_CLK_FSR_ETH_25_MHZ 0x1
2174 +#define LTQ_CGU_CLK_FSR_ETH_2_5_MHZ 0x2
2175 +#define LTQ_CGU_CLK_FSR_ETH_125_MHZ 0x3
2177 +/* Valid CLK_FSR.PPE values */
2178 +#define LTQ_CGU_CLK_FSR_PPE_SHIFT 16
2179 +#define LTQ_CGU_CLK_FSR_PPE_500_MHZ 0x0 /* Overclock frequency */
2180 +#define LTQ_CGU_CLK_FSR_PPE_450_MHZ 0x1 /* High frequency */
2181 +#define LTQ_CGU_CLK_FSR_PPE_400_MHZ 0x2 /* Low frequency */
2183 +#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_500_DDR_250)
2184 +#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_500_MHZ
2185 +#define LTQ_CGU_SYS_OCP_CONFIG LTQ_CGU_SYS_OCP_2
2186 +#define LTQ_CGU_CLK_FSR_ETH_CONFIG LTQ_CGU_CLK_FSR_ETH_125_MHZ
2187 +#define LTQ_CGU_CLK_FSR_PPE_CONFIG LTQ_CGU_CLK_FSR_PPE_450_MHZ
2189 +#error "Invalid system clock configuration!"
2192 +/* Build register values */
2193 +#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_CPU_CONFIG << \
2194 + LTQ_CGU_SYS_CPU_SHIFT) | \
2195 + LTQ_CGU_SYS_OCP_CONFIG)
2197 +#define LTQ_CGU_CLK_FSR_VALUE ((LTQ_CGU_CLK_FSR_ETH_CONFIG << \
2198 + LTQ_CGU_CLK_FSR_ETH_SHIFT) | \
2199 + (LTQ_CGU_CLK_FSR_PPE_CONFIG << \
2200 + LTQ_CGU_CLK_FSR_PPE_SHIFT))
2205 + /* Load current CGU register values */
2206 + li t0, (LTQ_CGU_BASE | KSEG1)
2207 + lw t1, LTQ_CGU_SYS(t0)
2208 + lw t2, LTQ_CGU_CLK_FSR(t0)
2210 + /* Load target CGU register values */
2211 + li t3, LTQ_CGU_SYS_VALUE
2212 + li t4, LTQ_CGU_CLK_FSR_VALUE
2214 + /* Only update registers if values differ */
2215 + bne t1, t3, update
2217 + beq t2, t4, finished
2221 + /* Store target register values */
2222 + sw t3, LTQ_CGU_SYS(t0)
2223 + sw t4, LTQ_CGU_CLK_FSR(t0)
2225 + /* Perform software reset to activate new clock config */
2227 + li t0, (LTQ_RCU_BASE | KSEG1)
2228 + lw t1, LTQ_RCU_RST_REQ(t0)
2229 + or t1, LTQ_RCU_RST_REQ_VALUE
2230 + sw t1, LTQ_RCU_RST_REQ(t0)
2233 + sw t1, LTQ_CGU_UPDATE(t0)
2247 diff --git a/arch/mips/cpu/mips32/vrx200/chipid.c b/arch/mips/cpu/mips32/vrx200/chipid.c
2248 new file mode 100644
2249 index 0000000..f916e87
2251 +++ b/arch/mips/cpu/mips32/vrx200/chipid.c
2254 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2256 + * SPDX-License-Identifier: GPL-2.0+
2259 +#include <common.h>
2260 +#include <asm/lantiq/io.h>
2261 +#include <asm/lantiq/chipid.h>
2262 +#include <asm/arch/soc.h>
2264 +#define LTQ_CHIPID_VERSION_SHIFT 28
2265 +#define LTQ_CHIPID_VERSION_MASK (0x7 << LTQ_CHIPID_VERSION_SHIFT)
2266 +#define LTQ_CHIPID_PNUM_SHIFT 12
2267 +#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
2269 +struct ltq_chipid_regs {
2270 + u32 manid; /* Manufacturer identification */
2271 + u32 chipid; /* Chip identification */
2274 +static struct ltq_chipid_regs *ltq_chipid_regs =
2275 + (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
2277 +unsigned int ltq_chip_version_get(void)
2281 + chipid = ltq_readl(<q_chipid_regs->chipid);
2283 + return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
2286 +unsigned int ltq_chip_partnum_get(void)
2290 + chipid = ltq_readl(<q_chipid_regs->chipid);
2292 + return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
2295 +const char *ltq_chip_partnum_str(void)
2297 + enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
2299 + switch (partnum) {
2300 + case LTQ_SOC_VRX268:
2301 + case LTQ_SOC_VRX268_2:
2303 + case LTQ_SOC_VRX288:
2304 + case LTQ_SOC_VRX288_2:
2306 + case LTQ_SOC_GRX288:
2307 + case LTQ_SOC_GRX288_2:
2310 + printf("Unknown partnum: %x\n", partnum);
2315 diff --git a/arch/mips/cpu/mips32/vrx200/config.mk b/arch/mips/cpu/mips32/vrx200/config.mk
2316 new file mode 100644
2317 index 0000000..442156a
2319 +++ b/arch/mips/cpu/mips32/vrx200/config.mk
2322 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2324 +# SPDX-License-Identifier: GPL-2.0+
2327 +PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
2328 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
2330 +ifdef CONFIG_SPL_BUILD
2331 +PF_ABICALLS := -mno-abicalls
2334 +USE_PRIVATE_LIBGCC := yes
2337 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
2339 +ifndef CONFIG_SPL_BUILD
2340 +ifdef CONFIG_SYS_BOOT_SFSPL
2341 +ALL-y += $(obj)u-boot.ltq.sfspl
2342 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
2343 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl
2345 +ifdef CONFIG_SYS_BOOT_NORSPL
2346 +ALL-y += $(obj)u-boot.ltq.norspl
2347 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
2348 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
2351 diff --git a/arch/mips/cpu/mips32/vrx200/dcdc.c b/arch/mips/cpu/mips32/vrx200/dcdc.c
2352 new file mode 100644
2353 index 0000000..11ca0d7
2355 +++ b/arch/mips/cpu/mips32/vrx200/dcdc.c
2358 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2359 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2361 + * SPDX-License-Identifier: GPL-2.0+
2364 +#include <common.h>
2365 +#include <asm/arch/soc.h>
2366 +#include <asm/lantiq/io.h>
2368 +#define LTQ_DCDC_CLK_SET0_CLK_SEL_P (1 << 6)
2369 +#define LTQ_DCDC_CLK_SET1_SEL_DIV25 (1 << 5)
2370 +#define LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE (1 << 5)
2372 +struct ltq_dcdc_regs {
2373 + u8 b0_coeh; /* Coefficient b0 */
2374 + u8 b0_coel; /* Coefficient b0 */
2375 + u8 b1_coeh; /* Coefficient b1 */
2376 + u8 b1_coel; /* Coefficient b1 */
2377 + u8 b2_coeh; /* Coefficient b2 */
2378 + u8 b2_coel; /* Coefficient b2 */
2379 + u8 clk_set0; /* Clock setup */
2380 + u8 clk_set1; /* Clock setup */
2381 + u8 pwm_confh; /* Configure PWM */
2382 + u8 pwm_confl; /* Configure PWM */
2383 + u8 bias_vreg0; /* Bias and regulator setup */
2384 + u8 bias_vreg1; /* Bias and regulator setup */
2385 + u8 adc_gen0; /* ADC and general control */
2386 + u8 adc_gen1; /* ADC and general control */
2387 + u8 adc_con0; /* ADC and general config */
2388 + u8 adc_con1; /* ADC and general config */
2389 + u8 conf_test_ana; /* not documented */
2390 + u8 conf_test_dig; /* not documented */
2391 + u8 dcdc_status; /* not documented */
2392 + u8 pid_status; /* not documented */
2393 + u8 duty_cycle; /* not documented */
2394 + u8 non_ov_delay; /* not documented */
2395 + u8 analog_gain; /* not documented */
2396 + u8 duty_cycle_max_sat; /* not documented */
2397 + u8 duty_cycle_min_sat; /* not documented */
2398 + u8 duty_cycle_max; /* not documented */
2399 + u8 duty_cycle_min; /* not documented */
2400 + u8 error_max; /* not documented */
2401 + u8 error_read; /* not documented */
2402 + u8 delay_deglitch; /* not documented */
2403 + u8 latch_control; /* not documented */
2405 + u8 osc_conf; /* OSC general config */
2406 + u8 osc_stat; /* OSC general status */
2409 +static struct ltq_dcdc_regs *ltq_dcdc_regs =
2410 + (struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE);
2412 +void ltq_dcdc_init(unsigned int dig_ref)
2414 + u8 dig_ref_cur, val;
2416 + /* Set duty cycle max sat. to 70/90, enable PID freeze */
2417 + ltq_writeb(<q_dcdc_regs->duty_cycle_max_sat, 0x5A);
2418 + ltq_writeb(<q_dcdc_regs->duty_cycle_min_sat, 0x46);
2419 + val = ltq_readb(<q_dcdc_regs->conf_test_dig);
2420 + val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2421 + ltq_writeb(<q_dcdc_regs->conf_test_dig, val);
2423 + /* Program new coefficients */
2424 + ltq_writeb(<q_dcdc_regs->b0_coeh, 0x00);
2425 + ltq_writeb(<q_dcdc_regs->b0_coel, 0x00);
2426 + ltq_writeb(<q_dcdc_regs->b1_coeh, 0xFF);
2427 + ltq_writeb(<q_dcdc_regs->b1_coel, 0xE6);
2428 + ltq_writeb(<q_dcdc_regs->b2_coeh, 0x00);
2429 + ltq_writeb(<q_dcdc_regs->b2_coel, 0x1B);
2430 + ltq_writeb(<q_dcdc_regs->non_ov_delay, 0x8B);
2432 + /* Set duty cycle max sat. to 60/108, disable PID freeze */
2433 + ltq_writeb(<q_dcdc_regs->duty_cycle_max_sat, 0x6C);
2434 + ltq_writeb(<q_dcdc_regs->duty_cycle_min_sat, 0x3C);
2435 + val = ltq_readb(<q_dcdc_regs->conf_test_dig);
2436 + val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2437 + ltq_writeb(<q_dcdc_regs->conf_test_dig, val);
2439 + /* Init clock and DLL settings */
2440 + val = ltq_readb(<q_dcdc_regs->clk_set0);
2441 + val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P;
2442 + ltq_writeb(<q_dcdc_regs->clk_set0, val);
2443 + val = ltq_readb(<q_dcdc_regs->clk_set1);
2444 + val |= LTQ_DCDC_CLK_SET1_SEL_DIV25;
2445 + ltq_writeb(<q_dcdc_regs->clk_set1, val);
2446 + ltq_writeb(<q_dcdc_regs->pwm_confh, 0xF9);
2450 + /* Adapt value of digital reference of DCDC converter */
2451 + dig_ref_cur = ltq_readb(<q_dcdc_regs->bias_vreg1);
2453 + while (dig_ref_cur != dig_ref) {
2454 + if (dig_ref >= dig_ref_cur)
2456 + else if (dig_ref < dig_ref_cur)
2459 + ltq_writeb(<q_dcdc_regs->bias_vreg1, dig_ref_cur);
2463 diff --git a/arch/mips/cpu/mips32/vrx200/ebu.c b/arch/mips/cpu/mips32/vrx200/ebu.c
2464 new file mode 100644
2465 index 0000000..4ab3cf1
2467 +++ b/arch/mips/cpu/mips32/vrx200/ebu.c
2470 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2472 + * SPDX-License-Identifier: GPL-2.0+
2475 +#include <common.h>
2476 +#include <asm/arch/soc.h>
2477 +#include <asm/lantiq/io.h>
2479 +#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4)
2480 +#define EBU_ADDRSEL_REGEN (1 << 0)
2482 +#define EBU_CON_WRDIS (1 << 31)
2483 +#define EBU_CON_AGEN_DEMUX (0x0 << 24)
2484 +#define EBU_CON_AGEN_MUX (0x2 << 24)
2485 +#define EBU_CON_SETUP (1 << 22)
2486 +#define EBU_CON_WAIT_DIS (0x0 << 20)
2487 +#define EBU_CON_WAIT_ASYNC (0x1 << 20)
2488 +#define EBU_CON_WAIT_SYNC (0x2 << 20)
2489 +#define EBU_CON_WINV (1 << 19)
2490 +#define EBU_CON_PW_8BIT (0x0 << 16)
2491 +#define EBU_CON_PW_16BIT (0x1 << 16)
2492 +#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14)
2493 +#define EBU_CON_BCGEN_CS (0x0 << 12)
2494 +#define EBU_CON_BCGEN_INTEL (0x1 << 12)
2495 +#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12)
2496 +#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8)
2497 +#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6)
2498 +#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4)
2499 +#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2)
2500 +#define EBU_CON_CMULT_1 0x0
2501 +#define EBU_CON_CMULT_4 0x1
2502 +#define EBU_CON_CMULT_8 0x2
2503 +#define EBU_CON_CMULT_16 0x3
2505 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
2506 +#define ebu_region0_enable 1
2508 +#define ebu_region0_enable 0
2511 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
2512 +#define ebu_region1_enable 1
2514 +#define ebu_region1_enable 0
2517 +struct ltq_ebu_regs {
2535 +static struct ltq_ebu_regs *ltq_ebu_regs =
2536 + (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
2538 +void ltq_ebu_init(void)
2540 + if (ebu_region0_enable) {
2542 + * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
2543 + * region control. This supports up to 32 MiB NOR flash in
2546 + ltq_writel(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
2547 + EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
2549 + ltq_writel(<q_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
2550 + EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
2551 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
2552 + EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
2553 + EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
2554 + EBU_CON_CMULT_16);
2556 + ltq_clrbits(<q_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
2558 + if (ebu_region1_enable) {
2560 + * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
2561 + * region control. This supports NAND flash in bank 1.
2563 + ltq_writel(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
2564 + EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
2566 + ltq_writel(<q_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
2567 + EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
2568 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
2569 + EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
2570 + EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
2573 + ltq_clrbits(<q_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
2576 +void *flash_swap_addr(unsigned long addr)
2578 + return (void *)(addr ^ 2);
2580 diff --git a/arch/mips/cpu/mips32/vrx200/fw_phy11g_a1x.blob b/arch/mips/cpu/mips32/vrx200/fw_phy11g_a1x.blob
2581 new file mode 100644
2582 index 0000000..cdf3d30
2583 Binary files /dev/null and b/arch/mips/cpu/mips32/vrx200/fw_phy11g_a1x.blob differ
2584 diff --git a/arch/mips/cpu/mips32/vrx200/fw_phy11g_a2x.blob b/arch/mips/cpu/mips32/vrx200/fw_phy11g_a2x.blob
2585 new file mode 100644
2586 index 0000000..1559081
2587 Binary files /dev/null and b/arch/mips/cpu/mips32/vrx200/fw_phy11g_a2x.blob differ
2588 diff --git a/arch/mips/cpu/mips32/vrx200/fw_phy22f_a1x.blob b/arch/mips/cpu/mips32/vrx200/fw_phy22f_a1x.blob
2589 new file mode 100644
2590 index 0000000..02b88a0
2591 Binary files /dev/null and b/arch/mips/cpu/mips32/vrx200/fw_phy22f_a1x.blob differ
2592 diff --git a/arch/mips/cpu/mips32/vrx200/fw_phy22f_a2x.blob b/arch/mips/cpu/mips32/vrx200/fw_phy22f_a2x.blob
2593 new file mode 100644
2594 index 0000000..eeab2ab
2595 Binary files /dev/null and b/arch/mips/cpu/mips32/vrx200/fw_phy22f_a2x.blob differ
2596 diff --git a/arch/mips/cpu/mips32/vrx200/gphy.c b/arch/mips/cpu/mips32/vrx200/gphy.c
2597 new file mode 100644
2598 index 0000000..269ca5d
2600 +++ b/arch/mips/cpu/mips32/vrx200/gphy.c
2603 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2605 + * SPDX-License-Identifier: GPL-2.0+
2608 +#include <common.h>
2609 +#include <asm/lantiq/io.h>
2610 +#include <asm/arch/soc.h>
2611 +#include <asm/arch/gphy.h>
2613 +static inline void ltq_gphy_copy(const void *fw_start, const void *fw_end,
2616 + const ulong fw_len = (ulong) fw_end - (ulong) fw_start;
2617 + const ulong addr = CKSEG1ADDR(dst_addr);
2619 + debug("ltq_gphy_copy: addr %08lx, fw_start %p, fw_end %p\n",
2620 + addr, fw_start, fw_end);
2622 + memcpy((void *) addr, fw_start, fw_len);
2625 +void ltq_gphy_phy11g_a1x_load(ulong addr)
2627 + extern ulong __ltq_fw_phy11g_a1x_start;
2628 + extern ulong __ltq_fw_phy11g_a1x_end;
2630 + ltq_gphy_copy(&__ltq_fw_phy11g_a1x_start, &__ltq_fw_phy11g_a1x_end,
2634 +void ltq_gphy_phy11g_a2x_load(ulong addr)
2636 + extern ulong __ltq_fw_phy11g_a2x_start;
2637 + extern ulong __ltq_fw_phy11g_a2x_end;
2639 + ltq_gphy_copy(&__ltq_fw_phy11g_a2x_start, &__ltq_fw_phy11g_a2x_end,
2643 +void ltq_gphy_phy22f_a1x_load(ulong addr)
2645 + extern ulong __ltq_fw_phy22f_a1x_start;
2646 + extern ulong __ltq_fw_phy22f_a1x_end;
2648 + ltq_gphy_copy(&__ltq_fw_phy22f_a1x_start, &__ltq_fw_phy22f_a1x_end,
2652 +void ltq_gphy_phy22f_a2x_load(ulong addr)
2654 + extern ulong __ltq_fw_phy22f_a2x_start;
2655 + extern ulong __ltq_fw_phy22f_a2x_end;
2657 + ltq_gphy_copy(&__ltq_fw_phy22f_a2x_start, &__ltq_fw_phy22f_a2x_end,
2660 diff --git a/arch/mips/cpu/mips32/vrx200/gphy_fw.S b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
2661 new file mode 100644
2662 index 0000000..3a0417a
2664 +++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
2667 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2669 + * SPDX-License-Identifier: GPL-2.0+
2672 +#include <asm/asm.h>
2674 + .section .rodata.__ltq_fw_phy11g_a1x
2675 +EXPORT(__ltq_fw_phy11g_a1x_start)
2676 + .incbin "fw_phy11g_a1x.blob"
2677 +EXPORT(__ltq_fw_phy11g_a1x_end)
2679 + .section .rodata.__ltq_fw_phy11g_a2x
2680 +EXPORT(__ltq_fw_phy11g_a2x_start)
2681 + .incbin "fw_phy11g_a2x.blob"
2682 +EXPORT(__ltq_fw_phy11g_a2x_end)
2684 + .section .rodata.__ltq_fw_phy22f_a1x
2685 +EXPORT(__ltq_fw_phy22f_a1x_start)
2686 + .incbin "fw_phy22f_a1x.blob"
2687 +EXPORT(__ltq_fw_phy22f_a1x_end)
2689 + .section .rodata.__ltq_fw_phy22f_a2x
2690 +EXPORT(__ltq_fw_phy22f_a2x_start)
2691 + .incbin "fw_phy22f_a2x.blob"
2692 +EXPORT(__ltq_fw_phy22f_a2x_end)
2693 diff --git a/arch/mips/cpu/mips32/vrx200/mem.c b/arch/mips/cpu/mips32/vrx200/mem.c
2694 new file mode 100644
2695 index 0000000..c3e14ab
2697 +++ b/arch/mips/cpu/mips32/vrx200/mem.c
2700 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2702 + * SPDX-License-Identifier: GPL-2.0+
2705 +#include <common.h>
2706 +#include <asm/arch/soc.h>
2707 +#include <asm/lantiq/io.h>
2709 +#define LTQ_CCR03_EIGHT_BANK_MODE (1 << 0)
2710 +#define LTQ_CCR08_CS_MAP_SHIFT 24
2711 +#define LTQ_CCR08_CS_MAP_MASK (0x3 << LTQ_CCR08_CS_MAP_SHIFT)
2712 +#define LTQ_CCR11_COLUMN_SIZE_SHIFT 24
2713 +#define LTQ_CCR11_COLUMN_SIZE_MASK (0x7 << LTQ_CCR11_COLUMN_SIZE_SHIFT)
2714 +#define LTQ_CCR11_ADDR_PINS_MASK 0x7
2715 +#define LTQ_CCR15_MAX_COL_REG_SHIFT 24
2716 +#define LTQ_CCR15_MAX_COL_REG_MASK (0xF << LTQ_CCR15_MAX_COL_REG_SHIFT)
2717 +#define LTQ_CCR16_MAX_ROW_REG_MASK 0xF
2719 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
2721 +static inline u32 ltq_mc_ccr_read(u32 index)
2723 + return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index));
2726 +phys_size_t initdram(int board_type)
2728 + u32 max_col_reg, max_row_reg, column_size, addr_pins;
2729 + u32 banks, cs_map;
2732 + banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4;
2734 + cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >>
2735 + LTQ_CCR08_CS_MAP_SHIFT;
2737 + column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >>
2738 + LTQ_CCR11_COLUMN_SIZE_SHIFT;
2740 + addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK;
2742 + max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >>
2743 + LTQ_CCR15_MAX_COL_REG_SHIFT;
2745 + max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK;
2748 + * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects
2749 + * * datawidth (bytes)
2751 + size = (2 << (max_col_reg - column_size - 1)) *
2752 + (2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2;
2756 diff --git a/arch/mips/cpu/mips32/vrx200/mem_init.S b/arch/mips/cpu/mips32/vrx200/mem_init.S
2757 new file mode 100644
2758 index 0000000..a296845
2760 +++ b/arch/mips/cpu/mips32/vrx200/mem_init.S
2763 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2764 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2766 + * SPDX-License-Identifier: GPL-2.0+
2769 +#include <config.h>
2770 +#include <asm/asm.h>
2771 +#include <asm/regdef.h>
2772 +#include <asm/addrspace.h>
2773 +#include <asm/arch/soc.h>
2775 +/* Must be configured in BOARDDIR */
2776 +#include <ddr_settings.h>
2778 +#define LTQ_MC_DDR_START (1 << 8)
2779 +#define LTQ_MC_DDR_DLL_LOCK_IND 1
2781 +#define CCS_ALWAYS_LAST 0x0430
2782 +#define CCS_AHBM_CR_BURST_EN (1 << 2)
2783 +#define CCS_FPIM_CR_BURST_EN (1 << 1)
2785 +#define CCR03_EIGHT_BANK_MODE (1 << 0)
2787 + /* Store given value in MC DDR CCRx register */
2788 + .macro ccr_sw num, val
2790 + sw t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0)
2794 + /* Load MC DDR module base */
2795 + li t0, (LTQ_MC_DDR_BASE | KSEG1)
2797 + /* Put memory controller in inactive mode */
2798 + sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2800 + /* Init MC DDR CCR registers with values from ddr_settings.h */
2801 + ccr_sw 0, MC_CCR00_VALUE
2802 + ccr_sw 1, MC_CCR01_VALUE
2803 + ccr_sw 2, MC_CCR02_VALUE
2804 + ccr_sw 3, MC_CCR03_VALUE
2805 + ccr_sw 4, MC_CCR04_VALUE
2806 + ccr_sw 5, MC_CCR05_VALUE
2807 + ccr_sw 6, MC_CCR06_VALUE
2808 + ccr_sw 7, MC_CCR07_VALUE
2809 + ccr_sw 8, MC_CCR08_VALUE
2810 + ccr_sw 9, MC_CCR09_VALUE
2812 + ccr_sw 10, MC_CCR10_VALUE
2813 + ccr_sw 11, MC_CCR11_VALUE
2814 + ccr_sw 12, MC_CCR12_VALUE
2815 + ccr_sw 13, MC_CCR13_VALUE
2816 + ccr_sw 14, MC_CCR14_VALUE
2817 + ccr_sw 15, MC_CCR15_VALUE
2818 + ccr_sw 16, MC_CCR16_VALUE
2819 + ccr_sw 17, MC_CCR17_VALUE
2820 + ccr_sw 18, MC_CCR18_VALUE
2821 + ccr_sw 19, MC_CCR19_VALUE
2823 + ccr_sw 20, MC_CCR20_VALUE
2824 + ccr_sw 21, MC_CCR21_VALUE
2825 + ccr_sw 22, MC_CCR22_VALUE
2826 + ccr_sw 23, MC_CCR23_VALUE
2827 + ccr_sw 24, MC_CCR24_VALUE
2828 + ccr_sw 25, MC_CCR25_VALUE
2829 + ccr_sw 26, MC_CCR26_VALUE
2830 + ccr_sw 27, MC_CCR27_VALUE
2831 + ccr_sw 28, MC_CCR28_VALUE
2832 + ccr_sw 29, MC_CCR29_VALUE
2834 + ccr_sw 30, MC_CCR30_VALUE
2835 + ccr_sw 31, MC_CCR31_VALUE
2836 + ccr_sw 32, MC_CCR32_VALUE
2837 + ccr_sw 33, MC_CCR33_VALUE
2838 + ccr_sw 34, MC_CCR34_VALUE
2839 + ccr_sw 35, MC_CCR35_VALUE
2840 + ccr_sw 36, MC_CCR36_VALUE
2841 + ccr_sw 37, MC_CCR37_VALUE
2842 + ccr_sw 38, MC_CCR38_VALUE
2843 + ccr_sw 39, MC_CCR39_VALUE
2845 + ccr_sw 40, MC_CCR40_VALUE
2846 + ccr_sw 41, MC_CCR41_VALUE
2847 + ccr_sw 42, MC_CCR42_VALUE
2848 + ccr_sw 43, MC_CCR43_VALUE
2849 + ccr_sw 44, MC_CCR44_VALUE
2850 + ccr_sw 45, MC_CCR45_VALUE
2851 + ccr_sw 46, MC_CCR46_VALUE
2853 + ccr_sw 52, MC_CCR52_VALUE
2854 + ccr_sw 53, MC_CCR53_VALUE
2855 + ccr_sw 54, MC_CCR54_VALUE
2856 + ccr_sw 55, MC_CCR55_VALUE
2857 + ccr_sw 56, MC_CCR56_VALUE
2858 + ccr_sw 57, MC_CCR57_VALUE
2859 + ccr_sw 58, MC_CCR58_VALUE
2860 + ccr_sw 59, MC_CCR59_VALUE
2862 + ccr_sw 60, MC_CCR60_VALUE
2863 + ccr_sw 61, MC_CCR61_VALUE
2865 + /* Disable bursts between FPI Master bus and XBAR bus */
2866 + li t4, (LTQ_MC_GLOBAL_BASE | KSEG1)
2867 + li t5, CCS_AHBM_CR_BURST_EN
2868 + sw t5, CCS_ALWAYS_LAST(t4)
2870 + /* Init abort condition for DRAM probe */
2874 + * Put memory controller in active mode and start initialitation
2875 + * sequence for connected DDR-SDRAM device
2878 + lw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2879 + li t2, LTQ_MC_DDR_START
2881 + sw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2884 + * Wait until DLL has locked and core is ready for data transfers.
2885 + * DLL lock indication is in register CCR47 and CCR48
2888 + li t1, LTQ_MC_DDR_DLL_LOCK_IND
2889 + lw t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0)
2891 + bne t1, t2, wait_ready
2893 + lw t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0)
2895 + bne t1, t2, wait_ready
2897 +#ifdef CONFIG_SYS_DRAM_PROBE
2899 + /* Initialization is finished after the second MC start */
2900 + bnez t4, mc_finished
2903 + * Preload register values for CCR03 and CCR11. Initial settings
2904 + * are 8-bank mode enabled, 14 use address row bits, 10 used
2905 + * column address bits.
2907 + li t1, CONFIG_SYS_SDRAM_BASE_UC
2908 + li t5, MC_CCR03_VALUE
2909 + li t6, MC_CCR11_VALUE
2913 + * Store test values to DRAM at offsets 0 and 2^13 (bit 2 in bank select
2914 + * address BA[3]) and read back the value at offset 0. If the resulting
2915 + * value is equal to 1 we can skip to the next test. Otherwise
2916 + * the 8-bank mode does not work with the current DRAM device,
2917 + * thus we need to clear the according bit in register CCR03.
2925 + bnez t3, row_col_test
2927 + /* Clear CCR03.EIGHT_BANK_MODE */
2928 + li t3, ~CCR03_EIGHT_BANK_MODE
2933 + * Store test values to DRAM at offsets 0, 2^27 (bit 13 of row address
2934 + * RA[14]) and 2^26 (bit 12 of RA[14]). The chosen test values
2935 + * represent the difference between max. row address bits (14) and used
2936 + * row address bits. Then the read back value at offset 0 indicates
2937 + * the useable row address bits with the current DRAM device. This
2938 + * value must be set in the CCR11 register.
2952 + /* Update CCR11.ADDR_PINS */
2957 + * Store test values to DRAM at offsets 0, 2^10 (bit 9 of column address
2958 + * CA[10]) and 2^9 (bit 8 of CA[10]). The chosen test values represent
2959 + * the difference between max. column address bits (12) and used
2960 + * column address bits. Then the read back value at offset 0 indicates
2961 + * the useable column address bits with the current DRAM device. This
2962 + * value must be set in the CCR11 register.
2976 + /* Update CCR11.COLUMN_SIZE */
2981 + /* Put memory controller in inactive mode */
2982 + sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2984 + /* Update CCR03 and CCR11 and restart memory controller initialiation */
2985 + sw t5, LTQ_MC_DDR_CCR_OFFSET(3)(t0)
2986 + sw t6, LTQ_MC_DDR_CCR_OFFSET(11)(t0)
2990 +#endif /* CONFIG_SYS_DRAM_PROBE */
2995 diff --git a/arch/mips/cpu/mips32/vrx200/pmu.c b/arch/mips/cpu/mips32/vrx200/pmu.c
2996 new file mode 100644
2997 index 0000000..a144473
2999 +++ b/arch/mips/cpu/mips32/vrx200/pmu.c
3002 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3004 + * SPDX-License-Identifier: GPL-2.0+
3007 +#include <common.h>
3008 +#include <asm/lantiq/io.h>
3009 +#include <asm/lantiq/pm.h>
3010 +#include <asm/arch/soc.h>
3012 +#define LTQ_PMU_PWDCR_RESERVED ((1 << 13) | (1 << 4))
3014 +#define LTQ_PMU_PWDCR_PCIELOC_EN (1 << 31)
3015 +#define LTQ_PMU_PWDCR_GPHY (1 << 30)
3016 +#define LTQ_PMU_PWDCR_PPE_TOP (1 << 29)
3017 +#define LTQ_PMU_PWDCR_SWITCH (1 << 28)
3018 +#define LTQ_PMU_PWDCR_USB1 (1 << 27)
3019 +#define LTQ_PMU_PWDCR_USB1_PHY (1 << 26)
3020 +#define LTQ_PMU_PWDCR_TDM (1 << 25)
3021 +#define LTQ_PMU_PWDCR_PPE_DPLUS (1 << 24)
3022 +#define LTQ_PMU_PWDCR_PPE_DPLUM (1 << 23)
3023 +#define LTQ_PMU_PWDCR_PPE_EMA (1 << 22)
3024 +#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
3025 +#define LTQ_PMU_PWDCR_DEU (1 << 20)
3026 +#define LTQ_PMU_PWDCR_PPE_SLL01 (1 << 19)
3027 +#define LTQ_PMU_PWDCR_PPE_QSB (1 << 18)
3028 +#define LTQ_PMU_PWDCR_UART1 (1 << 17)
3029 +#define LTQ_PMU_PWDCR_SDIO (1 << 16)
3030 +#define LTQ_PMU_PWDCR_AHBM (1 << 15)
3031 +#define LTQ_PMU_PWDCR_FPIM (1 << 14)
3032 +#define LTQ_PMU_PWDCR_GPTC (1 << 12)
3033 +#define LTQ_PMU_PWDCR_LEDC (1 << 11)
3034 +#define LTQ_PMU_PWDCR_EBU (1 << 10)
3035 +#define LTQ_PMU_PWDCR_DSL (1 << 9)
3036 +#define LTQ_PMU_PWDCR_SPI (1 << 8)
3037 +#define LTQ_PMU_PWDCR_USIF (1 << 7)
3038 +#define LTQ_PMU_PWDCR_USB0 (1 << 6)
3039 +#define LTQ_PMU_PWDCR_DMA (1 << 5)
3040 +#define LTQ_PMU_PWDCR_DFEV1 (1 << 3)
3041 +#define LTQ_PMU_PWDCR_DFEV0 (1 << 2)
3042 +#define LTQ_PMU_PWDCR_FPIS (1 << 1)
3043 +#define LTQ_PMU_PWDCR_USB0_PHY (1 << 0)
3045 +struct ltq_pmu_regs {
3047 + u32 pwdcr; /* Power down control */
3048 + u32 sr; /* Power down status */
3049 + u32 pwdcr1; /* Power down control 1 */
3050 + u32 sr1; /* Power down status 1 */
3053 +static struct ltq_pmu_regs *ltq_pmu_regs =
3054 + (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
3056 +u32 ltq_pm_map(enum ltq_pm_modules module)
3062 + val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM |
3063 + LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
3066 + val = LTQ_PMU_PWDCR_DMA;
3069 + val = LTQ_PMU_PWDCR_GPHY | LTQ_PMU_PWDCR_PPE_TOP |
3070 + LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DPLUS |
3071 + LTQ_PMU_PWDCR_PPE_DPLUM | LTQ_PMU_PWDCR_PPE_EMA |
3072 + LTQ_PMU_PWDCR_PPE_TC | LTQ_PMU_PWDCR_PPE_SLL01 |
3073 + LTQ_PMU_PWDCR_PPE_QSB;
3076 + val = LTQ_PMU_PWDCR_SPI;
3086 +int ltq_pm_enable(enum ltq_pm_modules module)
3088 + const unsigned long timeout = 1000;
3089 + unsigned long timebase;
3092 + val = ltq_pm_map(module);
3093 + if (unlikely(!val))
3096 + ltq_clrbits(<q_pmu_regs->pwdcr, val);
3098 + timebase = get_timer(0);
3101 + sr = ltq_readl(<q_pmu_regs->sr);
3104 + } while (get_timer(timebase) < timeout);
3109 +int ltq_pm_disable(enum ltq_pm_modules module)
3113 + val = ltq_pm_map(module);
3114 + if (unlikely(!val))
3117 + ltq_setbits(<q_pmu_regs->pwdcr, val);
3122 +void ltq_pmu_init(void)
3126 + clr = ltq_pm_map(LTQ_PM_CORE);
3127 + set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
3129 + ltq_clrsetbits(<q_pmu_regs->pwdcr, clr, set);
3131 diff --git a/arch/mips/cpu/mips32/vrx200/rcu.c b/arch/mips/cpu/mips32/vrx200/rcu.c
3132 new file mode 100644
3133 index 0000000..763f287
3135 +++ b/arch/mips/cpu/mips32/vrx200/rcu.c
3138 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3140 + * SPDX-License-Identifier: GPL-2.0+
3143 +#include <common.h>
3144 +#include <asm/lantiq/io.h>
3145 +#include <asm/lantiq/reset.h>
3146 +#include <asm/lantiq/cpu.h>
3147 +#include <asm/arch/soc.h>
3149 +#define LTQ_RCU_RD_GPHY0 (1 << 31) /* GPHY0 */
3150 +#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
3151 +#define LTQ_RCU_RD_GPHY1 (1 << 29) /* GPHY1 */
3152 +#define LTQ_RCU_RD_ENMIP2 (1 << 28) /* Enable NMI of PLL2 */
3153 +#define LTQ_RCU_RD_REG25_PD (1 << 26) /* Power down 2.5V regulator */
3154 +#define LTQ_RCU_RD_ENDINIT (1 << 25) /* FPI slave bus access */
3155 +#define LTQ_RCU_RD_PPE_ATM_TC (1 << 23) /* PPE ATM TC */
3156 +#define LTQ_RCU_RD_PCIE (1 << 22) /* PCI-E core */
3157 +#define LTQ_RCU_RD_ETHSW (1 << 21) /* Ethernet switch */
3158 +#define LTQ_RCU_RD_DSP_DEN (1 << 20) /* Enable DSP JTAG */
3159 +#define LTQ_RCU_RD_TDM (1 << 19) /* TDM module interface */
3160 +#define LTQ_RCU_RD_ENMIP1 (1 << 18) /* Enable NMI of PLL1 */
3161 +#define LTQ_RCU_RD_SWBCK (1 << 17) /* Switch backward compat */
3162 +#define LTQ_RCU_RD_HSNAND (1 << 16) /* HSNAND controller */
3163 +#define LTQ_RCU_RD_ENMIP0 (1 << 15) /* Enable NMI of PLL0 */
3164 +#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
3165 +#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
3166 +#define LTQ_RCU_RD_PCIE_PHY (1 << 12) /* PCI-E Phy */
3167 +#define LTQ_RCU_RD_DFE_CORE (1 << 11) /* DFE core */
3168 +#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
3169 +#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
3170 +#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
3171 +#define LTQ_RCU_RD_DFE (1 << 7) /* DFE core */
3172 +#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
3173 +#define LTQ_RCU_RD_HRST_CFG (1 << 5) /* HW reset configuration */
3174 +#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
3175 +#define LTQ_RCU_RD_PPE_DSP (1 << 3) /* PPE DSP interface */
3176 +#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
3177 +#define LTQ_RCU_RD_CPU (1 << 1) /* CPU subsystem */
3178 +#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
3180 +#define LTQ_RCU_STAT_BOOT_SHIFT 17
3181 +#define LTQ_RCU_STAT_BOOT_MASK (0xF << LTQ_RCU_STAT_BOOT_SHIFT)
3182 +#define LTQ_RCU_STAT_BOOT_H (1 << 12)
3184 +#define LTQ_RCU_GP_STRAP_CLOCKSOURCE (1 << 15)
3186 +struct ltq_rcu_regs {
3188 + u32 req; /* Reset request */
3189 + u32 stat; /* Reset status */
3190 + u32 usb0_cfg; /* USB0 configure */
3191 + u32 gp_strap; /* GPIO strapping */
3192 + u32 gfs_add0; /* GPHY0 firmware base addr */
3193 + u32 stat2; /* SLIC and USB reset status */
3194 + u32 pci_rdy; /* PCI boot ready */
3195 + u32 ppe_conf; /* PPE ethernet config */
3196 + u32 pcie_phy_con; /* PCIE PHY config/status */
3197 + u32 usb1_cfg; /* USB1 configure */
3198 + u32 usb_ana_cfg1a; /* USB analog config 1a */
3199 + u32 usb_ana_cfg1b; /* USB analog config 1b */
3201 + u32 gf_mdio_add; /* GPHY0/1 MDIO address */
3202 + u32 req2; /* SLIC and USB reset request */
3203 + u32 ahb_endian; /* AHB bus endianess */
3205 + u32 gcc; /* General CPU config */
3207 + u32 gfs_add1; /* GPHY1 firmware base addr */
3210 +static struct ltq_rcu_regs *ltq_rcu_regs =
3211 + (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
3213 +u32 ltq_reset_map(enum ltq_reset_modules module)
3218 + case LTQ_RESET_CORE:
3219 + case LTQ_RESET_SOFT:
3220 + val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU | LTQ_RCU_RD_ENMIP2 |
3221 + LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
3223 + case LTQ_RESET_DMA:
3224 + val = LTQ_RCU_RD_DMA;
3226 + case LTQ_RESET_ETH:
3227 + val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
3229 + case LTQ_RESET_PHY:
3230 + val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
3232 + case LTQ_RESET_HARD:
3233 + val = LTQ_RCU_RD_HRST;
3243 +int ltq_reset_activate(enum ltq_reset_modules module)
3247 + val = ltq_reset_map(module);
3248 + if (unlikely(!val))
3251 + ltq_setbits(<q_rcu_regs->req, val);
3256 +int ltq_reset_deactivate(enum ltq_reset_modules module)
3260 + val = ltq_reset_map(module);
3261 + if (unlikely(!val))
3264 + ltq_clrbits(<q_rcu_regs->req, val);
3269 +enum ltq_boot_select ltq_boot_select(void)
3272 + unsigned int bootstrap;
3275 + * Boot select value is built from bits 20-17 and bit 12.
3276 + * The bit sequence is read as 4-2-1-0-3.
3278 + stat = ltq_readl(<q_rcu_regs->stat);
3279 + bootstrap = ((stat & LTQ_RCU_STAT_BOOT_H) << 4) |
3280 + ((stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT);
3282 + switch (bootstrap) {
3284 + return BOOT_NOR_NO_BOOTROM;
3286 + return BOOT_RGMII1;
3290 + return BOOT_UART_NO_EEPROM;
3300 + return BOOT_UNKNOWN;
3304 +void ltq_rcu_gphy_boot(unsigned int id, ulong addr)
3311 + module = LTQ_RCU_RD_GPHY0;
3312 + gfs_add = <q_rcu_regs->gfs_add0;
3315 + module = LTQ_RCU_RD_GPHY1;
3316 + gfs_add = <q_rcu_regs->gfs_add1;
3322 + /* Stop and reset GPHY */
3323 + ltq_setbits(<q_rcu_regs->req, module);
3325 + /* Configure firmware and boot address */
3326 + ltq_writel(gfs_add, CPHYSADDR(addr & 0xFFFFC000));
3328 + /* Start GPHY by releasing reset */
3329 + ltq_clrbits(<q_rcu_regs->req, module);
3331 diff --git a/arch/mips/include/asm/arch-danube/config.h b/arch/mips/include/asm/arch-danube/config.h
3332 new file mode 100644
3333 index 0000000..d84f66f
3335 +++ b/arch/mips/include/asm/arch-danube/config.h
3338 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
3339 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3341 + * SPDX-License-Identifier: GPL-2.0+
3343 + * Common board configuration for Lantiq XWAY Danube family
3345 + * Use following defines in your board config to enable specific features
3346 + * and drivers for this SoC:
3348 + * CONFIG_LTQ_SUPPORT_UART
3349 + * - support the Danube ASC/UART interface and console
3351 + * CONFIG_LTQ_SUPPORT_NOR_FLASH
3352 + * - support a parallel NOR flash via the CFI interface in flash bank 0
3354 + * CONFIG_LTQ_SUPPORT_ETHERNET
3355 + * - support the Danube ETOP and MAC interface
3357 + * CONFIG_LTQ_SUPPORT_SPI_FLASH
3358 + * - support the Danube SPI interface and serial flash drivers
3359 + * - specific SPI flash drivers must be configured separately
3362 +#ifndef __DANUBE_CONFIG_H__
3363 +#define __DANUBE_CONFIG_H__
3365 +/* CPU and SoC type */
3366 +#define CONFIG_SOC_LANTIQ
3367 +#define CONFIG_SOC_XWAY_DANUBE
3369 +/* Cache configuration */
3370 +#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
3371 +#define CONFIG_SYS_DCACHE_SIZE (16 * 1024)
3372 +#define CONFIG_SYS_ICACHE_SIZE (16 * 1024)
3373 +#define CONFIG_SYS_CACHELINE_SIZE 32
3374 +#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
3377 + * Supported clock modes
3378 + * PLL0 clock output is 333 MHz
3379 + * PLL1 clock output is 262.144 MHz
3381 +#define LTQ_CLK_CPU_333_DDR_167 0 /* Base PLL0, OCP 2 */
3382 +#define LTQ_CLK_CPU_111_DDR_111 1 /* Base PLL0, OCP 1 */
3385 +#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_333_DDR_167
3386 +#define CONFIG_SYS_MIPS_TIMER_FREQ 166666667
3387 +#define CONFIG_SYS_HZ 1000
3390 +#define CONFIG_NR_DRAM_BANKS 1
3391 +#define CONFIG_SYS_SDRAM_BASE 0x80000000
3392 +#define CONFIG_SYS_MEMTEST_START 0x81000000
3393 +#define CONFIG_SYS_MEMTEST_END 0x82000000
3394 +#define CONFIG_SYS_LOAD_ADDR 0x81000000
3395 +#define CONFIG_SYS_INIT_SP_OFFSET 0x4000
3398 +#define CONFIG_SYS_SRAM_BASE 0xBE1A0000
3399 +#define CONFIG_SYS_SRAM_SIZE 0x10000
3401 +/* ASC/UART driver and console */
3402 +#define CONFIG_LANTIQ_SERIAL
3403 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
3406 +#define CONFIG_LANTIQ_GPIO
3407 +#define CONFIG_LTQ_GPIO_MAX_BANKS 2
3410 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
3411 +#define CONFIG_SYS_MAX_FLASH_BANKS 1
3412 +#define CONFIG_SYS_MAX_FLASH_SECT 256
3413 +#define CONFIG_SYS_FLASH_BASE 0xB0000000
3414 +#define CONFIG_FLASH_16BIT
3415 +#define CONFIG_SYS_FLASH_CFI
3416 +#define CONFIG_FLASH_CFI_DRIVER
3417 +#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT
3418 +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
3419 +#define CONFIG_FLASH_SHOW_PROGRESS 50
3420 +#define CONFIG_SYS_FLASH_PROTECTION
3421 +#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
3423 +#define CONFIG_CMD_FLASH
3425 +#define CONFIG_SYS_NO_FLASH
3426 +#endif /* CONFIG_NOR_FLASH */
3428 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
3429 +#define CONFIG_LANTIQ_SPI
3430 +#define CONFIG_SPI_FLASH
3432 +#define CONFIG_CMD_SF
3433 +#define CONFIG_CMD_SPI
3436 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
3437 +#define CONFIG_NAND_LANTIQ
3438 +#define CONFIG_SYS_MAX_NAND_DEVICE 1
3439 +#define CONFIG_SYS_NAND_BASE 0xB4000000
3441 +#define CONFIG_CMD_NAND
3444 +#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
3445 +#define CONFIG_LANTIQ_DMA
3446 +#define CONFIG_LANTIQ_DANUBE_ETOP
3448 +#define CONFIG_PHYLIB
3451 +#define CONFIG_CMD_MII
3452 +#define CONFIG_CMD_NET
3455 +#define CONFIG_SPL_MAX_SIZE (32 * 1024)
3456 +#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024)
3457 +#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024)
3458 +#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024)
3459 +/*#define CONFIG_SPL_STACK_BSS_IN_SRAM*/
3461 +#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
3462 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \
3463 + CONFIG_SPL_MAX_SIZE + \
3464 + CONFIG_SPL_STACK_MAX_SIZE - 1)
3465 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
3466 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \
3467 + CONFIG_SYS_INIT_SP_OFFSET)
3469 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \
3470 + CONFIG_SYS_INIT_SP_OFFSET + \
3471 + CONFIG_SPL_STACK_MAX_SIZE - 1)
3472 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
3473 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \
3474 + CONFIG_SPL_BSS_MAX_SIZE)
3477 +#if defined(CONFIG_SYS_BOOT_RAM)
3478 +#define CONFIG_SYS_TEXT_BASE 0xa0100000
3479 +#define CONFIG_SKIP_LOWLEVEL_INIT
3480 +#define CONFIG_SYS_DISABLE_CACHE
3483 +#if defined(CONFIG_SYS_BOOT_NOR)
3484 +#define CONFIG_SYS_TEXT_BASE 0xB0000000
3487 +#if defined(CONFIG_SYS_BOOT_NORSPL)
3488 +#define CONFIG_SYS_TEXT_BASE 0x80100000
3489 +#define CONFIG_SPL_TEXT_BASE 0xB0000000
3492 +#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
3493 +#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C
3494 +#define CONFIG_XWAY_SWAP_BYTES
3497 +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
3499 +#endif /* __DANUBE_CONFIG_H__ */
3500 diff --git a/arch/mips/include/asm/arch-danube/gpio.h b/arch/mips/include/asm/arch-danube/gpio.h
3501 new file mode 100644
3502 index 0000000..70eb086
3504 +++ b/arch/mips/include/asm/arch-danube/gpio.h
3507 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3509 + * SPDX-License-Identifier: GPL-2.0+
3512 +#ifndef __DANUBE_GPIO_H__
3513 +#define __DANUBE_GPIO_H__
3515 +#include <asm/lantiq/gpio.h>
3517 +#endif /* __DANUBE_GPIO_H__ */
3518 diff --git a/arch/mips/include/asm/arch-danube/nand.h b/arch/mips/include/asm/arch-danube/nand.h
3519 new file mode 100644
3520 index 0000000..c7a573a
3522 +++ b/arch/mips/include/asm/arch-danube/nand.h
3525 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3527 + * SPDX-License-Identifier: GPL-2.0+
3530 +#ifndef __DANUBE_NAND_H__
3531 +#define __DANUBE_NAND_H__
3534 +int ltq_nand_init(struct nand_chip *nand);
3536 +#endif /* __DANUBE_NAND_H__ */
3537 diff --git a/arch/mips/include/asm/arch-danube/soc.h b/arch/mips/include/asm/arch-danube/soc.h
3538 new file mode 100644
3539 index 0000000..47ef62a
3541 +++ b/arch/mips/include/asm/arch-danube/soc.h
3544 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
3545 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3547 + * SPDX-License-Identifier: GPL-2.0+
3550 +#ifndef __DANUBE_SOC_H__
3551 +#define __DANUBE_SOC_H__
3553 +#define LTQ_ASC0_BASE 0x1E100400
3554 +#define LTQ_SPI_BASE 0x1E100800
3555 +#define LTQ_GPIO_BASE 0x1E100B00
3556 +#define LTQ_SSIO_BASE 0x1E100BB0
3557 +#define LTQ_ASC1_BASE 0x1E100C00
3558 +#define LTQ_DMA_BASE 0x1E104100
3560 +#define LTQ_EBU_BASE 0x1E105300
3561 +#define LTQ_EBU_REGION0_BASE 0x10000000
3562 +#define LTQ_EBU_REGION1_BASE 0x14000000
3563 +#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0)
3565 +#define LTQ_PPE_BASE 0x1E180000
3566 +#define LTQ_PPE_ETOP_BASE (LTQ_PPE_BASE + 0x11800)
3567 +#define LTQ_PPE_ENET0_BASE (LTQ_PPE_BASE + 0x11840)
3569 +#define LTQ_PMU_BASE 0x1F102000
3570 +#define LTQ_CGU_BASE 0x1F103000
3571 +#define LTQ_MPS_BASE 0x1F107000
3572 +#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340)
3573 +#define LTQ_RCU_BASE 0x1F203000
3575 +#define LTQ_MC_GEN_BASE 0x1F800000
3576 +#define LTQ_MC_SDR_BASE 0x1F800200
3577 +#define LTQ_MC_DDR_BASE 0x1F801000
3578 +#define LTQ_MC_DDR_DC_OFFSET(x) (x * 0x10)
3580 +#endif /* __DANUBE_SOC_H__ */
3581 diff --git a/arch/mips/include/asm/arch-vrx200/config.h b/arch/mips/include/asm/arch-vrx200/config.h
3582 new file mode 100644
3583 index 0000000..88ef256
3585 +++ b/arch/mips/include/asm/arch-vrx200/config.h
3588 + * Copyright (C) 2010 Lantiq Deutschland GmbH
3589 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3591 + * SPDX-License-Identifier: GPL-2.0+
3593 + * Common board configuration for Lantiq XWAY VRX200 family
3595 + * Use following defines in your board config to enable specific features
3596 + * and drivers for this SoC:
3598 + * CONFIG_LTQ_SUPPORT_UART
3599 + * - support the VRX200 ASC/UART interface and console
3601 + * CONFIG_LTQ_SUPPORT_NOR_FLASH
3602 + * - support a parallel NOR flash via the CFI interface in flash bank 0
3604 + * CONFIG_LTQ_SUPPORT_ETHERNET
3605 + * - support the VRX200 internal switch
3607 + * CONFIG_LTQ_SUPPORT_SPI_FLASH
3608 + * - support the VRX200 SPI interface and serial flash drivers
3609 + * - specific SPI flash drivers must be configured separately
3611 + * CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH
3612 + * - build a preloader that runs in the internal SRAM and loads
3613 + * the U-Boot from SPI flash into RAM
3616 +#ifndef __VRX200_CONFIG_H__
3617 +#define __VRX200_CONFIG_H__
3619 +/* CPU and SoC type */
3620 +#define CONFIG_SOC_LANTIQ
3621 +#define CONFIG_SOC_XWAY_VRX200
3623 +/* Cache configuration */
3624 +#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
3625 +#define CONFIG_SYS_DCACHE_SIZE (32 * 1024)
3626 +#define CONFIG_SYS_ICACHE_SIZE (32 * 1024)
3627 +#define CONFIG_SYS_CACHELINE_SIZE 32
3628 +#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
3631 + * Supported clock modes
3632 + * PLL0 clock output is 1000 MHz
3633 + * PLL1 clock output is 393.219 MHz
3635 +#define LTQ_CLK_CPU_600_DDR_300 0 /* Base PLL0, OCP 2 */
3636 +#define LTQ_CLK_CPU_600_DDR_200 1 /* Base PLL0, OCP 3 */
3637 +#define LTQ_CLK_CPU_500_DDR_250 2 /* Base PLL0, OCP 2 */
3638 +#define LTQ_CLK_CPU_500_DDR_200 3 /* Base PLL0, OCP 2.5 */
3639 +#define LTQ_CLK_CPU_333_DDR_167 4 /* Base PLL0, OCP 2 */
3640 +#define LTQ_CLK_CPU_167_DDR_167 5 /* Base PLL0, OCP 1 */
3641 +#define LTQ_CLK_CPU_125_DDR_125 6 /* Base PLL0, OCP 1 */
3642 +#define LTQ_CLK_CPU_393_DDR_197 7 /* Base PLL1, OCP 2 */
3643 +#define LTQ_CLK_CPU_197_DDR_197 8 /* Base PLL1, OCP 1 */
3646 +#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_500_DDR_250
3647 +#define CONFIG_SYS_MIPS_TIMER_FREQ 250000000
3648 +#define CONFIG_SYS_HZ 1000
3651 +#define CONFIG_NR_DRAM_BANKS 1
3652 +#define CONFIG_SYS_SDRAM_BASE 0x80000000
3653 +#define CONFIG_SYS_SDRAM_BASE_UC 0xa0000000
3654 +#define CONFIG_SYS_MEMTEST_START 0x81000000
3655 +#define CONFIG_SYS_MEMTEST_END 0x82000000
3656 +#define CONFIG_SYS_LOAD_ADDR 0x81000000
3657 +#define CONFIG_SYS_INIT_SP_OFFSET (32 * 1024)
3660 +#define CONFIG_SYS_SRAM_BASE 0xBE220000
3661 +#define CONFIG_SYS_SRAM_SIZE 0x10000
3663 +/* ASC/UART driver and console */
3664 +#define CONFIG_LANTIQ_SERIAL
3665 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
3668 +#define CONFIG_LANTIQ_GPIO
3669 +#define CONFIG_LTQ_GPIO_MAX_BANKS 3
3670 +#define CONFIG_LTQ_HAS_GPIO_BANK3
3673 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
3674 +#define CONFIG_SYS_MAX_FLASH_BANKS 1
3675 +#define CONFIG_SYS_MAX_FLASH_SECT 256
3676 +#define CONFIG_SYS_FLASH_BASE 0xB0000000
3677 +#define CONFIG_FLASH_16BIT
3678 +#define CONFIG_SYS_FLASH_CFI
3679 +#define CONFIG_FLASH_CFI_DRIVER
3680 +#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT
3681 +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
3682 +#define CONFIG_FLASH_SHOW_PROGRESS 50
3683 +#define CONFIG_SYS_FLASH_PROTECTION
3684 +#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
3686 +#define CONFIG_CMD_FLASH
3688 +#define CONFIG_SYS_NO_FLASH
3689 +#endif /* CONFIG_NOR_FLASH */
3691 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
3692 +#define CONFIG_LANTIQ_SPI
3693 +#define CONFIG_SPI_FLASH
3695 +#define CONFIG_CMD_SF
3696 +#define CONFIG_CMD_SPI
3699 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
3700 +#define CONFIG_NAND_LANTIQ
3701 +#define CONFIG_SYS_MAX_NAND_DEVICE 1
3702 +#define CONFIG_SYS_NAND_BASE 0xB4000000
3704 +#define CONFIG_CMD_NAND
3707 +#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
3708 +#define CONFIG_LANTIQ_DMA
3709 +#define CONFIG_LANTIQ_VRX200_SWITCH
3710 +#define CONFIG_PHY_LANTIQ
3712 +#define CONFIG_SYS_RX_ETH_BUFFER 8
3713 +#define CONFIG_PHYLIB
3715 +#define CONFIG_UDP_CHECKSUM
3717 +#define CONFIG_CMD_MII
3718 +#define CONFIG_CMD_NET
3721 +#define CONFIG_SPL_MAX_SIZE (32 * 1024)
3722 +#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024)
3723 +#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024)
3724 +#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024)
3725 +#define CONFIG_SPL_STACK_BSS_IN_SRAM
3727 +#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
3728 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \
3729 + CONFIG_SPL_MAX_SIZE + \
3730 + CONFIG_SPL_STACK_MAX_SIZE - 1)
3731 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
3732 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \
3733 + CONFIG_SYS_INIT_SP_OFFSET)
3735 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \
3736 + CONFIG_SYS_INIT_SP_OFFSET + \
3737 + CONFIG_SPL_STACK_MAX_SIZE - 1)
3738 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
3739 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \
3740 + CONFIG_SPL_BSS_MAX_SIZE)
3743 +#if defined(CONFIG_SYS_BOOT_RAM)
3744 +#define CONFIG_SYS_TEXT_BASE 0xA0100000
3745 +#define CONFIG_SKIP_LOWLEVEL_INIT
3746 +#define CONFIG_SYS_DISABLE_CACHE
3749 +#if defined(CONFIG_SYS_BOOT_NOR)
3750 +#define CONFIG_SYS_TEXT_BASE 0xB0000000
3753 +#if defined(CONFIG_SYS_BOOT_SFSPL)
3754 +#define CONFIG_SYS_TEXT_BASE 0x80100000
3755 +#define CONFIG_SPL_TEXT_BASE 0xBE220000
3758 +#if defined(CONFIG_SYS_BOOT_NORSPL)
3759 +#define CONFIG_SYS_TEXT_BASE 0x80100000
3760 +#define CONFIG_SPL_TEXT_BASE 0xB0000000
3763 +#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
3764 +#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C
3765 +#define CONFIG_XWAY_SWAP_BYTES
3768 +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
3770 +#endif /* __VRX200_CONFIG_H__ */
3771 diff --git a/arch/mips/include/asm/arch-vrx200/gphy.h b/arch/mips/include/asm/arch-vrx200/gphy.h
3772 new file mode 100644
3773 index 0000000..6cdb268
3775 +++ b/arch/mips/include/asm/arch-vrx200/gphy.h
3778 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3780 + * SPDX-License-Identifier: GPL-2.0+
3783 +#ifndef __VRX200_GPHY_H__
3784 +#define __VRX200_GPHY_H__
3786 +enum ltq_gphy_clk {
3787 + /* XTAL 36 MHz input */
3788 + LTQ_GPHY_CLK_36MHZ_XTAL = 1,
3789 + /* 25 MHz from PLL0 with divider */
3790 + LTQ_GPHY_CLK_25MHZ_PLL0 = 2,
3791 + /* derived from PLL2 output (XTAL is 36 MHz) */
3792 + LTQ_GPHY_CLK_24MHZ_PLL2 = 3,
3793 + /* 25 MHz Clock from Pin GPIO3 */
3794 + LTQ_GPHY_CLK_25MHZ_GPIO3 = 4,
3798 + * Load PHY11G firmware for VRX200 v1.1 to given RAM address
3800 + * Address must be 16k aligned!
3802 +extern void ltq_gphy_phy11g_a1x_load(ulong addr);
3805 + * Load PHY11G firmware for VRX200 v1.2 to given RAM address
3807 + * Address must be 16k aligned!
3809 +extern void ltq_gphy_phy11g_a2x_load(ulong addr);
3812 + * Load PHY22F firmware for VRX200 v1.1 to given RAM address
3814 + * Address must be 16k aligned!
3816 +extern void ltq_gphy_phy22f_a1x_load(ulong addr);
3819 + * Load PHY22F firmware for VRX200 v1.2 to given RAM address
3821 + * Address must be 16k aligned!
3823 +extern void ltq_gphy_phy22f_a2x_load(ulong addr);
3826 + * Set clock source of internal GPHYs
3828 + * According registers resides in CGU address space. Thus this function
3829 + * is implemented by the CGU driver.
3831 +extern void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk);
3834 + * Boot internal GPHY with id from given RAM address
3836 + * According registers resides in RCU address space. Thus this function
3837 + * is implemented by the RCU driver.
3839 +extern void ltq_rcu_gphy_boot(unsigned int id, ulong addr);
3841 +#endif /* __VRX200_GPHY_H__ */
3842 diff --git a/arch/mips/include/asm/arch-vrx200/gpio.h b/arch/mips/include/asm/arch-vrx200/gpio.h
3843 new file mode 100644
3844 index 0000000..b8d7676
3846 +++ b/arch/mips/include/asm/arch-vrx200/gpio.h
3849 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3851 + * SPDX-License-Identifier: GPL-2.0+
3854 +#ifndef __VRX200_GPIO_H__
3855 +#define __VRX200_GPIO_H__
3857 +#include <asm/lantiq/gpio.h>
3859 +#endif /* __VRX200_GPIO_H__ */
3860 diff --git a/arch/mips/include/asm/arch-vrx200/nand.h b/arch/mips/include/asm/arch-vrx200/nand.h
3861 new file mode 100644
3862 index 0000000..231b68f
3864 +++ b/arch/mips/include/asm/arch-vrx200/nand.h
3867 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3869 + * SPDX-License-Identifier: GPL-2.0+
3872 +#ifndef __VRX200_NAND_H__
3873 +#define __VRX200_NAND_H__
3876 +int ltq_nand_init(struct nand_chip *nand);
3878 +#endif /* __VRX200_NAND_H__ */
3879 diff --git a/arch/mips/include/asm/arch-vrx200/soc.h b/arch/mips/include/asm/arch-vrx200/soc.h
3880 new file mode 100644
3881 index 0000000..fae5906
3883 +++ b/arch/mips/include/asm/arch-vrx200/soc.h
3886 + * Copyright (C) 2010 Lantiq Deutschland GmbH
3887 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3889 + * SPDX-License-Identifier: GPL-2.0+
3892 +#ifndef __VRX200_SOC_H__
3893 +#define __VRX200_SOC_H__
3895 +#define LTQ_ASC0_BASE 0x1E100400
3896 +#define LTQ_SPI_BASE 0x1E100800
3897 +#define LTQ_GPIO_BASE 0x1E100B00
3898 +#define LTQ_SSIO_BASE 0x1E100BB0
3899 +#define LTQ_ASC1_BASE 0x1E100C00
3900 +#define LTQ_DMA_BASE 0x1E104100
3902 +#define LTQ_EBU_BASE 0x1E105300
3903 +#define LTQ_EBU_REGION0_BASE 0x10000000
3904 +#define LTQ_EBU_REGION1_BASE 0x14000000
3905 +#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0)
3907 +#define LTQ_SWITCH_BASE 0x1E108000
3908 +#define LTQ_SWITCH_CORE_BASE LTQ_SWITCH_BASE
3909 +#define LTQ_SWITCH_TOP_PDI_BASE LTQ_SWITCH_CORE_BASE
3910 +#define LTQ_SWITCH_BM_PDI_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x40)
3911 +#define LTQ_SWITCH_MAC_PDI_0_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x900)
3912 +#define LTQ_SWITCH_MAC_PDI_X_BASE(x) (LTQ_SWITCH_MAC_PDI_0_BASE + x * 0x30)
3913 +#define LTQ_SWITCH_TOPLEVEL_BASE (LTQ_SWITCH_BASE + 4 * 0xC40)
3914 +#define LTQ_SWITCH_MDIO_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE)
3915 +#define LTQ_SWITCH_MII_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x36)
3916 +#define LTQ_SWITCH_PMAC_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x82)
3918 +#define LTQ_PMU_BASE 0x1F102000
3919 +#define LTQ_CGU_BASE 0x1F103000
3920 +#define LTQ_DCDC_BASE 0x1F106A00
3921 +#define LTQ_MPS_BASE 0x1F107000
3922 +#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340)
3923 +#define LTQ_RCU_BASE 0x1F203000
3925 +#define LTQ_MC_GLOBAL_BASE 0x1F400000
3926 +#define LTQ_MC_DDR_BASE 0x1F401000
3927 +#define LTQ_MC_DDR_CCR_OFFSET(x) (x * 0x10)
3929 +#endif /* __VRX200_SOC_H__ */
3930 diff --git a/arch/mips/include/asm/arch-vrx200/switch.h b/arch/mips/include/asm/arch-vrx200/switch.h
3931 new file mode 100644
3932 index 0000000..e505099
3934 +++ b/arch/mips/include/asm/arch-vrx200/switch.h
3937 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3939 + * SPDX-License-Identifier: GPL-2.0+
3942 +#ifndef __VRX200_SWITCH_H__
3943 +#define __VRX200_SWITCH_H__
3945 +/* Switch core registers */
3946 +struct vr9_switch_core_regs {
3948 + /* TODO: implement registers */
3949 + __be32 rsvd0[0x3f];
3952 +/* Switch buffer management registers */
3953 +struct vr9_switch_bm_regs {
3955 + __be32 ram_val3; /* RAM value 3 */
3956 + __be32 ram_val2; /* RAM value 2 */
3957 + __be32 ram_val1; /* RAM value 1 */
3958 + __be32 ram_val0; /* RAM value 0 */
3959 + __be32 ram_addr; /* RAM address */
3960 + __be32 ram_ctrl; /* RAM access control */
3961 + __be32 fsqm_gctrl; /* Free segment queue global control */
3962 + __be32 cons_sel; /* Number of consumed segments */
3963 + __be32 cons_pkt; /* Number of consumed packet pointers */
3964 + __be32 gctrl; /* Global control */
3965 + __be32 queue_gctrl; /* Queue manager global control */
3966 + /* TODO: implement registers */
3967 + __be32 rsvd0[0x35];
3971 + __be32 pcfg; /* Port config */
3972 + __be32 rmon_ctrl; /* RMON control */
3975 + __be32 rsvd0[0x66];
3979 + __be32 pqm_rs; /* Packet queue manager rate shape assignment */
3982 + struct bm_shaper {
3983 + __be32 ctrl; /* Rate shaper control */
3984 + __be32 cbs; /* Rate shaper committed burst size */
3985 + __be32 ibs; /* Rate shaper instantaneous burst size */
3986 + __be32 cir_ext; /* Rate shaper rate exponent */
3987 + __be32 cir_mant; /* Rate shaper rate mantissa */
3990 + __be32 rsvd1[0x2a8];
3993 +/* Switch parser and classification engine registers */
3994 +struct vr9_switch_pce_regs {
3996 + __be32 tbl_key[16]; /* Table key data */
3997 + __be32 tbl_mask; /* Table mask */
3998 + __be32 tbl_val[5]; /* Table value */
3999 + __be32 tbl_addr; /* Table entry address */
4000 + __be32 tbl_ctrl; /* Table access control */
4001 + __be32 tbl_stat; /* Table general status */
4002 + __be32 age_0; /* Aging counter config 0 */
4003 + __be32 age_1; /* Aging counter config 1 */
4004 + __be32 pmap_1; /* Port map (monitoring) */
4005 + __be32 pmap_2; /* Port map (multicast) */
4006 + __be32 pmap_3; /* Port map (unknown unicast) */
4007 + __be32 gctrl_0; /* Global control 0 */
4008 + __be32 gctrl_1; /* Global control 1 */
4009 + __be32 tcm_gctrl; /* Three-color marker global control */
4010 + __be32 igmp_ctrl; /* IGMP control */
4011 + __be32 igmp_drpm; /* IGMP default router port map */
4012 + __be32 igmp_age_0; /* IGMP aging 0 */
4013 + __be32 igmp_age_1; /* IGMP aging 1 */
4014 + __be32 igmp_stat; /* IGMP status */
4015 + __be32 wol_gctrl; /* Wake-on-LAN control */
4016 + __be32 wol_da_0; /* Wake-on-LAN destination address 0 */
4017 + __be32 wol_da_1; /* Wake-on-LAN destination address 1 */
4018 + __be32 wol_da_2; /* Wake-on-LAN destination address 2 */
4019 + __be32 wol_pw_0; /* Wake-on-LAN password 0 */
4020 + __be32 wol_pw_1; /* Wake-on-LAN password 1 */
4021 + __be32 wol_pw_2; /* Wake-on-LAN password 2 */
4022 + __be32 ier_0; /* PCE global interrupt enable 0 */
4023 + __be32 ier_1; /* PCE global interrupt enable 1 */
4024 + __be32 isr_0; /* PCE global interrupt status 0 */
4025 + __be32 isr_1; /* PCE global interrupt status 1 */
4026 + __be32 parser_stat; /* Parser status */
4027 + __be32 rsvd0[0x6];
4030 + __be32 rsvd0[0x10];
4033 + __be32 pctrl_0; /* Port control 0 */
4034 + __be32 pctrl_1; /* Port control 1 */
4035 + __be32 pctrl_2; /* Port control 2 */
4036 + __be32 pctrl_3; /* Port control 3 */
4037 + __be32 wol_ctrl; /* Wake-on-LAN control */
4038 + __be32 vlan_ctrl; /* VLAN control */
4039 + __be32 def_pvid; /* Default port VID */
4040 + __be32 pstat; /* Port status */
4041 + __be32 pier; /* Interrupt enable */
4042 + __be32 pisr; /* Interrupt status */
4045 + __be32 rsvd1[0x7e];
4047 + struct pce_meter {
4048 + /* TODO: implement registers */
4049 + __be32 rsvd0[0x7];
4052 + __be32 rsvd2[0x308];
4055 +static inline unsigned int to_pce_tbl_key_id(unsigned int id)
4062 +static inline unsigned int to_pce_tbl_value_id(unsigned int id)
4069 +/* Switch ethernet MAC registers */
4070 +struct vr9_switch_mac_regs {
4072 + __be32 test; /* MAC test */
4073 + __be32 pfad_cfg; /* Pause frame source address config */
4074 + __be32 pfsa_0; /* Pause frame source address 0 */
4075 + __be32 pfsa_1; /* Pause frame source address 1 */
4076 + __be32 pfsa_2; /* Pause frame source address 2 */
4077 + __be32 flen; /* Frame length */
4078 + __be32 vlan_etype_0; /* VLAN ethertype 0 */
4079 + __be32 vlan_etype_1; /* VLAN ethertype 1 */
4080 + __be32 ier; /* Interrupt enable */
4081 + __be32 isr; /* Interrupt status */
4082 + __be32 rsvd0[0x36];
4086 + __be32 pstat; /* Port status */
4087 + __be32 pisr; /* Interrupt status */
4088 + __be32 pier; /* Interrupt enable */
4089 + __be32 ctrl_0; /* Control 0 */
4090 + __be32 ctrl_1; /* Control 1 */
4091 + __be32 ctrl_2; /* Control 2 */
4092 + __be32 ctrl_3; /* Control 3 */
4093 + __be32 ctrl_4; /* Control 4 */
4094 + __be32 ctrl_5; /* Control 5 */
4095 + __be32 rsvd0[0x2];
4096 + __be32 testen; /* Test enable */
4099 + __be32 rsvd0[0xa4];
4102 +/* Switch Fetch DMA registers */
4103 +struct vr9_switch_fdma_regs {
4104 + struct fdma_core {
4105 + __be32 ctrl; /* FDMA control */
4106 + __be32 stetype; /* Special tag ethertype control */
4107 + __be32 vtetype; /* VLAN tag ethertype control */
4108 + __be32 stat; /* FDMA status */
4109 + __be32 ier; /* FDMA interrupt enable */
4110 + __be32 isr; /* FDMA interrupt status */
4113 + __be32 rsvd0[0x3a];
4115 + struct fdma_port {
4116 + __be32 pctrl; /* Port control */
4117 + __be32 prio; /* Port priority */
4118 + __be32 pstat_0; /* Port status 0 */
4119 + __be32 pstat_1; /* Port status 1 */
4120 + __be32 tstamp_0; /* Egress time stamp 0 */
4121 + __be32 tstamp_1; /* Egress time stamp 1 */
4124 + __be32 rsvd1[0x72];
4127 +/* Switch Store DMA registers */
4128 +struct vr9_switch_sdma_regs {
4129 + struct sdma_core {
4130 + __be32 ctrl; /* SDMA Control */
4131 + __be32 fcthr_1; /* Flow control threshold 1 */
4133 + __be32 fcthr_3; /* Flow control threshold 3 */
4134 + __be32 fcthr_4; /* Flow control threshold 4 */
4135 + __be32 fcthr_5; /* Flow control threshold 5 */
4136 + __be32 fcthr_6; /* Flow control threshold 6 */
4137 + __be32 fcthr_7; /* Flow control threshold 7 */
4138 + __be32 stat_0; /* SDMA status 0 */
4139 + __be32 stat_1; /* SDMA status 1 */
4140 + __be32 stat_2; /* SDMA status 2 */
4141 + __be32 ier; /* SDMA interrupt enable */
4142 + __be32 isr; /* SDMA interrupt status */
4145 + __be32 rsvd0[0x73];
4147 + struct sdma_port {
4148 + __be32 pctrl; /* Port control */
4149 + __be32 prio; /* Port priority */
4150 + __be32 pstat_0; /* Port status 0 */
4151 + __be32 pstat_1; /* Port status 1 */
4152 + __be32 tstamp_0; /* Ingress time stamp 0 */
4153 + __be32 tstamp_1; /* Ingress time stamp 1 */
4156 + __be32 rsvd1[0x32];
4159 +/* Switch MDIO control and status registers */
4160 +struct vr9_switch_mdio_regs {
4161 + __be32 glob_ctrl; /* Global control 0 */
4163 + __be32 mdio_ctrl; /* MDIO control */
4164 + __be32 mdio_read; /* MDIO read data */
4165 + __be32 mdio_write; /* MDIO write data */
4166 + __be32 mdc_cfg_0; /* MDC clock configuration 0 */
4167 + __be32 mdc_cfg_1; /* MDC clock configuration 1 */
4168 + __be32 rsvd1[0x3];
4169 + __be32 phy_addr[6]; /* PHY address port 5..0 */
4170 + __be32 mdio_stat[6]; /* MDIO PHY polling status port 0..5 */
4171 + __be32 aneg_eee[6]; /* EEE auto-neg overrides port 0..5 */
4172 + __be32 rsvd2[0x14];
4175 +static inline unsigned int to_mdio_phyaddr_id(unsigned int id)
4182 +/* Switch xMII control registers */
4183 +struct vr9_switch_mii_regs {
4184 + __be32 mii_cfg0; /* xMII port 0 configuration */
4185 + __be32 pcdu0; /* Port 0 clock delay configuration */
4186 + __be32 mii_cfg1; /* xMII port 1 configuration */
4187 + __be32 pcdu1; /* Port 1 clock delay configuration */
4188 + __be32 rsvd0[0x6];
4189 + __be32 mii_cfg5; /* xMII port 5 configuration */
4190 + __be32 pcdu5; /* Port 5 clock delay configuration */
4191 + __be32 rsvd1[0x14];
4192 + __be32 rxb_ctl_0; /* Port 0 receive buffer control */
4193 + __be32 rxb_ctl_1; /* Port 1 receive buffer control */
4194 + __be32 rxb_ctl_5; /* Port 5 receive buffer control */
4195 + __be32 rsvd2[0x28];
4196 + __be32 dbg_ctl; /* Debug control */
4199 +/* Switch Pseudo-MAC registers */
4200 +struct vr9_switch_pmac_regs {
4201 + __be32 hd_ctl; /* PMAC header control */
4202 + __be32 tl; /* PMAC type/length */
4203 + __be32 sa1; /* PMAC source address 1 */
4204 + __be32 sa2; /* PMAC source address 2 */
4205 + __be32 sa3; /* PMAC source address 3 */
4206 + __be32 da1; /* PMAC destination address 1 */
4207 + __be32 da2; /* PMAC destination address 2 */
4208 + __be32 da3; /* PMAC destination address 3 */
4209 + __be32 vlan; /* PMAC VLAN */
4210 + __be32 rx_ipg; /* PMAC interpacket gap in RX direction */
4211 + __be32 st_etype; /* PMAC special tag ethertype */
4212 + __be32 ewan; /* PMAC ethernet WAN group */
4213 + __be32 ctl; /* PMAC control */
4214 + __be32 rsvd0[0x2];
4217 +struct vr9_switch_regs {
4218 + struct vr9_switch_core_regs core;
4219 + struct vr9_switch_bm_regs bm;
4220 + struct vr9_switch_pce_regs pce;
4221 + struct vr9_switch_mac_regs mac;
4222 + struct vr9_switch_fdma_regs fdma;
4223 + struct vr9_switch_sdma_regs sdma;
4224 + struct vr9_switch_mdio_regs mdio;
4225 + struct vr9_switch_mii_regs mii;
4226 + struct vr9_switch_pmac_regs pmac;
4229 +static inline void *to_pce_tbl_key(struct vr9_switch_regs *regs,
4232 + return ®s->pce.core.tbl_key[to_pce_tbl_key_id(id)];
4235 +static inline void *to_pce_tbl_value(struct vr9_switch_regs *regs,
4238 + return ®s->pce.core.tbl_val[to_pce_tbl_value_id(id)];
4241 +static inline void *to_mac_ctrl(struct vr9_switch_regs *regs,
4242 + unsigned int id, unsigned int ctrl)
4244 + struct mac_port *mac = ®s->mac.port[id];
4248 + return &mac->ctrl_0;
4250 + return &mac->ctrl_1;
4252 + return &mac->ctrl_2;
4254 + return &mac->ctrl_3;
4256 + return &mac->ctrl_4;
4258 + return &mac->ctrl_5;
4264 +static inline void *to_mdio_phyaddr(struct vr9_switch_regs *regs,
4267 + return ®s->mdio.phy_addr[to_mdio_phyaddr_id(id)];
4270 +static inline void *to_mii_miicfg(struct vr9_switch_regs *regs,
4275 + return ®s->mii.mii_cfg0;
4277 + return ®s->mii.mii_cfg1;
4279 + return ®s->mii.mii_cfg5;
4285 +static inline void *to_mii_pcdu(struct vr9_switch_regs *regs,
4290 + return ®s->mii.pcdu0;
4292 + return ®s->mii.pcdu1;
4294 + return ®s->mii.pcdu5;
4300 +#define VR9_SWITCH_REG_OFFSET(reg) (4 * (reg))
4302 +#define BUILD_CHECK_VR9_REG(name, offset) \
4303 + BUILD_BUG_ON(offsetof(struct vr9_switch_regs, name) != (4 * offset))
4305 +static inline void build_check_vr9_registers(void)
4307 + BUILD_CHECK_VR9_REG(core, 0x0);
4308 + BUILD_CHECK_VR9_REG(bm.core, 0x40);
4309 + BUILD_CHECK_VR9_REG(bm.core.queue_gctrl, 0x4a);
4310 + BUILD_CHECK_VR9_REG(bm.port[0], 0x80);
4311 + BUILD_CHECK_VR9_REG(bm.queue, 0x100);
4312 + BUILD_CHECK_VR9_REG(bm.shaper, 0x140);
4313 + BUILD_CHECK_VR9_REG(pce.core, 0x438);
4314 + BUILD_CHECK_VR9_REG(pce.core.tbl_ctrl, 0x44f);
4315 + BUILD_CHECK_VR9_REG(pce.core.parser_stat, 0x469);
4316 + BUILD_CHECK_VR9_REG(pce.port[0], 0x480);
4317 + BUILD_CHECK_VR9_REG(pce.meter[0], 0x580);
4318 + BUILD_CHECK_VR9_REG(mac.core, 0x8c0);
4319 + BUILD_CHECK_VR9_REG(mac.port[0].pstat, 0x900);
4320 + BUILD_CHECK_VR9_REG(mac.port[0].ctrl_0, 0x903);
4321 + BUILD_CHECK_VR9_REG(mac.port[1].pstat, 0x90c);
4322 + BUILD_CHECK_VR9_REG(mac.port[1].ctrl_0, 0x90f);
4323 + BUILD_CHECK_VR9_REG(mac.port[2].pstat, 0x918);
4324 + BUILD_CHECK_VR9_REG(mac.port[2].ctrl_0, 0x91b);
4325 + BUILD_CHECK_VR9_REG(fdma.core, 0xa40);
4326 + BUILD_CHECK_VR9_REG(fdma.port[0], 0xa80);
4327 + BUILD_CHECK_VR9_REG(sdma.core, 0xb40);
4328 + BUILD_CHECK_VR9_REG(sdma.port[0], 0xbc0);
4329 + BUILD_CHECK_VR9_REG(mdio, 0xc40);
4330 + BUILD_CHECK_VR9_REG(mii, (0xc40 + 0x36));
4331 + BUILD_CHECK_VR9_REG(pmac, (0xc40 + 0x82));
4334 +#define BM_GCTRL_F_SRES 1
4336 +#define MAC_CTRL0_BM (1 << 12)
4337 +#define MAC_CTRL0_APADEN (1 << 11)
4338 +#define MAC_CTRL0_VPAD2EN (1 << 10)
4339 +#define MAC_CTRL0_VPADEN (1 << 9)
4340 +#define MAC_CTRL0_PADEN (1 << 8)
4341 +#define MAC_CTRL0_FCS (1 << 7)
4342 +#define MAC_CTRL0_FCON_SHIFT 4
4343 +#define MAC_CTRL0_FCON_AUTO (0x0 << MAC_CTRL0_FCON_SHIFT)
4344 +#define MAC_CTRL0_FCON_RX (0x1 << MAC_CTRL0_FCON_SHIFT)
4345 +#define MAC_CTRL0_FCON_TX (0x2 << MAC_CTRL0_FCON_SHIFT)
4346 +#define MAC_CTRL0_FCON_RXTX (0x3 << MAC_CTRL0_FCON_SHIFT)
4347 +#define MAC_CTRL0_FCON_NONE (0x4 << MAC_CTRL0_FCON_SHIFT)
4348 +#define MAC_CTRL0_FDUP_SHIFT 2
4349 +#define MAC_CTRL0_FDUP_AUTO (0x0 << MAC_CTRL0_FDUP_SHIFT)
4350 +#define MAC_CTRL0_FDUP_EN (0x1 << MAC_CTRL0_FDUP_SHIFT)
4351 +#define MAC_CTRL0_FDUP_DIS (0x3 << MAC_CTRL0_FDUP_SHIFT)
4352 +#define MAC_CTRL0_GMII_AUTO 0x0
4353 +#define MAC_CTRL0_GMII_MII 0x1
4354 +#define MAC_CTRL0_GMII_GMII 0x2
4355 +#define MAC_CTRL0_GMII_GMII_2G 0x3
4357 +#define MAC_CTRL1_DEFERMODE (1 << 15)
4358 +#define MAC_CTRL1_SHORTPRE (1 << 8)
4360 +#define MAC_CTRL2_MLEN (1 << 3)
4361 +#define MAC_CTRL2_LCHKL (1 << 2)
4362 +#define MAC_CTRL2_LCHKS_DIS 0x0
4363 +#define MAC_CTRL2_LCHKS_UNTAG 0x1
4364 +#define MAC_CTRL2_LCHKS_TAG 0x2
4366 +#define PHY_ADDR_LNKST_SHIFT 13
4367 +#define PHY_ADDR_LNKST_AUTO (0x0 << PHY_ADDR_LNKST_SHIFT)
4368 +#define PHY_ADDR_LNKST_UP (0x1 << PHY_ADDR_LNKST_SHIFT)
4369 +#define PHY_ADDR_LNKST_DOWN (0x2 << PHY_ADDR_LNKST_SHIFT)
4370 +#define PHY_ADDR_SPEED_SHIFT 11
4371 +#define PHY_ADDR_SPEED_M10 (0x0 << PHY_ADDR_SPEED_SHIFT)
4372 +#define PHY_ADDR_SPEED_M100 (0x1 << PHY_ADDR_SPEED_SHIFT)
4373 +#define PHY_ADDR_SPEED_G1 (0x2 << PHY_ADDR_SPEED_SHIFT)
4374 +#define PHY_ADDR_SPEED_AUTO (0x3 << PHY_ADDR_SPEED_SHIFT)
4375 +#define PHY_ADDR_FDUP_SHIFT 9
4376 +#define PHY_ADDR_FDUP_AUTO (0x0 << PHY_ADDR_FDUP_SHIFT)
4377 +#define PHY_ADDR_FDUP_EN (0x1 << PHY_ADDR_FDUP_SHIFT)
4378 +#define PHY_ADDR_FDUP_DIS (0x3 << PHY_ADDR_FDUP_SHIFT)
4379 +#define PHY_ADDR_FCONTX_SHIFT 7
4380 +#define PHY_ADDR_FCONTX_AUTO (0x0 << PHY_ADDR_FCONTX_SHIFT)
4381 +#define PHY_ADDR_FCONTX_EN (0x1 << PHY_ADDR_FCONTX_SHIFT)
4382 +#define PHY_ADDR_FCONTX_DIS (0x3 << PHY_ADDR_FCONTX_SHIFT)
4383 +#define PHY_ADDR_FCONRX_SHIFT 5
4384 +#define PHY_ADDR_FCONRX_AUTO (0x0 << PHY_ADDR_FCONRX_SHIFT)
4385 +#define PHY_ADDR_FCONRX_EN (0x1 << PHY_ADDR_FCONRX_SHIFT)
4386 +#define PHY_ADDR_FCONRX_DIS (0x3 << PHY_ADDR_FCONRX_SHIFT)
4388 +#define MII_CFG_RES (1 << 15)
4389 +#define MII_CFG_EN (1 << 14)
4390 +#define MII_CFG_LDCLKDIS (1 << 12)
4391 +#define MII_CFG_MIIRATE_SHIFT 4
4392 +#define MII_CFG_MIIRATE_MASK (0x7 << MII_CFG_MIIRATE_SHIFT)
4393 +#define MII_CFG_MIIRATE_M2P5 (0x0 << MII_CFG_MIIRATE_SHIFT)
4394 +#define MII_CFG_MIIRATE_M25 (0x1 << MII_CFG_MIIRATE_SHIFT)
4395 +#define MII_CFG_MIIRATE_M125 (0x2 << MII_CFG_MIIRATE_SHIFT)
4396 +#define MII_CFG_MIIRATE_M50 (0x3 << MII_CFG_MIIRATE_SHIFT)
4397 +#define MII_CFG_MIIRATE_AUTO (0x4 << MII_CFG_MIIRATE_SHIFT)
4398 +#define MII_CFG_MIIMODE_MASK 0xf
4399 +#define MII_CFG_MIIMODE_MIIP 0x0
4400 +#define MII_CFG_MIIMODE_MIIM 0x1
4401 +#define MII_CFG_MIIMODE_RMIIP 0x2
4402 +#define MII_CFG_MIIMODE_RMIIM 0x3
4403 +#define MII_CFG_MIIMODE_RGMII 0x4
4405 +#define PCDU_RXDLY_SHIFT 7
4406 +#define PCDU_RXDLY_MASK (0x7 << PCDU_RXDLY_SHIFT)
4407 +#define PCDU_TXDLY_MASK 0x7
4409 +#define PMAC_HD_CTL_FC (1 << 10)
4410 +#define PMAC_HD_CTL_CCRC (1 << 9)
4411 +#define PMAC_HD_CTL_RST (1 << 8)
4412 +#define PMAC_HD_CTL_AST (1 << 7)
4413 +#define PMAC_HD_CTL_RXSH (1 << 6)
4414 +#define PMAC_HD_CTL_RC (1 << 4)
4415 +#define PMAC_HD_CTL_AS (1 << 3)
4416 +#define PMAC_HD_CTL_AC (1 << 2)
4418 +#define PCE_PCTRL_0_IGSTEN (1 << 11)
4420 +#define FDMA_PCTRL_STEN (1 << 1)
4421 +#define FDMA_PCTRL_EN (1 << 0)
4423 +#define SDMA_PCTRL_EN (1 << 0)
4425 +#define MDIO_GLOB_CTRL_SE (1 << 15)
4427 +#define MDIO_MDC_CFG1_RES (1 << 15)
4428 +#define MDIO_MDC_CFG1_MCEN (1 << 8)
4430 +#define MDIO_CTRL_MBUSY (1 << 12)
4431 +#define MDIO_CTRL_OP_READ (1 << 11)
4432 +#define MDIO_CTRL_OP_WRITE (1 << 10)
4433 +#define MDIO_CTRL_PHYAD_SHIFT 5
4434 +#define MDIO_CTRL_PHYAD_MASK (0x1f << MDIO_CTRL_PHYAD_SHIFT)
4435 +#define MDIO_CTRL_REGAD_MASK 0x1f
4437 +#endif /* __VRX200_SWITCH_H__ */
4438 diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h
4439 index 933ccb1..dd0ffb6 100644
4440 --- a/arch/mips/include/asm/asm.h
4441 +++ b/arch/mips/include/asm/asm.h
4444 .type symbol, @function; \
4446 + .section .text.symbol,"x"; \
4447 symbol: .frame sp, 0, ra
4450 @@ -62,7 +63,8 @@ symbol: .frame sp, 0, ra
4453 .type symbol, @function; \
4456 + .section .text.symbol,"x"; \
4457 symbol: .frame sp, framesize, rpc
4460 diff --git a/arch/mips/include/asm/gpio.h b/arch/mips/include/asm/gpio.h
4461 new file mode 100644
4462 index 0000000..9be58b8
4464 +++ b/arch/mips/include/asm/gpio.h
4467 + * SPDX-License-Identifier: GPL-2.0+
4470 +#include <asm/arch/gpio.h>
4471 +#include <asm-generic/gpio.h>
4472 diff --git a/arch/mips/include/asm/lantiq/chipid.h b/arch/mips/include/asm/lantiq/chipid.h
4473 new file mode 100644
4474 index 0000000..c9921b0
4476 +++ b/arch/mips/include/asm/lantiq/chipid.h
4479 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4481 + * SPDX-License-Identifier: GPL-2.0+
4484 +#ifndef __LANTIQ_CHIPID_H__
4485 +#define __LANTIQ_CHIPID_H__
4487 +enum ltq_chip_partnum {
4488 + LTQ_SOC_UNKNOWN = 0,
4489 + LTQ_SOC_VRX288_2 = 0x000B, /* VRX288 v1.2 */
4490 + LTQ_SOC_VRX268_2 = 0x000C, /* VRX268 v1.2 */
4491 + LTQ_SOC_GRX288_2 = 0x000D, /* GRX288 v1.2 */
4492 + LTQ_SOC_DANUBE = 0x0129,
4493 + LTQ_SOC_DANUBE_S = 0x012B,
4494 + LTQ_SOC_TWINPASS = 0x012D,
4495 + LTQ_SOC_VRX288 = 0x01C0, /* VRX288 v1.1 */
4496 + LTQ_SOC_VRX268 = 0x01C2, /* VRX268 v1.1 */
4497 + LTQ_SOC_GRX288 = 0x01C9, /* GRX288 v1.1 */
4500 +extern unsigned int ltq_chip_version_get(void);
4501 +extern unsigned int ltq_chip_partnum_get(void);
4502 +extern const char *ltq_chip_partnum_str(void);
4504 +extern void ltq_chip_print_info(void);
4506 +#ifdef CONFIG_SOC_XWAY_DANUBE
4507 +static inline int ltq_soc_is_danube(void)
4512 +static inline int ltq_soc_is_danube(void)
4518 +#ifdef CONFIG_SOC_XWAY_VRX200
4519 +static inline int ltq_soc_is_vrx200(void)
4524 +static inline int ltq_soc_is_vrx200_v1(void)
4526 + return ltq_chip_version_get() == 1;
4529 +static inline int ltq_soc_is_vrx200_v2(void)
4531 + return ltq_chip_version_get() == 2;
4534 +static inline int ltq_soc_is_vrx200(void)
4539 +static inline int ltq_soc_is_vrx200_v1(void)
4544 +static inline int ltq_soc_is_vrx200_v2(void)
4550 +#endif /* __LANTIQ_CHIPID_H__ */
4551 diff --git a/arch/mips/include/asm/lantiq/clk.h b/arch/mips/include/asm/lantiq/clk.h
4552 new file mode 100644
4553 index 0000000..e13f000
4555 +++ b/arch/mips/include/asm/lantiq/clk.h
4558 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
4559 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4561 + * SPDX-License-Identifier: GPL-2.0+
4564 +#ifndef __LANTIQ_CLK_H__
4565 +#define __LANTIQ_CLK_H__
4567 +/* Symbolic clock speeds */
4569 + CLOCK_83_MHZ = 83333333,
4570 + CLOCK_111_MHZ = 111111111,
4571 + CLOCK_125_MHZ = 125000000,
4572 + CLOCK_133_MHZ = 133333333,
4573 + CLOCK_166_MHZ = 166666667,
4574 + CLOCK_197_MHZ = 197000000,
4575 + CLOCK_333_MHZ = 333333333,
4576 + CLOCK_393_MHZ = 393219000,
4577 + CLOCK_500_MHZ = 500000000,
4578 + CLOCK_600_MHZ = 600000000,
4579 + CLOCK_1000_MHZ = 1000000000,
4582 +extern unsigned long ltq_get_cpu_clock(void);
4583 +extern unsigned long ltq_get_bus_clock(void);
4584 +extern unsigned long ltq_get_io_region_clock(void);
4586 +#endif /* __LANTIQ_CLK_H__ */
4587 diff --git a/arch/mips/include/asm/lantiq/config.h b/arch/mips/include/asm/lantiq/config.h
4588 new file mode 100644
4589 index 0000000..feac30d
4591 +++ b/arch/mips/include/asm/lantiq/config.h
4594 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
4595 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4597 + * SPDX-License-Identifier: GPL-2.0+
4600 +#ifndef __LANTIQ_CONFIG_H__
4601 +#define __LANTIQ_CONFIG_H__
4604 +#define CONFIG_SYS_MAXARGS 24
4605 +#define CONFIG_SYS_MALLOC_LEN 1024*1024
4606 +#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024
4609 +#define CONFIG_SYS_PROMPT CONFIG_MACH_TYPE " # "
4610 +#define CONFIG_SYS_CBSIZE 512
4611 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
4612 + sizeof(CONFIG_SYS_PROMPT)+16)
4614 +#define CONFIG_SYS_HUSH_PARSER
4615 +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
4618 + * Enable advanced console features on demand to reduce
4619 + * flash and RAM footprint
4621 +#if defined(CONFIG_LTQ_ADVANCED_CONSOLE)
4622 +#define CONFIG_SYS_LONGHELP
4623 +#define CONFIG_AUTO_COMPLETE
4624 +#define CONFIG_CMDLINE_EDITING
4627 +/* SPI flash SPL */
4628 +#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
4630 +#define CONFIG_SPL_SPI_SUPPORT
4631 +#define CONFIG_SPL_SPI_FLASH_SUPPORT
4632 +#define CONFIG_SPI_SPL_SIMPLE
4635 +#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
4640 +#if defined(CONFIG_SPL)
4641 +#define CONFIG_SKIP_LOWLEVEL_INIT
4642 +#define CONFIG_SPL_LIBGENERIC_SUPPORT
4643 +#define CONFIG_SPL_GPIO_SUPPORT
4644 +#define CONFIG_SPL_START_S_PATH \
4645 + "arch/mips/cpu/mips32/lantiq-common"
4646 +#define CONFIG_SPL_LDSCRIPT \
4647 + "arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds"
4650 +#if defined(CONFIG_LTQ_SPL_CONSOLE)
4651 +#define CONFIG_SPL_SERIAL_SUPPORT
4652 +#define CONFIG_SPL_LIBCOMMON_SUPPORT
4655 +#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
4656 +#define CONFIG_LZMA
4657 +#define CONFIG_SPL_LZMA_SUPPORT
4660 +#if defined(CONFIG_LTQ_SPL_COMP_LZO)
4662 +#define CONFIG_SPL_LZO_SUPPORT
4665 +/* Basic commands */
4666 +#define CONFIG_CMD_BDI
4667 +#define CONFIG_CMD_EDITENV
4668 +#define CONFIG_CMD_IMI
4669 +#define CONFIG_CMD_MEMORY
4670 +#define CONFIG_CMD_RUN
4671 +#define CONFIG_CMD_SAVEENV
4672 +#define CONFIG_CMD_LOADB
4674 +/* Other U-Boot settings */
4675 +#define CONFIG_TIMESTAMP
4677 +/* Default environment */
4678 +#define CONFIG_ENV_CONSOLEDEV \
4679 + "consoledev=" CONFIG_CONSOLE_DEV "\0"
4681 +#define CONFIG_ENV_ADDCONSOLE \
4682 + "addconsole=setenv bootargs $bootargs" \
4683 + " console=$consoledev,$baudrate\0"
4685 +#if defined(CONFIG_NET_DEV)
4686 +#define CONFIG_ENV_NETDEV \
4687 + "netdev=" CONFIG_NET_DEV "\0"
4689 +#define CONFIG_ENV_NETDEV \
4693 +#define CONFIG_ENV_ADDIP \
4694 + "addip=setenv bootargs $bootargs" \
4695 + " ip=$ipaddr:$serverip::::$netdev:off\0"
4697 +#define CONFIG_ENV_ADDETH \
4698 + "addeth=setenv bootargs $bootargs" \
4699 + " ethaddr=$ethaddr\0"
4701 +#define CONFIG_ENV_ADDMACHTYPE \
4702 + "addmachtype=setenv bootargs $bootargs" \
4703 + " machtype=" CONFIG_MACH_TYPE "\0"
4705 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
4706 +#define CONFIG_ENV_WRITE_UBOOT_NOR \
4707 + "write-uboot-nor=" \
4708 + "protect off " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
4709 + "erase " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
4710 + "cp.b $fileaddr " __stringify(CONFIG_SYS_FLASH_BASE) " $filesize\0"
4712 +#define CONFIG_ENV_LOAD_UBOOT_NOR \
4713 + "load-uboot-nor=tftpboot u-boot.bin\0" \
4714 + "load-uboot-norspl=tftpboot u-boot.ltq.norspl\0" \
4715 + "load-uboot-norspl-lzo=tftpboot u-boot.ltq.lzo.norspl\0" \
4716 + "load-uboot-norspl-lzma=tftpboot u-boot.ltq.lzma.norspl\0"
4718 +#define CONFIG_ENV_WRITE_UBOOT_NOR
4719 +#define CONFIG_ENV_LOAD_UBOOT_NOR
4722 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
4723 +#define CONFIG_ENV_SF_PROBE \
4724 + "sf-probe=sf probe " __stringify(CONFIG_ENV_SPI_CS) " " \
4725 + __stringify(CONFIG_ENV_SPI_MAX_HZ) " " \
4726 + __stringify(CONFIG_ENV_SPI_MODE) " \0"
4728 +#define CONFIG_ENV_WRITE_UBOOT_SF \
4729 + "write-uboot-sf=" \
4730 + "run sf-probe && sf erase 0 +$filesize && " \
4731 + "sf write $fileaddr 0 $filesize\0"
4733 +#define CONFIG_ENV_LOAD_UBOOT_SF \
4734 + "load-uboot-sfspl=tftpboot u-boot.ltq.sfspl\0" \
4735 + "load-uboot-sfspl-lzo=tftpboot u-boot.ltq.lzo.sfspl\0" \
4736 + "load-uboot-sfspl-lzma=tftpboot u-boot.ltq.lzma.sfspl\0"
4738 +#define CONFIG_ENV_SF_PROBE
4739 +#define CONFIG_ENV_WRITE_UBOOT_SF
4740 +#define CONFIG_ENV_LOAD_UBOOT_SF
4743 +#define CONFIG_ENV_LANTIQ_DEFAULTS \
4744 + CONFIG_ENV_CONSOLEDEV \
4745 + CONFIG_ENV_ADDCONSOLE \
4746 + CONFIG_ENV_NETDEV \
4747 + CONFIG_ENV_ADDIP \
4748 + CONFIG_ENV_ADDETH \
4749 + CONFIG_ENV_ADDMACHTYPE \
4750 + CONFIG_ENV_WRITE_UBOOT_NOR \
4751 + CONFIG_ENV_LOAD_UBOOT_NOR \
4752 + CONFIG_ENV_SF_PROBE \
4753 + CONFIG_ENV_WRITE_UBOOT_SF \
4754 + CONFIG_ENV_LOAD_UBOOT_SF
4756 +#endif /* __LANTIQ_CONFIG_H__ */
4757 diff --git a/arch/mips/include/asm/lantiq/cpu.h b/arch/mips/include/asm/lantiq/cpu.h
4758 new file mode 100644
4759 index 0000000..b3a504e
4761 +++ b/arch/mips/include/asm/lantiq/cpu.h
4764 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4766 + * SPDX-License-Identifier: GPL-2.0+
4769 +#ifndef __LANTIQ_CPU_H__
4770 +#define __LANTIQ_CPU_H__
4772 +enum ltq_boot_select {
4774 + BOOT_NOR_NO_BOOTROM,
4776 + BOOT_UART_NO_EEPROM,
4786 +enum ltq_boot_select ltq_boot_select(void);
4787 +const char *ltq_boot_select_str(void);
4789 +void ltq_pmu_init(void);
4790 +void ltq_ebu_init(void);
4791 +void ltq_gpio_init(void);
4793 +void ltq_pll_init(void);
4794 +void ltq_dcdc_init(unsigned int dig_ref);
4796 +#endif /* __LANTIQ_CPU_H__ */
4797 diff --git a/arch/mips/include/asm/lantiq/dma.h b/arch/mips/include/asm/lantiq/dma.h
4798 new file mode 100644
4799 index 0000000..15a29c9
4801 +++ b/arch/mips/include/asm/lantiq/dma.h
4804 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4806 + * SPDX-License-Identifier: GPL-2.0+
4809 +#ifndef __LANTIQ_DMA_H__
4810 +#define __LANTIQ_DMA_H__
4812 +enum ltq_dma_endianess {
4813 + LTQ_DMA_ENDIANESS_B0_B1_B2_B3, /* No byte swapping */
4814 + LTQ_DMA_ENDIANESS_B1_B0_B3_B2, /* B0B1B2B3 => B1B0B3B2 */
4815 + LTQ_DMA_ENDIANESS_B2_B3_B0_B1, /* B0B1B2B3 => B2B3B0B1 */
4816 + LTQ_DMA_ENDIANESS_B3_B2_B1_B0, /* B0B1B2B3 => B3B2B1B0 */
4819 +enum ltq_dma_burst_len {
4820 + LTQ_DMA_BURST_2WORDS = 1,
4821 + LTQ_DMA_BURST_4WORDS = 2,
4822 + LTQ_DMA_BURST_8WORDS = 3,
4825 +struct ltq_dma_desc {
4830 +struct ltq_dma_channel {
4831 + struct ltq_dma_device *dev;
4835 + struct ltq_dma_desc *desc_base;
4840 +struct ltq_dma_device {
4841 + enum ltq_dma_endianess rx_endian_swap;
4842 + enum ltq_dma_endianess tx_endian_swap;
4843 + enum ltq_dma_burst_len rx_burst_len;
4844 + enum ltq_dma_burst_len tx_burst_len;
4845 + struct ltq_dma_channel rx_chan;
4846 + struct ltq_dma_channel tx_chan;
4851 + * Initialize DMA hardware and driver
4853 +void ltq_dma_init(void);
4856 + * Register given DMA client context
4858 + * @returns 0 on success, negative value otherwise
4860 +int ltq_dma_register(struct ltq_dma_device *dev);
4863 + * Reset and halt all channels related to given DMA client
4865 +void ltq_dma_reset(struct ltq_dma_device *dev);
4866 +void ltq_dma_enable(struct ltq_dma_device *dev);
4867 +void ltq_dma_disable(struct ltq_dma_device *dev);
4870 + * Map RX DMA descriptor to memory region
4872 + * @returns 0 on success, negative value otherwise
4874 +int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len);
4877 + * Check if new data is available.
4879 + * @returns length of received data, 0 otherwise
4881 +int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index);
4883 +int ltq_dma_rx_length(struct ltq_dma_device *dev, int index);
4886 + * Map TX DMA descriptor to memory region
4888 + * @returns 0 on success, negative value otherwise
4890 +int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
4891 + unsigned long timeout);
4893 +int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
4894 + unsigned long timeout);
4896 +#endif /* __LANTIQ_DMA_H__ */
4897 diff --git a/arch/mips/include/asm/lantiq/eth.h b/arch/mips/include/asm/lantiq/eth.h
4898 new file mode 100644
4899 index 0000000..d09e9cf
4901 +++ b/arch/mips/include/asm/lantiq/eth.h
4904 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4906 + * SPDX-License-Identifier: GPL-2.0+
4909 +#ifndef __LANTIQ_ETH_H__
4910 +#define __LANTIQ_ETH_H__
4914 +enum LTQ_ETH_PORT_FLAGS {
4915 + LTQ_ETH_PORT_NONE = 0,
4916 + LTQ_ETH_PORT_PHY = 1,
4917 + LTQ_ETH_PORT_SWITCH = (1 << 1),
4918 + LTQ_ETH_PORT_MAC = (1 << 2),
4921 +struct ltq_eth_port_config {
4925 + phy_interface_t phy_if;
4926 + u8 rgmii_rx_delay;
4927 + u8 rgmii_tx_delay;
4930 +struct ltq_eth_board_config {
4931 + const struct ltq_eth_port_config *ports;
4935 +extern int ltq_eth_initialize(const struct ltq_eth_board_config *board_config);
4937 +#endif /* __LANTIQ_ETH_H__ */
4938 diff --git a/arch/mips/include/asm/lantiq/gpio.h b/arch/mips/include/asm/lantiq/gpio.h
4939 new file mode 100644
4940 index 0000000..66e227f
4942 +++ b/arch/mips/include/asm/lantiq/gpio.h
4945 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4947 + * SPDX-License-Identifier: GPL-2.0+
4950 +#ifndef __LANTIQ_GPIO_H__
4951 +#define __LANTIQ_GPIO_H__
4953 +enum ltq_gpio_dir {
4959 + GPIO_OD_ACTIVE = 0,
4963 +enum ltq_gpio_altsel {
4964 + GPIO_ALTSEL_CLR = 0,
4968 +extern int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir);
4969 +extern int gpio_set_opendrain(unsigned gpio, int od);
4971 +static inline int gpio_to_port(unsigned gpio)
4976 +static inline int gpio_to_pin(unsigned gpio)
4978 + return gpio & 0xF;
4981 +static inline int gpio_to_bit(unsigned gpio)
4983 + return 1 << gpio_to_pin(gpio);
4986 +static inline int gpio_to_gpio(unsigned port, unsigned pin)
4988 + return (port << 4) | (pin & 0xF);
4991 +#include <asm-generic/gpio.h>
4993 +#endif /* __LANTIQ_GPIO_H__ */
4994 diff --git a/arch/mips/include/asm/lantiq/io.h b/arch/mips/include/asm/lantiq/io.h
4995 new file mode 100644
4996 index 0000000..5ac7696
4998 +++ b/arch/mips/include/asm/lantiq/io.h
5001 + * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
5002 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5004 + * SPDX-License-Identifier: GPL-2.0+
5007 +#ifndef __LANTIQ_IO_H__
5008 +#define __LANTIQ_IO_H__
5010 +#include <asm/io.h>
5012 +#define ltq_readb(a) __raw_readb(a)
5013 +#define ltq_writeb(a, v) __raw_writeb(v, a)
5015 +#define ltq_readl(a) __raw_readl(a)
5016 +#define ltq_writel(a, v) __raw_writel(v, a)
5018 +#define ltq_clrbits(a, clear) \
5019 + ltq_writel(a, ltq_readl(a) & ~(clear))
5021 +#define ltq_setbits(a, set) \
5022 + ltq_writel(a, ltq_readl(a) | (set))
5024 +#define ltq_clrsetbits(a, clear, set) \
5025 + ltq_writel(a, (ltq_readl(a) & ~(clear)) | (set))
5027 +static inline void ltq_reg_dump(const void *addr, const char *desc)
5031 + data = ltq_readl(addr);
5032 + printf("ltq_reg_dump: %s 0x%p = 0x%08x\n",
5033 + desc, addr, data);
5036 +#endif /* __LANTIQ_IO_H__ */
5037 diff --git a/arch/mips/include/asm/lantiq/pm.h b/arch/mips/include/asm/lantiq/pm.h
5038 new file mode 100644
5039 index 0000000..9db7117
5041 +++ b/arch/mips/include/asm/lantiq/pm.h
5044 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5046 + * SPDX-License-Identifier: GPL-2.0+
5049 +#ifndef __LANTIQ_PM_H__
5050 +#define __LANTIQ_PM_H__
5052 +enum ltq_pm_modules {
5059 +u32 ltq_pm_map(enum ltq_pm_modules module);
5060 +int ltq_pm_enable(enum ltq_pm_modules module);
5061 +int ltq_pm_disable(enum ltq_pm_modules module);
5063 +#endif /* __LANTIQ_PM_H__ */
5064 diff --git a/arch/mips/include/asm/lantiq/reset.h b/arch/mips/include/asm/lantiq/reset.h
5065 new file mode 100644
5066 index 0000000..0dbc994
5068 +++ b/arch/mips/include/asm/lantiq/reset.h
5071 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5073 + * SPDX-License-Identifier: GPL-2.0+
5076 +#ifndef __LANTIQ_RESET_H__
5077 +#define __LANTIQ_RESET_H__
5079 +enum ltq_reset_modules {
5088 +extern u32 ltq_reset_map(enum ltq_reset_modules module);
5089 +extern int ltq_reset_activate(enum ltq_reset_modules module);
5090 +extern int ltq_reset_deactivate(enum ltq_reset_modules module);
5092 +static inline int ltq_reset_once(enum ltq_reset_modules module, ulong usec)
5096 + ret = ltq_reset_activate(module);
5101 + ret = ltq_reset_deactivate(module);
5106 +#endif /* __LANTIQ_RESET_H__ */
5107 diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
5108 index be7e5c6..b3bc255 100644
5109 --- a/arch/mips/include/asm/mipsregs.h
5110 +++ b/arch/mips/include/asm/mipsregs.h
5112 #define CP0_ENTRYLO1 $3
5114 #define CP0_CONTEXT $4
5115 +#define CP0_CONTEXTCONFIG $4,1
5116 +#define CP0_USERLOCAL $4,1
5117 #define CP0_PAGEMASK $5
5118 +#define CP0_PAGEGRAIN $5,1
5119 #define CP0_WIRED $6
5121 #define CP0_BADVADDR $8
5123 #define CP0_ENTRYHI $10
5124 #define CP0_COMPARE $11
5125 #define CP0_STATUS $12
5126 +#define CP0_INTCTL $12,1
5127 +#define CP0_SRSCTL $12,2
5128 +#define CP0_SRSMAP $12,3
5129 +#define CP0_SRSHIGH $12,4
5130 #define CP0_CAUSE $13
5132 #define CP0_PRID $15
5133 +#define CP0_EBASE $15,1
5134 #define CP0_CONFIG $16
5135 +#define CP0_CONFIG1 $16,1
5136 +#define CP0_CONFIG2 $16,2
5137 +#define CP0_CONFIG3 $16,3
5138 +#define CP0_CONFIG7 $16,7
5139 #define CP0_LLADDR $17
5140 #define CP0_WATCHLO $18
5141 #define CP0_WATCHHI $19
5144 #define CP0_CACHEERR $27
5145 #define CP0_TAGLO $28
5146 +#define CP0_ITAGLO $28
5147 +#define CP0_IDATALO $28,1
5148 +#define CP0_DTAGLO $28,2
5149 +#define CP0_DDATALO $28,3
5150 +#define CP0_L23TAGLO $28,4
5151 +#define CP0_L23DATALO $28,5
5152 #define CP0_TAGHI $29
5153 +#define CP0_IDATAHI $29,1
5154 +#define CP0_DTAGHI $29,2
5155 +#define CP0_L23TAGHI $29,4
5156 +#define CP0_L23DATAHI $29,5
5157 #define CP0_ERROREPC $30
5158 #define CP0_DESAVE $31
5160 @@ -395,6 +417,12 @@
5161 #define CAUSEF_BD (_ULCAST_(1) << 31)
5164 + * Bits in the coprocessor 0 EBase register.
5166 +#define EBASEB_CPUNUM 0
5167 +#define EBASEF_CPUNUM (_ULCAST_(1023))
5170 * Bits in the coprocessor 0 config register.
5173 diff --git a/arch/mips/include/asm/u-boot-mips.h b/arch/mips/include/asm/u-boot-mips.h
5174 index 9f3cce9..30fb469 100644
5175 --- a/arch/mips/include/asm/u-boot-mips.h
5176 +++ b/arch/mips/include/asm/u-boot-mips.h
5177 @@ -23,3 +23,4 @@ static inline unsigned long image_copy_end(void)
5180 extern int incaip_set_cpuclk(void);
5181 +extern int arch_cpu_init(void);
5182 diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c
5183 index 9e6ba15..daa0182 100644
5184 --- a/arch/mips/lib/board.c
5185 +++ b/arch/mips/lib/board.c
5186 @@ -33,6 +33,16 @@ static char *failed = "*** failed ***\n";
5188 const unsigned long mips_io_port_base = -1;
5190 +int __arch_cpu_init(void)
5193 + * Nothing to do in this dummy implementation
5197 +int arch_cpu_init(void)
5198 + __attribute__((weak, alias("__arch_cpu_init")));
5200 int __board_early_init_f(void)
5203 @@ -106,6 +116,7 @@ static int init_baudrate(void)
5204 typedef int (init_fnc_t)(void);
5206 init_fnc_t *init_sequence[] = {
5210 env_init, /* initialize environment */
5211 diff --git a/board/lantiq/easy50712/Makefile b/board/lantiq/easy50712/Makefile
5212 new file mode 100644
5213 index 0000000..3a547c2
5215 +++ b/board/lantiq/easy50712/Makefile
5218 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
5220 +# SPDX-License-Identifier: GPL-2.0+
5223 +include $(TOPDIR)/config.mk
5225 +LIB = $(obj)lib$(BOARD).o
5229 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
5230 +OBJS := $(addprefix $(obj),$(COBJS))
5231 +SOBJS := $(addprefix $(obj),$(SOBJS))
5233 +$(LIB): $(obj).depend $(OBJS) $(SOBJS)
5234 + $(call cmd_link_o_target, $(OBJS) $(SOBJS))
5236 +#########################################################################
5238 +# defines $(obj).depend target
5239 +include $(SRCTREE)/rules.mk
5241 +sinclude $(obj).depend
5243 +#########################################################################
5244 diff --git a/board/lantiq/easy50712/config.mk b/board/lantiq/easy50712/config.mk
5245 new file mode 100644
5246 index 0000000..9d8953b
5248 +++ b/board/lantiq/easy50712/config.mk
5251 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5253 +# SPDX-License-Identifier: GPL-2.0+
5256 +PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
5257 diff --git a/board/lantiq/easy50712/ddr_settings.h b/board/lantiq/easy50712/ddr_settings.h
5258 new file mode 100644
5259 index 0000000..36a4118
5261 +++ b/board/lantiq/easy50712/ddr_settings.h
5264 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
5265 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5267 + * SPDX-License-Identifier: GPL-2.0+
5270 +#define MC_DC00_VALUE 0x1B1B
5271 +#define MC_DC01_VALUE 0x0
5272 +#define MC_DC02_VALUE 0x0
5273 +#define MC_DC03_VALUE 0x0
5274 +#define MC_DC04_VALUE 0x0
5275 +#define MC_DC05_VALUE 0x200
5276 +#define MC_DC06_VALUE 0x605
5277 +#define MC_DC07_VALUE 0x303
5278 +#define MC_DC08_VALUE 0x102
5279 +#define MC_DC09_VALUE 0x70a
5280 +#define MC_DC10_VALUE 0x203
5281 +#define MC_DC11_VALUE 0xc02
5282 +#define MC_DC12_VALUE 0x1C8
5283 +#define MC_DC13_VALUE 0x1
5284 +#define MC_DC14_VALUE 0x0
5285 +#define MC_DC15_VALUE 0x13c
5286 +#define MC_DC16_VALUE 0xC800
5287 +#define MC_DC17_VALUE 0xd
5288 +#define MC_DC18_VALUE 0x300
5289 +#define MC_DC19_VALUE 0x200
5290 +#define MC_DC20_VALUE 0xA04
5291 +#define MC_DC21_VALUE 0xd00
5292 +#define MC_DC22_VALUE 0xd0d
5293 +#define MC_DC23_VALUE 0x0
5294 +#define MC_DC24_VALUE 0x62
5295 +#define MC_DC25_VALUE 0x0
5296 +#define MC_DC26_VALUE 0x0
5297 +#define MC_DC27_VALUE 0x0
5298 +#define MC_DC28_VALUE 0x510
5299 +#define MC_DC29_VALUE 0x2d89
5300 +#define MC_DC30_VALUE 0x8300
5301 +#define MC_DC31_VALUE 0x0
5302 +#define MC_DC32_VALUE 0x0
5303 +#define MC_DC33_VALUE 0x0
5304 +#define MC_DC34_VALUE 0x0
5305 +#define MC_DC35_VALUE 0x0
5306 +#define MC_DC36_VALUE 0x0
5307 +#define MC_DC37_VALUE 0x0
5308 +#define MC_DC38_VALUE 0x0
5309 +#define MC_DC39_VALUE 0x0
5310 +#define MC_DC40_VALUE 0x0
5311 +#define MC_DC41_VALUE 0x0
5312 +#define MC_DC42_VALUE 0x0
5313 +#define MC_DC43_VALUE 0x0
5314 +#define MC_DC44_VALUE 0x0
5315 +#define MC_DC45_VALUE 0x500
5316 +#define MC_DC46_VALUE 0x0
5317 diff --git a/board/lantiq/easy50712/easy50712.c b/board/lantiq/easy50712/easy50712.c
5318 new file mode 100644
5319 index 0000000..4f6a237
5321 +++ b/board/lantiq/easy50712/easy50712.c
5324 + * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
5325 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5327 + * SPDX-License-Identifier: GPL-2.0+
5330 +#include <common.h>
5331 +#include <switch.h>
5333 +#include <asm/gpio.h>
5334 +#include <asm/lantiq/eth.h>
5335 +#include <asm/lantiq/reset.h>
5336 +#include <asm/lantiq/chipid.h>
5338 +static void gpio_init(void)
5340 + /* SPI/CS output (low-active) for serial flash */
5341 + gpio_direction_output(22, 1);
5343 + /* EBU.FL_CS1 as output for NAND CE */
5344 + gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5345 + /* EBU.FL_A23 as output for NAND CLE */
5346 + gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5347 + /* EBU.FL_A24 as output for NAND ALE */
5348 + gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5350 + /* enable CLK_OUT2 for external switch */
5351 + gpio_set_altfunc(3, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5354 +int board_early_init_f(void)
5361 +int checkboard(void)
5363 + puts("Board: " CONFIG_BOARD_NAME "\n");
5364 + ltq_chip_print_info();
5369 +static const struct ltq_eth_port_config eth_port_config[] = {
5370 + /* MAC0: Lantiq ADM6996I switch */
5371 + { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
5374 +static const struct ltq_eth_board_config eth_board_config = {
5375 + .ports = eth_port_config,
5376 + .num_ports = ARRAY_SIZE(eth_port_config),
5379 +int board_eth_init(bd_t *bis)
5381 + return ltq_eth_initialize(ð_board_config);
5384 +static struct switch_device adm6996i_dev = {
5385 + .name = "adm6996i",
5390 +int board_switch_init(void)
5392 + /* Deactivate HRST line to release reset of ADM6996I switch */
5393 + ltq_reset_once(LTQ_RESET_HARD, 200000);
5395 + /* ADM6996I needs some time to come out of reset */
5398 + return switch_device_register(&adm6996i_dev);
5401 +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
5414 +void spi_cs_activate(struct spi_slave *slave)
5416 + switch (slave->cs) {
5418 + gpio_set_value(22, 0);
5425 +void spi_cs_deactivate(struct spi_slave *slave)
5427 + switch (slave->cs) {
5429 + gpio_set_value(22, 1);
5435 diff --git a/board/lantiq/easy80920/Makefile b/board/lantiq/easy80920/Makefile
5436 new file mode 100644
5437 index 0000000..3a547c2
5439 +++ b/board/lantiq/easy80920/Makefile
5442 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
5444 +# SPDX-License-Identifier: GPL-2.0+
5447 +include $(TOPDIR)/config.mk
5449 +LIB = $(obj)lib$(BOARD).o
5453 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
5454 +OBJS := $(addprefix $(obj),$(COBJS))
5455 +SOBJS := $(addprefix $(obj),$(SOBJS))
5457 +$(LIB): $(obj).depend $(OBJS) $(SOBJS)
5458 + $(call cmd_link_o_target, $(OBJS) $(SOBJS))
5460 +#########################################################################
5462 +# defines $(obj).depend target
5463 +include $(SRCTREE)/rules.mk
5465 +sinclude $(obj).depend
5467 +#########################################################################
5468 diff --git a/board/lantiq/easy80920/config.mk b/board/lantiq/easy80920/config.mk
5469 new file mode 100644
5470 index 0000000..9d8953b
5472 +++ b/board/lantiq/easy80920/config.mk
5475 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5477 +# SPDX-License-Identifier: GPL-2.0+
5480 +PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
5481 diff --git a/board/lantiq/easy80920/ddr_settings.h b/board/lantiq/easy80920/ddr_settings.h
5482 new file mode 100644
5483 index 0000000..671d1c1
5485 +++ b/board/lantiq/easy80920/ddr_settings.h
5488 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
5489 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5491 + * SPDX-License-Identifier: GPL-2.0+
5494 +#define MC_CCR00_VALUE 0x101
5495 +#define MC_CCR01_VALUE 0x1000100
5496 +#define MC_CCR02_VALUE 0x1010000
5497 +#define MC_CCR03_VALUE 0x101
5498 +#define MC_CCR04_VALUE 0x1000000
5499 +#define MC_CCR05_VALUE 0x1000101
5500 +#define MC_CCR06_VALUE 0x1000100
5501 +#define MC_CCR07_VALUE 0x1010000
5502 +#define MC_CCR08_VALUE 0x1000101
5503 +#define MC_CCR09_VALUE 0x0
5504 +#define MC_CCR10_VALUE 0x2000100
5505 +#define MC_CCR11_VALUE 0x2000300
5506 +#define MC_CCR12_VALUE 0x30000
5507 +#define MC_CCR13_VALUE 0x202
5508 +#define MC_CCR14_VALUE 0x7080A0F
5509 +#define MC_CCR15_VALUE 0x2040F
5510 +#define MC_CCR16_VALUE 0x40000
5511 +#define MC_CCR17_VALUE 0x70102
5512 +#define MC_CCR18_VALUE 0x4020002
5513 +#define MC_CCR19_VALUE 0x30302
5514 +#define MC_CCR20_VALUE 0x8000700
5515 +#define MC_CCR21_VALUE 0x40F020A
5516 +#define MC_CCR22_VALUE 0x0
5517 +#define MC_CCR23_VALUE 0xC020000
5518 +#define MC_CCR24_VALUE 0x4401B04
5519 +#define MC_CCR25_VALUE 0x0
5520 +#define MC_CCR26_VALUE 0x0
5521 +#define MC_CCR27_VALUE 0x6420000
5522 +#define MC_CCR28_VALUE 0x0
5523 +#define MC_CCR29_VALUE 0x0
5524 +#define MC_CCR30_VALUE 0x798
5525 +#define MC_CCR31_VALUE 0x0
5526 +#define MC_CCR32_VALUE 0x0
5527 +#define MC_CCR33_VALUE 0x650000
5528 +#define MC_CCR34_VALUE 0x200C8
5529 +#define MC_CCR35_VALUE 0x1D445D
5530 +#define MC_CCR36_VALUE 0xC8
5531 +#define MC_CCR37_VALUE 0xC351
5532 +#define MC_CCR38_VALUE 0x0
5533 +#define MC_CCR39_VALUE 0x141F04
5534 +#define MC_CCR40_VALUE 0x142704
5535 +#define MC_CCR41_VALUE 0x141b42
5536 +#define MC_CCR42_VALUE 0x141b42
5537 +#define MC_CCR43_VALUE 0x566504
5538 +#define MC_CCR44_VALUE 0x566504
5539 +#define MC_CCR45_VALUE 0x565F17
5540 +#define MC_CCR46_VALUE 0x565F17
5541 +#define MC_CCR47_VALUE 0x0
5542 +#define MC_CCR48_VALUE 0x0
5543 +#define MC_CCR49_VALUE 0x0
5544 +#define MC_CCR50_VALUE 0x0
5545 +#define MC_CCR51_VALUE 0x0
5546 +#define MC_CCR52_VALUE 0x133
5547 +#define MC_CCR53_VALUE 0xF3014B27
5548 +#define MC_CCR54_VALUE 0xF3014B27
5549 +#define MC_CCR55_VALUE 0xF3014B27
5550 +#define MC_CCR56_VALUE 0xF3014B27
5551 +#define MC_CCR57_VALUE 0x7800301
5552 +#define MC_CCR58_VALUE 0x7800301
5553 +#define MC_CCR59_VALUE 0x7800301
5554 +#define MC_CCR60_VALUE 0x7800301
5555 +#define MC_CCR61_VALUE 0x4
5556 diff --git a/board/lantiq/easy80920/easy80920.c b/board/lantiq/easy80920/easy80920.c
5557 new file mode 100644
5558 index 0000000..d9a4f81
5560 +++ b/board/lantiq/easy80920/easy80920.c
5563 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5565 + * SPDX-License-Identifier: GPL-2.0+
5568 +#include <common.h>
5570 +#include <asm/gpio.h>
5571 +#include <asm/lantiq/eth.h>
5572 +#include <asm/lantiq/chipid.h>
5573 +#include <asm/lantiq/cpu.h>
5574 +#include <asm/arch/gphy.h>
5576 +#if defined(CONFIG_SPL_BUILD)
5577 +#define do_gpio_init 1
5578 +#define do_pll_init 1
5579 +#define do_dcdc_init 0
5580 +#elif defined(CONFIG_SYS_BOOT_RAM)
5581 +#define do_gpio_init 1
5582 +#define do_pll_init 0
5583 +#define do_dcdc_init 1
5584 +#elif defined(CONFIG_SYS_BOOT_NOR)
5585 +#define do_gpio_init 1
5586 +#define do_pll_init 1
5587 +#define do_dcdc_init 1
5589 +#define do_gpio_init 0
5590 +#define do_pll_init 0
5591 +#define do_dcdc_init 1
5594 +static void gpio_init(void)
5596 + /* SPI CS 0.4 to serial flash */
5597 + gpio_direction_output(10, 1);
5599 + /* EBU.FL_CS1 as output for NAND CE */
5600 + gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5601 + /* EBU.FL_A23 as output for NAND CLE */
5602 + gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5603 + /* EBU.FL_A24 as output for NAND ALE */
5604 + gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5605 + /* GPIO 3.0 as input for NAND Ready Busy */
5606 + gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
5607 + /* GPIO 3.1 as output for NAND Read */
5608 + gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5611 +int board_early_init_f(void)
5620 + ltq_dcdc_init(0x7F);
5625 +int checkboard(void)
5627 + puts("Board: " CONFIG_BOARD_NAME "\n");
5628 + ltq_chip_print_info();
5633 +static const struct ltq_eth_port_config eth_port_config[] = {
5634 + /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
5635 + { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
5636 + /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
5637 + { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
5638 + /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
5639 + { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
5640 + /* GMAC3: unused */
5641 + { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
5642 + /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
5643 + { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
5644 + /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
5645 + { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
5648 +static const struct ltq_eth_board_config eth_board_config = {
5649 + .ports = eth_port_config,
5650 + .num_ports = ARRAY_SIZE(eth_port_config),
5653 +int board_eth_init(bd_t * bis)
5655 + const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
5656 + const ulong fw_addr = 0x80FF0000;
5658 + ltq_gphy_phy11g_a1x_load(fw_addr);
5660 + ltq_cgu_gphy_clk_src(clk);
5662 + ltq_rcu_gphy_boot(0, fw_addr);
5663 + ltq_rcu_gphy_boot(1, fw_addr);
5665 + return ltq_eth_initialize(ð_board_config);
5668 +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
5679 +void spi_cs_activate(struct spi_slave *slave)
5681 + switch (slave->cs) {
5683 + gpio_set_value(10, 0);
5690 +void spi_cs_deactivate(struct spi_slave *slave)
5692 + switch (slave->cs) {
5694 + gpio_set_value(10, 1);
5700 diff --git a/boards.cfg b/boards.cfg
5701 index aa2ee64..f090726 100644
5704 @@ -502,10 +502,17 @@ Active mips mips32 au1x00 - dbau1x00
5705 Active mips mips32 au1x00 - dbau1x00 dbau1550 dbau1x00:DBAU1550 Thomas Lange <thomas@corelatus.se>
5706 Active mips mips32 au1x00 - dbau1x00 dbau1550_el dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN Thomas Lange <thomas@corelatus.se>
5707 Active mips mips32 au1x00 - pb1x00 pb1000 pb1x00:PB1000 -
5708 +Active mips mips32 danube lantiq easy50712 easy50712_nor easy50712:SYS_BOOT_NOR Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5709 +Active mips mips32 danube lantiq easy50712 easy50712_norspl easy50712:SYS_BOOT_NORSPL Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5710 +Active mips mips32 danube lantiq easy50712 easy50712_ram easy50712:SYS_BOOT_RAM Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5711 Active mips mips32 incaip - incaip incaip - Wolfgang Denk <wd@denx.de>
5712 Active mips mips32 incaip - incaip incaip_100MHz incaip:CPU_CLOCK_RATE=100000000 Wolfgang Denk <wd@denx.de>
5713 Active mips mips32 incaip - incaip incaip_133MHz incaip:CPU_CLOCK_RATE=133000000 Wolfgang Denk <wd@denx.de>
5714 Active mips mips32 incaip - incaip incaip_150MHz incaip:CPU_CLOCK_RATE=150000000 Wolfgang Denk <wd@denx.de>
5715 +Active mips mips32 vrx200 lantiq easy80920 easy80920_nor easy80920:SYS_BOOT_NOR Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5716 +Active mips mips32 vrx200 lantiq easy80920 easy80920_norspl easy80920:SYS_BOOT_NORSPL Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5717 +Active mips mips32 vrx200 lantiq easy80920 easy80920_ram easy80920:SYS_BOOT_RAM Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5718 +Active mips mips32 vrx200 lantiq easy80920 easy80920_sfspl easy80920:SYS_BOOT_SFSPL Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5719 Active mips mips64 - - qemu-mips qemu_mips64 qemu-mips64:SYS_BIG_ENDIAN -
5720 Active mips mips64 - - qemu-mips qemu_mips64el qemu-mips64:SYS_LITTLE_ENDIAN -
5721 Active nds32 n1213 ag101 AndesTech adp-ag101 adp-ag101 - Andes <uboot@andestech.com>
5722 diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
5723 index a6132e2..5a4bcef 100644
5724 --- a/drivers/dma/Makefile
5725 +++ b/drivers/dma/Makefile
5726 @@ -12,6 +12,7 @@ LIB := $(obj)libdma.o
5727 COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
5728 COBJS-$(CONFIG_APBH_DMA) += apbh_dma.o
5729 COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
5730 +COBJS-$(CONFIG_LANTIQ_DMA) += lantiq_dma.o
5731 COBJS-$(CONFIG_OMAP3_DMA) += omap3_dma.o
5734 diff --git a/drivers/dma/lantiq_dma.c b/drivers/dma/lantiq_dma.c
5735 new file mode 100644
5736 index 0000000..a78212a
5738 +++ b/drivers/dma/lantiq_dma.c
5741 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5743 + * SPDX-License-Identifier: GPL-2.0+
5746 +#include <common.h>
5747 +#include <malloc.h>
5748 +#include <watchdog.h>
5749 +#include <linux/compiler.h>
5750 +#include <asm/lantiq/io.h>
5751 +#include <asm/lantiq/dma.h>
5752 +#include <asm/lantiq/pm.h>
5753 +#include <asm/lantiq/reset.h>
5754 +#include <asm/arch/soc.h>
5755 +#include <asm/processor.h>
5757 +#define DMA_CTRL_PKTARB (1 << 31)
5758 +#define DMA_CTRL_MBRSTARB (1 << 30)
5759 +#define DMA_CTRL_MBRSTCNT_SHIFT 16
5760 +#define DMA_CTRL_MBRSTCNT_MASK (0x3ff << DMA_CTRL_MBRSTCNT_SHIFT)
5761 +#define DMA_CTRL_DRB (1 << 8)
5762 +#define DMA_CTRL_RESET (1 << 0)
5764 +#define DMA_CPOLL_EN (1 << 31)
5765 +#define DMA_CPOLL_CNT_SHIFT 4
5766 +#define DMA_CPOLL_CNT_MASK (0xFFF << DMA_CPOLL_CNT_SHIFT)
5768 +#define DMA_CCTRL_TXWGT_SHIFT 16
5769 +#define DMA_CCTRL_TXWGT_MASK (0x3 << DMA_CCTRL_TXWGT_SHIFT)
5770 +#define DMA_CCTRL_CLASS_SHIFT 9
5771 +#define DMA_CCTRL_CLASS_MASK (0x3 << DMA_CCTRL_CLASS_SHIFT)
5772 +#define DMA_CCTRL_RST (1 << 1)
5773 +#define DMA_CCTRL_ONOFF (1 << 0)
5775 +#define DMA_PCTRL_TXBL_SHIFT 4
5776 +#define DMA_PCTRL_TXBL_2WORDS (1 << DMA_PCTRL_TXBL_SHIFT)
5777 +#define DMA_PCTRL_TXBL_4WORDS (2 << DMA_PCTRL_TXBL_SHIFT)
5778 +#define DMA_PCTRL_TXBL_8WORDS (3 << DMA_PCTRL_TXBL_SHIFT)
5779 +#define DMA_PCTRL_RXBL_SHIFT 2
5780 +#define DMA_PCTRL_RXBL_2WORDS (1 << DMA_PCTRL_RXBL_SHIFT)
5781 +#define DMA_PCTRL_RXBL_4WORDS (2 << DMA_PCTRL_RXBL_SHIFT)
5782 +#define DMA_PCTRL_RXBL_8WORDS (3 << DMA_PCTRL_RXBL_SHIFT)
5783 +#define DMA_PCTRL_TXENDI_SHIFT 10
5784 +#define DMA_PCTRL_TXENDI_MASK (0x3 << DMA_PCTRL_TXENDI_SHIFT)
5785 +#define DMA_PCTRL_RXENDI_SHIFT 8
5786 +#define DMA_PCTRL_RXENDI_MASK (0x3 << DMA_PCTRL_RXENDI_SHIFT)
5788 +#define DMA_DESC_OWN (1 << 31)
5789 +#define DMA_DESC_C (1 << 30)
5790 +#define DMA_DESC_SOP (1 << 29)
5791 +#define DMA_DESC_EOP (1 << 28)
5792 +#define DMA_DESC_TX_OFFSET(x) ((x & 0x1f) << 23)
5793 +#define DMA_DESC_RX_OFFSET(x) ((x & 0x3) << 23)
5794 +#define DMA_DESC_LENGTH(x) (x & 0xffff)
5796 +#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
5798 +struct ltq_dma_regs {
5799 + u32 clc; /* Clock control */
5801 + u32 id; /* Identification */
5803 + u32 ctrl; /* Control */
5804 + u32 cpoll; /* Channel polling */
5805 + u32 cs; /* Channel select */
5806 + u32 cctrl; /* Channel control */
5807 + u32 cdba; /* Channel descriptor base address */
5808 + u32 cdlen; /* Channel descriptor length */
5809 + u32 cis; /* Channel interrupt status */
5810 + u32 cie; /* Channel interrupt enable */
5811 + u32 cgbl; /* Channel global buffer length */
5812 + u32 cdptnrd; /* Current descriptor pointer */
5814 + u32 ps; /* Port select */
5815 + u32 pctrl; /* Port control */
5817 + u32 irnen; /* Interrupt node enable */
5818 + u32 irncr; /* Interrupt node control */
5819 + u32 irnicr; /* Interrupt capture */
5822 +static struct ltq_dma_regs *ltq_dma_regs =
5823 + (struct ltq_dma_regs *) CKSEG1ADDR(LTQ_DMA_BASE);
5825 +static inline unsigned long ltq_dma_addr_to_virt(u32 dma_addr)
5827 + return KSEG0ADDR(dma_addr);
5830 +static inline u32 ltq_virt_to_dma_addr(void *addr)
5832 + return CPHYSADDR(addr);
5835 +static inline int ltq_dma_burst_align(enum ltq_dma_burst_len burst_len)
5837 + switch (burst_len) {
5838 + case LTQ_DMA_BURST_2WORDS:
5840 + case LTQ_DMA_BURST_4WORDS:
5842 + case LTQ_DMA_BURST_8WORDS:
5849 +static inline void ltq_dma_sync(void)
5851 + __asm__ __volatile__("sync");
5854 +static inline void ltq_dma_dcache_wb_inv(const void *ptr, size_t size)
5856 + unsigned long addr = (unsigned long) ptr;
5858 + flush_dcache_range(addr, addr + size);
5862 +static inline void ltq_dma_dcache_inv(const void *ptr, size_t size)
5864 + unsigned long addr = (unsigned long) ptr;
5866 + invalidate_dcache_range(addr, addr + size);
5869 +void ltq_dma_init(void)
5871 + /* Power up DMA */
5872 + ltq_pm_enable(LTQ_PM_DMA);
5875 + ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_RESET);
5877 + /* Disable and clear all interrupts */
5878 + ltq_writel(<q_dma_regs->irnen, 0);
5879 + ltq_writel(<q_dma_regs->irncr, 0xFFFFF);
5882 + /* Enable packet arbitration */
5883 + ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_PKTARB);
5887 + /* Enable descriptor read back */
5888 + ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_DRB);
5891 + /* Enable polling for descriptor fetching for all channels */
5892 + ltq_writel(<q_dma_regs->cpoll, DMA_CPOLL_EN |
5893 + (4 << DMA_CPOLL_CNT_SHIFT));
5896 +static void ltq_dma_channel_reset(struct ltq_dma_channel *chan)
5898 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5899 + ltq_setbits(<q_dma_regs->cctrl, DMA_CCTRL_RST);
5902 +static void ltq_dma_channel_enable(struct ltq_dma_channel *chan)
5904 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5905 + ltq_setbits(<q_dma_regs->cctrl, DMA_CCTRL_ONOFF);
5908 +static void ltq_dma_channel_disable(struct ltq_dma_channel *chan)
5910 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5911 + ltq_clrbits(<q_dma_regs->cctrl, DMA_CCTRL_ONOFF);
5914 +static void ltq_dma_port_init(struct ltq_dma_device *dev)
5918 + pctrl = dev->tx_endian_swap << DMA_PCTRL_TXENDI_SHIFT;
5919 + pctrl |= dev->rx_endian_swap << DMA_PCTRL_RXENDI_SHIFT;
5920 + pctrl |= dev->tx_burst_len << DMA_PCTRL_TXBL_SHIFT;
5921 + pctrl |= dev->rx_burst_len << DMA_PCTRL_RXBL_SHIFT;
5923 + ltq_writel(<q_dma_regs->ps, dev->port);
5924 + ltq_writel(<q_dma_regs->pctrl, pctrl);
5927 +static int ltq_dma_alloc_descriptors(struct ltq_dma_device *dev,
5928 + struct ltq_dma_channel *chan)
5933 + size = ALIGN(sizeof(struct ltq_dma_desc) * chan->num_desc +
5934 + ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
5936 + chan->mem_base = malloc(size);
5937 + if (!chan->mem_base)
5940 + memset(chan->mem_base, 0, size);
5941 + ltq_dma_dcache_wb_inv(chan->mem_base, size);
5943 + desc_base = PTR_ALIGN(chan->mem_base, ARCH_DMA_MINALIGN);
5945 + debug("DMA: mem %p, desc %p\n", chan->mem_base, desc_base);
5947 + /* Align descriptor base to 8 bytes */
5948 + chan->desc_base = (void *) CKSEG1ADDR(desc_base);
5949 + chan->dma_addr = CPHYSADDR(desc_base);
5952 + debug("DMA: desc_base %p, size %u\n", chan->desc_base, size);
5954 + /* Configure hardware with location of descriptor list */
5955 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5956 + ltq_writel(<q_dma_regs->cdba, chan->dma_addr);
5957 + ltq_writel(<q_dma_regs->cdlen, chan->num_desc);
5958 + ltq_writel(<q_dma_regs->cctrl, (3 << DMA_CCTRL_TXWGT_SHIFT) |
5959 + (chan->class << DMA_CCTRL_CLASS_SHIFT));
5960 + ltq_writel(<q_dma_regs->cctrl, DMA_CCTRL_RST);
5965 +static void ltq_dma_free_descriptors(struct ltq_dma_channel *chan)
5967 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5968 + ltq_writel(<q_dma_regs->cdba, 0);
5969 + ltq_writel(<q_dma_regs->cdlen, 0);
5971 + ltq_dma_channel_reset(chan);
5973 + free(chan->mem_base);
5976 +int ltq_dma_register(struct ltq_dma_device *dev)
5980 + ltq_dma_port_init(dev);
5982 + ret = ltq_dma_alloc_descriptors(dev, &dev->rx_chan);
5986 + ret = ltq_dma_alloc_descriptors(dev, &dev->tx_chan);
5988 + ltq_dma_free_descriptors(&dev->rx_chan);
5995 +void ltq_dma_reset(struct ltq_dma_device *dev)
5997 + ltq_dma_channel_reset(&dev->rx_chan);
5998 + ltq_dma_channel_reset(&dev->tx_chan);
6001 +void ltq_dma_enable(struct ltq_dma_device *dev)
6003 + ltq_dma_channel_enable(&dev->rx_chan);
6004 + ltq_dma_channel_enable(&dev->tx_chan);
6007 +void ltq_dma_disable(struct ltq_dma_device *dev)
6009 + ltq_dma_channel_disable(&dev->rx_chan);
6010 + ltq_dma_channel_disable(&dev->tx_chan);
6013 +int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len)
6015 + struct ltq_dma_channel *chan = &dev->rx_chan;
6016 + struct ltq_dma_desc *desc = &chan->desc_base[index];
6017 + u32 dma_addr = ltq_virt_to_dma_addr(data);
6018 + unsigned int offset;
6020 + offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
6022 + ltq_dma_dcache_inv(data, len);
6025 + printf("%s: index %d, data %p, dma_addr %08x, offset %u, len %d\n",
6026 + __func__, index, data, dma_addr, offset, len);
6030 + desc->addr = dma_addr - offset;
6031 + desc->ctl = DMA_DESC_OWN | DMA_DESC_RX_OFFSET(offset) |
6032 + DMA_DESC_LENGTH(len);
6035 + printf("%s: index %d, desc %p, desc->ctl %08x\n",
6036 + __func__, index, desc, desc->ctl);
6042 +int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index)
6044 + struct ltq_dma_channel *chan = &dev->rx_chan;
6045 + struct ltq_dma_desc *desc = &chan->desc_base[index];
6048 + printf("%s: index %d, desc %p, desc->ctl %08x\n",
6049 + __func__, index, desc, desc->ctl);
6052 + if (desc->ctl & DMA_DESC_OWN)
6055 + if (desc->ctl & DMA_DESC_C)
6061 +int ltq_dma_rx_length(struct ltq_dma_device *dev, int index)
6063 + struct ltq_dma_channel *chan = &dev->rx_chan;
6064 + struct ltq_dma_desc *desc = &chan->desc_base[index];
6066 + return DMA_DESC_LENGTH(desc->ctl);
6069 +int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
6070 + unsigned long timeout)
6072 + struct ltq_dma_channel *chan = &dev->tx_chan;
6073 + struct ltq_dma_desc *desc = &chan->desc_base[index];
6074 + unsigned int offset;
6075 + unsigned long timebase = get_timer(0);
6076 + u32 dma_addr = ltq_virt_to_dma_addr(data);
6078 + while (desc->ctl & DMA_DESC_OWN) {
6081 + if (get_timer(timebase) >= timeout) {
6083 + printf("%s: timeout: index %d, desc %p, desc->ctl %08x\n",
6084 + __func__, index, desc, desc->ctl);
6090 + offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
6093 + printf("%s: index %d, desc %p, data %p, dma_addr %08x, offset %u, len %d\n",
6094 + __func__, index, desc, data, dma_addr, offset, len);
6097 + ltq_dma_dcache_wb_inv(data, len);
6099 + desc->addr = dma_addr - offset;
6100 + desc->ctl = DMA_DESC_OWN | DMA_DESC_SOP | DMA_DESC_EOP |
6101 + DMA_DESC_TX_OFFSET(offset) | DMA_DESC_LENGTH(len);
6104 + printf("%s: index %d, desc %p, desc->ctl %08x\n",
6105 + __func__, index, desc, desc->ctl);
6111 +int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
6112 + unsigned long timeout)
6114 + struct ltq_dma_channel *chan = &dev->tx_chan;
6115 + struct ltq_dma_desc *desc = &chan->desc_base[index];
6116 + unsigned long timebase = get_timer(0);
6118 + while ((desc->ctl & (DMA_DESC_OWN | DMA_DESC_C)) != DMA_DESC_C) {
6121 + if (get_timer(timebase) >= timeout)
6127 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
6128 index 71ddb00..5fb505b 100644
6129 --- a/drivers/gpio/Makefile
6130 +++ b/drivers/gpio/Makefile
6131 @@ -12,6 +12,7 @@ LIB := $(obj)libgpio.o
6132 COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o
6133 COBJS-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
6134 COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
6135 +COBJS-$(CONFIG_LANTIQ_GPIO) += lantiq_gpio.o
6136 COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o
6137 COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o
6138 COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o
6139 diff --git a/drivers/gpio/lantiq_gpio.c b/drivers/gpio/lantiq_gpio.c
6140 new file mode 100644
6141 index 0000000..374a668
6143 +++ b/drivers/gpio/lantiq_gpio.c
6146 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6148 + * SPDX-License-Identifier: GPL-2.0+
6151 +#include <common.h>
6152 +#include <asm/arch/soc.h>
6153 +#include <asm/arch/gpio.h>
6154 +#include <asm/lantiq/io.h>
6156 +#define SSIO_GPIO_BASE 64
6158 +#define SSIO_CON0_SWU (1 << 31)
6159 +#define SSIO_CON0_RZFL (1 << 26)
6160 +#define SSIO_CON0_GPHY1_SHIFT 27
6161 +#define SSIO_CON0_GPHY1_CONFIG ((CONFIG_LTQ_SSIO_GPHY1_MODE & 0x7) << 27)
6163 +#define SSIO_CON1_US_FPI (2 << 30)
6164 +#define SSIO_CON1_FPID_2HZ (0 << 23)
6165 +#define SSIO_CON1_FPID_4HZ (1 << 23)
6166 +#define SSIO_CON1_FPID_8HZ (2 << 23)
6167 +#define SSIO_CON1_FPID_10HZ (3 << 23)
6168 +#define SSIO_CON1_FPIS_1_2 (1 << 20)
6169 +#define SSIO_CON1_FPIS_1_32 (2 << 20)
6170 +#define SSIO_CON1_FPIS_1_64 (3 << 20)
6172 +#define SSIO_CON1_GPHY2_SHIFT 15
6173 +#define SSIO_CON1_GPHY2_CONFIG ((CONFIG_LTQ_SSIO_GPHY2_MODE & 0x7) << 15)
6175 +#define SSIO_CON1_GROUP2 (1 << 2)
6176 +#define SSIO_CON1_GROUP1 (1 << 1)
6177 +#define SSIO_CON1_GROUP0 (1 << 0)
6178 +#define SSIO_CON1_GROUP_CONFIG (0x3)
6180 +#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
6181 +#define enable_ssio 1
6183 +#define enable_ssio 0
6185 +#define CONFIG_LTQ_SSIO_GPHY1_MODE 0
6186 +#define CONFIG_LTQ_SSIO_GPHY2_MODE 0
6187 +#define CONFIG_LTQ_SSIO_INIT_VALUE 0
6190 +#ifdef CONFIG_LTQ_SSIO_EDGE_FALLING
6191 +#define SSIO_RZFL_CONFIG SSIO_CON0_RZFL
6193 +#define SSIO_RZFL_CONFIG 0
6196 +struct ltq_gpio_port_regs {
6209 +struct ltq_gpio_regs {
6211 + struct ltq_gpio_port_regs ports[CONFIG_LTQ_GPIO_MAX_BANKS];
6214 +struct ltq_gpio3_regs {
6228 +struct ltq_ssio_regs {
6236 +static struct ltq_gpio_regs *ltq_gpio_regs =
6237 + (struct ltq_gpio_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
6239 +static struct ltq_gpio3_regs *ltq_gpio3_regs =
6240 + (struct ltq_gpio3_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
6242 +static struct ltq_ssio_regs *ltq_ssio_regs =
6243 + (struct ltq_ssio_regs *) CKSEG1ADDR(LTQ_SSIO_BASE);
6245 +static int is_gpio_bank3(unsigned int port)
6247 +#ifdef CONFIG_LTQ_HAS_GPIO_BANK3
6254 +static int is_gpio_ssio(unsigned int gpio)
6256 +#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
6257 + return gpio >= SSIO_GPIO_BASE;
6263 +static inline int ssio_gpio_to_bit(unsigned gpio)
6265 + return 1 << (gpio - SSIO_GPIO_BASE);
6268 +int ltq_gpio_init(void)
6270 + ltq_writel(<q_ssio_regs->ar, 0);
6271 + ltq_writel(<q_ssio_regs->cpu0, CONFIG_LTQ_SSIO_INIT_VALUE);
6272 + ltq_writel(<q_ssio_regs->cpu1, 0);
6273 + ltq_writel(<q_ssio_regs->con0, SSIO_CON0_SWU);
6275 + if (enable_ssio) {
6276 + ltq_writel(<q_ssio_regs->con0, SSIO_CON0_GPHY1_CONFIG |
6277 + SSIO_RZFL_CONFIG);
6278 + ltq_writel(<q_ssio_regs->con1, SSIO_CON1_US_FPI |
6279 + SSIO_CON1_FPID_8HZ | SSIO_CON1_GPHY2_CONFIG |
6280 + SSIO_CON1_GROUP_CONFIG);
6286 +int gpio_request(unsigned gpio, const char *label)
6291 +int gpio_free(unsigned gpio)
6296 +int gpio_direction_input(unsigned gpio)
6298 + unsigned port = gpio_to_port(gpio);
6299 + const void *gpio_od = <q_gpio_regs->ports[port].od;
6300 + const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0;
6301 + const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1;
6302 + const void *gpio_dir = <q_gpio_regs->ports[port].dir;
6304 + if (is_gpio_ssio(gpio))
6307 + if (is_gpio_bank3(port)) {
6308 + gpio_od = <q_gpio3_regs->od;
6309 + gpio_altsel0 = <q_gpio3_regs->altsel0;
6310 + gpio_altsel1 = <q_gpio3_regs->altsel1;
6311 + gpio_dir = <q_gpio3_regs->dir;
6315 + * Reset open drain and altsel configs to workaround improper
6316 + * reset values or unwanted modifications by BootROM
6318 + ltq_clrbits(gpio_od, gpio_to_bit(gpio));
6319 + ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
6320 + ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
6322 + /* Switch to input */
6323 + ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
6328 +int gpio_direction_output(unsigned gpio, int value)
6330 + unsigned port = gpio_to_port(gpio);
6331 + const void *gpio_od = <q_gpio_regs->ports[port].od;
6332 + const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0;
6333 + const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1;
6334 + const void *gpio_dir = <q_gpio_regs->ports[port].dir;
6335 + const void *gpio_out = <q_gpio_regs->ports[port].out;
6336 + u32 data = gpio_to_bit(gpio);
6338 + if (is_gpio_ssio(gpio)) {
6339 + data = ssio_gpio_to_bit(gpio);
6341 + ltq_setbits(<q_ssio_regs->cpu0, data);
6343 + ltq_clrbits(<q_ssio_regs->cpu0, data);
6348 + if (is_gpio_bank3(port)) {
6349 + gpio_od = <q_gpio3_regs->od;
6350 + gpio_altsel0 = <q_gpio3_regs->altsel0;
6351 + gpio_altsel1 = <q_gpio3_regs->altsel1;
6352 + gpio_dir = <q_gpio3_regs->dir;
6353 + gpio_out = <q_gpio3_regs->out;
6357 + * Reset open drain and altsel configs to workaround improper
6358 + * reset values or unwanted modifications by BootROM
6360 + ltq_setbits(gpio_od, data);
6361 + ltq_clrbits(gpio_altsel0, data);
6362 + ltq_clrbits(gpio_altsel1, data);
6365 + ltq_setbits(gpio_out, data);
6367 + ltq_clrbits(gpio_out, data);
6369 + /* Switch to output */
6370 + ltq_setbits(gpio_dir, data);
6375 +int gpio_get_value(unsigned gpio)
6377 + unsigned port = gpio_to_port(gpio);
6378 + const void *gpio_in = <q_gpio_regs->ports[port].in;
6379 + u32 data = gpio_to_bit(gpio);
6382 + if (is_gpio_ssio(gpio)) {
6383 + gpio_in = <q_ssio_regs->cpu0;
6384 + data = ssio_gpio_to_bit(gpio);
6387 + if (is_gpio_bank3(port))
6388 + gpio_in = <q_gpio3_regs->in;
6390 + val = ltq_readl(gpio_in);
6392 + return !!(val & data);
6395 +int gpio_set_value(unsigned gpio, int value)
6397 + unsigned port = gpio_to_port(gpio);
6398 + const void *gpio_out = <q_gpio_regs->ports[port].out;
6399 + u32 data = gpio_to_bit(gpio);
6401 + if (is_gpio_ssio(gpio)) {
6402 + gpio_out = <q_ssio_regs->cpu0;
6403 + data = ssio_gpio_to_bit(gpio);
6406 + if (is_gpio_bank3(port))
6407 + gpio_out = <q_gpio3_regs->out;
6410 + ltq_setbits(gpio_out, data);
6412 + ltq_clrbits(gpio_out, data);
6417 +int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir)
6419 + unsigned port = gpio_to_port(gpio);
6420 + const void *gpio_od = <q_gpio_regs->ports[port].od;
6421 + const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0;
6422 + const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1;
6423 + const void *gpio_dir = <q_gpio_regs->ports[port].dir;
6425 + if (is_gpio_ssio(gpio))
6428 + if (is_gpio_bank3(port)) {
6429 + gpio_od = <q_gpio3_regs->od;
6430 + gpio_altsel0 = <q_gpio3_regs->altsel0;
6431 + gpio_altsel1 = <q_gpio3_regs->altsel1;
6432 + gpio_dir = <q_gpio3_regs->dir;
6436 + ltq_setbits(gpio_altsel0, gpio_to_bit(gpio));
6438 + ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
6441 + ltq_setbits(gpio_altsel1, gpio_to_bit(gpio));
6443 + ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
6446 + ltq_setbits(gpio_od, gpio_to_bit(gpio));
6447 + ltq_setbits(gpio_dir, gpio_to_bit(gpio));
6449 + ltq_clrbits(gpio_od, gpio_to_bit(gpio));
6450 + ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
6456 +int gpio_set_opendrain(unsigned gpio, int od)
6458 + unsigned port = gpio_to_port(gpio);
6459 + const void *gpio_od = <q_gpio_regs->ports[port].od;
6461 + if (is_gpio_ssio(gpio))
6464 + if (is_gpio_bank3(port))
6465 + gpio_od = <q_gpio3_regs->od;
6468 + ltq_setbits(gpio_od, gpio_to_bit(gpio));
6470 + ltq_clrbits(gpio_od, gpio_to_bit(gpio));
6474 diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
6475 index a389cd1..fa4fae7 100644
6476 --- a/drivers/mtd/cfi_flash.c
6477 +++ b/drivers/mtd/cfi_flash.c
6478 @@ -161,6 +161,18 @@ u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64")));
6479 #define flash_read64 __flash_read64
6482 +static inline void *__flash_swap_addr(unsigned long addr)
6484 + return (void *) addr;
6487 +#ifdef CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
6488 +void *flash_swap_addr(unsigned long addr)
6489 + __attribute__((weak, alias("__flash_swap_addr")));
6491 +#define flash_swap_addr __flash_swap_addr
6494 /*-----------------------------------------------------------------------
6496 #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
6497 @@ -196,7 +208,7 @@ flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
6499 unsigned int byte_offset = offset * info->portwidth;
6501 - return (void *)(info->start[sect] + byte_offset);
6502 + return flash_swap_addr(info->start[sect] + byte_offset);
6505 static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
6506 diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
6507 index 366dee6..e9adaaa 100644
6508 --- a/drivers/mtd/nand/Makefile
6509 +++ b/drivers/mtd/nand/Makefile
6510 @@ -53,6 +53,7 @@ COBJS-$(CONFIG_NAND_JZ4740) += jz4740_nand.o
6511 COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
6512 COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
6513 COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
6514 +COBJS-$(CONFIG_NAND_LANTIQ) += lantiq_nand.o
6515 COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
6516 COBJS-$(CONFIG_NAND_MXC) += mxc_nand.o
6517 COBJS-$(CONFIG_NAND_MXS) += mxs_nand.o
6518 diff --git a/drivers/mtd/nand/lantiq_nand.c b/drivers/mtd/nand/lantiq_nand.c
6519 new file mode 100644
6520 index 0000000..85f8f68
6522 +++ b/drivers/mtd/nand/lantiq_nand.c
6525 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6527 + * SPDX-License-Identifier: GPL-2.0+
6530 +#include <common.h>
6531 +#include <linux/mtd/nand.h>
6532 +#include <linux/compiler.h>
6533 +#include <asm/arch/soc.h>
6534 +#include <asm/arch/nand.h>
6535 +#include <asm/lantiq/io.h>
6537 +#define NAND_CON_ECC_ON (1 << 31)
6538 +#define NAND_CON_LATCH_PRE (1 << 23)
6539 +#define NAND_CON_LATCH_WP (1 << 22)
6540 +#define NAND_CON_LATCH_SE (1 << 21)
6541 +#define NAND_CON_LATCH_CS (1 << 20)
6542 +#define NAND_CON_LATCH_CLE (1 << 19)
6543 +#define NAND_CON_LATCH_ALE (1 << 18)
6544 +#define NAND_CON_OUT_CS1 (1 << 10)
6545 +#define NAND_CON_IN_CS1 (1 << 8)
6546 +#define NAND_CON_PRE_P (1 << 7)
6547 +#define NAND_CON_WP_P (1 << 6)
6548 +#define NAND_CON_SE_P (1 << 5)
6549 +#define NAND_CON_CS_P (1 << 4)
6550 +#define NAND_CON_CLE_P (1 << 3)
6551 +#define NAND_CON_ALE_P (1 << 2)
6552 +#define NAND_CON_CSMUX (1 << 1)
6553 +#define NAND_CON_NANDM (1 << 0)
6555 +#define NAND_WAIT_WR_C (1 << 3)
6556 +#define NAND_WAIT_RDBY (1 << 0)
6558 +#define NAND_CMD_ALE (1 << 2)
6559 +#define NAND_CMD_CLE (1 << 3)
6560 +#define NAND_CMD_CS (1 << 4)
6561 +#define NAND_CMD_SE (1 << 5)
6562 +#define NAND_CMD_WP (1 << 6)
6563 +#define NAND_CMD_PRE (1 << 7)
6565 +struct ltq_nand_regs {
6566 + __be32 con; /* NAND controller control */
6567 + __be32 wait; /* NAND Flash Device RD/BY State */
6568 + __be32 ecc0; /* NAND Flash ECC Register 0 */
6569 + __be32 ecc_ac; /* NAND Flash ECC Register address counter */
6570 + __be32 ecc_cr; /* NAND Flash ECC Comparison */
6573 +static struct ltq_nand_regs *ltq_nand_regs =
6574 + (struct ltq_nand_regs *) CKSEG1ADDR(LTQ_EBU_NAND_BASE);
6576 +static void ltq_nand_wait_ready(void)
6578 + while ((ltq_readl(<q_nand_regs->wait) & NAND_WAIT_WR_C) == 0)
6582 +static int ltq_nand_dev_ready(struct mtd_info *mtd)
6584 + u32 data = ltq_readl(<q_nand_regs->wait);
6585 + return data & NAND_WAIT_RDBY;
6588 +static void ltq_nand_select_chip(struct mtd_info *mtd, int chip)
6591 + ltq_setbits(<q_nand_regs->con, NAND_CON_NANDM);
6592 + ltq_setbits(<q_nand_regs->con, NAND_CON_LATCH_CS);
6594 + ltq_clrbits(<q_nand_regs->con, NAND_CON_LATCH_CS);
6595 + ltq_clrbits(<q_nand_regs->con, NAND_CON_NANDM);
6599 +static void ltq_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
6601 + struct nand_chip *chip = mtd->priv;
6602 + unsigned long addr = (unsigned long) chip->IO_ADDR_W;
6604 + if (ctrl & NAND_CTRL_CHANGE) {
6605 + if (ctrl & NAND_ALE)
6606 + addr |= NAND_CMD_ALE;
6608 + addr &= ~NAND_CMD_ALE;
6610 + if (ctrl & NAND_CLE)
6611 + addr |= NAND_CMD_CLE;
6613 + addr &= ~NAND_CMD_CLE;
6615 + chip->IO_ADDR_W = (void __iomem *) addr;
6618 + if (cmd != NAND_CMD_NONE) {
6619 + writeb(cmd, chip->IO_ADDR_W);
6620 + ltq_nand_wait_ready();
6624 +int ltq_nand_init(struct nand_chip *nand)
6626 + /* Enable NAND, set NAND CS to EBU CS1, enable EBU CS mux */
6627 + ltq_writel(<q_nand_regs->con, NAND_CON_OUT_CS1 | NAND_CON_IN_CS1 |
6628 + NAND_CON_PRE_P | NAND_CON_WP_P | NAND_CON_SE_P |
6629 + NAND_CON_CS_P | NAND_CON_CSMUX);
6631 + nand->dev_ready = ltq_nand_dev_ready;
6632 + nand->select_chip = ltq_nand_select_chip;
6633 + nand->cmd_ctrl = ltq_nand_cmd_ctrl;
6635 + nand->chip_delay = 30;
6636 + nand->options = 0;
6637 + nand->ecc.mode = NAND_ECC_SOFT;
6639 + /* Enable CS bit in address offset */
6640 + nand->IO_ADDR_R = nand->IO_ADDR_R + NAND_CMD_CS;
6641 + nand->IO_ADDR_W = nand->IO_ADDR_W + NAND_CMD_CS;
6646 +__weak int board_nand_init(struct nand_chip *chip)
6648 + return ltq_nand_init(chip);
6650 diff --git a/drivers/net/Makefile b/drivers/net/Makefile
6651 index 18fd54f..bbc2c92 100644
6652 --- a/drivers/net/Makefile
6653 +++ b/drivers/net/Makefile
6654 @@ -37,6 +37,8 @@ COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
6655 COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
6656 COBJS-$(CONFIG_KS8851_MLL) += ks8851_mll.o
6657 COBJS-$(CONFIG_LAN91C96) += lan91c96.o
6658 +COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o
6659 +COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o
6660 COBJS-$(CONFIG_MACB) += macb.o
6661 COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
6662 COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
6663 diff --git a/drivers/net/lantiq_danube_etop.c b/drivers/net/lantiq_danube_etop.c
6664 new file mode 100644
6665 index 0000000..7453882
6667 +++ b/drivers/net/lantiq_danube_etop.c
6670 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6672 + * SPDX-License-Identifier: GPL-2.0+
6675 +#include <common.h>
6676 +#include <malloc.h>
6677 +#include <netdev.h>
6678 +#include <miiphy.h>
6679 +#include <switch.h>
6680 +#include <asm/lantiq/io.h>
6681 +#include <asm/lantiq/eth.h>
6682 +#include <asm/lantiq/pm.h>
6683 +#include <asm/lantiq/reset.h>
6684 +#include <asm/lantiq/dma.h>
6685 +#include <asm/arch/soc.h>
6687 +#define LTQ_PPE_ETOP_MDIO_ACC_RA (1 << 31)
6688 +#define LTQ_PPE_ETOP_MDIO_CFG_UMM1 (1 << 2)
6689 +#define LTQ_PPE_ETOP_MDIO_CFG_UMM0 (1 << 1)
6691 +#define LTQ_PPE_ETOP_CFG_TCKINV1 (1 << 11)
6692 +#define LTQ_PPE_ETOP_CFG_TCKINV0 (1 << 10)
6693 +#define LTQ_PPE_ETOP_CFG_FEN1 (1 << 9)
6694 +#define LTQ_PPE_ETOP_CFG_FEN0 (1 << 8)
6695 +#define LTQ_PPE_ETOP_CFG_SEN1 (1 << 7)
6696 +#define LTQ_PPE_ETOP_CFG_SEN0 (1 << 6)
6697 +#define LTQ_PPE_ETOP_CFG_TURBO1 (1 << 5)
6698 +#define LTQ_PPE_ETOP_CFG_REMII1 (1 << 4)
6699 +#define LTQ_PPE_ETOP_CFG_OFF1 (1 << 3)
6700 +#define LTQ_PPE_ETOP_CFG_TURBO0 (1 << 2)
6701 +#define LTQ_PPE_ETOP_CFG_REMII0 (1 << 1)
6702 +#define LTQ_PPE_ETOP_CFG_OFF0 (1 << 0)
6704 +#define LTQ_PPE_ENET0_MAC_CFG_CGEN (1 << 11)
6705 +#define LTQ_PPE_ENET0_MAC_CFG_DUPLEX (1 << 2)
6706 +#define LTQ_PPE_ENET0_MAC_CFG_SPEED (1 << 1)
6707 +#define LTQ_PPE_ENET0_MAC_CFG_LINK (1 << 0)
6709 +#define LTQ_PPE_ENETS0_CFG_FTUC (1 << 28)
6711 +#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX
6712 +#define LTQ_ETH_TX_BUFFER_CNT 8
6713 +#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN
6714 +#define LTQ_ETH_IP_ALIGN 2
6716 +#define LTQ_MDIO_DRV_NAME "ltq-mdio"
6717 +#define LTQ_ETH_DRV_NAME "ltq-eth"
6719 +struct ltq_ppe_etop_regs {
6720 + u32 mdio_cfg; /* MDIO configuration */
6721 + u32 mdio_acc; /* MDIO access */
6722 + u32 cfg; /* ETOP configuration */
6723 + u32 ig_vlan_cos; /* IG VLAN priority CoS mapping */
6724 + u32 ig_dscp_cos3; /* IG DSCP CoS mapping 3 */
6725 + u32 ig_dscp_cos2; /* IG DSCP CoS mapping 2 */
6726 + u32 ig_dscp_cos1; /* IG DSCP CoS mapping 1 */
6727 + u32 ig_dscp_cos0; /* IG DSCP CoS mapping 0 */
6728 + u32 ig_plen_ctrl; /* IG frame length control */
6730 + u32 vpid; /* VLAN protocol ID */
6733 +struct ltq_ppe_enet_regs {
6734 + u32 mac_cfg; /* MAC configuration */
6736 + u32 ig_cfg; /* Ingress configuration */
6737 + u32 ig_pgcnt; /* Ingress buffer used page count */
6739 + u32 ig_buf_ctrl; /* Ingress buffer backpressure ctrl */
6740 + u32 cos_cfg; /* Classification configuration */
6741 + u32 ig_drop; /* Total ingress drop frames */
6742 + u32 ig_err; /* Total ingress error frames */
6743 + u32 mac_da0; /* Ingress MAC address 0 */
6744 + u32 mac_da1; /* Ingress MAC address 1 */
6746 + u32 pgcnt; /* Page counter */
6748 + u32 hf_ctrl; /* Half duplex control */
6749 + u32 tx_ctrl; /* Transmit control */
6751 + u32 vlcos0; /* VLAN insertion config CoS 0 */
6752 + u32 vlcos1; /* VLAN insertion config CoS 1 */
6753 + u32 vlcos2; /* VLAN insertion config CoS 2 */
6754 + u32 vlcos3; /* VLAN insertion config CoS 3 */
6755 + u32 eg_col; /* Total egress collision frames */
6756 + u32 eg_drop; /* Total egress drop frames */
6759 +struct ltq_eth_priv {
6760 + struct ltq_dma_device dma_dev;
6761 + struct mii_dev *bus;
6762 + struct eth_device *dev;
6767 +struct ltq_mdio_access {
6781 +static struct ltq_ppe_etop_regs *ltq_ppe_etop_regs =
6782 + (struct ltq_ppe_etop_regs *) CKSEG1ADDR(LTQ_PPE_ETOP_BASE);
6784 +static struct ltq_ppe_enet_regs *ltq_ppe_enet0_regs =
6785 + (struct ltq_ppe_enet_regs *) CKSEG1ADDR(LTQ_PPE_ENET0_BASE);
6787 +static inline int ltq_mdio_poll(void)
6789 + struct ltq_mdio_access acc;
6790 + unsigned cnt = 10000;
6792 + while (likely(cnt--)) {
6793 + acc.val = ltq_readl(<q_ppe_etop_regs->mdio_acc);
6801 +static int ltq_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
6804 + struct ltq_mdio_access acc;
6810 + acc.reg.phya = addr;
6811 + acc.reg.rega = regnum;
6813 + ret = ltq_mdio_poll();
6817 + ltq_writel(<q_ppe_etop_regs->mdio_acc, acc.val);
6819 + ret = ltq_mdio_poll();
6823 + acc.val = ltq_readl(<q_ppe_etop_regs->mdio_acc);
6825 + return acc.reg.phyd;
6828 +static int ltq_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
6829 + int regnum, u16 val)
6831 + struct ltq_mdio_access acc;
6837 + acc.reg.phya = addr;
6838 + acc.reg.rega = regnum;
6839 + acc.reg.phyd = val;
6841 + ret = ltq_mdio_poll();
6845 + ltq_writel(<q_ppe_etop_regs->mdio_acc, acc.val);
6850 +static inline void ltq_eth_write_hwaddr(const struct eth_device *dev)
6854 + da0 = (dev->enetaddr[0] << 24) + (dev->enetaddr[1] << 16) +
6855 + (dev->enetaddr[2] << 8) + dev->enetaddr[3];
6856 + da1 = (dev->enetaddr[4] << 24) + (dev->enetaddr[5] << 16);
6858 + ltq_writel(<q_ppe_enet0_regs->mac_da0, da0);
6859 + ltq_writel(<q_ppe_enet0_regs->mac_da1, da1);
6862 +static inline u8 *ltq_eth_rx_packet_align(int rx_num)
6864 + u8 *packet = (u8 *) NetRxPackets[rx_num];
6869 + return packet + LTQ_ETH_IP_ALIGN;
6872 +static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
6874 + struct ltq_eth_priv *priv = dev->priv;
6875 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6878 + ltq_eth_write_hwaddr(dev);
6880 + for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
6881 + ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
6882 + LTQ_ETH_RX_DATA_SIZE);
6884 + ltq_dma_enable(dma_dev);
6892 +static void ltq_eth_halt(struct eth_device *dev)
6894 + struct ltq_eth_priv *priv = dev->priv;
6895 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6897 + ltq_dma_reset(dma_dev);
6900 +static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
6902 + struct ltq_eth_priv *priv = dev->priv;
6903 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6906 + /* Minimum payload length w/ CRC is 60 bytes */
6910 + err = ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
6912 + puts("NET: timeout on waiting for TX descriptor\n");
6916 + priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
6921 +static int ltq_eth_recv(struct eth_device *dev)
6923 + struct ltq_eth_priv *priv = dev->priv;
6924 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6928 + if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
6932 + printf("%s: rx_num %d\n", __func__, priv->rx_num);
6935 + len = ltq_dma_rx_length(dma_dev, priv->rx_num);
6936 + packet = ltq_eth_rx_packet_align(priv->rx_num);
6939 + printf("%s: received: packet %p, len %u, rx_num %d\n",
6940 + __func__, packet, len, priv->rx_num);
6944 + NetReceive(packet, len);
6946 + ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
6947 + LTQ_ETH_RX_DATA_SIZE);
6949 + priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
6954 +static void ltq_eth_hw_init(const struct ltq_eth_port_config *port)
6958 + /* Power up ethernet subsystems */
6959 + ltq_pm_enable(LTQ_PM_ETH);
6961 + /* Reset ethernet subsystems */
6962 + ltq_reset_once(LTQ_RESET_ETH, 1);
6964 + /* Disable MDIO auto-detection */
6965 + ltq_clrbits(<q_ppe_etop_regs->mdio_cfg, LTQ_PPE_ETOP_MDIO_CFG_UMM1 |
6966 + LTQ_PPE_ETOP_MDIO_CFG_UMM0);
6968 + /* Enable CRC generation, Full Duplex, 100Mbps, Link up */
6969 + ltq_writel(<q_ppe_enet0_regs->mac_cfg, LTQ_PPE_ENET0_MAC_CFG_CGEN |
6970 + LTQ_PPE_ENET0_MAC_CFG_DUPLEX |
6971 + LTQ_PPE_ENET0_MAC_CFG_SPEED |
6972 + LTQ_PPE_ENET0_MAC_CFG_LINK);
6974 + /* Reset ETOP cfg and disable all */
6975 + data = LTQ_PPE_ETOP_CFG_OFF0 | LTQ_PPE_ETOP_CFG_OFF1;
6977 + /* Enable ENET0, enable store and fetch */
6978 + data &= ~LTQ_PPE_ETOP_CFG_OFF0;
6979 + data |= LTQ_PPE_ETOP_CFG_SEN0 | LTQ_PPE_ETOP_CFG_FEN0;
6981 + if (port->phy_if == PHY_INTERFACE_MODE_RMII)
6982 + data |= LTQ_PPE_ETOP_CFG_REMII0;
6984 + data &= ~LTQ_PPE_ETOP_CFG_REMII0;
6986 + ltq_writel(<q_ppe_etop_regs->cfg, data);
6988 + /* Set allowed packet length from 64 bytes to 1518 bytes */
6989 + ltq_writel(<q_ppe_etop_regs->ig_plen_ctrl, (64 << 16) | 1518);
6991 + /* Enable filter for unicast packets */
6992 + ltq_setbits(<q_ppe_enet0_regs->ig_cfg, LTQ_PPE_ENETS0_CFG_FTUC);
6995 +int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
6997 + struct eth_device *dev;
6998 + struct mii_dev *bus;
6999 + struct ltq_eth_priv *priv;
7000 + struct ltq_dma_device *dma_dev;
7001 + const struct ltq_eth_port_config *port = &board_config->ports[0];
7002 + struct phy_device *phy;
7003 + struct switch_device *sw;
7007 + ltq_eth_hw_init(port);
7009 + dev = calloc(1, sizeof(*dev));
7013 + priv = calloc(1, sizeof(*priv));
7017 + bus = mdio_alloc();
7021 + sprintf(dev->name, LTQ_ETH_DRV_NAME);
7023 + dev->init = ltq_eth_init;
7024 + dev->halt = ltq_eth_halt;
7025 + dev->recv = ltq_eth_recv;
7026 + dev->send = ltq_eth_send;
7028 + sprintf(bus->name, LTQ_MDIO_DRV_NAME);
7029 + bus->read = ltq_mdio_read;
7030 + bus->write = ltq_mdio_write;
7033 + dma_dev = &priv->dma_dev;
7034 + dma_dev->port = 0;
7035 + dma_dev->rx_chan.chan_no = 6;
7036 + dma_dev->rx_chan.class = 3;
7037 + dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
7038 + dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
7039 + dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
7040 + dma_dev->tx_chan.chan_no = 7;
7041 + dma_dev->tx_chan.class = 3;
7042 + dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
7043 + dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
7044 + dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
7049 + ret = ltq_dma_register(dma_dev);
7053 + ret = mdio_register(bus);
7057 + ret = eth_register(dev);
7061 + if (port->flags & LTQ_ETH_PORT_SWITCH) {
7062 + sw = switch_connect(bus);
7069 + if (port->flags & LTQ_ETH_PORT_PHY) {
7070 + phy = phy_connect(bus, port->phy_addr, dev, port->phy_if);
7079 diff --git a/drivers/net/lantiq_vrx200_switch.c b/drivers/net/lantiq_vrx200_switch.c
7080 new file mode 100644
7081 index 0000000..174427d
7083 +++ b/drivers/net/lantiq_vrx200_switch.c
7086 + * Copyright (C) 2010-2011 Lantiq Deutschland GmbH
7087 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
7089 + * SPDX-License-Identifier: GPL-2.0+
7094 +#include <common.h>
7095 +#include <malloc.h>
7096 +#include <netdev.h>
7097 +#include <miiphy.h>
7098 +#include <linux/compiler.h>
7099 +#include <asm/gpio.h>
7100 +#include <asm/processor.h>
7101 +#include <asm/lantiq/io.h>
7102 +#include <asm/lantiq/eth.h>
7103 +#include <asm/lantiq/pm.h>
7104 +#include <asm/lantiq/reset.h>
7105 +#include <asm/lantiq/dma.h>
7106 +#include <asm/arch/soc.h>
7107 +#include <asm/arch/switch.h>
7109 +#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX
7110 +#define LTQ_ETH_TX_BUFFER_CNT 8
7111 +#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN
7112 +#define LTQ_ETH_IP_ALIGN 2
7114 +#define LTQ_MDIO_DRV_NAME "ltq-mdio"
7115 +#define LTQ_ETH_DRV_NAME "ltq-eth"
7117 +#define LTQ_ETHSW_MAX_GMAC 6
7118 +#define LTQ_ETHSW_PMAC 6
7120 +struct ltq_mdio_phy_addr_reg {
7124 + unsigned lnkst:2; /* Link status control */
7125 + unsigned speed:2; /* Speed control */
7126 + unsigned fdup:2; /* Full duplex control */
7127 + unsigned fcontx:2; /* Flow control mode TX */
7128 + unsigned fconrx:2; /* Flow control mode RX */
7129 + unsigned addr:5; /* PHY address */
7135 +enum ltq_mdio_phy_addr_lnkst {
7136 + LTQ_MDIO_PHY_ADDR_LNKST_AUTO = 0,
7137 + LTQ_MDIO_PHY_ADDR_LNKST_UP = 1,
7138 + LTQ_MDIO_PHY_ADDR_LNKST_DOWN = 2,
7141 +enum ltq_mdio_phy_addr_speed {
7142 + LTQ_MDIO_PHY_ADDR_SPEED_M10 = 0,
7143 + LTQ_MDIO_PHY_ADDR_SPEED_M100 = 1,
7144 + LTQ_MDIO_PHY_ADDR_SPEED_G1 = 2,
7145 + LTQ_MDIO_PHY_ADDR_SPEED_AUTO = 3,
7148 +enum ltq_mdio_phy_addr_fdup {
7149 + LTQ_MDIO_PHY_ADDR_FDUP_AUTO = 0,
7150 + LTQ_MDIO_PHY_ADDR_FDUP_ENABLE = 1,
7151 + LTQ_MDIO_PHY_ADDR_FDUP_DISABLE = 3,
7154 +enum ltq_mdio_phy_addr_fcon {
7155 + LTQ_MDIO_PHY_ADDR_FCON_AUTO = 0,
7156 + LTQ_MDIO_PHY_ADDR_FCON_ENABLE = 1,
7157 + LTQ_MDIO_PHY_ADDR_FCON_DISABLE = 3,
7160 +struct ltq_mii_mii_cfg_reg {
7163 + unsigned res:1; /* Hardware reset */
7164 + unsigned en:1; /* xMII interface enable */
7165 + unsigned isol:1; /* xMII interface isolate */
7166 + unsigned ldclkdis:1; /* Link down clock disable */
7168 + unsigned crs:2; /* CRS sensitivity config */
7169 + unsigned rgmii_ibs:1; /* RGMII In Band status */
7170 + unsigned rmii:1; /* RMII ref clock direction */
7171 + unsigned miirate:3; /* xMII interface clock rate */
7172 + unsigned miimode:4; /* xMII interface mode */
7178 +enum ltq_mii_mii_cfg_miirate {
7179 + LTQ_MII_MII_CFG_MIIRATE_M2P5 = 0,
7180 + LTQ_MII_MII_CFG_MIIRATE_M25 = 1,
7181 + LTQ_MII_MII_CFG_MIIRATE_M125 = 2,
7182 + LTQ_MII_MII_CFG_MIIRATE_M50 = 3,
7183 + LTQ_MII_MII_CFG_MIIRATE_AUTO = 4,
7186 +enum ltq_mii_mii_cfg_miimode {
7187 + LTQ_MII_MII_CFG_MIIMODE_MIIP = 0,
7188 + LTQ_MII_MII_CFG_MIIMODE_MIIM = 1,
7189 + LTQ_MII_MII_CFG_MIIMODE_RMIIP = 2,
7190 + LTQ_MII_MII_CFG_MIIMODE_RMIIM = 3,
7191 + LTQ_MII_MII_CFG_MIIMODE_RGMII = 4,
7194 +struct ltq_eth_priv {
7195 + struct ltq_dma_device dma_dev;
7196 + struct mii_dev *bus;
7197 + struct eth_device *dev;
7198 + struct phy_device *phymap[LTQ_ETHSW_MAX_GMAC];
7203 +static struct vr9_switch_regs *switch_regs =
7204 + (struct vr9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE);
7206 +static inline void vr9_switch_sync(void)
7211 +static inline int vr9_switch_mdio_is_busy(void)
7213 + u32 mdio_ctrl = ltq_readl(&switch_regs->mdio.mdio_ctrl);
7215 + return mdio_ctrl & MDIO_CTRL_MBUSY;
7218 +static inline void vr9_switch_mdio_poll(void)
7220 + while (vr9_switch_mdio_is_busy())
7224 +static int vr9_switch_mdio_read(struct mii_dev *bus, int phyad, int devad,
7230 + mdio_ctrl = MDIO_CTRL_OP_READ |
7231 + ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
7232 + (regad & MDIO_CTRL_REGAD_MASK);
7234 + vr9_switch_mdio_poll();
7235 + ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
7236 + vr9_switch_mdio_poll();
7237 + retval = ltq_readl(&switch_regs->mdio.mdio_read);
7242 +static int vr9_switch_mdio_write(struct mii_dev *bus, int phyad, int devad,
7243 + int regad, u16 val)
7247 + mdio_ctrl = MDIO_CTRL_OP_WRITE |
7248 + ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
7249 + (regad & MDIO_CTRL_REGAD_MASK);
7251 + vr9_switch_mdio_poll();
7252 + ltq_writel(&switch_regs->mdio.mdio_write, val);
7253 + ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
7258 +static void ltq_eth_gmac_update(struct phy_device *phydev, int num)
7260 + struct ltq_mdio_phy_addr_reg phy_addr_reg;
7261 + struct ltq_mii_mii_cfg_reg mii_cfg_reg;
7263 + phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
7269 + mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
7272 + mii_cfg_reg.val = 0;
7276 + phy_addr_reg.bits.addr = phydev->addr;
7279 + phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_UP;
7281 + phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
7283 + switch (phydev->speed) {
7285 + phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_G1;
7286 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M125;
7289 + phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M100;
7290 + switch (mii_cfg_reg.bits.miimode) {
7291 + case LTQ_MII_MII_CFG_MIIMODE_RMIIM:
7292 + case LTQ_MII_MII_CFG_MIIMODE_RMIIP:
7293 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M50;
7296 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M25;
7301 + phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
7302 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
7306 + if (phydev->duplex == DUPLEX_FULL)
7307 + phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_ENABLE;
7309 + phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
7311 + ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
7317 + ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
7324 +static inline u8 *ltq_eth_rx_packet_align(int rx_num)
7326 + u8 *packet = (u8 *) NetRxPackets[rx_num];
7331 + return packet + LTQ_ETH_IP_ALIGN;
7334 +static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
7336 + struct ltq_eth_priv *priv = dev->priv;
7337 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
7338 + struct phy_device *phydev;
7341 + for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
7342 + phydev = priv->phymap[i];
7346 + phy_startup(phydev);
7347 + ltq_eth_gmac_update(phydev, i);
7350 + for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
7351 + ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
7352 + LTQ_ETH_RX_DATA_SIZE);
7354 + ltq_dma_enable(dma_dev);
7362 +static void ltq_eth_halt(struct eth_device *dev)
7364 + struct ltq_eth_priv *priv = dev->priv;
7365 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
7366 + struct phy_device *phydev;
7369 + ltq_dma_reset(dma_dev);
7371 + for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
7372 + phydev = priv->phymap[i];
7376 + phy_shutdown(phydev);
7378 + ltq_eth_gmac_update(phydev, i);
7382 +static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
7384 + struct ltq_eth_priv *priv = dev->priv;
7385 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
7388 + printf("%s: packet %p, len %d\n", __func__, packet, length);
7391 + ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
7392 + priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
7397 +static int ltq_eth_recv(struct eth_device *dev)
7399 + struct ltq_eth_priv *priv = dev->priv;
7400 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
7404 + if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
7408 + printf("%s: rx_num %d\n", __func__, priv->rx_num);
7411 + len = ltq_dma_rx_length(dma_dev, priv->rx_num);
7412 + packet = ltq_eth_rx_packet_align(priv->rx_num);
7415 + printf("%s: received: packet %p, len %u, rx_num %d\n",
7416 + __func__, packet, len, priv->rx_num);
7420 + NetReceive(packet, len);
7422 + ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
7423 + LTQ_ETH_RX_DATA_SIZE);
7425 + priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
7430 +static void ltq_eth_gmac_init(int num)
7432 + struct ltq_mdio_phy_addr_reg phy_addr_reg;
7433 + struct ltq_mii_mii_cfg_reg mii_cfg_reg;
7435 + /* Reset PHY status to link down */
7436 + phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
7437 + phy_addr_reg.bits.addr = num;
7438 + phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
7439 + phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
7440 + phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
7441 + ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
7443 + /* Reset and disable MII interface */
7448 + mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
7449 + mii_cfg_reg.bits.en = 0;
7450 + mii_cfg_reg.bits.res = 1;
7451 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
7452 + ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
7459 + * - enable frame checksum generation
7460 + * - enable padding of short frames
7461 + * - disable flow control
7463 + ltq_writel(to_mac_ctrl(switch_regs, num, 0),
7464 + MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
7466 + vr9_switch_sync();
7469 +static void ltq_eth_pmac_init(void)
7472 + * WAR: buffer congestion:
7473 + * - shorten preambel to 1 byte
7474 + * - set TX IPG to 7 bytes
7477 + ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 1),
7478 + MAC_CTRL1_SHORTPRE | 7);
7482 + * WAR: systematical concept weakness ACM bug
7483 + * - set maximum number of used buffer segments to 254
7484 + * - soft-reset BM FSQM
7487 + ltq_writel(&switch_regs->bm.core.fsqm_gctrl, 253);
7488 + ltq_setbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
7489 + ltq_clrbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
7493 + * WAR: switch MAC drop bug
7496 + ltq_writel(to_pce_tbl_key(switch_regs, 0), 0xf);
7497 + ltq_writel(to_pce_tbl_value(switch_regs, 0), 0x40);
7498 + ltq_writel(&switch_regs->pce.core.tbl_addr, 0x3);
7499 + ltq_writel(&switch_regs->pce.core.tbl_ctrl, 0x902f);
7503 + * Configure frame header control:
7504 + * - enable flow control
7505 + * - enable CRC check for packets from DMA to PMAC
7506 + * - remove special tag from packets from PMAC to DMA
7507 + * - add CRC for packets from DMA to PMAC
7509 + ltq_writel(&switch_regs->pmac.hd_ctl, /*PMAC_HD_CTL_FC |*/
7510 + PMAC_HD_CTL_CCRC | PMAC_HD_CTL_RST | PMAC_HD_CTL_AC |
7514 + ltq_writel(&switch_regs->pmac.rx_ipg, 0x8b);
7518 + * - enable frame checksum generation
7519 + * - enable padding of short frames
7520 + * - disable flow control
7522 + ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 0),
7523 + MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
7525 + vr9_switch_sync();
7528 +static void ltq_eth_hw_init(void)
7532 + /* Power up ethernet and switch subsystems */
7533 + ltq_pm_enable(LTQ_PM_ETH);
7535 + /* Reset ethernet and switch subsystems */
7537 + ltq_reset_once(LTQ_RESET_ETH, 10);
7540 + /* Enable switch macro */
7541 + ltq_setbits(&switch_regs->mdio.glob_ctrl, MDIO_GLOB_CTRL_SE);
7543 + /* Disable MDIO auto-polling for all ports */
7544 + ltq_writel(&switch_regs->mdio.mdc_cfg_0, 0);
7547 + * Enable and set MDIO management clock to 2.5 MHz. This is the
7548 + * maximum clock for FE PHYs.
7549 + * Formula for clock is:
7552 + * x = ----------- - 1
7555 + ltq_writel(&switch_regs->mdio.mdc_cfg_1, MDIO_MDC_CFG1_RES |
7556 + MDIO_MDC_CFG1_MCEN | 5);
7558 + vr9_switch_sync();
7560 + /* Init MAC connected to CPU */
7561 + ltq_eth_pmac_init();
7563 + /* Init MACs connected to external MII interfaces */
7564 + for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++)
7565 + ltq_eth_gmac_init(i);
7568 +static void ltq_eth_port_config(struct ltq_eth_priv *priv,
7569 + const struct ltq_eth_port_config *port)
7571 + struct ltq_mii_mii_cfg_reg mii_cfg_reg;
7572 + struct phy_device *phydev;
7573 + int setup_gpio = 0;
7575 + switch (port->num) {
7576 + case 0: /* xMII0 */
7577 + case 1: /* xMII1 */
7578 + mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
7580 + mii_cfg_reg.bits.en = port->flags ? 1 : 0;
7582 + switch (port->phy_if) {
7583 + case PHY_INTERFACE_MODE_MII:
7584 + if (port->flags & LTQ_ETH_PORT_PHY)
7585 + /* MII MAC mode, connected to external PHY */
7586 + mii_cfg_reg.bits.miimode =
7587 + LTQ_MII_MII_CFG_MIIMODE_MIIM;
7589 + /* MII PHY mode, connected to external MAC */
7590 + mii_cfg_reg.bits.miimode =
7591 + LTQ_MII_MII_CFG_MIIMODE_MIIP;
7594 + case PHY_INTERFACE_MODE_RMII:
7595 + if (port->flags & LTQ_ETH_PORT_PHY)
7596 + /* RMII MAC mode, connected to external PHY */
7597 + mii_cfg_reg.bits.miimode =
7598 + LTQ_MII_MII_CFG_MIIMODE_RMIIM;
7600 + /* RMII PHY mode, connected to external MAC */
7601 + mii_cfg_reg.bits.miimode =
7602 + LTQ_MII_MII_CFG_MIIMODE_RMIIP;
7605 + case PHY_INTERFACE_MODE_RGMII:
7606 + /* RGMII MAC mode, connected to external PHY */
7607 + mii_cfg_reg.bits.miimode =
7608 + LTQ_MII_MII_CFG_MIIMODE_RGMII;
7611 + /* RGMII clock delays */
7612 + ltq_writel(to_mii_pcdu(switch_regs, port->num),
7613 + port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
7614 + port->rgmii_tx_delay);
7620 + ltq_writel(to_mii_miicfg(switch_regs, port->num),
7623 + case 2: /* internal GPHY0 */
7624 + case 3: /* internal GPHY0 */
7625 + case 4: /* internal GPHY1 */
7626 + switch (port->phy_if) {
7627 + case PHY_INTERFACE_MODE_MII:
7628 + case PHY_INTERFACE_MODE_GMII:
7635 + case 5: /* internal GPHY1 or xMII2 */
7636 + mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
7638 + mii_cfg_reg.bits.en = port->flags ? 1 : 0;
7640 + switch (port->phy_if) {
7641 + case PHY_INTERFACE_MODE_MII:
7642 + /* MII MAC mode, connected to internal GPHY */
7643 + mii_cfg_reg.bits.miimode =
7644 + LTQ_MII_MII_CFG_MIIMODE_MIIM;
7647 + case PHY_INTERFACE_MODE_RGMII:
7648 + /* RGMII MAC mode, connected to external PHY */
7649 + mii_cfg_reg.bits.miimode =
7650 + LTQ_MII_MII_CFG_MIIMODE_RGMII;
7653 + /* RGMII clock delays */
7654 + ltq_writel(to_mii_pcdu(switch_regs, port->num),
7655 + port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
7656 + port->rgmii_tx_delay);
7662 + ltq_writel(to_mii_miicfg(switch_regs, port->num),
7669 + /* Setup GPIOs for MII with external PHYs/MACs */
7672 + gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
7675 + gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
7679 + /* Connect to internal/external PHYs */
7680 + if (port->flags & LTQ_ETH_PORT_PHY) {
7681 + phydev = phy_connect(priv->bus, port->phy_addr, priv->dev,
7684 + phy_config(phydev);
7686 + priv->phymap[port->num] = phydev;
7690 +int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
7692 + struct eth_device *dev;
7693 + struct mii_dev *bus;
7694 + struct ltq_eth_priv *priv;
7695 + struct ltq_dma_device *dma_dev;
7698 + build_check_vr9_registers();
7701 + ltq_eth_hw_init();
7703 + dev = calloc(1, sizeof(struct eth_device));
7707 + priv = calloc(1, sizeof(struct ltq_eth_priv));
7711 + bus = mdio_alloc();
7715 + sprintf(dev->name, LTQ_ETH_DRV_NAME);
7717 + dev->init = ltq_eth_init;
7718 + dev->halt = ltq_eth_halt;
7719 + dev->recv = ltq_eth_recv;
7720 + dev->send = ltq_eth_send;
7722 + sprintf(bus->name, LTQ_MDIO_DRV_NAME);
7723 + bus->read = vr9_switch_mdio_read;
7724 + bus->write = vr9_switch_mdio_write;
7727 + dma_dev = &priv->dma_dev;
7728 + dma_dev->port = 0;
7729 + dma_dev->rx_chan.chan_no = 0;
7730 + dma_dev->rx_chan.class = 0;
7731 + dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
7732 + dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
7733 + dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
7734 + dma_dev->tx_chan.chan_no = 1;
7735 + dma_dev->tx_chan.class = 0;
7736 + dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
7737 + dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
7738 + dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
7743 + ret = ltq_dma_register(dma_dev);
7747 + ret = mdio_register(bus);
7751 + ret = eth_register(dev);
7755 + for (i = 0; i < board_config->num_ports; i++)
7756 + ltq_eth_port_config(priv, &board_config->ports[i]);
7760 diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
7761 index fe762e9..9eb08b8 100644
7762 --- a/drivers/net/phy/Makefile
7763 +++ b/drivers/net/phy/Makefile
7764 @@ -20,6 +20,7 @@ COBJS-$(CONFIG_PHY_BROADCOM) += broadcom.o
7765 COBJS-$(CONFIG_PHY_DAVICOM) += davicom.o
7766 COBJS-$(CONFIG_PHY_ET1011C) += et1011c.o
7767 COBJS-$(CONFIG_PHY_ICPLUS) += icplus.o
7768 +COBJS-$(CONFIG_PHY_LANTIQ) += lantiq.o
7769 COBJS-$(CONFIG_PHY_LXT) += lxt.o
7770 COBJS-$(CONFIG_PHY_MARVELL) += marvell.o
7771 COBJS-$(CONFIG_PHY_MICREL) += micrel.o
7772 diff --git a/drivers/net/phy/lantiq.c b/drivers/net/phy/lantiq.c
7773 new file mode 100644
7774 index 0000000..572c8c3
7776 +++ b/drivers/net/phy/lantiq.c
7779 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
7781 + * SPDX-License-Identifier: GPL-2.0+
7786 +#include <common.h>
7787 +#include <miiphy.h>
7789 +#define ADVERTIZE_MPD (1 << 10)
7791 +DECLARE_GLOBAL_DATA_PTR;
7794 + * Update link status.
7796 + * Based on genphy_update_link in phylib.c
7798 +static int ltq_phy_update_link(struct phy_device *phydev)
7800 + unsigned int mii_reg;
7802 + mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7805 + * If we already saw the link up, and it hasn't gone down, then
7806 + * we don't need to wait for autoneg again
7808 + if (phydev->link && mii_reg & BMSR_LSTATUS)
7811 + if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
7815 + /* Read the link a second time to clear the latched state */
7816 + mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7818 + if (mii_reg & BMSR_LSTATUS)
7828 + * Update speed and duplex.
7830 + * Based on genphy_parse_link in phylib.c
7832 +static int ltq_phy_parse_link(struct phy_device *phydev)
7834 + unsigned int mii_reg;
7836 + mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7838 + /* We're using autonegotiation */
7839 + if (mii_reg & BMSR_ANEGCAPABLE) {
7843 + /* Check for gigabit capability */
7844 + if (mii_reg & BMSR_ERCAP) {
7845 + /* We want a list of states supported by
7846 + * both PHYs in the link
7848 + gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
7849 + gblpa &= phy_read(phydev,
7850 + MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
7853 + /* Set the baseline so we only have to set them
7854 + * if they're different
7856 + phydev->speed = SPEED_10;
7857 + phydev->duplex = DUPLEX_HALF;
7859 + /* Check the gigabit fields */
7860 + if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
7861 + phydev->speed = SPEED_1000;
7863 + if (gblpa & PHY_1000BTSR_1000FD)
7864 + phydev->duplex = DUPLEX_FULL;
7870 + lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
7871 + lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
7873 + if (lpa & (LPA_100FULL | LPA_100HALF)) {
7874 + phydev->speed = SPEED_100;
7876 + if (lpa & LPA_100FULL)
7877 + phydev->duplex = DUPLEX_FULL;
7879 + } else if (lpa & LPA_10FULL)
7880 + phydev->duplex = DUPLEX_FULL;
7882 + u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
7884 + phydev->speed = SPEED_10;
7885 + phydev->duplex = DUPLEX_HALF;
7887 + if (bmcr & BMCR_FULLDPLX)
7888 + phydev->duplex = DUPLEX_FULL;
7890 + if (bmcr & BMCR_SPEED1000)
7891 + phydev->speed = SPEED_1000;
7892 + else if (bmcr & BMCR_SPEED100)
7893 + phydev->speed = SPEED_100;
7899 +static int ltq_phy_config(struct phy_device *phydev)
7903 + /* Advertise as Multi-port device */
7904 + val = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
7905 + val |= ADVERTIZE_MPD;
7906 + phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, val);
7908 + genphy_config_aneg(phydev);
7913 +static int ltq_phy_startup(struct phy_device *phydev)
7916 + * Update PHY status immediately without any delays as genphy_startup
7917 + * does because VRX200 switch needs to be configured dependent
7918 + * on this information.
7920 + ltq_phy_update_link(phydev);
7921 + ltq_phy_parse_link(phydev);
7923 + debug("ltq_phy: addr %d, link %d, speed %d, duplex %d\n",
7924 + phydev->addr, phydev->link, phydev->speed, phydev->duplex);
7929 +static struct phy_driver xrx_11g_13_driver = {
7930 + .name = "Lantiq XWAY XRX PHY11G v1.3 and earlier",
7931 + .uid = 0x030260D0,
7932 + .mask = 0xFFFFFFF0,
7933 + .features = PHY_GBIT_FEATURES,
7934 + .config = ltq_phy_config,
7935 + .startup = ltq_phy_startup,
7936 + .shutdown = genphy_shutdown,
7939 +static struct phy_driver xrx_11g_14_driver = {
7940 + .name = "Lantiq XWAY XRX PHY11G v1.4 and later",
7941 + .uid = 0xd565a408,
7942 + .mask = 0xFFFFFFF8,
7943 + .features = PHY_GBIT_FEATURES,
7944 + .config = ltq_phy_config,
7945 + .startup = ltq_phy_startup,
7946 + .shutdown = genphy_shutdown,
7949 +static struct phy_driver xrx_22f_14_driver = {
7950 + .name = "Lantiq XWAY XRX PHY22F v1.4 and later",
7951 + .uid = 0xd565a418,
7952 + .mask = 0xFFFFFFF8,
7953 + .features = PHY_BASIC_FEATURES,
7954 + .config = ltq_phy_config,
7955 + .startup = ltq_phy_startup,
7956 + .shutdown = genphy_shutdown,
7959 +static struct phy_driver pef7071_driver = {
7960 + .name = "Lantiq XWAY PEF7071",
7961 + .uid = 0xd565a400,
7962 + .mask = 0xFFFFFFFF,
7963 + .features = PHY_GBIT_FEATURES,
7964 + .config = ltq_phy_config,
7965 + .startup = ltq_phy_startup,
7966 + .shutdown = genphy_shutdown,
7969 +static struct phy_driver xrx_genphy_driver = {
7970 + .name = "Generic PHY at Lantiq XWAY XRX switch",
7974 + .config = genphy_config,
7975 + .startup = ltq_phy_startup,
7976 + .shutdown = genphy_shutdown,
7979 +int phy_lantiq_init(void)
7981 +#ifdef CONFIG_NEEDS_MANUAL_RELOC
7982 + xrx_11g_13_driver.config = ltq_phy_config;
7983 + xrx_11g_13_driver.startup = ltq_phy_startup;
7984 + xrx_11g_13_driver.shutdown = genphy_shutdown;
7985 + xrx_11g_13_driver.name += gd->reloc_off;
7987 + xrx_11g_14_driver.config = ltq_phy_config;
7988 + xrx_11g_14_driver.startup = ltq_phy_startup;
7989 + xrx_11g_14_driver.shutdown = genphy_shutdown;
7990 + xrx_11g_14_driver.name += gd->reloc_off;
7992 + xrx_22f_14_driver.config = ltq_phy_config;
7993 + xrx_22f_14_driver.startup = ltq_phy_startup;
7994 + xrx_22f_14_driver.shutdown = genphy_shutdown;
7995 + xrx_22f_14_driver.name += gd->reloc_off;
7997 + pef7071_driver.config = ltq_phy_config;
7998 + pef7071_driver.startup = ltq_phy_startup;
7999 + pef7071_driver.shutdown = genphy_shutdown;
8000 + pef7071_driver.name += gd->reloc_off;
8002 + xrx_genphy_driver.config = genphy_config;
8003 + xrx_genphy_driver.startup = ltq_phy_startup;
8004 + xrx_genphy_driver.shutdown = genphy_shutdown;
8005 + xrx_genphy_driver.name += gd->reloc_off;
8008 + phy_register(&xrx_11g_13_driver);
8009 + phy_register(&xrx_11g_14_driver);
8010 + phy_register(&xrx_22f_14_driver);
8011 + phy_register(&pef7071_driver);
8012 + phy_register(&xrx_genphy_driver);
8016 diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
8017 index 62925bb..dfbe108 100644
8018 --- a/drivers/net/phy/phy.c
8019 +++ b/drivers/net/phy/phy.c
8021 #include <command.h>
8025 #include <linux/err.h>
8027 +DECLARE_GLOBAL_DATA_PTR;
8029 /* Generic PHY support and helper functions */
8032 @@ -440,6 +441,16 @@ static LIST_HEAD(phy_drivers);
8036 +#ifdef CONFIG_NEEDS_MANUAL_RELOC
8037 + INIT_LIST_HEAD(&phy_drivers);
8039 + genphy_driver.config = genphy_config;
8040 + genphy_driver.startup = genphy_startup;
8041 + genphy_driver.shutdown = genphy_shutdown;
8043 + genphy_driver.name += gd->reloc_off;
8046 #ifdef CONFIG_PHY_ATHEROS
8049 @@ -455,6 +466,9 @@ int phy_init(void)
8050 #ifdef CONFIG_PHY_ICPLUS
8053 +#ifdef CONFIG_PHY_LANTIQ
8054 + phy_lantiq_init();
8056 #ifdef CONFIG_PHY_LXT
8059 diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
8060 index e1fd7a5..3247b82 100644
8061 --- a/drivers/serial/Makefile
8062 +++ b/drivers/serial/Makefile
8063 @@ -24,6 +24,7 @@ COBJS-$(CONFIG_SYS_NS16550_SERIAL) += serial_ns16550.o
8064 COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
8065 COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
8066 COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
8067 +COBJS-$(CONFIG_LANTIQ_SERIAL) += serial_lantiq.o
8068 COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
8069 COBJS-$(CONFIG_MXC_UART) += serial_mxc.o
8070 COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
8071 diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
8072 index df2b84a..b955f30 100644
8073 --- a/drivers/serial/serial.c
8074 +++ b/drivers/serial/serial.c
8075 @@ -160,6 +160,7 @@ serial_initfunc(sa1100_serial_initialize);
8076 serial_initfunc(sh_serial_initialize);
8077 serial_initfunc(arm_dcc_initialize);
8078 serial_initfunc(mxs_auart_initialize);
8079 +serial_initfunc(ltq_serial_initialize);
8082 * serial_register() - Register serial driver with serial driver core
8083 @@ -253,6 +254,7 @@ void serial_initialize(void)
8084 sh_serial_initialize();
8085 arm_dcc_initialize();
8086 mxs_auart_initialize();
8087 + ltq_serial_initialize();
8089 serial_assign(default_serial_console()->name);
8091 diff --git a/drivers/serial/serial_lantiq.c b/drivers/serial/serial_lantiq.c
8092 new file mode 100644
8093 index 0000000..07b2f9d
8095 +++ b/drivers/serial/serial_lantiq.c
8098 + * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
8099 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
8101 + * SPDX-License-Identifier: GPL-2.0+
8104 +#include <common.h>
8105 +#include <serial.h>
8106 +#include <asm/errno.h>
8107 +#include <asm/arch/soc.h>
8108 +#include <asm/lantiq/clk.h>
8109 +#include <asm/lantiq/io.h>
8111 +#if CONFIG_CONSOLE_ASC == 0
8112 +#define LTQ_ASC_BASE LTQ_ASC0_BASE
8114 +#define LTQ_ASC_BASE LTQ_ASC1_BASE
8117 +#define LTQ_ASC_ID_TXFS_SHIFT 24
8118 +#define LTQ_ASC_ID_TXFS_MASK (0x3F << LTQ_ASC_ID_TXFS_SHIFT)
8119 +#define LTQ_ASC_ID_RXFS_SHIFT 16
8120 +#define LTQ_ASC_ID_RXFS_MASK (0x3F << LTQ_ASC_ID_RXFS_SHIFT)
8122 +#define LTQ_ASC_MCON_R (1 << 15)
8123 +#define LTQ_ASC_MCON_FDE (1 << 9)
8125 +#define LTQ_ASC_WHBSTATE_SETREN (1 << 1)
8126 +#define LTQ_ASC_WHBSTATE_CLRREN (1 << 0)
8128 +#define LTQ_ASC_RXFCON_RXFITL_SHIFT 8
8129 +#define LTQ_ASC_RXFCON_RXFITL_MASK (0x3F << LTQ_ASC_RXFCON_RXFITL_SHIFT)
8130 +#define LTQ_ASC_RXFCON_RXFITL_RXFFLU (1 << 1)
8131 +#define LTQ_ASC_RXFCON_RXFITL_RXFEN (1 << 0)
8133 +#define LTQ_ASC_TXFCON_TXFITL_SHIFT 8
8134 +#define LTQ_ASC_TXFCON_TXFITL_MASK (0x3F << LTQ_ASC_TXFCON_TXFITL_SHIFT)
8135 +#define LTQ_ASC_TXFCON_TXFITL_TXFFLU (1 << 1)
8136 +#define LTQ_ASC_TXFCON_TXFITL_TXFEN (1 << 0)
8138 +#define LTQ_ASC_FSTAT_TXFREE_SHIFT 24
8139 +#define LTQ_ASC_FSTAT_TXFREE_MASK (0x3F << LTQ_ASC_FSTAT_TXFREE_SHIFT)
8140 +#define LTQ_ASC_FSTAT_RXFREE_SHIFT 16
8141 +#define LTQ_ASC_FSTAT_RXFREE_MASK (0x3F << LTQ_ASC_FSTAT_RXFREE_SHIFT)
8142 +#define LTQ_ASC_FSTAT_TXFFL_SHIFT 8
8143 +#define LTQ_ASC_FSTAT_TXFFL_MASK (0x3F << LTQ_ASC_FSTAT_TXFFL_SHIFT)
8144 +#define LTQ_ASC_FSTAT_RXFFL_MASK 0x3F
8146 +#ifdef __BIG_ENDIAN
8147 +#define LTQ_ASC_RBUF_OFFSET 3
8148 +#define LTQ_ASC_TBUF_OFFSET 3
8150 +#define LTQ_ASC_RBUF_OFFSET 0
8151 +#define LTQ_ASC_TBUF_OFFSET 0
8154 +struct ltq_asc_regs {
8182 +DECLARE_GLOBAL_DATA_PTR;
8184 +static struct ltq_asc_regs *ltq_asc_regs =
8185 + (struct ltq_asc_regs *) CKSEG1ADDR(LTQ_ASC_BASE);
8187 +static int ltq_serial_init(void)
8189 + /* Set clock divider for normal run mode to 1 and enable module */
8190 + ltq_writel(<q_asc_regs->clc, 0x100);
8192 + /* Reset MCON register */
8193 + ltq_writel(<q_asc_regs->mcon, 0);
8195 + /* Use Port A as receiver input */
8196 + ltq_writel(<q_asc_regs->pisel, 0);
8198 + /* Enable and flush RX/TX FIFOs */
8199 + ltq_setbits(<q_asc_regs->rxfcon,
8200 + LTQ_ASC_RXFCON_RXFITL_RXFFLU | LTQ_ASC_RXFCON_RXFITL_RXFEN);
8201 + ltq_setbits(<q_asc_regs->txfcon,
8202 + LTQ_ASC_TXFCON_TXFITL_TXFFLU | LTQ_ASC_TXFCON_TXFITL_TXFEN);
8206 + /* Disable error flags, enable receiver */
8207 + ltq_writel(<q_asc_regs->whbstate, LTQ_ASC_WHBSTATE_SETREN);
8214 + * Baudrate = ----- * -------------
8215 + * 512 16 * (bg + 1)
8217 +static void ltq_serial_calc_br_fdv(unsigned long asc_clk,
8218 + unsigned long baudrate, u16 *fdv,
8221 + const u32 c = asc_clk / (16 * 512);
8223 + u32 bg_calc, br_calc, i;
8226 + for (i = 512; i > 0; i--) {
8227 + /* Calc bg for current fdv value */
8228 + bg_calc = i * c / baudrate;
8230 + /* Impossible baudrate */
8235 + * Calc diff to target baudrate dependent on current
8236 + * bg and fdv values
8238 + br_calc = i * c / bg_calc;
8239 + if (br_calc > baudrate)
8240 + diff2 = br_calc - baudrate;
8242 + diff2 = baudrate - br_calc;
8244 + /* Perfect values found */
8247 + *bg = bg_calc - 1;
8251 + if (diff2 < diff1) {
8253 + *bg = bg_calc - 1;
8259 +static void ltq_serial_setbrg(void)
8261 + unsigned long asc_clk, baudrate;
8265 + /* ASC clock is same as FPI clock with CLC.RMS = 1 */
8266 + asc_clk = ltq_get_bus_clock();
8267 + baudrate = gd->baudrate;
8269 + /* Calculate FDV and BG values */
8270 + ltq_serial_calc_br_fdv(asc_clk, baudrate, &fdv, &bg);
8272 + /* Disable baudrate generator */
8273 + ltq_clrbits(<q_asc_regs->mcon, LTQ_ASC_MCON_R);
8275 + /* Enable fractional divider */
8276 + ltq_setbits(<q_asc_regs->mcon, LTQ_ASC_MCON_FDE);
8278 + /* Set fdv and bg values */
8279 + ltq_writel(<q_asc_regs->fdv, fdv);
8280 + ltq_writel(<q_asc_regs->bg, bg);
8282 + /* Enable baudrate generator */
8283 + ltq_setbits(<q_asc_regs->mcon, LTQ_ASC_MCON_R);
8286 +static unsigned int ltq_serial_tx_free(void)
8288 + unsigned int txfree;
8290 + txfree = (ltq_readl(<q_asc_regs->fstat) &
8291 + LTQ_ASC_FSTAT_TXFREE_MASK) >>
8292 + LTQ_ASC_FSTAT_TXFREE_SHIFT;
8297 +static unsigned int ltq_serial_rx_fill(void)
8299 + unsigned int rxffl;
8301 + rxffl = ltq_readl(<q_asc_regs->fstat) & LTQ_ASC_FSTAT_RXFFL_MASK;
8306 +static void ltq_serial_tx(const char c)
8308 + ltq_writeb(<q_asc_regs->tbuf[LTQ_ASC_TBUF_OFFSET], c);
8311 +static u8 ltq_serial_rx(void)
8313 + return ltq_readb(<q_asc_regs->rbuf[LTQ_ASC_RBUF_OFFSET]);
8316 +static void ltq_serial_putc(const char c)
8319 + ltq_serial_putc('\r');
8321 + while (!ltq_serial_tx_free())
8327 +static int ltq_serial_getc(void)
8329 + while (!ltq_serial_rx_fill())
8332 + return ltq_serial_rx();
8335 +static int ltq_serial_tstc(void)
8337 + return (0 != ltq_serial_rx_fill());
8340 +static struct serial_device ltq_serial_drv = {
8341 + .name = "ltq_serial",
8342 + .start = ltq_serial_init,
8344 + .setbrg = ltq_serial_setbrg,
8345 + .putc = ltq_serial_putc,
8346 + .puts = default_serial_puts,
8347 + .getc = ltq_serial_getc,
8348 + .tstc = ltq_serial_tstc,
8351 +void ltq_serial_initialize(void)
8353 + serial_register(<q_serial_drv);
8356 +__weak struct serial_device *default_serial_console(void)
8358 + return <q_serial_drv;
8360 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
8361 index e5941b0..f831ea1 100644
8362 --- a/drivers/spi/Makefile
8363 +++ b/drivers/spi/Makefile
8364 @@ -25,6 +25,7 @@ COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
8365 COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
8366 COBJS-$(CONFIG_ICH_SPI) += ich.o
8367 COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
8368 +COBJS-$(CONFIG_LANTIQ_SPI) += lantiq_spi.o
8369 COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
8370 COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
8371 COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
8372 diff --git a/drivers/spi/lantiq_spi.c b/drivers/spi/lantiq_spi.c
8373 new file mode 100644
8374 index 0000000..b327878
8376 +++ b/drivers/spi/lantiq_spi.c
8379 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
8381 + * SPDX-License-Identifier: GPL-2.0+
8384 +#include <common.h>
8386 +#include <malloc.h>
8387 +#include <watchdog.h>
8388 +#include <asm/gpio.h>
8389 +#include <asm/lantiq/io.h>
8390 +#include <asm/lantiq/clk.h>
8391 +#include <asm/lantiq/pm.h>
8392 +#include <asm/arch/soc.h>
8394 +#define LTQ_SPI_CLC_RMC_SHIFT 8
8395 +#define LTQ_SPI_CLC_RMC_MASK (0xFF << LTQ_SPI_CLC_RMC_SHIFT)
8396 +#define LTQ_SPI_CLC_DISS (1 << 1)
8397 +#define LTQ_SPI_CLC_DISR 1
8399 +#define LTQ_SPI_ID_TXFS_SHIFT 24
8400 +#define LTQ_SPI_ID_TXFS_MASK (0x3F << LTQ_SPI_ID_TXFS_SHIFT)
8401 +#define LTQ_SPI_ID_RXFS_SHIFT 16
8402 +#define LTQ_SPI_ID_RXFS_MASK (0x3F << LTQ_SPI_ID_RXFS_SHIFT)
8404 +#define LTQ_SPI_CON_ENBV (1 << 22)
8405 +#define LTQ_SPI_CON_BM_SHIFT 16
8406 +#define LTQ_SPI_CON_BM_MASK (0x1F << LTQ_SPI_CON_BM_SHIFT)
8407 +#define LTQ_SPI_CON_IDLE (1 << 23)
8408 +#define LTQ_SPI_CON_RUEN (1 << 12)
8409 +#define LTQ_SPI_CON_AEN (1 << 10)
8410 +#define LTQ_SPI_CON_REN (1 << 9)
8411 +#define LTQ_SPI_CON_TEN (1 << 8)
8412 +#define LTQ_SPI_CON_LB (1 << 7)
8413 +#define LTQ_SPI_CON_PO (1 << 6)
8414 +#define LTQ_SPI_CON_PH (1 << 5)
8415 +#define LTQ_SPI_CON_HB (1 << 4)
8416 +#define LTQ_SPI_CON_RXOFF (1 << 1)
8417 +#define LTQ_SPI_CON_TXOFF 1
8419 +#define LTQ_SPI_STAT_RXBV_SHIFT 28
8420 +#define LTQ_SPI_STAT_RXBV_MASK (0x7 << LTQ_SPI_STAT_RXBV_SHIFT)
8421 +#define LTQ_SPI_STAT_BSY (1 << 13)
8423 +#define LTQ_SPI_WHBSTATE_SETMS (1 << 3)
8424 +#define LTQ_SPI_WHBSTATE_CLRMS (1 << 2)
8425 +#define LTQ_SPI_WHBSTATE_SETEN (1 << 1)
8426 +#define LTQ_SPI_WHBSTATE_CLREN 1
8427 +#define LTQ_SPI_WHBSTATE_CLR_ERRORS 0x0F50
8429 +#define LTQ_SPI_TXFCON_TXFLU (1 << 1)
8430 +#define LTQ_SPI_TXFCON_TXFEN 1
8432 +#define LTQ_SPI_RXFCON_RXFLU (1 << 1)
8433 +#define LTQ_SPI_RXFCON_RXFEN 1
8435 +#define LTQ_SPI_FSTAT_RXFFL_MASK 0x3f
8436 +#define LTQ_SPI_FSTAT_TXFFL_SHIFT 8
8437 +#define LTQ_SPI_FSTAT_TXFFL_MASK (0x3f << LTQ_SPI_FSTAT_TXFFL_SHIFT)
8439 +#define LTQ_SPI_RXREQ_RXCNT_MASK 0xFFFF
8440 +#define LTQ_SPI_RXCNT_TODO_MASK 0xFFFF
8442 +#define LTQ_SPI_GPIO_DIN 16
8443 +#define LTQ_SPI_GPIO_DOUT 17
8444 +#define LTQ_SPI_GPIO_CLK 18
8446 +struct ltq_spi_regs {
8447 + __be32 clc; /* Clock control */
8448 + __be32 pisel; /* Port input select */
8449 + __be32 id; /* Identification */
8451 + __be32 con; /* Control */
8452 + __be32 stat; /* Status */
8453 + __be32 whbstate; /* Write HW modified state */
8455 + __be32 tb; /* Transmit buffer */
8456 + __be32 rb; /* Receive buffer */
8458 + __be32 rxfcon; /* Recevie FIFO control */
8459 + __be32 txfcon; /* Transmit FIFO control */
8460 + __be32 fstat; /* FIFO status */
8462 + __be32 brt; /* Baudrate timer */
8463 + __be32 brstat; /* Baudrate timer status */
8465 + __be32 sfcon; /* Serial frame control */
8466 + __be32 sfstat; /* Serial frame status */
8468 + __be32 gpocon; /* General purpose output control */
8469 + __be32 gpostat; /* General purpose output status */
8470 + __be32 fgpo; /* Force general purpose output */
8472 + __be32 rxreq; /* Receive request */
8473 + __be32 rxcnt; /* Receive count */
8475 + __be32 dmacon; /* DMA control */
8477 + __be32 irnen; /* Interrupt node enable */
8478 + __be32 irnicr; /* Interrupt node interrupt capture */
8479 + __be32 irncr; /* Interrupt node control */
8482 +struct ltq_spi_drv_data {
8483 + struct ltq_spi_regs __iomem *regs;
8485 + struct spi_slave slave;
8486 + unsigned int max_hz;
8487 + unsigned int mode;
8488 + unsigned int tx_todo;
8489 + unsigned int rx_todo;
8490 + unsigned int rx_req;
8491 + unsigned int bits_per_word;
8492 + unsigned int speed_hz;
8498 +static struct ltq_spi_drv_data *to_ltq_spi_slave(struct spi_slave *slave)
8500 + return container_of(slave, struct ltq_spi_drv_data, slave);
8503 +#ifdef CONFIG_SPL_BUILD
8505 + * We do not have or want malloc in a SPI flash SPL.
8506 + * Neither we have to support multiple SPI slaves. Thus we put the
8507 + * SPI slave context in BSS for SPL builds.
8509 +static struct ltq_spi_drv_data ltq_spi_slave;
8511 +static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
8514 + ltq_spi_slave.slave.bus = bus;
8515 + ltq_spi_slave.slave.cs = cs;
8517 + return <q_spi_slave;
8520 +static void ltq_spi_slave_free(struct spi_slave *slave)
8524 +static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
8527 + return spi_alloc_slave(struct ltq_spi_drv_data, bus, cs);
8530 +static void ltq_spi_slave_free(struct spi_slave *slave)
8532 + struct ltq_spi_drv_data *drv;
8535 + drv = to_ltq_spi_slave(slave);
8541 +static unsigned int tx_fifo_size(struct ltq_spi_drv_data *drv)
8543 + u32 id = ltq_readl(&drv->regs->id);
8545 + return (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT;
8548 +static unsigned int rx_fifo_size(struct ltq_spi_drv_data *drv)
8550 + u32 id = ltq_readl(&drv->regs->id);
8552 + return (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT;
8555 +static unsigned int tx_fifo_level(struct ltq_spi_drv_data *drv)
8557 + u32 fstat = ltq_readl(&drv->regs->fstat);
8559 + return (fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >> LTQ_SPI_FSTAT_TXFFL_SHIFT;
8562 +static unsigned int rx_fifo_level(struct ltq_spi_drv_data *drv)
8564 + u32 fstat = ltq_readl(&drv->regs->fstat);
8566 + return fstat & LTQ_SPI_FSTAT_RXFFL_MASK;
8569 +static unsigned int tx_fifo_free(struct ltq_spi_drv_data *drv)
8571 + return tx_fifo_size(drv) - tx_fifo_level(drv);
8574 +static void hw_power_on(struct ltq_spi_drv_data *drv)
8578 + /* Power-up mdule */
8579 + ltq_pm_enable(LTQ_PM_SPI);
8582 + * Set clock divider for run mode to 1 to
8583 + * run at same frequency as FPI bus
8585 + clc = (1 << LTQ_SPI_CLC_RMC_SHIFT);
8586 + ltq_writel(&drv->regs->clc, clc);
8589 +static void hw_reset_fifos(struct ltq_spi_drv_data *drv)
8593 + val = LTQ_SPI_TXFCON_TXFEN | LTQ_SPI_TXFCON_TXFLU;
8594 + ltq_writel(&drv->regs->txfcon, val);
8596 + val = LTQ_SPI_RXFCON_RXFEN | LTQ_SPI_RXFCON_RXFLU;
8597 + ltq_writel(&drv->regs->rxfcon, val);
8600 +static int hw_is_busy(struct ltq_spi_drv_data *drv)
8602 + u32 stat = ltq_readl(&drv->regs->stat);
8604 + return stat & LTQ_SPI_STAT_BSY;
8607 +static void hw_enter_config_mode(struct ltq_spi_drv_data *drv)
8609 + ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_CLREN);
8612 +static void hw_enter_active_mode(struct ltq_spi_drv_data *drv)
8614 + ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETEN);
8617 +static void hw_setup_speed_hz(struct ltq_spi_drv_data *drv,
8618 + unsigned int max_speed_hz)
8620 + unsigned int spi_hz, speed_hz, brt;
8623 + * SPI module clock is derived from FPI bus clock dependent on
8624 + * divider value in CLC.RMS which is always set to 1.
8627 + * baudrate = --------------
8630 + spi_hz = ltq_get_bus_clock() / 2;
8632 + /* TODO: optimize baudrate calculation */
8633 + for (brt = 0; brt < 0xFFFF; brt++) {
8634 + speed_hz = spi_hz / (brt + 1);
8635 + if (speed_hz <= max_speed_hz)
8639 + ltq_writel(&drv->regs->brt, brt);
8642 +static void hw_setup_bits_per_word(struct ltq_spi_drv_data *drv,
8643 + unsigned int bits_per_word)
8647 + /* CON.BM value = bits_per_word - 1 */
8648 + bm = (bits_per_word - 1) << LTQ_SPI_CON_BM_SHIFT;
8650 + ltq_clrsetbits(&drv->regs->con, LTQ_SPI_CON_BM_MASK, bm);
8653 +static void hw_setup_clock_mode(struct ltq_spi_drv_data *drv, unsigned int mode)
8655 + u32 con_set = 0, con_clr = 0;
8658 + * SPI mode mapping in CON register:
8659 + * Mode CPOL CPHA CON.PO CON.PH
8665 + if (mode & SPI_CPHA)
8666 + con_clr |= LTQ_SPI_CON_PH;
8668 + con_set |= LTQ_SPI_CON_PH;
8670 + if (mode & SPI_CPOL)
8671 + con_set |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
8673 + con_clr |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
8675 + /* Set heading control */
8676 + if (mode & SPI_LSB_FIRST)
8677 + con_clr |= LTQ_SPI_CON_HB;
8679 + con_set |= LTQ_SPI_CON_HB;
8681 + /* Set loopback mode */
8682 + if (mode & SPI_LOOP)
8683 + con_set |= LTQ_SPI_CON_LB;
8685 + con_clr |= LTQ_SPI_CON_LB;
8687 + ltq_clrsetbits(&drv->regs->con, con_clr, con_set);
8690 +static void hw_set_rxtx(struct ltq_spi_drv_data *drv)
8694 + /* Configure transmitter and receiver */
8695 + con = ltq_readl(&drv->regs->con);
8697 + con &= ~LTQ_SPI_CON_TXOFF;
8699 + con |= LTQ_SPI_CON_TXOFF;
8702 + con &= ~LTQ_SPI_CON_RXOFF;
8704 + con |= LTQ_SPI_CON_RXOFF;
8706 + ltq_writel(&drv->regs->con, con);
8709 +static void hw_init(struct ltq_spi_drv_data *drv)
8713 + /* Put controller into config mode */
8714 + hw_enter_config_mode(drv);
8716 + /* Disable all interrupts */
8717 + ltq_writel(&drv->regs->irnen, 0);
8719 + /* Clear error flags */
8720 + ltq_clrsetbits(&drv->regs->whbstate, 0, LTQ_SPI_WHBSTATE_CLR_ERRORS);
8722 + /* Enable error checking, disable TX/RX */
8723 + ltq_writel(&drv->regs->con, LTQ_SPI_CON_RUEN | LTQ_SPI_CON_AEN |
8724 + LTQ_SPI_CON_TEN | LTQ_SPI_CON_REN | LTQ_SPI_CON_TXOFF |
8725 + LTQ_SPI_CON_RXOFF);
8727 + /* Setup default SPI mode */
8728 + drv->bits_per_word = 8;
8729 + drv->speed_hz = 0;
8730 + hw_setup_bits_per_word(drv, drv->bits_per_word);
8731 + hw_setup_clock_mode(drv, SPI_MODE_0);
8733 + /* Enable master mode and clear error flags */
8734 + ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETMS |
8735 + LTQ_SPI_WHBSTATE_CLR_ERRORS);
8737 + /* Reset GPIO/CS registers */
8738 + ltq_writel(&drv->regs->gpocon, 0);
8739 + ltq_writel(&drv->regs->fgpo, 0xFF00);
8741 + /* Enable and flush FIFOs */
8742 + hw_reset_fifos(drv);
8744 + /* SPI/DIN input */
8745 + gpio_set_altfunc(16, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
8746 + /* SPI/DOUT output */
8747 + gpio_set_altfunc(17, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
8748 + /* SPI/CLK output */
8749 + gpio_set_altfunc(18, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
8752 +static void tx_fifo_write(struct ltq_spi_drv_data *drv)
8758 + unsigned int tx_free = tx_fifo_free(drv);
8760 + while (drv->tx_todo && tx_free) {
8761 + switch (drv->bits_per_word) {
8769 + tx16 = (u16 *) drv->tx;
8771 + drv->tx_todo -= 2;
8775 + tx32 = (u32 *) drv->tx;
8777 + drv->tx_todo -= 4;
8784 + ltq_writel(&drv->regs->tb, data);
8789 +static void rx_fifo_read_full_duplex(struct ltq_spi_drv_data *drv)
8795 + unsigned int rx_fill = rx_fifo_level(drv);
8798 + data = ltq_readl(&drv->regs->rb);
8800 + switch (drv->bits_per_word) {
8808 + rx16 = (u16 *) drv->rx;
8810 + drv->rx_todo -= 2;
8814 + rx32 = (u32 *) drv->rx;
8816 + drv->rx_todo -= 4;
8827 +static void rx_fifo_read_half_duplex(struct ltq_spi_drv_data *drv)
8831 + unsigned int rxbv, shift;
8832 + unsigned int rx_fill = rx_fifo_level(drv);
8835 + * In RX-only mode the bits per word value is ignored by HW. A value
8836 + * of 32 is used instead. Thus all 4 bytes per FIFO must be read.
8837 + * If remaining RX bytes are less than 4, the FIFO must be read
8838 + * differently. The amount of received and valid bytes is indicated
8839 + * by STAT.RXBV register value.
8842 + if (drv->rx_todo < 4) {
8843 + rxbv = (ltq_readl(&drv->regs->stat) &
8844 + LTQ_SPI_STAT_RXBV_MASK) >>
8845 + LTQ_SPI_STAT_RXBV_SHIFT;
8846 + data = ltq_readl(&drv->regs->rb);
8848 + shift = (rxbv - 1) * 8;
8852 + *rx8++ = (data >> shift) & 0xFF;
8862 + data = ltq_readl(&drv->regs->rb);
8863 + rx32 = (u32 *) drv->rx;
8866 + drv->rx_todo -= 4;
8869 + if (drv->rx_req >= 4)
8876 +static void rx_request(struct ltq_spi_drv_data *drv)
8878 + unsigned int rxreq, rxreq_max;
8884 + * To avoid receive overflows at high clocks it is better to request
8885 + * only the amount of bytes that fits into all FIFOs. This value
8886 + * depends on the FIFO size implemented in hardware.
8888 + rxreq = drv->rx_todo;
8889 + rxreq_max = rx_fifo_size(drv) * 4;
8890 + if (rxreq > rxreq_max)
8891 + rxreq = rxreq_max;
8893 + drv->rx_req = rxreq;
8894 + ltq_writel(&drv->regs->rxreq, rxreq);
8897 +void spi_init(void)
8901 +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
8902 + unsigned int max_hz, unsigned int mode)
8904 + struct ltq_spi_drv_data *drv;
8906 + if (!spi_cs_is_valid(bus, cs))
8909 + drv = ltq_spi_slave_alloc(bus, cs);
8913 + drv->regs = (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE);
8917 + drv->max_hz = max_hz;
8920 + return &drv->slave;
8923 +void spi_free_slave(struct spi_slave *slave)
8925 + ltq_spi_slave_free(slave);
8928 +static int ltq_spi_wait_ready(struct ltq_spi_drv_data *drv)
8930 + const unsigned long timeout = 20000;
8931 + unsigned long timebase;
8933 + timebase = get_timer(0);
8938 + if (!hw_is_busy(drv))
8940 + } while (get_timer(timebase) < timeout);
8945 +int spi_claim_bus(struct spi_slave *slave)
8947 + struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8950 + ret = ltq_spi_wait_ready(drv);
8952 + debug("cannot claim bus\n");
8956 + hw_enter_config_mode(drv);
8957 + hw_setup_clock_mode(drv, drv->mode);
8958 + hw_setup_speed_hz(drv, drv->max_hz);
8959 + hw_setup_bits_per_word(drv, drv->bits_per_word);
8960 + hw_enter_active_mode(drv);
8965 +void spi_release_bus(struct spi_slave *slave)
8967 + struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8969 + hw_enter_config_mode(drv);
8972 +int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
8973 + const void *dout, void *din, unsigned long flags)
8976 + struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8987 + if (flags & SPI_XFER_BEGIN)
8988 + spi_cs_activate(slave);
8997 + drv->tx_todo = bitlen / 8;
8999 + tx_fifo_write(drv);
9003 + drv->rx_todo = bitlen / 8;
9011 + if (drv->rx && drv->rx_todo)
9012 + rx_fifo_read_full_duplex(drv);
9015 + tx_fifo_write(drv);
9018 + } else if (drv->rx) {
9019 + if (drv->rx_todo) {
9020 + rx_fifo_read_half_duplex(drv);
9033 + ret = ltq_spi_wait_ready(drv);
9039 + if (flags & SPI_XFER_END)
9040 + spi_cs_deactivate(slave);
9044 diff --git a/include/configs/easy50712.h b/include/configs/easy50712.h
9045 new file mode 100644
9046 index 0000000..6d7988c
9048 +++ b/include/configs/easy50712.h
9051 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
9053 + * SPDX-License-Identifier: GPL-2.0+
9059 +#define CONFIG_MACH_TYPE "EASY50712"
9060 +#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
9061 +#define CONFIG_BOARD_NAME "Lantiq EASY50712 Danube Reference Board"
9063 +/* Configure SoC */
9064 +#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
9066 +#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
9068 +#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
9070 +#define CONFIG_LTQ_SUPPORT_SPI_FLASH
9071 +#define CONFIG_SPI_FLASH_ATMEL /* Have an AT45DB321D serial flash */
9073 +#define CONFIG_LTQ_SUPPORT_NAND_FLASH
9075 +#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */
9077 +#define CONFIG_LTQ_SPL_COMP_LZO
9078 +#define CONFIG_LTQ_SPL_CONSOLE
9080 +/* Switch devices */
9081 +#define CONFIG_SWITCH_MULTI
9082 +#define CONFIG_SWITCH_ADM6996I
9085 +#define CONFIG_ENV_SPI_BUS 0
9086 +#define CONFIG_ENV_SPI_CS 2
9087 +#define CONFIG_ENV_SPI_MAX_HZ 20000000
9088 +#define CONFIG_ENV_SPI_MODE 0
9090 +#if defined(CONFIG_SYS_BOOT_NOR)
9091 +#define CONFIG_ENV_IS_IN_FLASH
9092 +#define CONFIG_ENV_OVERWRITE
9093 +#define CONFIG_ENV_OFFSET (256 * 1024)
9094 +#define CONFIG_ENV_SECT_SIZE (64 * 1024)
9095 +#elif defined(CONFIG_SYS_BOOT_NORSPL)
9096 +#define CONFIG_ENV_IS_IN_FLASH
9097 +#define CONFIG_ENV_OVERWRITE
9098 +#define CONFIG_ENV_OFFSET (128 * 1024)
9099 +#define CONFIG_ENV_SECT_SIZE (64 * 1024)
9101 +#define CONFIG_ENV_IS_NOWHERE
9104 +#define CONFIG_ENV_SIZE (8 * 1024)
9106 +#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
9109 +#define CONFIG_LTQ_ADVANCED_CONSOLE
9110 +#define CONFIG_BAUDRATE 115200
9111 +#define CONFIG_CONSOLE_ASC 1
9112 +#define CONFIG_CONSOLE_DEV "ttyLTQ1"
9115 +#define CONFIG_CMD_PING
9117 +/* Pull in default board configs for Lantiq XWAY Danube */
9118 +#include <asm/lantiq/config.h>
9119 +#include <asm/arch/config.h>
9121 +#define CONFIG_ENV_UPDATE_UBOOT_NOR \
9122 + "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
9124 +#define CONFIG_EXTRA_ENV_SETTINGS \
9125 + CONFIG_ENV_LANTIQ_DEFAULTS \
9126 + CONFIG_ENV_UPDATE_UBOOT_NOR
9128 +#endif /* __CONFIG_H */
9129 diff --git a/include/configs/easy80920.h b/include/configs/easy80920.h
9130 new file mode 100644
9131 index 0000000..ad69bc2
9133 +++ b/include/configs/easy80920.h
9136 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
9138 + * SPDX-License-Identifier: GPL-2.0+
9144 +#define CONFIG_MACH_TYPE "EASY80920"
9145 +#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE
9146 +#define CONFIG_BOARD_NAME "Lantiq EASY80920 VRX200 Family Board"
9148 +/* Configure SoC */
9149 +#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */
9151 +#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */
9153 +#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */
9155 +#define CONFIG_LTQ_SUPPORT_SPI_FLASH
9156 +#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29LV620 serial flash */
9158 +#define CONFIG_LTQ_SUPPORT_NAND_FLASH
9160 +#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH /* Build SPI flash SPL */
9161 +#define CONFIG_SPL_SPI_BUS 0
9162 +#define CONFIG_SPL_SPI_CS 4
9163 +#define CONFIG_SPL_SPI_MAX_HZ 25000000
9164 +#define CONFIG_SPL_SPI_MODE 0
9166 +#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */
9168 +#define CONFIG_LTQ_SPL_COMP_LZO
9169 +#define CONFIG_LTQ_SPL_CONSOLE
9171 +#define CONFIG_SYS_DRAM_PROBE
9174 +#define CONFIG_ENV_SPI_BUS CONFIG_SPL_SPI_BUS
9175 +#define CONFIG_ENV_SPI_CS CONFIG_SPL_SPI_CS
9176 +#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SPL_SPI_MAX_HZ
9177 +#define CONFIG_ENV_SPI_MODE CONFIG_SPL_SPI_MODE
9179 +#if defined(CONFIG_SYS_BOOT_NOR)
9180 +#define CONFIG_ENV_IS_IN_FLASH
9181 +#define CONFIG_ENV_OVERWRITE
9182 +#define CONFIG_ENV_OFFSET (384 * 1024)
9183 +#define CONFIG_ENV_SECT_SIZE (64 * 1024)
9184 +#elif defined(CONFIG_SYS_BOOT_NORSPL)
9185 +#define CONFIG_ENV_IS_IN_FLASH
9186 +#define CONFIG_ENV_OVERWRITE
9187 +#define CONFIG_ENV_OFFSET (192 * 1024)
9188 +#define CONFIG_ENV_SECT_SIZE (64 * 1024)
9189 +#elif defined(CONFIG_SYS_BOOT_SFSPL)
9190 +#define CONFIG_ENV_IS_IN_SPI_FLASH
9191 +#define CONFIG_ENV_OVERWRITE
9192 +#define CONFIG_ENV_OFFSET (192 * 1024)
9193 +#define CONFIG_ENV_SECT_SIZE (64 * 1024)
9195 +#define CONFIG_ENV_IS_NOWHERE
9198 +#define CONFIG_ENV_SIZE (8 * 1024)
9200 +#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
9203 +#define CONFIG_LTQ_ADVANCED_CONSOLE
9204 +#define CONFIG_BAUDRATE 115200
9205 +#define CONFIG_CONSOLE_ASC 1
9206 +#define CONFIG_CONSOLE_DEV "ttyLTQ1"
9209 +#define CONFIG_CMD_PING
9211 +/* Pull in default board configs for Lantiq XWAY VRX200 */
9212 +#include <asm/lantiq/config.h>
9213 +#include <asm/arch/config.h>
9215 +#define CONFIG_ENV_UPDATE_UBOOT_NOR \
9216 + "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
9218 +#define CONFIG_ENV_UPDATE_UBOOT_SF \
9219 + "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0"
9221 +#define CONFIG_EXTRA_ENV_SETTINGS \
9222 + CONFIG_ENV_LANTIQ_DEFAULTS \
9223 + CONFIG_ENV_UPDATE_UBOOT_NOR \
9224 + CONFIG_ENV_UPDATE_UBOOT_SF
9226 +#endif /* __CONFIG_H */
9227 diff --git a/include/phy.h b/include/phy.h
9228 index f0f522a..818bd7f 100644
9231 @@ -214,6 +214,7 @@ int phy_atheros_init(void);
9232 int phy_broadcom_init(void);
9233 int phy_davicom_init(void);
9234 int phy_et1011c_init(void);
9235 +int phy_lantiq_init(void);
9236 int phy_lxt_init(void);
9237 int phy_marvell_init(void);
9238 int phy_micrel_init(void);
9239 diff --git a/spl/Makefile b/spl/Makefile
9240 index b366ac2..46eb851 100644
9243 @@ -100,6 +100,8 @@ LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/net/phy/libphy.o
9244 LIBS-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/libusb_musb-new.o
9245 LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/libusb_gadget.o
9246 LIBS-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/libwatchdog.o
9247 +LIBS-$(CONFIG_SPL_LZMA_SUPPORT) += lib/lzma/liblzma.o
9248 +LIBS-$(CONFIG_SPL_LZO_SUPPORT) += lib/lzo/liblzo.o
9250 ifneq ($(CONFIG_OMAP_COMMON),)
9251 LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
9252 diff --git a/tools/.gitignore b/tools/.gitignore
9253 index a7fee26..4d56882 100644
9254 --- a/tools/.gitignore
9255 +++ b/tools/.gitignore
9264 diff --git a/tools/Makefile b/tools/Makefile
9265 index ca76f94..ae1714b 100644
9266 --- a/tools/Makefile
9267 +++ b/tools/Makefile
9268 @@ -49,6 +49,7 @@ BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo$(SFX)
9269 BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
9270 BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX)
9271 BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
9272 +BIN_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image$(SFX)
9273 BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
9274 BIN_FILES-y += mkenvimage$(SFX)
9275 BIN_FILES-y += mkimage$(SFX)
9276 @@ -95,6 +96,7 @@ OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
9277 OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
9278 OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o
9279 OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
9280 +OBJ_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image.o
9281 OBJ_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo.o
9282 OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
9284 @@ -195,6 +197,10 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o
9285 $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
9288 +$(obj)ltq-boot-image$(SFX): $(obj)ltq-boot-image.o
9289 + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
9292 $(obj)xway-swap-bytes$(SFX): $(obj)xway-swap-bytes.o
9293 $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
9295 diff --git a/tools/ltq-boot-image.c b/tools/ltq-boot-image.c
9296 new file mode 100644
9297 index 0000000..75a188c
9299 +++ b/tools/ltq-boot-image.c
9302 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
9304 + * SPDX-License-Identifier: GPL-2.0+
9308 +#include <stdlib.h>
9309 +#include <string.h>
9310 +#include <unistd.h>
9311 +#include <getopt.h>
9312 +#include <compiler.h>
9313 +#include <sys/stat.h>
9320 +/* Lantiq non-volatile bootstrap command IDs */
9322 + NVB_CMD_DEBUG = 0x11,
9323 + NVB_CMD_REGCFG = 0x22,
9324 + NVB_CMD_IDWNLD = 0x33,
9325 + NVB_CMD_CDWNLD = 0x44,
9326 + NVB_CMD_DWNLD = 0x55,
9327 + NVB_CMD_IFCFG = 0x66,
9328 + NVB_CMD_START = 0x77
9331 +/* Lantiq non-volatile bootstrap command flags */
9332 +enum nvb_cmd_flags {
9333 + NVB_FLAG_START = 1,
9334 + NVB_FLAG_DEC = (1 << 1),
9335 + NVB_FLAG_DBG = (1 << 2),
9336 + NVB_FLAG_SDBG = (1 << 3),
9337 + NVB_FLAG_CFG0 = (1 << 4),
9338 + NVB_FLAG_CFG1 = (1 << 5),
9339 + NVB_FLAG_CFG2 = (1 << 6),
9340 + NVB_FLAG_RST = (1 << 7)
9344 + enum image_types type;
9346 + const char *uboot_bin;
9347 + const char *spl_bin;
9348 + const char *out_bin;
9351 +static void usage_msg(const char *name)
9353 + fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n",
9355 + fprintf(stderr, " Image types:\n"
9356 + " sfspl - SPL + [compressed] U-Boot for SPI flash\n");
9359 +static enum image_types parse_image_type(const char *type)
9362 + return IMAGE_NONE;
9364 + if (!strncmp(type, "sfspl", 6))
9365 + return IMAGE_SFSPL;
9367 + return IMAGE_NONE;
9370 +static int parse_args(int argc, char *argv[], struct args *arg)
9374 + memset(arg, 0, sizeof(*arg));
9376 + while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) {
9379 + usage_msg(argv[0]);
9382 + arg->type = parse_image_type(optarg);
9385 + arg->entry_addr = strtoul(optarg, NULL, 16);
9388 + arg->uboot_bin = optarg;
9391 + arg->spl_bin = optarg;
9394 + arg->out_bin = optarg;
9397 + fprintf(stderr, "Invalid option -%c\n", opt);
9402 + if (arg->type == IMAGE_NONE) {
9403 + fprintf(stderr, "Invalid image type\n");
9407 + if (!arg->uboot_bin) {
9408 + fprintf(stderr, "Missing U-Boot binary\n");
9412 + if (!arg->out_bin) {
9413 + fprintf(stderr, "Missing output binary\n");
9417 + if (arg->type == IMAGE_SFSPL && !arg->spl_bin) {
9418 + fprintf(stderr, "Missing SPL binary\n");
9425 + usage_msg(argv[0]);
9429 +static __u32 build_nvb_command(unsigned cmdid, unsigned cmdflags)
9434 + tag = (cmdid << 8) | cmdflags;
9435 + cmd = (tag << 16) | (0xFFFF - tag);
9437 + return cpu_to_be32(cmd);
9440 +static int write_header(int fd, const void *hdr, size_t size)
9444 + n = write(fd, hdr, size);
9446 + fprintf(stderr, "Cannot write header: %s\n",
9454 +static int write_nvb_dwnld_header(int fd, size_t size, __u32 addr)
9458 + hdr[0] = build_nvb_command(NVB_CMD_DWNLD, NVB_FLAG_START |
9460 + hdr[1] = cpu_to_be32(size + 4);
9461 + hdr[2] = cpu_to_be32(addr);
9463 + return write_header(fd, hdr, sizeof(hdr));
9466 +static int write_nvb_start_header(int fd, __u32 addr)
9470 + hdr[0] = build_nvb_command(NVB_CMD_START, NVB_FLAG_SDBG);
9471 + hdr[1] = cpu_to_be32(4);
9472 + hdr[2] = cpu_to_be32(addr);
9474 + return write_header(fd, hdr, sizeof(hdr));
9477 +static int open_input_bin(const char *name, void **ptr, size_t *size)
9482 + fd = open(name, O_RDONLY | O_BINARY);
9484 + fprintf(stderr, "Cannot open %s: %s\n", name,
9489 + ret = fstat(fd, &sbuf);
9491 + fprintf(stderr, "Cannot fstat %s: %s\n", name,
9496 + *ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
9497 + if (*ptr == MAP_FAILED) {
9498 + fprintf(stderr, "Cannot mmap %s: %s\n", name,
9503 + *size = sbuf.st_size;
9508 +static void close_input_bin(int fd, void *ptr, size_t size)
9510 + munmap(ptr, size);
9514 +static int copy_bin(int fd, void *ptr, size_t size)
9518 + n = write(fd, ptr, size);
9520 + fprintf(stderr, "Cannot copy binary: %s\n", strerror(errno));
9527 +static int open_output_bin(const char *name)
9531 + fd = open(name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666);
9533 + fprintf(stderr, "Cannot open %s: %s\n", name,
9541 +static int create_sfspl(const struct args *arg)
9543 + int out_fd, uboot_fd, spl_fd, ret;
9544 + void *uboot_ptr, *spl_ptr;
9545 + size_t uboot_size, spl_size;
9547 + out_fd = open_output_bin(arg->out_bin);
9551 + spl_fd = open_input_bin(arg->spl_bin, &spl_ptr, &spl_size);
9555 + uboot_fd = open_input_bin(arg->uboot_bin, &uboot_ptr, &uboot_size);
9559 + ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr);
9563 + ret = copy_bin(out_fd, spl_ptr, spl_size);
9567 + ret = write_nvb_start_header(out_fd, arg->entry_addr);
9571 + ret = copy_bin(out_fd, uboot_ptr, uboot_size);
9575 + close_input_bin(uboot_fd, uboot_ptr, uboot_size);
9576 + close_input_bin(spl_fd, spl_ptr, spl_size);
9582 + close_input_bin(uboot_fd, uboot_ptr, uboot_size);
9584 + close_input_bin(spl_fd, spl_ptr, spl_size);
9591 +int main(int argc, char *argv[])
9596 + ret = parse_args(argc, argv, &arg);
9600 + switch (arg.type) {
9602 + ret = create_sfspl(&arg);
9605 + fprintf(stderr, "Image type not implemented\n");
9612 + return EXIT_SUCCESS;
9614 + return EXIT_FAILURE;