uboot-lantiq: update to v2013.10
[openwrt.git] / package / boot / uboot-lantiq / patches / 0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch
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
5
6 Signed-off-by: Luka Perkov <luka@openwrt.org>
7 Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
8
9 diff --git a/.gitignore b/.gitignore
10 index a39bd54..7abdc37 100644
11 --- a/.gitignore
12 +++ b/.gitignore
13 @@ -49,6 +49,13 @@
14  /u-boot.sb
15  /u-boot.bd
16  /u-boot.geany
17 +/u-boot.bin.lzma
18 +/u-boot.bin.lzo
19 +/u-boot.ltq.lzma.norspl
20 +/u-boot.ltq.lzo.norspl
21 +/u-boot.ltq.norspl
22 +/u-boot.lzma.img
23 +/u-boot.lzo.img
24  
25  #
26  # Generated files
27 diff --git a/Makefile b/Makefile
28 index 6ee9a3c..73ec67d 100644
29 --- a/Makefile
30 +++ b/Makefile
31 @@ -435,6 +435,12 @@ $(obj)u-boot.bin:  $(obj)u-boot
32                 $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
33                 $(BOARD_SIZE_CHECK)
34  
35 +$(obj)u-boot.bin.lzma: $(obj)u-boot.bin
36 +               cat $< | lzma -9 -f - > $@
37 +
38 +$(obj)u-boot.bin.lzo:  $(obj)u-boot.bin
39 +               cat $< | lzop -9 -f - > $@
40 +
41  $(obj)u-boot.ldr:      $(obj)u-boot
42                 $(CREATE_LDR_ENV)
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
46  endif
47  
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"/') \
56                 -d $< $@
57 +endef
58 +
59 +$(obj)u-boot.img:      $(obj)u-boot.bin
60 +               $(call GEN_UBOOT_IMAGE,none)
61 +
62 +$(obj)u-boot.lzma.img: $(obj)u-boot.bin.lzma
63 +               $(call GEN_UBOOT_IMAGE,lzma)
64 +
65 +$(obj)u-boot.lzo.img:  $(obj)u-boot.bin.lzo
66 +               $(call GEN_UBOOT_IMAGE,lzo)
67  
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 > $@
73  
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 $@
77 +
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 $@
81 +
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 $@
85 +
86 +$(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
87 +       cat $(obj)spl/u-boot-spl.bin $< > $@
88 +
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 $< > $@
91 +
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 $< > $@
94 +
95  ifeq ($(CONFIG_SANDBOX),y)
96  GEN_UBOOT = \
97                 cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
98 diff --git a/README b/README
99 index 09662a4..1acceff 100644
100 --- a/README
101 +++ b/README
102 @@ -468,6 +468,11 @@ The following options need to be configured:
103                         CONF_CM_CACHABLE_CUW
104                         CONF_CM_CACHABLE_ACCELERATED
105  
106 +               CONFIG_SYS_MIPS_CACHE_EXT_INIT
107 +
108 +               Enable this to use extended cache initialization for recent
109 +               MIPS CPU cores.
110 +
111                 CONFIG_SYS_XWAY_EBU_BOOTCFG
112  
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.
121  #
122 -PLATFORM_CPPFLAGS              += -G 0 -mabicalls -fpic $(ENDIANNESS)
123 +PF_ABICALLS                    ?= -mabicalls
124 +PF_PIC                         ?= -fpic
125 +PF_PIE                         ?= -pie
126 +
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
138 @@ -29,7 +29,11 @@
139   */
140  #define MIPS_MAX_CACHE_SIZE    0x10000
141  
142 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
143 +#define INDEX_BASE     0x9fc00000
144 +#else
145  #define INDEX_BASE     CKSEG0
146 +#endif
147  
148         .macro  cache_op op addr
149         .set    push
150 @@ -65,7 +69,11 @@
151   */
152  LEAF(mips_init_icache)
153         blez            a1, 9f
154 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
155 +       mtc0            zero, CP0_ITAGLO
156 +#else
157         mtc0            zero, CP0_TAGLO
158 +#endif
159         /* clear tag to invalidate */
160         PTR_LI          t0, INDEX_BASE
161         PTR_ADDU        t1, t0, a1
162 @@ -90,7 +98,11 @@ LEAF(mips_init_icache)
163   */
164  LEAF(mips_init_dcache)
165         blez            a1, 9f
166 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
167 +       mtc0            zero, CP0_DTAGLO
168 +#else
169         mtc0            zero, CP0_TAGLO
170 +#endif
171         /* clear all tags */
172         PTR_LI          t0, INDEX_BASE
173         PTR_ADDU        t1, t0, a1
174 diff --git a/arch/mips/cpu/mips32/danube/Makefile b/arch/mips/cpu/mips32/danube/Makefile
175 new file mode 100644
176 index 0000000..98f5f73
177 --- /dev/null
178 +++ b/arch/mips/cpu/mips32/danube/Makefile
179 @@ -0,0 +1,31 @@
180 +#
181 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
182 +#
183 +# SPDX-License-Identifier:     GPL-2.0+
184 +#
185 +
186 +include $(TOPDIR)/config.mk
187 +
188 +LIB    = $(obj)lib$(SOC).o
189 +
190 +COBJS-y        += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
191 +SOBJS-y        += cgu_init.o mem_init.o
192 +
193 +COBJS  := $(COBJS-y)
194 +SOBJS  := $(SOBJS-y)
195 +SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
196 +OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
197 +
198 +all:   $(LIB)
199 +
200 +$(LIB):        $(obj).depend $(OBJS)
201 +       $(call cmd_link_o_target, $(OBJS))
202 +
203 +#########################################################################
204 +
205 +# defines $(obj).depend target
206 +include $(SRCTREE)/rules.mk
207 +
208 +sinclude $(obj).depend
209 +
210 +#########################################################################
211 diff --git a/arch/mips/cpu/mips32/danube/cgu.c b/arch/mips/cpu/mips32/danube/cgu.c
212 new file mode 100644
213 index 0000000..4fd110a
214 --- /dev/null
215 +++ b/arch/mips/cpu/mips32/danube/cgu.c
216 @@ -0,0 +1,117 @@
217 +/*
218 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
219 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
220 + *
221 + * SPDX-License-Identifier:    GPL-2.0+
222 + */
223 +
224 +#include <common.h>
225 +#include <asm/arch/soc.h>
226 +#include <asm/lantiq/clk.h>
227 +#include <asm/lantiq/io.h>
228 +
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
235 +
236 +struct ltq_cgu_regs {
237 +       u32     rsvd0;
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 */
246 +       u32     rsvd1[3];
247 +       u32     pcm_cr;         /* PCM control */
248 +       u32     pci_cr;         /* PCI clock control */
249 +};
250 +
251 +static struct ltq_cgu_regs *ltq_cgu_regs =
252 +       (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
253 +
254 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
255 +{
256 +       return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
257 +}
258 +
259 +unsigned long ltq_get_io_region_clock(void)
260 +{
261 +       u32 ddr_sel;
262 +       unsigned long clk;
263 +
264 +       ddr_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_DDR_MASK,
265 +                                       LTQ_CGU_SYS_DDR_SHIFT);
266 +
267 +       switch (ddr_sel) {
268 +       case 0:
269 +               clk = CLOCK_166_MHZ;
270 +               break;
271 +       case 1:
272 +               clk = CLOCK_133_MHZ;
273 +               break;
274 +       case 2:
275 +               clk = CLOCK_111_MHZ;
276 +               break;
277 +       case 3:
278 +               clk = CLOCK_83_MHZ;
279 +               break;
280 +       default:
281 +               clk = 0;
282 +               break;
283 +       }
284 +
285 +       return clk;
286 +}
287 +
288 +unsigned long ltq_get_cpu_clock(void)
289 +{
290 +       u32 cpu0_sel;
291 +       unsigned long clk;
292 +
293 +       cpu0_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU0_MASK,
294 +                                       LTQ_CGU_SYS_CPU0_SHIFT);
295 +
296 +       switch (cpu0_sel) {
297 +               /* Same as PLL0 output (333,33 MHz) */
298 +       case 0:
299 +               clk = CLOCK_333_MHZ;
300 +               break;
301 +               /* 1/1 fixed ratio to DDR clock */
302 +       case 1:
303 +               clk = ltq_get_io_region_clock();
304 +               break;
305 +               /* 1/2 fixed ratio to DDR clock */
306 +       case 2:
307 +               clk = ltq_get_io_region_clock() << 1;
308 +               break;
309 +       default:
310 +               clk = 0;
311 +               break;
312 +       }
313 +
314 +       return clk;
315 +}
316 +
317 +unsigned long ltq_get_bus_clock(void)
318 +{
319 +       u32 fpi_sel;
320 +       unsigned long clk;
321 +
322 +       fpi_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_FPI_MASK,
323 +                                       LTQ_CGU_SYS_FPI_SHIFT);
324 +
325 +       if (fpi_sel)
326 +               /* Half the DDR clock */
327 +               clk = ltq_get_io_region_clock() >> 1;
328 +       else
329 +               /* Same as DDR clock */
330 +               clk = ltq_get_io_region_clock();
331 +
332 +       return clk;
333 +}
334 diff --git a/arch/mips/cpu/mips32/danube/cgu_init.S b/arch/mips/cpu/mips32/danube/cgu_init.S
335 new file mode 100644
336 index 0000000..e0922f1
337 --- /dev/null
338 +++ b/arch/mips/cpu/mips32/danube/cgu_init.S
339 @@ -0,0 +1,142 @@
340 +/*
341 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
342 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
343 + *
344 + * SPDX-License-Identifier:    GPL-2.0+
345 + */
346 +
347 +#include <config.h>
348 +#include <asm/asm.h>
349 +#include <asm/regdef.h>
350 +#include <asm/addrspace.h>
351 +#include <asm/arch/soc.h>
352 +
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
358 +
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 */
364 +
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
371 +
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
378 +
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
383 +
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
390 +
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
401 +#else
402 +#error "Invalid system clock configuration!"
403 +#endif
404 +
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)
415 +
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
420 +
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
425 +
426 +LEAF(ltq_cgu_init)
427 +       /* Load current CGU register value */
428 +       li      t0, (LTQ_CGU_BASE | KSEG1)
429 +       lw      t1, LTQ_CGU_SYS(t0)
430 +
431 +       /* Load target CGU register values */
432 +       li      t3, LTQ_CGU_SYS_VALUE
433 +
434 +       /* Only update registers if values differ */
435 +       beq     t1, t3, finished
436 +
437 +       /*
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.
441 +        */
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
446 +
447 +boot_35mhz:
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)
455 +
456 +       b       do_reset
457 +
458 +boot_36mhz:
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)
466 +
467 +do_reset:
468 +       /* Store new clock config */
469 +       sw      t3, LTQ_CGU_SYS(t0)
470 +
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)
474 +
475 +wait_reset:
476 +       b       wait_reset
477 +
478 +finished:
479 +       jr      ra
480 +
481 +       END(ltq_cgu_init)
482 diff --git a/arch/mips/cpu/mips32/danube/chipid.c b/arch/mips/cpu/mips32/danube/chipid.c
483 new file mode 100644
484 index 0000000..02d9554
485 --- /dev/null
486 +++ b/arch/mips/cpu/mips32/danube/chipid.c
487 @@ -0,0 +1,59 @@
488 +/*
489 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
490 + *
491 + * SPDX-License-Identifier:    GPL-2.0+
492 + */
493 +
494 +#include <common.h>
495 +#include <asm/lantiq/io.h>
496 +#include <asm/lantiq/chipid.h>
497 +#include <asm/arch/soc.h>
498 +
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)
503 +
504 +struct ltq_chipid_regs {
505 +       u32     manid;          /* Manufacturer identification */
506 +       u32     chipid;         /* Chip identification */
507 +};
508 +
509 +static struct ltq_chipid_regs *ltq_chipid_regs =
510 +       (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
511 +
512 +unsigned int ltq_chip_version_get(void)
513 +{
514 +       u32 chipid;
515 +
516 +       chipid = ltq_readl(&ltq_chipid_regs->chipid);
517 +
518 +       return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
519 +}
520 +
521 +unsigned int ltq_chip_partnum_get(void)
522 +{
523 +       u32 chipid;
524 +
525 +       chipid = ltq_readl(&ltq_chipid_regs->chipid);
526 +
527 +       return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
528 +}
529 +
530 +const char *ltq_chip_partnum_str(void)
531 +{
532 +       enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
533 +
534 +       switch (partnum) {
535 +       case LTQ_SOC_DANUBE:
536 +               return "Danube";
537 +       case LTQ_SOC_DANUBE_S:
538 +               return "Danube-S";
539 +       case LTQ_SOC_TWINPASS:
540 +               return "Twinpass";
541 +       default:
542 +               printf("Unknown partnum: %x\n", partnum);
543 +       }
544 +
545 +       return "";
546 +}
547 diff --git a/arch/mips/cpu/mips32/danube/config.mk b/arch/mips/cpu/mips32/danube/config.mk
548 new file mode 100644
549 index 0000000..cee376f
550 --- /dev/null
551 +++ b/arch/mips/cpu/mips32/danube/config.mk
552 @@ -0,0 +1,25 @@
553 +#
554 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
555 +#
556 +# SPDX-License-Identifier:     GPL-2.0+
557 +#
558 +
559 +PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,)
560 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE)
561 +
562 +ifdef CONFIG_SPL_BUILD
563 +PF_ABICALLS            := -mno-abicalls
564 +PF_PIC                 := -fno-pic
565 +PF_PIE                 :=
566 +USE_PRIVATE_LIBGCC     := yes
567 +endif
568 +
569 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
570 +
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
576 +endif
577 +endif
578 diff --git a/arch/mips/cpu/mips32/danube/ebu.c b/arch/mips/cpu/mips32/danube/ebu.c
579 new file mode 100644
580 index 0000000..902f6a7
581 --- /dev/null
582 +++ b/arch/mips/cpu/mips32/danube/ebu.c
583 @@ -0,0 +1,105 @@
584 +/*
585 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
586 + *
587 + * SPDX-License-Identifier:    GPL-2.0+
588 + */
589 +
590 +#include <common.h>
591 +#include <asm/arch/soc.h>
592 +#include <asm/lantiq/io.h>
593 +
594 +#define EBU_ADDRSEL_MASK(mask)         ((mask & 0xf) << 4)
595 +#define EBU_ADDRSEL_REGEN              (1 << 0)
596 +
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
619 +
620 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
621 +#define ebu_region0_enable             1
622 +#else
623 +#define ebu_region0_enable             0
624 +#endif
625 +
626 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
627 +#define ebu_region1_enable             1
628 +#else
629 +#define ebu_region1_enable             0
630 +#endif
631 +
632 +struct ltq_ebu_regs {
633 +       u32     clc;
634 +       u32     rsvd0[3];
635 +       u32     con;
636 +       u32     rsvd1[3];
637 +       u32     addr_sel_0;
638 +       u32     addr_sel_1;
639 +       u32     rsvd2[14];
640 +       u32     con_0;
641 +       u32     con_1;
642 +};
643 +
644 +static struct ltq_ebu_regs *ltq_ebu_regs =
645 +       (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
646 +
647 +void ltq_ebu_init(void)
648 +{
649 +       if (ebu_region0_enable) {
650 +               /*
651 +                * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
652 +                * region control. This supports up to 32 MiB NOR flash in
653 +                * bank 0.
654 +                */
655 +               ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
656 +                       EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
657 +
658 +               ltq_writel(&ltq_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) |
663 +                       EBU_CON_CMULT_16);
664 +       } else
665 +               ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
666 +
667 +       if (ebu_region1_enable) {
668 +               /*
669 +                * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
670 +                * region control. This supports NAND flash in bank 1.
671 +                */
672 +               ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
673 +                       EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
674 +
675 +               ltq_writel(&ltq_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) |
680 +                       EBU_CON_CMULT_4);
681 +       } else
682 +               ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
683 +}
684 +
685 +void *flash_swap_addr(unsigned long addr)
686 +{
687 +       return (void *)(addr ^ 2);
688 +}
689 diff --git a/arch/mips/cpu/mips32/danube/mem.c b/arch/mips/cpu/mips32/danube/mem.c
690 new file mode 100644
691 index 0000000..be1922c
692 --- /dev/null
693 +++ b/arch/mips/cpu/mips32/danube/mem.c
694 @@ -0,0 +1,30 @@
695 +/*
696 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
697 + *
698 + * SPDX-License-Identifier:    GPL-2.0+
699 + */
700 +
701 +#include <common.h>
702 +#include <asm/arch/soc.h>
703 +#include <asm/lantiq/io.h>
704 +
705 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
706 +
707 +static inline u32 ltq_mc_dc_read(u32 index)
708 +{
709 +       return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
710 +}
711 +
712 +phys_size_t initdram(int board_type)
713 +{
714 +       u32 col, row, dc04, dc19, dc20;
715 +
716 +       dc04 = ltq_mc_dc_read(4);
717 +       dc19 = ltq_mc_dc_read(19);
718 +       dc20 = ltq_mc_dc_read(20);
719 +
720 +       row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
721 +       col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
722 +
723 +       return (1 << (row + col)) * 4 * 2;
724 +}
725 diff --git a/arch/mips/cpu/mips32/danube/mem_init.S b/arch/mips/cpu/mips32/danube/mem_init.S
726 new file mode 100644
727 index 0000000..47a35e1
728 --- /dev/null
729 +++ b/arch/mips/cpu/mips32/danube/mem_init.S
730 @@ -0,0 +1,114 @@
731 +/*
732 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
733 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
734 + *
735 + * SPDX-License-Identifier:    GPL-2.0+
736 + */
737 +
738 +#include <config.h>
739 +#include <asm/asm.h>
740 +#include <asm/regdef.h>
741 +#include <asm/addrspace.h>
742 +#include <asm/arch/soc.h>
743 +
744 +/* Must be configured in BOARDDIR */
745 +#include <ddr_settings.h>
746 +
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
753 +
754 +#define LTQ_MC_DDR_DC03_MC_START       0x100
755 +
756 +       /* Store given value in MC DDR CCRx register */
757 +       .macro dc_sw num, val
758 +       li      t2, \val
759 +       sw      t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
760 +       .endm
761 +
762 +LEAF(ltq_mem_init)
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)
766 +
767 +       /* Clear access error log registers */
768 +       sw      zero, LTQ_MC_GEN_ERRCAUSE(t0)
769 +       sw      zero, LTQ_MC_GEN_ERRADDR(t0)
770 +
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)
774 +
775 +       /* Clear start bit of DDR memory controller */
776 +       sw      zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
777 +
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
788 +
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
799 +
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
810 +
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
821 +
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
829 +
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)
833 +
834 +       /* Wait until DLL has locked and core is ready for data transfers */
835 +wait_ready:
836 +       lw      t2, LTQ_MC_GEN_STAT(t0)
837 +       li      t3, LTQ_MC_GEN_STAT_DLCK_PWRON
838 +       and     t2, t3
839 +       bne     t2, t3, wait_ready
840 +
841 +finished:
842 +       jr      ra
843 +
844 +       END(ltq_mem_init)
845 diff --git a/arch/mips/cpu/mips32/danube/pmu.c b/arch/mips/cpu/mips32/danube/pmu.c
846 new file mode 100644
847 index 0000000..7dd8aea
848 --- /dev/null
849 +++ b/arch/mips/cpu/mips32/danube/pmu.c
850 @@ -0,0 +1,117 @@
851 +/*
852 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
853 + *
854 + * SPDX-License-Identifier:    GPL-2.0+
855 + */
856 +
857 +#include <common.h>
858 +#include <asm/lantiq/io.h>
859 +#include <asm/lantiq/pm.h>
860 +#include <asm/arch/soc.h>
861 +
862 +#define LTQ_PMU_PWDCR_RESERVED         0xFD0C001C
863 +
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)
884 +
885 +struct ltq_pmu_regs {
886 +       u32     rsvd0[7];
887 +       u32     pwdcr;
888 +       u32     sr;
889 +       u32     pwdcr1;
890 +       u32     sr1;
891 +};
892 +
893 +static struct ltq_pmu_regs *ltq_pmu_regs =
894 +       (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
895 +
896 +u32 ltq_pm_map(enum ltq_pm_modules module)
897 +{
898 +       u32 val;
899 +
900 +       switch (module) {
901 +       case LTQ_PM_CORE:
902 +               val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 |
903 +                       LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
904 +               break;
905 +       case LTQ_PM_DMA:
906 +               val = LTQ_PMU_PWDCR_DMA;
907 +               break;
908 +       case LTQ_PM_ETH:
909 +               val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC |
910 +                       LTQ_PMU_PWDCR_PPE;
911 +               break;
912 +       case LTQ_PM_SPI:
913 +               val = LTQ_PMU_PWDCR_SPI;
914 +               break;
915 +       default:
916 +               val = 0;
917 +               break;
918 +       }
919 +
920 +       return val;
921 +}
922 +
923 +int ltq_pm_enable(enum ltq_pm_modules module)
924 +{
925 +       const unsigned long timeout = 1000;
926 +       unsigned long timebase;
927 +       u32 sr, val;
928 +
929 +       val = ltq_pm_map(module);
930 +       if (unlikely(!val))
931 +               return 1;
932 +
933 +       ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
934 +
935 +       timebase = get_timer(0);
936 +
937 +       do {
938 +               sr = ltq_readl(&ltq_pmu_regs->sr);
939 +               if (~sr & val)
940 +                       return 0;
941 +       } while (get_timer(timebase) < timeout);
942 +
943 +       return 1;
944 +}
945 +
946 +int ltq_pm_disable(enum ltq_pm_modules module)
947 +{
948 +       u32 val;
949 +
950 +       val = ltq_pm_map(module);
951 +       if (unlikely(!val))
952 +               return 1;
953 +
954 +       ltq_setbits(&ltq_pmu_regs->pwdcr, val);
955 +
956 +       return 0;
957 +}
958 +
959 +void ltq_pmu_init(void)
960 +{
961 +       u32 set, clr;
962 +
963 +       clr = ltq_pm_map(LTQ_PM_CORE);
964 +       set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
965 +
966 +       ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
967 +}
968 diff --git a/arch/mips/cpu/mips32/danube/rcu.c b/arch/mips/cpu/mips32/danube/rcu.c
969 new file mode 100644
970 index 0000000..906491a
971 --- /dev/null
972 +++ b/arch/mips/cpu/mips32/danube/rcu.c
973 @@ -0,0 +1,125 @@
974 +/*
975 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
976 + *
977 + * SPDX-License-Identifier:    GPL-2.0+
978 + */
979 +
980 +#include <common.h>
981 +#include <asm/lantiq/io.h>
982 +#include <asm/lantiq/reset.h>
983 +#include <asm/lantiq/cpu.h>
984 +#include <asm/arch/soc.h>
985 +
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 */
1002 +
1003 +#define LTQ_RCU_STAT_BOOT_SHIFT                18
1004 +#define LTQ_RCU_STAT_BOOT_MASK         (0x7 << LTQ_RCU_STAT_BOOT_SHIFT)
1005 +
1006 +struct ltq_rcu_regs {
1007 +       u32     rsvd0[4];
1008 +       u32     req;            /* Reset request */
1009 +       u32     stat;           /* Reset status */
1010 +       u32     usb_cfg;        /* USB configure */
1011 +       u32     rsvd1[2];
1012 +       u32     pci_rdy;        /* PCI boot ready */
1013 +};
1014 +
1015 +static struct ltq_rcu_regs *ltq_rcu_regs =
1016 +       (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
1017 +
1018 +u32 ltq_reset_map(enum ltq_reset_modules module)
1019 +{
1020 +       u32 val;
1021 +
1022 +       switch (module) {
1023 +       case LTQ_RESET_CORE:
1024 +       case LTQ_RESET_SOFT:
1025 +               val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1;
1026 +               break;
1027 +       case LTQ_RESET_DMA:
1028 +               val = LTQ_RCU_RD_DMA;
1029 +               break;
1030 +       case LTQ_RESET_ETH:
1031 +               val = LTQ_RCU_RD_PPE;
1032 +               break;
1033 +       case LTQ_RESET_HARD:
1034 +               val = LTQ_RCU_RD_HRST;
1035 +               break;
1036 +       default:
1037 +               val = 0;
1038 +               break;
1039 +       }
1040 +
1041 +       return val;
1042 +}
1043 +
1044 +int ltq_reset_activate(enum ltq_reset_modules module)
1045 +{
1046 +       u32 val;
1047 +
1048 +       val = ltq_reset_map(module);
1049 +       if (unlikely(!val))
1050 +               return 1;
1051 +
1052 +       ltq_setbits(&ltq_rcu_regs->req, val);
1053 +
1054 +       return 0;
1055 +}
1056 +
1057 +int ltq_reset_deactivate(enum ltq_reset_modules module)
1058 +{
1059 +       u32 val;
1060 +
1061 +       val = ltq_reset_map(module);
1062 +       if (unlikely(!val))
1063 +               return 1;
1064 +
1065 +       ltq_clrbits(&ltq_rcu_regs->req, val);
1066 +
1067 +       return 0;
1068 +}
1069 +
1070 +enum ltq_boot_select ltq_boot_select(void)
1071 +{
1072 +       u32 stat;
1073 +       unsigned int bootstrap;
1074 +
1075 +       stat = ltq_readl(&ltq_rcu_regs->stat);
1076 +       bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
1077 +
1078 +       switch (bootstrap) {
1079 +       case 0:
1080 +               return BOOT_NOR_NO_BOOTROM;
1081 +       case 1:
1082 +               return BOOT_NOR;
1083 +       case 2:
1084 +               return BOOT_MII0;
1085 +       case 3:
1086 +               return BOOT_PCI;
1087 +       case 4:
1088 +               return BOOT_UART;
1089 +       case 5:
1090 +               return BOOT_SPI;
1091 +       case 6:
1092 +               return BOOT_NAND;
1093 +       case 7:
1094 +               return BOOT_RMII0;
1095 +       default:
1096 +               return BOOT_UNKNOWN;
1097 +       }
1098 +}
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
1102 --- /dev/null
1103 +++ b/arch/mips/cpu/mips32/lantiq-common/Makefile
1104 @@ -0,0 +1,34 @@
1105 +#
1106 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1107 +#
1108 +# SPDX-License-Identifier:     GPL-2.0+
1109 +#
1110 +
1111 +include $(TOPDIR)/config.mk
1112 +
1113 +LIB    = $(obj)liblantiq-common.o
1114 +
1115 +START  = start.o
1116 +COBJS-y        = cpu.o pmu.o
1117 +COBJS-$(CONFIG_SPL_BUILD) += spl.o
1118 +SOBJS-y        = lowlevel_init.o
1119 +
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))
1125 +
1126 +all:   $(LIB)
1127 +
1128 +$(LIB):        $(obj).depend $(OBJS)
1129 +       $(call cmd_link_o_target, $(OBJS))
1130 +
1131 +#########################################################################
1132 +
1133 +# defines $(obj).depend target
1134 +include $(SRCTREE)/rules.mk
1135 +
1136 +sinclude $(obj).depend
1137 +
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
1142 --- /dev/null
1143 +++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
1144 @@ -0,0 +1,59 @@
1145 +/*
1146 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1147 + *
1148 + * SPDX-License-Identifier:    GPL-2.0+
1149 + */
1150 +
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>
1156 +
1157 +static const char ltq_bootsel_strings[][16] = {
1158 +       "NOR",
1159 +       "NOR w/o BootROM",
1160 +       "UART",
1161 +       "UART w/o EEPROM",
1162 +       "SPI",
1163 +       "NAND",
1164 +       "PCI",
1165 +       "MII0",
1166 +       "RMII0",
1167 +       "RGMII1",
1168 +       "unknown",
1169 +};
1170 +
1171 +const char *ltq_boot_select_str(void)
1172 +{      enum ltq_boot_select bootsel = ltq_boot_select();
1173 +
1174 +       if (bootsel > BOOT_UNKNOWN)
1175 +               bootsel = BOOT_UNKNOWN;
1176 +
1177 +       return ltq_bootsel_strings[bootsel];
1178 +}
1179 +
1180 +void ltq_chip_print_info(void)
1181 +{
1182 +       char buf[32];
1183 +
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());
1190 +}
1191 +
1192 +int arch_cpu_init(void)
1193 +{
1194 +       ltq_pmu_init();
1195 +       ltq_ebu_init();
1196 +
1197 +       return 0;
1198 +}
1199 +
1200 +void _machine_restart(void)
1201 +{
1202 +       ltq_reset_activate(LTQ_RESET_CORE);
1203 +}
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
1207 --- /dev/null
1208 +++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
1209 @@ -0,0 +1,20 @@
1210 +/*
1211 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1212 + *
1213 + * SPDX-License-Identifier:    GPL-2.0+
1214 + */
1215 +
1216 +#include <asm/asm.h>
1217 +#include <asm/regdef.h>
1218 +
1219 +NESTED(lowlevel_init, 0, ra)
1220 +       move    t8, ra
1221 +
1222 +       la      t7, ltq_cgu_init
1223 +       jalr    t7
1224 +
1225 +       la      t7, ltq_mem_init
1226 +       jalr    t7
1227 +
1228 +       jr      t8
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
1233 --- /dev/null
1234 +++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c
1235 @@ -0,0 +1,9 @@
1236 +/*
1237 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1238 + *
1239 + * SPDX-License-Identifier:    GPL-2.0+
1240 + */
1241 +
1242 +#include <common.h>
1243 +#include <asm/lantiq/pm.h>
1244 +
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
1248 --- /dev/null
1249 +++ b/arch/mips/cpu/mips32/lantiq-common/spl.c
1250 @@ -0,0 +1,403 @@
1251 +/*
1252 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1253 + *
1254 + * SPDX-License-Identifier:    GPL-2.0+
1255 + */
1256 +
1257 +#include <common.h>
1258 +#include <image.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>
1265 +
1266 +#if defined(CONFIG_LTQ_SPL_CONSOLE)
1267 +#define spl_has_console                1
1268 +
1269 +#if defined(CONFIG_LTQ_SPL_DEBUG)
1270 +#define spl_has_debug          1
1271 +#else
1272 +#define spl_has_debug          0
1273 +#endif
1274 +
1275 +#else
1276 +#define spl_has_console                0
1277 +#define spl_has_debug          0
1278 +#endif
1279 +
1280 +#define spl_debug(fmt, args...)                        \
1281 +       do {                                    \
1282 +               if (spl_has_debug)              \
1283 +                       printf(fmt, ##args);    \
1284 +       } while (0)
1285 +
1286 +#define spl_puts(msg)                          \
1287 +       do {                                    \
1288 +               if (spl_has_console)            \
1289 +                       puts(msg);              \
1290 +       } while (0)
1291 +
1292 +#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
1293 +#define spl_boot_spi_flash     1
1294 +#else
1295 +#define spl_boot_spi_flash     0
1296 +#ifndef CONFIG_SPL_SPI_BUS
1297 +#define CONFIG_SPL_SPI_BUS     0
1298 +#endif
1299 +#ifndef CONFIG_SPL_SPI_CS
1300 +#define CONFIG_SPL_SPI_CS      0
1301 +#endif
1302 +#ifndef CONFIG_SPL_SPI_MAX_HZ
1303 +#define CONFIG_SPL_SPI_MAX_HZ  0
1304 +#endif
1305 +#ifndef CONFIG_SPL_SPI_MODE
1306 +#define CONFIG_SPL_SPI_MODE    0
1307 +#endif
1308 +#endif
1309 +
1310 +#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
1311 +#define spl_boot_nor_flash     1
1312 +#else
1313 +#define spl_boot_nor_flash     0
1314 +#endif
1315 +
1316 +#define spl_sync()     __asm__ __volatile__("sync");
1317 +
1318 +struct spl_image {
1319 +       ulong data_addr;
1320 +       ulong entry_addr;
1321 +       ulong data_size;
1322 +       ulong entry_size;
1323 +       ulong data_crc;
1324 +       u8 comp;
1325 +};
1326 +
1327 +DECLARE_GLOBAL_DATA_PTR;
1328 +
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;
1332 +
1333 +static int spl_is_comp_lzma(const struct spl_image *spl)
1334 +{
1335 +#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
1336 +       return spl->comp == IH_COMP_LZMA;
1337 +#else
1338 +       return 0;
1339 +#endif
1340 +}
1341 +
1342 +static int spl_is_comp_lzo(const struct spl_image *spl)
1343 +{
1344 +#if defined(CONFIG_LTQ_SPL_COMP_LZO)
1345 +       return spl->comp == IH_COMP_LZO;
1346 +#else
1347 +       return 0;
1348 +#endif
1349 +}
1350 +
1351 +static int spl_is_compressed(const struct spl_image *spl)
1352 +{
1353 +       if (spl_is_comp_lzma(spl))
1354 +               return 1;
1355 +
1356 +       if (spl_is_comp_lzo(spl))
1357 +               return 1;
1358 +
1359 +       return 0;
1360 +}
1361 +
1362 +static void spl_console_init(void)
1363 +{
1364 +       if (!spl_has_console)
1365 +               return;
1366 +
1367 +       gd->flags |= GD_FLG_RELOC;
1368 +       gd->baudrate = CONFIG_BAUDRATE;
1369 +
1370 +       serial_init();
1371 +
1372 +       gd->have_console = 1;
1373 +
1374 +       spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
1375 +               U_BOOT_TIME ")\n");
1376 +}
1377 +
1378 +static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl)
1379 +{
1380 +       spl_puts("SPL: checking U-Boot image\n");
1381 +
1382 +       if (!image_check_magic(hdr)) {
1383 +               spl_puts("SPL: invalid magic\n");
1384 +               return -1;
1385 +       }
1386 +
1387 +        if (!image_check_hcrc(hdr)) {
1388 +               spl_puts("SPL: invalid header CRC\n");
1389 +               return -1;
1390 +       }
1391 +
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);
1397 +
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);
1400 +
1401 +       return 0;
1402 +}
1403 +
1404 +static int spl_check_data(const struct spl_image *spl, ulong loadaddr)
1405 +{
1406 +       ulong dcrc = crc32(0, (unsigned char *)loadaddr, spl->data_size);
1407 +
1408 +       if (dcrc != spl->data_crc) {
1409 +               spl_puts("SPL: invalid data CRC\n");
1410 +               return 0;
1411 +       }
1412 +
1413 +       return 1;
1414 +}
1415 +
1416 +static void *spl_lzma_alloc(void *p, size_t size)
1417 +{
1418 +       u8 *ret;
1419 +
1420 +       if (size > spl_mem_size)
1421 +               return NULL;
1422 +
1423 +       ret = spl_mem_ptr;
1424 +       spl_mem_ptr += size;
1425 +       spl_mem_size -= size;
1426 +
1427 +       return ret;
1428 +}
1429 +
1430 +static void spl_lzma_free(void *p, void *addr)
1431 +{
1432 +}
1433 +
1434 +static int spl_copy_image(struct spl_image *spl)
1435 +{
1436 +       spl_puts("SPL: copying U-Boot to RAM\n");
1437 +
1438 +       memcpy((void *) spl->entry_addr, (const void *) spl->data_addr,
1439 +               spl->data_size);
1440 +
1441 +       spl->entry_size = spl->data_size;
1442 +
1443 +       return 0;
1444 +}
1445 +
1446 +static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr)
1447 +{
1448 +       SRes res;
1449 +       const Byte *prop = (const Byte *) loadaddr;
1450 +       const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE +
1451 +                                                       sizeof(uint64_t);
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;
1456 +       ISzAlloc alloc;
1457 +
1458 +       spl_puts("SPL: decompressing U-Boot with LZMA\n");
1459 +
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;
1464 +
1465 +       res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE,
1466 +               LZMA_FINISH_ANY, &status, &alloc);
1467 +       if (res != SZ_OK)
1468 +               return 1;
1469 +
1470 +       spl->entry_size = dest_len;
1471 +
1472 +       return 0;
1473 +}
1474 +
1475 +static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr)
1476 +{
1477 +       size_t len;
1478 +       int ret;
1479 +
1480 +       spl_puts("SPL: decompressing U-Boot with LZO\n");
1481 +
1482 +       ret = lzop_decompress(
1483 +               (const unsigned char*) loadaddr, spl->data_size,
1484 +               (unsigned char *) spl->entry_addr, &len);
1485 +
1486 +       spl->entry_size = len;
1487 +
1488 +       return ret;
1489 +}
1490 +
1491 +static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr)
1492 +{
1493 +       int ret;
1494 +
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);
1499 +       else
1500 +               ret = 1;
1501 +
1502 +       return ret;
1503 +}
1504 +
1505 +static int spl_load_spi_flash(struct spl_image *spl)
1506 +{
1507 +       struct spi_flash sf = { 0 };
1508 +       image_header_t hdr;
1509 +       int ret;
1510 +       unsigned long loadaddr;
1511 +
1512 +       /*
1513 +        * Image format:
1514 +        *
1515 +        * - 12 byte non-volatile bootstrap header
1516 +        * - SPL binary
1517 +        * - 12 byte non-volatile bootstrap header
1518 +        * - 64 byte U-Boot mkimage header
1519 +        * - U-Boot binary
1520 +        */
1521 +       spl->data_addr = image_copy_end() - CONFIG_SPL_TEXT_BASE + 24;
1522 +
1523 +       spl_puts("SPL: probing SPI flash\n");
1524 +
1525 +       spi_init();
1526 +       ret = spl_spi_flash_probe(&sf);
1527 +       if (ret)
1528 +               return ret;
1529 +
1530 +       spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr);
1531 +
1532 +       ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr);
1533 +       if (ret)
1534 +               return ret;
1535 +
1536 +       spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr);
1537 +
1538 +       ret = spl_parse_image(&hdr, spl);
1539 +       if (ret)
1540 +               return ret;
1541 +
1542 +       if (spl_is_compressed(spl))
1543 +               loadaddr = CONFIG_LOADADDR;
1544 +       else
1545 +               loadaddr = spl->entry_addr;
1546 +
1547 +       spl_puts("SPL: loading U-Boot to RAM\n");
1548 +
1549 +       ret = spi_flash_read(&sf, spl->data_addr, spl->data_size,
1550 +                               (void *) loadaddr);
1551 +
1552 +       if (!spl_check_data(spl, loadaddr))
1553 +               return -1;
1554 +
1555 +       if (spl_is_compressed(spl))
1556 +               ret = spl_uncompress(spl, loadaddr);
1557 +
1558 +       return ret;
1559 +}
1560 +
1561 +static int spl_load_nor_flash(struct spl_image *spl)
1562 +{
1563 +       const image_header_t *hdr;
1564 +       int ret;
1565 +
1566 +       /*
1567 +        * Image format:
1568 +        *
1569 +        * - SPL binary
1570 +        * - 64 byte U-Boot mkimage header
1571 +        * - U-Boot binary
1572 +        */
1573 +       spl->data_addr = image_copy_end();
1574 +       hdr = (const image_header_t *) image_copy_end();
1575 +
1576 +       spl_debug("SPL: checking image header at address %p\n", hdr);
1577 +
1578 +       ret = spl_parse_image(hdr, spl);
1579 +       if (ret)
1580 +               return ret;
1581 +
1582 +       if (spl_is_compressed(spl))
1583 +               ret = spl_uncompress(spl, spl->data_addr);
1584 +       else
1585 +               ret = spl_copy_image(spl);
1586 +
1587 +       return ret;
1588 +}
1589 +
1590 +static int spl_load(struct spl_image *spl)
1591 +{
1592 +       int ret;
1593 +
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);
1598 +       else
1599 +               ret = 1;
1600 +
1601 +       return ret;
1602 +}
1603 +
1604 +void __noreturn spl_lantiq_init(void)
1605 +{
1606 +       void (*uboot)(void) __noreturn;
1607 +       struct spl_image spl;
1608 +       gd_t gd_data;
1609 +       int ret;
1610 +
1611 +       gd = &gd_data;
1612 +       barrier();
1613 +       memset((void *)gd, 0, sizeof(gd_t));
1614 +
1615 +       spl_console_init();
1616 +
1617 +       spl_debug("SPL: initializing\n");
1618 +
1619 +#if 0
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());
1628 +#endif
1629 +
1630 +       board_early_init_f();
1631 +       timer_init();
1632 +
1633 +       memset(&spl, 0, sizeof(spl));
1634 +
1635 +       ret = spl_load(&spl);
1636 +       if (ret)
1637 +               goto hang;
1638 +
1639 +       spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr);
1640 +       spl_puts("SPL: jumping to U-Boot\n");
1641 +
1642 +       flush_cache(spl.entry_addr, spl.entry_size);
1643 +       spl_sync();
1644 +
1645 +       uboot = (void *) spl.entry_addr;
1646 +       uboot();
1647 +
1648 +hang:
1649 +       spl_puts("SPL: cannot start U-Boot\n");
1650 +
1651 +       for (;;)
1652 +               ;
1653 +}
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
1657 --- /dev/null
1658 +++ b/arch/mips/cpu/mips32/lantiq-common/start.S
1659 @@ -0,0 +1,143 @@
1660 +/*
1661 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1662 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1663 + *
1664 + * SPDX-License-Identifier:    GPL-2.0+
1665 + */
1666 +
1667 +#include <config.h>
1668 +#include <asm/regdef.h>
1669 +#include <asm/mipsregs.h>
1670 +
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)
1675 +
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 */
1685 +
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
1692 +
1693 +#define S_ConfigMM             18      /* Merge mode (implementation specific) */
1694 +#define M_ConfigMM             (0x1 << S_ConfigMM)
1695 +
1696 +#define S_StatusBEV            22      /* Enable Boot Exception Vectors (R/W) */
1697 +#define M_StatusBEV            (0x1 << S_StatusBEV)
1698 +
1699 +#define S_StatusFR             26      /* Enable 64-bit FPRs (R/W) */
1700 +#define M_StatusFR             (0x1 << S_StatusFR)
1701 +
1702 +#define S_ConfigK0             0       /* Kseg0 coherency algorithm (R/W) */
1703 +#define M_ConfigK0             (0x7 << S_ConfigK0)
1704 +
1705 +#define CONFIG0_MIPS32_64_MSK  0x8000ffff
1706 +#define STATUS_MIPS32_64_MSK   0xfffcffff
1707 +
1708 +#define STATUS_MIPS24K         0
1709 +#define CONFIG0_MIPS24K                ((K_CacheAttrCN << S_ConfigK23) |\
1710 +                               (K_CacheAttrCN << S_ConfigKU)  |\
1711 +                               (M_ConfigMM))
1712 +
1713 +#define STATUS_MIPS34K         0
1714 +#define CONFIG0_MIPS34K                ((K_CacheAttrCN << S_ConfigK23) |\
1715 +                               (K_CacheAttrCN << S_ConfigKU) |\
1716 +                               (M_ConfigMM))
1717 +
1718 +#define STATUS_MIPS32_64       (M_StatusBEV | M_StatusFR)
1719 +#define CONFIG0_MIPS32_64      (K_CacheAttrCN << S_ConfigK0)
1720 +
1721 +#ifdef CONFIG_SOC_XWAY_DANUBE
1722 +#define CONFIG0_LANTIQ         (CONFIG0_MIPS24K | CONFIG0_MIPS32_64)
1723 +#define STATUS_LANTIQ          (STATUS_MIPS24K | STATUS_MIPS32_64)
1724 +#endif
1725 +
1726 +#ifdef CONFIG_SOC_XWAY_VRX200
1727 +#define CONFIG0_LANTIQ         (CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
1728 +#define STATUS_LANTIQ          (STATUS_MIPS34K | STATUS_MIPS32_64)
1729 +#endif
1730 +
1731 +
1732 +       .set noreorder
1733 +
1734 +       .globl _start
1735 +       .text
1736 +_start:
1737 +       /* Entry point */
1738 +       b       main
1739 +        nop
1740 +
1741 +       /* Lantiq SoC Boot config word */
1742 +       .org    0x10
1743 +#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
1744 +       .word   CONFIG_SYS_XWAY_EBU_BOOTCFG
1745 +#else
1746 +       .word   0
1747 +#endif
1748 +       .word   0
1749 +
1750 +       .align  4
1751 +main:
1752 +
1753 +       /* Init Timer */
1754 +       mtc0    zero, CP0_COUNT
1755 +       mtc0    zero, CP0_COMPARE
1756 +
1757 +       /* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */
1758 +       mfc0    t0, CP0_CONFIG
1759 +       li      t1, CONFIG0_MIPS32_64_MSK
1760 +       and     t0, t1
1761 +       li      t1, CONFIG0_LANTIQ
1762 +       or      t0, t1
1763 +       mtc0    t0, CP0_CONFIG
1764 +
1765 +       mfc0    t0, CP0_STATUS
1766 +       li      t1, STATUS_MIPS32_64_MSK
1767 +       and     t0, t1
1768 +       li      t1, STATUS_LANTIQ
1769 +       or      t0, t1
1770 +       mtc0    t0, CP0_STATUS
1771 +
1772 +       /* Initialize CGU */
1773 +       la      t9, ltq_cgu_init
1774 +       jalr    t9
1775 +        nop
1776 +
1777 +       /* Initialize memory controller */
1778 +       la      t9, ltq_mem_init
1779 +       jalr    t9
1780 +        nop
1781 +
1782 +       /* Initialize caches... */
1783 +       la      t9, mips_cache_reset
1784 +       jalr    t9
1785 +        nop
1786 +
1787 +       /* Clear BSS */
1788 +       la      t1, __bss_start
1789 +       la      t2, __bss_end
1790 +       sub     t1, 4
1791 +1:
1792 +       addi    t1, 4
1793 +       bltl    t1, t2, 1b
1794 +        sw     zero, 0(t1)
1795 +
1796 +       /* Setup stack pointer and force alignment on a 16 byte boundary */
1797 +       li      t0, (CONFIG_SPL_STACK_BASE & ~0xF)
1798 +       la      sp, 0(t0)
1799 +
1800 +       la      t9, spl_lantiq_init
1801 +       jr      t9
1802 +        nop
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
1806 --- /dev/null
1807 +++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
1808 @@ -0,0 +1,48 @@
1809 +/*
1810 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1811 + *
1812 + * SPDX-License-Identifier:    GPL-2.0+
1813 + */
1814 +
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 }
1819 +
1820 +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
1821 +OUTPUT_ARCH(mips)
1822 +ENTRY(_start)
1823 +SECTIONS
1824 +{
1825 +       . = ALIGN(4);
1826 +       .text : {
1827 +               *(.text*)
1828 +       } > .spl_mem
1829 +
1830 +       . = ALIGN(4);
1831 +       .rodata : {
1832 +               *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
1833 +       } > .spl_mem
1834 +
1835 +       . = ALIGN(4);
1836 +       .data : {
1837 +               *(SORT_BY_ALIGNMENT(.data*))
1838 +               *(SORT_BY_ALIGNMENT(.sdata*))
1839 +       } > .spl_mem
1840 +
1841 +       . = ALIGN(4);
1842 +       __image_copy_end = .;
1843 +       uboot_end_data = .;
1844 +
1845 +       .bss : {
1846 +               __bss_start = .;
1847 +               *(.bss*)
1848 +               *(.sbss*)
1849 +               . = ALIGN(4);
1850 +               __bss_end = .;
1851 +       } > .bss_mem
1852 +
1853 +       . = ALIGN(4);
1854 +       __end = .;
1855 +       uboot_end = .;
1856 +}
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
1864  
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
1869         mtc0    t0, CP0_CONFIG
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
1873 --- /dev/null
1874 +++ b/arch/mips/cpu/mips32/vrx200/Makefile
1875 @@ -0,0 +1,32 @@
1876 +#
1877 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1878 +#
1879 +# SPDX-License-Identifier:     GPL-2.0+
1880 +#
1881 +
1882 +include $(TOPDIR)/config.mk
1883 +
1884 +LIB    = $(obj)lib$(SOC).o
1885 +
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
1889 +
1890 +COBJS  := $(COBJS-y)
1891 +SOBJS  := $(SOBJS-y)
1892 +SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
1893 +OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
1894 +
1895 +all:   $(LIB)
1896 +
1897 +$(LIB):        $(obj).depend $(OBJS)
1898 +       $(call cmd_link_o_target, $(OBJS))
1899 +
1900 +#########################################################################
1901 +
1902 +# defines $(obj).depend target
1903 +include $(SRCTREE)/rules.mk
1904 +
1905 +sinclude $(obj).depend
1906 +
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
1911 --- /dev/null
1912 +++ b/arch/mips/cpu/mips32/vrx200/cgu.c
1913 @@ -0,0 +1,208 @@
1914 +/*
1915 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1916 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1917 + *
1918 + * SPDX-License-Identifier:    GPL-2.0+
1919 + */
1920 +
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>
1926 +
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
1933 +
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)
1938 +
1939 +#define LTQ_CGU_UPDATE                 1
1940 +
1941 +#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT   2
1942 +#define LTQ_CGU_IFCLK_GPHY_SEL_MASK    (0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT)
1943 +
1944 +struct ltq_cgu_regs {
1945 +       u32     rsvd0;
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 */
1960 +       u32     rsvd1;
1961 +       u32     gphy1_cfg;      /* GPHY1 config */
1962 +       u32     gphy0_cfg;      /* GPHY0 config */
1963 +       u32     rsvd2[6];
1964 +       u32     pll2_cfg;       /* PLL2 config */
1965 +};
1966 +
1967 +static struct ltq_cgu_regs *ltq_cgu_regs =
1968 +       (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
1969 +
1970 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
1971 +{
1972 +       return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
1973 +}
1974 +
1975 +unsigned long ltq_get_io_region_clock(void)
1976 +{
1977 +       unsigned int ocp_sel;
1978 +       unsigned long clk, cpu_clk;
1979 +
1980 +       cpu_clk = ltq_get_cpu_clock();
1981 +
1982 +       ocp_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_OCP_MASK,
1983 +                       LTQ_CGU_SYS_OCP_SHIFT);
1984 +
1985 +       switch (ocp_sel) {
1986 +       case 0:
1987 +               /* OCP ratio 1 */
1988 +               clk = cpu_clk;
1989 +               break;
1990 +       case 2:
1991 +               /* OCP ratio 2 */
1992 +               clk = cpu_clk / 2;
1993 +               break;
1994 +       case 3:
1995 +               /* OCP ratio 2.5 */
1996 +               clk = (cpu_clk * 2) / 5;
1997 +               break;
1998 +       case 4:
1999 +               /* OCP ratio 3 */
2000 +               clk = cpu_clk / 3;
2001 +               break;
2002 +       default:
2003 +               clk = 0;
2004 +               break;
2005 +       }
2006 +
2007 +       return clk;
2008 +}
2009 +
2010 +unsigned long ltq_get_cpu_clock(void)
2011 +{
2012 +       unsigned int cpu_sel;
2013 +       unsigned long clk;
2014 +
2015 +       cpu_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU_MASK,
2016 +                       LTQ_CGU_SYS_CPU_SHIFT);
2017 +
2018 +       switch (cpu_sel) {
2019 +       case 0:
2020 +               clk = CLOCK_600_MHZ;
2021 +               break;
2022 +       case 1:
2023 +               clk = CLOCK_500_MHZ;
2024 +               break;
2025 +       case 2:
2026 +               clk = CLOCK_393_MHZ;
2027 +               break;
2028 +       case 3:
2029 +               clk = CLOCK_333_MHZ;
2030 +               break;
2031 +       case 5:
2032 +       case 6:
2033 +               clk = CLOCK_197_MHZ;
2034 +               break;
2035 +       case 7:
2036 +               clk = CLOCK_166_MHZ;
2037 +               break;
2038 +       case 4:
2039 +       case 8:
2040 +       case 9:
2041 +               clk = CLOCK_125_MHZ;
2042 +               break;
2043 +       default:
2044 +               clk = 0;
2045 +               break;
2046 +       }
2047 +
2048 +       return clk;
2049 +}
2050 +
2051 +unsigned long ltq_get_bus_clock(void)
2052 +{
2053 +       return ltq_get_io_region_clock();
2054 +}
2055 +
2056 +void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk)
2057 +{
2058 +       ltq_clrbits(&ltq_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK);
2059 +       ltq_setbits(&ltq_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT);
2060 +}
2061 +
2062 +static inline int ltq_cgu_pll1_locked(void)
2063 +{
2064 +       u32 pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
2065 +
2066 +       return pll1_cfg & LTQ_CGU_PLL1_PLLL;
2067 +}
2068 +
2069 +static inline void ltq_cgu_pll1_restart(unsigned m, unsigned n)
2070 +{
2071 +       u32 pll1_cfg;
2072 +
2073 +       ltq_clrbits(&ltq_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN);
2074 +       ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
2075 +
2076 +       pll1_cfg = ltq_readl(&ltq_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(&ltq_cgu_regs->pll1_cfg, pll1_cfg);
2082 +       ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
2083 +
2084 +       __udelay(1000);
2085 +}
2086 +
2087 +/*
2088 + * From chapter 9 in errata sheet:
2089 + *
2090 + * Under certain condition, the PLL1 may failed to enter into lock
2091 + * status by hardware default N, M setting.
2092 + *
2093 + * Since system always starts from PLL0, the system software can run
2094 + * and re-program the PLL1 settings.
2095 + */
2096 +static void ltq_cgu_pll1_init(void)
2097 +{
2098 +       unsigned i;
2099 +       const unsigned pll1_m[] = { 1, 2, 3, 4 };
2100 +       const unsigned pll1_n[] = { 21, 32, 43, 54 };
2101 +
2102 +       /* Check if PLL1 has locked with hardware default settings */
2103 +       if (ltq_cgu_pll1_locked())
2104 +               return;
2105 +
2106 +       for (i = 0; i < 4; i++) {
2107 +               ltq_cgu_pll1_restart(pll1_m[i], pll1_n[i]);
2108 +
2109 +               if (ltq_cgu_pll1_locked())
2110 +                       goto done;
2111 +       }
2112 +
2113 +done:
2114 +       /* Restart with hardware default values M=5, N=64 */
2115 +       ltq_cgu_pll1_restart(5, 64);
2116 +}
2117 +
2118 +void ltq_pll_init(void)
2119 +{
2120 +       ltq_cgu_pll1_init();
2121 +}
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
2125 --- /dev/null
2126 +++ b/arch/mips/cpu/mips32/vrx200/cgu_init.S
2127 @@ -0,0 +1,119 @@
2128 +/*
2129 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2130 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2131 + *
2132 + * SPDX-License-Identifier:    GPL-2.0+
2133 + */
2134 +
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>
2140 +
2141 +/* RCU module register */
2142 +#define LTQ_RCU_RST_REQ                        0x0010  /* Reset request */
2143 +#define LTQ_RCU_RST_REQ_VALUE          ((1 << 14) | (1 << 1))
2144 +
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 */
2152 +
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
2162 +
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
2169 +
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
2176 +
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 */
2182 +
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
2188 +#else
2189 +#error "Invalid system clock configuration!"
2190 +#endif
2191 +
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)
2196 +
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))
2201 +
2202 +       .set noreorder
2203 +
2204 +LEAF(ltq_cgu_init)
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)
2209 +
2210 +       /* Load target CGU register values */
2211 +       li      t3, LTQ_CGU_SYS_VALUE
2212 +       li      t4, LTQ_CGU_CLK_FSR_VALUE
2213 +
2214 +       /* Only update registers if values differ */
2215 +       bne     t1, t3, update
2216 +        nop
2217 +       beq     t2, t4, finished
2218 +        nop
2219 +
2220 +update:
2221 +       /* Store target register values */
2222 +       sw      t3, LTQ_CGU_SYS(t0)
2223 +       sw      t4, LTQ_CGU_CLK_FSR(t0)
2224 +
2225 +       /* Perform software reset to activate new clock config */
2226 +#if 0
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)
2231 +#else
2232 +       li      t1, 1
2233 +       sw      t1, LTQ_CGU_UPDATE(t0)
2234 +#endif
2235 +
2236 +#if 0
2237 +wait_reset:
2238 +       b       wait_reset
2239 +        nop
2240 +#endif
2241 +
2242 +finished:
2243 +       jr      ra
2244 +        nop
2245 +
2246 +       END(ltq_cgu_init)
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
2250 --- /dev/null
2251 +++ b/arch/mips/cpu/mips32/vrx200/chipid.c
2252 @@ -0,0 +1,62 @@
2253 +/*
2254 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2255 + *
2256 + * SPDX-License-Identifier:    GPL-2.0+
2257 + */
2258 +
2259 +#include <common.h>
2260 +#include <asm/lantiq/io.h>
2261 +#include <asm/lantiq/chipid.h>
2262 +#include <asm/arch/soc.h>
2263 +
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)
2268 +
2269 +struct ltq_chipid_regs {
2270 +       u32     manid;          /* Manufacturer identification */
2271 +       u32     chipid;         /* Chip identification */
2272 +};
2273 +
2274 +static struct ltq_chipid_regs *ltq_chipid_regs =
2275 +       (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
2276 +
2277 +unsigned int ltq_chip_version_get(void)
2278 +{
2279 +       u32 chipid;
2280 +
2281 +       chipid = ltq_readl(&ltq_chipid_regs->chipid);
2282 +
2283 +       return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
2284 +}
2285 +
2286 +unsigned int ltq_chip_partnum_get(void)
2287 +{
2288 +       u32 chipid;
2289 +
2290 +       chipid = ltq_readl(&ltq_chipid_regs->chipid);
2291 +
2292 +       return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
2293 +}
2294 +
2295 +const char *ltq_chip_partnum_str(void)
2296 +{
2297 +       enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
2298 +
2299 +       switch (partnum) {
2300 +       case LTQ_SOC_VRX268:
2301 +       case LTQ_SOC_VRX268_2:
2302 +               return "VRX268";
2303 +       case LTQ_SOC_VRX288:
2304 +       case LTQ_SOC_VRX288_2:
2305 +               return "VRX288";
2306 +       case LTQ_SOC_GRX288:
2307 +       case LTQ_SOC_GRX288_2:
2308 +               return "GRX288";
2309 +       default:
2310 +               printf("Unknown partnum: %x\n", partnum);
2311 +       }
2312 +
2313 +       return "";
2314 +}
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
2318 --- /dev/null
2319 +++ b/arch/mips/cpu/mips32/vrx200/config.mk
2320 @@ -0,0 +1,30 @@
2321 +#
2322 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2323 +#
2324 +# SPDX-License-Identifier:     GPL-2.0+
2325 +#
2326 +
2327 +PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
2328 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
2329 +
2330 +ifdef CONFIG_SPL_BUILD
2331 +PF_ABICALLS            := -mno-abicalls
2332 +PF_PIC                 := -fno-pic
2333 +PF_PIE                 :=
2334 +USE_PRIVATE_LIBGCC     := yes
2335 +endif
2336 +
2337 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
2338 +
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
2344 +endif
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
2349 +endif
2350 +endif
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
2354 --- /dev/null
2355 +++ b/arch/mips/cpu/mips32/vrx200/dcdc.c
2356 @@ -0,0 +1,106 @@
2357 +/*
2358 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2359 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2360 + *
2361 + * SPDX-License-Identifier:    GPL-2.0+
2362 + */
2363 +
2364 +#include <common.h>
2365 +#include <asm/arch/soc.h>
2366 +#include <asm/lantiq/io.h>
2367 +
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)
2371 +
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 */
2404 +       u8      rsvd[240];
2405 +       u8      osc_conf;               /* OSC general config */
2406 +       u8      osc_stat;               /* OSC general status */
2407 +};
2408 +
2409 +static struct ltq_dcdc_regs *ltq_dcdc_regs =
2410 +       (struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE);
2411 +
2412 +void ltq_dcdc_init(unsigned int dig_ref)
2413 +{
2414 +       u8 dig_ref_cur, val;
2415 +
2416 +       /* Set duty cycle max sat. to 70/90, enable PID freeze */
2417 +       ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x5A);
2418 +       ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x46);
2419 +       val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
2420 +       val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2421 +       ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
2422 +
2423 +       /* Program new coefficients */
2424 +       ltq_writeb(&ltq_dcdc_regs->b0_coeh, 0x00);
2425 +       ltq_writeb(&ltq_dcdc_regs->b0_coel, 0x00);
2426 +       ltq_writeb(&ltq_dcdc_regs->b1_coeh, 0xFF);
2427 +       ltq_writeb(&ltq_dcdc_regs->b1_coel, 0xE6);
2428 +       ltq_writeb(&ltq_dcdc_regs->b2_coeh, 0x00);
2429 +       ltq_writeb(&ltq_dcdc_regs->b2_coel, 0x1B);
2430 +       ltq_writeb(&ltq_dcdc_regs->non_ov_delay, 0x8B);
2431 +
2432 +       /* Set duty cycle max sat. to 60/108, disable PID freeze */
2433 +       ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x6C);
2434 +       ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x3C);
2435 +       val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
2436 +       val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2437 +       ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
2438 +
2439 +       /* Init clock and DLL settings */
2440 +       val = ltq_readb(&ltq_dcdc_regs->clk_set0);
2441 +       val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P;
2442 +       ltq_writeb(&ltq_dcdc_regs->clk_set0, val);
2443 +       val = ltq_readb(&ltq_dcdc_regs->clk_set1);
2444 +       val |= LTQ_DCDC_CLK_SET1_SEL_DIV25;
2445 +       ltq_writeb(&ltq_dcdc_regs->clk_set1, val);
2446 +       ltq_writeb(&ltq_dcdc_regs->pwm_confh, 0xF9);
2447 +
2448 +       wmb();
2449 +
2450 +       /* Adapt value of digital reference of DCDC converter */
2451 +       dig_ref_cur = ltq_readb(&ltq_dcdc_regs->bias_vreg1);
2452 +
2453 +       while (dig_ref_cur != dig_ref) {
2454 +               if (dig_ref >= dig_ref_cur)
2455 +                       dig_ref_cur++;
2456 +               else if (dig_ref < dig_ref_cur)
2457 +                       dig_ref_cur--;
2458 +
2459 +               ltq_writeb(&ltq_dcdc_regs->bias_vreg1, dig_ref_cur);
2460 +               __udelay(1000);
2461 +       }
2462 +}
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
2466 --- /dev/null
2467 +++ b/arch/mips/cpu/mips32/vrx200/ebu.c
2468 @@ -0,0 +1,111 @@
2469 +/*
2470 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2471 + *
2472 + * SPDX-License-Identifier:    GPL-2.0+
2473 + */
2474 +
2475 +#include <common.h>
2476 +#include <asm/arch/soc.h>
2477 +#include <asm/lantiq/io.h>
2478 +
2479 +#define EBU_ADDRSEL_MASK(mask)         ((mask & 0xf) << 4)
2480 +#define EBU_ADDRSEL_REGEN              (1 << 0)
2481 +
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
2504 +
2505 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
2506 +#define ebu_region0_enable             1
2507 +#else
2508 +#define ebu_region0_enable             0
2509 +#endif
2510 +
2511 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
2512 +#define ebu_region1_enable             1
2513 +#else
2514 +#define ebu_region1_enable             0
2515 +#endif
2516 +
2517 +struct ltq_ebu_regs {
2518 +       u32     clc;
2519 +       u32     rsvd0;
2520 +       u32     id;
2521 +       u32     rsvd1;
2522 +       u32     con;
2523 +       u32     rsvd2[3];
2524 +       u32     addr_sel_0;
2525 +       u32     addr_sel_1;
2526 +       u32     addr_sel_2;
2527 +       u32     addr_sel_3;
2528 +       u32     rsvd3[12];
2529 +       u32     con_0;
2530 +       u32     con_1;
2531 +       u32     con_2;
2532 +       u32     con_3;
2533 +};
2534 +
2535 +static struct ltq_ebu_regs *ltq_ebu_regs =
2536 +       (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
2537 +
2538 +void ltq_ebu_init(void)
2539 +{
2540 +       if (ebu_region0_enable) {
2541 +               /*
2542 +                * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
2543 +                * region control. This supports up to 32 MiB NOR flash in
2544 +                * bank 0.
2545 +                */
2546 +               ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
2547 +                       EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
2548 +
2549 +               ltq_writel(&ltq_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);
2555 +       } else
2556 +               ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
2557 +
2558 +       if (ebu_region1_enable) {
2559 +               /*
2560 +                * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
2561 +                * region control. This supports NAND flash in bank 1.
2562 +                */
2563 +               ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
2564 +                       EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
2565 +
2566 +               ltq_writel(&ltq_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) |
2571 +                       EBU_CON_CMULT_4);
2572 +       } else
2573 +               ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
2574 +}
2575 +
2576 +void *flash_swap_addr(unsigned long addr)
2577 +{
2578 +       return (void *)(addr ^ 2);
2579 +}
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
2599 --- /dev/null
2600 +++ b/arch/mips/cpu/mips32/vrx200/gphy.c
2601 @@ -0,0 +1,58 @@
2602 +/*
2603 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2604 + *
2605 + * SPDX-License-Identifier:    GPL-2.0+
2606 + */
2607 +
2608 +#include <common.h>
2609 +#include <asm/lantiq/io.h>
2610 +#include <asm/arch/soc.h>
2611 +#include <asm/arch/gphy.h>
2612 +
2613 +static inline void ltq_gphy_copy(const void *fw_start, const void *fw_end,
2614 +                               ulong dst_addr)
2615 +{
2616 +       const ulong fw_len = (ulong) fw_end - (ulong) fw_start;
2617 +       const ulong addr = CKSEG1ADDR(dst_addr);
2618 +
2619 +       debug("ltq_gphy_copy: addr %08lx, fw_start %p, fw_end %p\n",
2620 +               addr, fw_start, fw_end);
2621 +
2622 +       memcpy((void *) addr, fw_start, fw_len);
2623 +}
2624 +
2625 +void ltq_gphy_phy11g_a1x_load(ulong addr)
2626 +{
2627 +       extern ulong __ltq_fw_phy11g_a1x_start;
2628 +       extern ulong __ltq_fw_phy11g_a1x_end;
2629 +
2630 +       ltq_gphy_copy(&__ltq_fw_phy11g_a1x_start, &__ltq_fw_phy11g_a1x_end,
2631 +                       addr);
2632 +}
2633 +
2634 +void ltq_gphy_phy11g_a2x_load(ulong addr)
2635 +{
2636 +       extern ulong __ltq_fw_phy11g_a2x_start;
2637 +       extern ulong __ltq_fw_phy11g_a2x_end;
2638 +
2639 +       ltq_gphy_copy(&__ltq_fw_phy11g_a2x_start, &__ltq_fw_phy11g_a2x_end,
2640 +                       addr);
2641 +}
2642 +
2643 +void ltq_gphy_phy22f_a1x_load(ulong addr)
2644 +{
2645 +       extern ulong __ltq_fw_phy22f_a1x_start;
2646 +       extern ulong __ltq_fw_phy22f_a1x_end;
2647 +
2648 +       ltq_gphy_copy(&__ltq_fw_phy22f_a1x_start, &__ltq_fw_phy22f_a1x_end,
2649 +                       addr);
2650 +}
2651 +
2652 +void ltq_gphy_phy22f_a2x_load(ulong addr)
2653 +{
2654 +       extern ulong __ltq_fw_phy22f_a2x_start;
2655 +       extern ulong __ltq_fw_phy22f_a2x_end;
2656 +
2657 +       ltq_gphy_copy(&__ltq_fw_phy22f_a2x_start, &__ltq_fw_phy22f_a2x_end,
2658 +                       addr);
2659 +}
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
2663 --- /dev/null
2664 +++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
2665 @@ -0,0 +1,27 @@
2666 +/*
2667 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2668 + *
2669 + * SPDX-License-Identifier:    GPL-2.0+
2670 + */
2671 +
2672 +#include <asm/asm.h>
2673 +
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)
2678 +
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)
2683 +
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)
2688 +
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
2696 --- /dev/null
2697 +++ b/arch/mips/cpu/mips32/vrx200/mem.c
2698 @@ -0,0 +1,57 @@
2699 +/*
2700 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2701 + *
2702 + * SPDX-License-Identifier:    GPL-2.0+
2703 + */
2704 +
2705 +#include <common.h>
2706 +#include <asm/arch/soc.h>
2707 +#include <asm/lantiq/io.h>
2708 +
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
2718 +
2719 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
2720 +
2721 +static inline u32 ltq_mc_ccr_read(u32 index)
2722 +{
2723 +       return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index));
2724 +}
2725 +
2726 +phys_size_t initdram(int board_type)
2727 +{
2728 +       u32 max_col_reg, max_row_reg, column_size, addr_pins;
2729 +       u32 banks, cs_map;
2730 +       phys_size_t size;
2731 +
2732 +       banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4;
2733 +
2734 +       cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >>
2735 +               LTQ_CCR08_CS_MAP_SHIFT;
2736 +
2737 +       column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >>
2738 +               LTQ_CCR11_COLUMN_SIZE_SHIFT;
2739 +
2740 +       addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK;
2741 +
2742 +       max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >>
2743 +               LTQ_CCR15_MAX_COL_REG_SHIFT;
2744 +
2745 +       max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK;
2746 +
2747 +       /*
2748 +        * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects
2749 +        *                 * datawidth (bytes)
2750 +        */
2751 +       size = (2 << (max_col_reg - column_size - 1)) *
2752 +               (2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2;
2753 +
2754 +       return size;
2755 +}
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
2759 --- /dev/null
2760 +++ b/arch/mips/cpu/mips32/vrx200/mem_init.S
2761 @@ -0,0 +1,233 @@
2762 +/*
2763 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2764 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2765 + *
2766 + * SPDX-License-Identifier:    GPL-2.0+
2767 + */
2768 +
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>
2774 +
2775 +/* Must be configured in BOARDDIR */
2776 +#include <ddr_settings.h>
2777 +
2778 +#define LTQ_MC_DDR_START               (1 << 8)
2779 +#define LTQ_MC_DDR_DLL_LOCK_IND        1
2780 +
2781 +#define CCS_ALWAYS_LAST                        0x0430
2782 +#define CCS_AHBM_CR_BURST_EN           (1 << 2)
2783 +#define CCS_FPIM_CR_BURST_EN           (1 << 1)
2784 +
2785 +#define CCR03_EIGHT_BANK_MODE          (1 << 0)
2786 +
2787 +       /* Store given value in MC DDR CCRx register */
2788 +       .macro ccr_sw num, val
2789 +       li      t1, \val
2790 +       sw      t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0)
2791 +       .endm
2792 +
2793 +LEAF(ltq_mem_init)
2794 +       /* Load MC DDR module base */
2795 +       li      t0, (LTQ_MC_DDR_BASE | KSEG1)
2796 +
2797 +       /* Put memory controller in inactive mode */
2798 +       sw      zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2799 +
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
2811 +
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
2822 +
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
2833 +
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
2844 +
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
2852 +
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
2861 +
2862 +       ccr_sw  60, MC_CCR60_VALUE
2863 +       ccr_sw  61, MC_CCR61_VALUE
2864 +
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)
2869 +
2870 +       /* Init abort condition for DRAM probe */
2871 +       move    t4, zero
2872 +
2873 +       /*
2874 +        * Put memory controller in active mode and start initialitation
2875 +        * sequence for connected DDR-SDRAM device
2876 +        */
2877 +mc_start:
2878 +       lw      t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2879 +       li      t2, LTQ_MC_DDR_START
2880 +       or      t1, t1, t2
2881 +       sw      t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2882 +
2883 +       /*
2884 +        * Wait until DLL has locked and core is ready for data transfers.
2885 +        * DLL lock indication is in register CCR47 and CCR48
2886 +        */
2887 +wait_ready:
2888 +       li      t1, LTQ_MC_DDR_DLL_LOCK_IND
2889 +       lw      t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0)
2890 +       and     t2, t2, t1
2891 +       bne     t1, t2, wait_ready
2892 +
2893 +       lw      t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0)
2894 +       and     t2, t2, t1
2895 +       bne     t1, t2, wait_ready
2896 +
2897 +#ifdef CONFIG_SYS_DRAM_PROBE
2898 +dram_probe:
2899 +       /* Initialization is finished after the second MC start */
2900 +       bnez    t4, mc_finished
2901 +
2902 +       /*
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.
2906 +        */
2907 +       li      t1, CONFIG_SYS_SDRAM_BASE_UC
2908 +       li      t5, MC_CCR03_VALUE
2909 +       li      t6, MC_CCR11_VALUE
2910 +       addi    t4, t4, 1
2911 +
2912 +       /*
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.
2918 +        */
2919 +       li      t2, 1
2920 +       sw      t2, 0x0(t1)
2921 +       li      t3, (1 << 13)
2922 +       add     t3, t3, t1
2923 +       sw      zero, 0(t3)
2924 +       lw      t3, 0(t1)
2925 +       bnez    t3, row_col_test
2926 +
2927 +       /* Clear CCR03.EIGHT_BANK_MODE */
2928 +       li      t3, ~CCR03_EIGHT_BANK_MODE
2929 +       and     t5, t5, t3
2930 +
2931 +row_col_test:
2932 +       /*
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.
2939 +        */
2940 +       sw      zero, 0(t1)
2941 +
2942 +       li      t2, 1
2943 +       li      t3, (1 << 27)
2944 +       add     t3, t3, t1
2945 +       sw      t2, 0(t3)
2946 +
2947 +       li      t2, 2
2948 +       li      t3, (1 << 26)
2949 +       add     t3, t3, t1
2950 +       sw      t2, 0(t3)
2951 +
2952 +       /* Update CCR11.ADDR_PINS */
2953 +       lw      t3, 0(t1)
2954 +       add     t6, t6, t3
2955 +
2956 +       /*
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.
2963 +        */
2964 +       sw      zero, 0(t1)
2965 +
2966 +       li      t2, 1
2967 +       li      t3, (1 << 10)
2968 +       add     t3, t3, t1
2969 +       sw      t2, 0(t3)
2970 +
2971 +       li      t2, 2
2972 +       li      t3, (1 << 9)
2973 +       add     t3, t3, t1
2974 +       sw      t2, 0(t3)
2975 +
2976 +       /* Update CCR11.COLUMN_SIZE */
2977 +       lw      t3, 0(t1)
2978 +       sll     t3, t3, 24
2979 +       add     t6, t6, t3
2980 +
2981 +       /* Put memory controller in inactive mode */
2982 +       sw      zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2983 +
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)
2987 +       b       mc_start
2988 +
2989 +mc_finished:
2990 +#endif /* CONFIG_SYS_DRAM_PROBE */
2991 +
2992 +       jr      ra
2993 +
2994 +       END(ltq_mem_init)
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
2998 --- /dev/null
2999 +++ b/arch/mips/cpu/mips32/vrx200/pmu.c
3000 @@ -0,0 +1,130 @@
3001 +/*
3002 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3003 + *
3004 + * SPDX-License-Identifier:    GPL-2.0+
3005 + */
3006 +
3007 +#include <common.h>
3008 +#include <asm/lantiq/io.h>
3009 +#include <asm/lantiq/pm.h>
3010 +#include <asm/arch/soc.h>
3011 +
3012 +#define LTQ_PMU_PWDCR_RESERVED         ((1 << 13) | (1 << 4))
3013 +
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)
3044 +
3045 +struct ltq_pmu_regs {
3046 +       u32     rsvd0[7];
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 */
3051 +};
3052 +
3053 +static struct ltq_pmu_regs *ltq_pmu_regs =
3054 +       (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
3055 +
3056 +u32 ltq_pm_map(enum ltq_pm_modules module)
3057 +{
3058 +       u32 val;
3059 +
3060 +       switch (module) {
3061 +       case LTQ_PM_CORE:
3062 +               val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM |
3063 +                       LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
3064 +               break;
3065 +       case LTQ_PM_DMA:
3066 +               val = LTQ_PMU_PWDCR_DMA;
3067 +               break;
3068 +       case LTQ_PM_ETH:
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;
3074 +               break;
3075 +       case LTQ_PM_SPI:
3076 +               val = LTQ_PMU_PWDCR_SPI;
3077 +               break;
3078 +       default:
3079 +               val = 0;
3080 +               break;
3081 +       }
3082 +
3083 +       return val;
3084 +}
3085 +
3086 +int ltq_pm_enable(enum ltq_pm_modules module)
3087 +{
3088 +       const unsigned long timeout = 1000;
3089 +       unsigned long timebase;
3090 +       u32 sr, val;
3091 +
3092 +       val = ltq_pm_map(module);
3093 +       if (unlikely(!val))
3094 +               return 1;
3095 +
3096 +       ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
3097 +
3098 +       timebase = get_timer(0);
3099 +
3100 +       do {
3101 +               sr = ltq_readl(&ltq_pmu_regs->sr);
3102 +               if (~sr & val)
3103 +                       return 0;
3104 +       } while (get_timer(timebase) < timeout);
3105 +
3106 +       return 1;
3107 +}
3108 +
3109 +int ltq_pm_disable(enum ltq_pm_modules module)
3110 +{
3111 +       u32 val;
3112 +
3113 +       val = ltq_pm_map(module);
3114 +       if (unlikely(!val))
3115 +               return 1;
3116 +
3117 +       ltq_setbits(&ltq_pmu_regs->pwdcr, val);
3118 +
3119 +       return 0;
3120 +}
3121 +
3122 +void ltq_pmu_init(void)
3123 +{
3124 +       u32 set, clr;
3125 +
3126 +       clr = ltq_pm_map(LTQ_PM_CORE);
3127 +       set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
3128 +
3129 +       ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
3130 +}
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
3134 --- /dev/null
3135 +++ b/arch/mips/cpu/mips32/vrx200/rcu.c
3136 @@ -0,0 +1,194 @@
3137 +/*
3138 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3139 + *
3140 + * SPDX-License-Identifier:    GPL-2.0+
3141 + */
3142 +
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>
3148 +
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 */
3179 +
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)
3183 +
3184 +#define LTQ_RCU_GP_STRAP_CLOCKSOURCE   (1 << 15)
3185 +
3186 +struct ltq_rcu_regs {
3187 +       u32     rsvd0[4];
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 */
3200 +       u32     rsvd1;
3201 +       u32     gf_mdio_add;    /* GPHY0/1 MDIO address */
3202 +       u32     req2;           /* SLIC and USB reset request */
3203 +       u32     ahb_endian;     /* AHB bus endianess */
3204 +       u32     rsvd2[4];
3205 +       u32     gcc;            /* General CPU config */
3206 +       u32     rsvd3;
3207 +       u32     gfs_add1;       /* GPHY1 firmware base addr */
3208 +};
3209 +
3210 +static struct ltq_rcu_regs *ltq_rcu_regs =
3211 +       (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
3212 +
3213 +u32 ltq_reset_map(enum ltq_reset_modules module)
3214 +{
3215 +       u32 val;
3216 +
3217 +       switch (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;
3222 +               break;
3223 +       case LTQ_RESET_DMA:
3224 +               val = LTQ_RCU_RD_DMA;
3225 +               break;
3226 +       case LTQ_RESET_ETH:
3227 +               val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
3228 +               break;
3229 +       case LTQ_RESET_PHY:
3230 +               val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
3231 +               break;
3232 +       case LTQ_RESET_HARD:
3233 +               val = LTQ_RCU_RD_HRST;
3234 +               break;
3235 +       default:
3236 +               val = 0;
3237 +               break;
3238 +       }
3239 +
3240 +       return val;
3241 +}
3242 +
3243 +int ltq_reset_activate(enum ltq_reset_modules module)
3244 +{
3245 +       u32 val;
3246 +
3247 +       val = ltq_reset_map(module);
3248 +       if (unlikely(!val))
3249 +               return 1;
3250 +
3251 +       ltq_setbits(&ltq_rcu_regs->req, val);
3252 +
3253 +       return 0;
3254 +}
3255 +
3256 +int ltq_reset_deactivate(enum ltq_reset_modules module)
3257 +{
3258 +       u32 val;
3259 +
3260 +       val = ltq_reset_map(module);
3261 +       if (unlikely(!val))
3262 +               return 1;
3263 +
3264 +       ltq_clrbits(&ltq_rcu_regs->req, val);
3265 +
3266 +       return 0;
3267 +}
3268 +
3269 +enum ltq_boot_select ltq_boot_select(void)
3270 +{
3271 +       u32 stat;
3272 +       unsigned int bootstrap;
3273 +
3274 +       /*
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.
3277 +        */
3278 +       stat = ltq_readl(&ltq_rcu_regs->stat);
3279 +       bootstrap = ((stat & LTQ_RCU_STAT_BOOT_H) << 4) |
3280 +               ((stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT);
3281 +
3282 +       switch (bootstrap) {
3283 +       case 0:
3284 +               return BOOT_NOR_NO_BOOTROM;
3285 +       case 1:
3286 +               return BOOT_RGMII1;
3287 +       case 2:
3288 +               return BOOT_NOR;
3289 +       case 4:
3290 +               return BOOT_UART_NO_EEPROM;
3291 +       case 6:
3292 +               return BOOT_PCI;
3293 +       case 8:
3294 +               return BOOT_UART;
3295 +       case 10:
3296 +               return BOOT_SPI;
3297 +       case 12:
3298 +               return BOOT_NAND;
3299 +       default:
3300 +               return BOOT_UNKNOWN;
3301 +       }
3302 +}
3303 +
3304 +void ltq_rcu_gphy_boot(unsigned int id, ulong addr)
3305 +{
3306 +       u32 module;
3307 +       void *gfs_add;
3308 +
3309 +       switch (id) {
3310 +       case 0:
3311 +               module = LTQ_RCU_RD_GPHY0;
3312 +               gfs_add = &ltq_rcu_regs->gfs_add0;
3313 +               break;
3314 +       case 1:
3315 +               module = LTQ_RCU_RD_GPHY1;
3316 +               gfs_add = &ltq_rcu_regs->gfs_add1;
3317 +               break;
3318 +       default:
3319 +               BUG();
3320 +       }
3321 +
3322 +       /* Stop and reset GPHY */
3323 +       ltq_setbits(&ltq_rcu_regs->req, module);
3324 +
3325 +       /* Configure firmware and boot address */
3326 +       ltq_writel(gfs_add, CPHYSADDR(addr & 0xFFFFC000));
3327 +
3328 +       /* Start GPHY by releasing reset */
3329 +       ltq_clrbits(&ltq_rcu_regs->req, module);
3330 +}
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
3334 --- /dev/null
3335 +++ b/arch/mips/include/asm/arch-danube/config.h
3336 @@ -0,0 +1,163 @@
3337 +/*
3338 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
3339 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3340 + *
3341 + * SPDX-License-Identifier:    GPL-2.0+
3342 + *
3343 + * Common board configuration for Lantiq XWAY Danube family
3344 + *
3345 + * Use following defines in your board config to enable specific features
3346 + * and drivers for this SoC:
3347 + *
3348 + * CONFIG_LTQ_SUPPORT_UART
3349 + * - support the Danube ASC/UART interface and console
3350 + *
3351 + * CONFIG_LTQ_SUPPORT_NOR_FLASH
3352 + * - support a parallel NOR flash via the CFI interface in flash bank 0
3353 + *
3354 + * CONFIG_LTQ_SUPPORT_ETHERNET
3355 + * - support the Danube ETOP and MAC interface
3356 + *
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
3360 + */
3361 +
3362 +#ifndef __DANUBE_CONFIG_H__
3363 +#define __DANUBE_CONFIG_H__
3364 +
3365 +/* CPU and SoC type */
3366 +#define CONFIG_SOC_LANTIQ
3367 +#define CONFIG_SOC_XWAY_DANUBE
3368 +
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
3375 +
3376 +/*
3377 + * Supported clock modes
3378 + * PLL0 clock output is 333 MHz
3379 + * PLL1 clock output is 262.144 MHz
3380 + */
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 */
3383 +
3384 +/* CPU speed */
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
3388 +
3389 +/* RAM */
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
3396 +
3397 +/* SRAM */
3398 +#define CONFIG_SYS_SRAM_BASE           0xBE1A0000
3399 +#define CONFIG_SYS_SRAM_SIZE           0x10000
3400 +
3401 +/* ASC/UART driver and console */
3402 +#define CONFIG_LANTIQ_SERIAL
3403 +#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200 }
3404 +
3405 +/* GPIO */
3406 +#define CONFIG_LANTIQ_GPIO
3407 +#define CONFIG_LTQ_GPIO_MAX_BANKS      2
3408 +
3409 +/* FLASH driver */
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
3422 +
3423 +#define CONFIG_CMD_FLASH
3424 +#else
3425 +#define CONFIG_SYS_NO_FLASH
3426 +#endif /* CONFIG_NOR_FLASH */
3427 +
3428 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
3429 +#define CONFIG_LANTIQ_SPI
3430 +#define CONFIG_SPI_FLASH
3431 +
3432 +#define CONFIG_CMD_SF
3433 +#define CONFIG_CMD_SPI
3434 +#endif
3435 +
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
3440 +
3441 +#define CONFIG_CMD_NAND
3442 +#endif
3443 +
3444 +#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
3445 +#define CONFIG_LANTIQ_DMA
3446 +#define CONFIG_LANTIQ_DANUBE_ETOP
3447 +
3448 +#define CONFIG_PHYLIB
3449 +#define CONFIG_MII
3450 +
3451 +#define CONFIG_CMD_MII
3452 +#define CONFIG_CMD_NET
3453 +#endif
3454 +
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*/
3460 +
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)
3468 +#else
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)
3475 +#endif
3476 +
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
3481 +#endif
3482 +
3483 +#if defined(CONFIG_SYS_BOOT_NOR)
3484 +#define CONFIG_SYS_TEXT_BASE           0xB0000000
3485 +#endif
3486 +
3487 +#if defined(CONFIG_SYS_BOOT_NORSPL)
3488 +#define CONFIG_SYS_TEXT_BASE           0x80100000
3489 +#define CONFIG_SPL_TEXT_BASE           0xB0000000
3490 +#endif
3491 +
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
3495 +#endif
3496 +
3497 +#define        CONFIG_SYS_MONITOR_BASE         CONFIG_SYS_TEXT_BASE
3498 +
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
3503 --- /dev/null
3504 +++ b/arch/mips/include/asm/arch-danube/gpio.h
3505 @@ -0,0 +1,12 @@
3506 +/*
3507 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3508 + *
3509 + * SPDX-License-Identifier:    GPL-2.0+
3510 + */
3511 +
3512 +#ifndef __DANUBE_GPIO_H__
3513 +#define __DANUBE_GPIO_H__
3514 +
3515 +#include <asm/lantiq/gpio.h>
3516 +
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
3521 --- /dev/null
3522 +++ b/arch/mips/include/asm/arch-danube/nand.h
3523 @@ -0,0 +1,13 @@
3524 +/*
3525 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3526 + *
3527 + * SPDX-License-Identifier:    GPL-2.0+
3528 + */
3529 +
3530 +#ifndef __DANUBE_NAND_H__
3531 +#define __DANUBE_NAND_H__
3532 +
3533 +struct nand_chip;
3534 +int ltq_nand_init(struct nand_chip *nand);
3535 +
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
3540 --- /dev/null
3541 +++ b/arch/mips/include/asm/arch-danube/soc.h
3542 @@ -0,0 +1,38 @@
3543 +/*
3544 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
3545 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3546 + *
3547 + * SPDX-License-Identifier:    GPL-2.0+
3548 + */
3549 +
3550 +#ifndef __DANUBE_SOC_H__
3551 +#define __DANUBE_SOC_H__
3552 +
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
3559 +
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)
3564 +
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)
3568 +
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
3574 +
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)
3579 +
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
3584 --- /dev/null
3585 +++ b/arch/mips/include/asm/arch-vrx200/config.h
3586 @@ -0,0 +1,184 @@
3587 +/*
3588 + * Copyright (C) 2010 Lantiq Deutschland GmbH
3589 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3590 + *
3591 + * SPDX-License-Identifier:    GPL-2.0+
3592 + *
3593 + * Common board configuration for Lantiq XWAY VRX200 family
3594 + *
3595 + * Use following defines in your board config to enable specific features
3596 + * and drivers for this SoC:
3597 + *
3598 + * CONFIG_LTQ_SUPPORT_UART
3599 + * - support the VRX200 ASC/UART interface and console
3600 + *
3601 + * CONFIG_LTQ_SUPPORT_NOR_FLASH
3602 + * - support a parallel NOR flash via the CFI interface in flash bank 0
3603 + *
3604 + * CONFIG_LTQ_SUPPORT_ETHERNET
3605 + * - support the VRX200 internal switch
3606 + *
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
3610 + *
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
3614 + */
3615 +
3616 +#ifndef __VRX200_CONFIG_H__
3617 +#define __VRX200_CONFIG_H__
3618 +
3619 +/* CPU and SoC type */
3620 +#define CONFIG_SOC_LANTIQ
3621 +#define CONFIG_SOC_XWAY_VRX200
3622 +
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
3629 +
3630 +/*
3631 + * Supported clock modes
3632 + * PLL0 clock output is 1000 MHz
3633 + * PLL1 clock output is 393.219 MHz
3634 + */
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 */
3644 +
3645 +/* CPU speed */
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
3649 +
3650 +/* RAM */
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)
3658 +
3659 +/* SRAM */
3660 +#define CONFIG_SYS_SRAM_BASE           0xBE220000
3661 +#define CONFIG_SYS_SRAM_SIZE           0x10000
3662 +
3663 +/* ASC/UART driver and console */
3664 +#define CONFIG_LANTIQ_SERIAL
3665 +#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200 }
3666 +
3667 +/* GPIO */
3668 +#define CONFIG_LANTIQ_GPIO
3669 +#define CONFIG_LTQ_GPIO_MAX_BANKS      3
3670 +#define CONFIG_LTQ_HAS_GPIO_BANK3
3671 +
3672 +/* FLASH driver */
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
3685 +
3686 +#define CONFIG_CMD_FLASH
3687 +#else
3688 +#define CONFIG_SYS_NO_FLASH
3689 +#endif /* CONFIG_NOR_FLASH */
3690 +
3691 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
3692 +#define CONFIG_LANTIQ_SPI
3693 +#define CONFIG_SPI_FLASH
3694 +
3695 +#define CONFIG_CMD_SF
3696 +#define CONFIG_CMD_SPI
3697 +#endif
3698 +
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
3703 +
3704 +#define CONFIG_CMD_NAND
3705 +#endif
3706 +
3707 +#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
3708 +#define CONFIG_LANTIQ_DMA
3709 +#define CONFIG_LANTIQ_VRX200_SWITCH
3710 +#define CONFIG_PHY_LANTIQ
3711 +
3712 +#define CONFIG_SYS_RX_ETH_BUFFER       8
3713 +#define CONFIG_PHYLIB
3714 +#define CONFIG_MII
3715 +#define CONFIG_UDP_CHECKSUM
3716 +
3717 +#define CONFIG_CMD_MII
3718 +#define CONFIG_CMD_NET
3719 +#endif
3720 +
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
3726 +
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)
3734 +#else
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)
3741 +#endif
3742 +
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
3747 +#endif
3748 +
3749 +#if defined(CONFIG_SYS_BOOT_NOR)
3750 +#define CONFIG_SYS_TEXT_BASE           0xB0000000
3751 +#endif
3752 +
3753 +#if defined(CONFIG_SYS_BOOT_SFSPL)
3754 +#define CONFIG_SYS_TEXT_BASE           0x80100000
3755 +#define CONFIG_SPL_TEXT_BASE           0xBE220000
3756 +#endif
3757 +
3758 +#if defined(CONFIG_SYS_BOOT_NORSPL)
3759 +#define CONFIG_SYS_TEXT_BASE           0x80100000
3760 +#define CONFIG_SPL_TEXT_BASE           0xB0000000
3761 +#endif
3762 +
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
3766 +#endif
3767 +
3768 +#define        CONFIG_SYS_MONITOR_BASE         CONFIG_SYS_TEXT_BASE
3769 +
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
3774 --- /dev/null
3775 +++ b/arch/mips/include/asm/arch-vrx200/gphy.h
3776 @@ -0,0 +1,65 @@
3777 +/*
3778 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3779 + *
3780 + * SPDX-License-Identifier:    GPL-2.0+
3781 + */
3782 +
3783 +#ifndef __VRX200_GPHY_H__
3784 +#define __VRX200_GPHY_H__
3785 +
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,
3795 +};
3796 +
3797 +/*
3798 + * Load PHY11G firmware for VRX200 v1.1 to given RAM address
3799 + *
3800 + * Address must be 16k aligned!
3801 + */
3802 +extern void ltq_gphy_phy11g_a1x_load(ulong addr);
3803 +
3804 +/*
3805 + * Load PHY11G firmware for VRX200 v1.2 to given RAM address
3806 + *
3807 + * Address must be 16k aligned!
3808 + */
3809 +extern void ltq_gphy_phy11g_a2x_load(ulong addr);
3810 +
3811 +/*
3812 + * Load PHY22F firmware for VRX200 v1.1 to given RAM address
3813 + *
3814 + * Address must be 16k aligned!
3815 + */
3816 +extern void ltq_gphy_phy22f_a1x_load(ulong addr);
3817 +
3818 +/*
3819 + * Load PHY22F firmware for VRX200 v1.2 to given RAM address
3820 + *
3821 + * Address must be 16k aligned!
3822 + */
3823 +extern void ltq_gphy_phy22f_a2x_load(ulong addr);
3824 +
3825 +/*
3826 + * Set clock source of internal GPHYs
3827 + *
3828 + * According registers resides in CGU address space. Thus this function
3829 + * is implemented by the CGU driver.
3830 + */
3831 +extern void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk);
3832 +
3833 +/*
3834 + * Boot internal GPHY with id from given RAM address
3835 + *
3836 + * According registers resides in RCU address space. Thus this function
3837 + * is implemented by the RCU driver.
3838 + */
3839 +extern void ltq_rcu_gphy_boot(unsigned int id, ulong addr);
3840 +
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
3845 --- /dev/null
3846 +++ b/arch/mips/include/asm/arch-vrx200/gpio.h
3847 @@ -0,0 +1,12 @@
3848 +/*
3849 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3850 + *
3851 + * SPDX-License-Identifier:    GPL-2.0+
3852 + */
3853 +
3854 +#ifndef __VRX200_GPIO_H__
3855 +#define __VRX200_GPIO_H__
3856 +
3857 +#include <asm/lantiq/gpio.h>
3858 +
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
3863 --- /dev/null
3864 +++ b/arch/mips/include/asm/arch-vrx200/nand.h
3865 @@ -0,0 +1,13 @@
3866 +/*
3867 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3868 + *
3869 + * SPDX-License-Identifier:    GPL-2.0+
3870 + */
3871 +
3872 +#ifndef __VRX200_NAND_H__
3873 +#define __VRX200_NAND_H__
3874 +
3875 +struct nand_chip;
3876 +int ltq_nand_init(struct nand_chip *nand);
3877 +
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
3882 --- /dev/null
3883 +++ b/arch/mips/include/asm/arch-vrx200/soc.h
3884 @@ -0,0 +1,45 @@
3885 +/*
3886 + * Copyright (C) 2010 Lantiq Deutschland GmbH
3887 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3888 + *
3889 + * SPDX-License-Identifier:    GPL-2.0+
3890 + */
3891 +
3892 +#ifndef __VRX200_SOC_H__
3893 +#define __VRX200_SOC_H__
3894 +
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
3901 +
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)
3906 +
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)
3917 +
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
3924 +
3925 +#define LTQ_MC_GLOBAL_BASE             0x1F400000
3926 +#define LTQ_MC_DDR_BASE                        0x1F401000
3927 +#define LTQ_MC_DDR_CCR_OFFSET(x)       (x * 0x10)
3928 +
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
3933 --- /dev/null
3934 +++ b/arch/mips/include/asm/arch-vrx200/switch.h
3935 @@ -0,0 +1,502 @@
3936 +/*
3937 + *   Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3938 + *
3939 + *   SPDX-License-Identifier:  GPL-2.0+
3940 + */
3941 +
3942 +#ifndef __VRX200_SWITCH_H__
3943 +#define __VRX200_SWITCH_H__
3944 +
3945 +/* Switch core registers */
3946 +struct vr9_switch_core_regs {
3947 +       __be32 swres;
3948 +       /* TODO: implement registers */
3949 +       __be32 rsvd0[0x3f];
3950 +};
3951 +
3952 +/* Switch buffer management registers */
3953 +struct vr9_switch_bm_regs {
3954 +       struct bm_core {
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];
3968 +       } core;
3969 +
3970 +       struct bm_port {
3971 +               __be32 pcfg;            /* Port config */
3972 +               __be32 rmon_ctrl;       /* RMON control */
3973 +       } port[13];
3974 +
3975 +       __be32 rsvd0[0x66];
3976 +
3977 +       struct bm_queue {
3978 +               __be32 rsvd0;
3979 +               __be32 pqm_rs;          /* Packet queue manager rate shape assignment */
3980 +       } queue[32];
3981 +
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 */
3988 +       } shaper[16];
3989 +
3990 +       __be32 rsvd1[0x2a8];
3991 +};
3992 +
3993 +/* Switch parser and classification engine registers */
3994 +struct vr9_switch_pce_regs {
3995 +       struct pce_core {
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];
4028 +       } core;
4029 +
4030 +       __be32 rsvd0[0x10];
4031 +
4032 +       struct pce_port {
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 */
4043 +       } port[13];
4044 +
4045 +       __be32 rsvd1[0x7e];
4046 +
4047 +       struct pce_meter {
4048 +               /* TODO: implement registers */
4049 +               __be32 rsvd0[0x7];
4050 +       } meter[8];
4051 +
4052 +       __be32 rsvd2[0x308];
4053 +};
4054 +
4055 +static inline unsigned int to_pce_tbl_key_id(unsigned int id)
4056 +{
4057 +       BUG_ON(id > 15);
4058 +
4059 +       return 15 - id;
4060 +}
4061 +
4062 +static inline unsigned int to_pce_tbl_value_id(unsigned int id)
4063 +{
4064 +       BUG_ON(id > 4);
4065 +
4066 +       return 4 - id;
4067 +}
4068 +
4069 +/* Switch ethernet MAC registers */
4070 +struct vr9_switch_mac_regs {
4071 +       struct mac_core {
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];
4083 +       } core;
4084 +
4085 +       struct mac_port {
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 */
4097 +       } port[13];
4098 +
4099 +       __be32 rsvd0[0xa4];
4100 +};
4101 +
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 */
4111 +       } core;
4112 +
4113 +       __be32 rsvd0[0x3a];
4114 +
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 */
4122 +       } port[13];
4123 +
4124 +       __be32 rsvd1[0x72];
4125 +};
4126 +
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 */
4132 +               __be32 rsvd0;
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 */
4143 +       } core;
4144 +
4145 +       __be32 rsvd0[0x73];
4146 +
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 */
4154 +       } port[13];
4155 +
4156 +       __be32 rsvd1[0x32];
4157 +};
4158 +
4159 +/* Switch MDIO control and status registers */
4160 +struct vr9_switch_mdio_regs {
4161 +       __be32 glob_ctrl;       /* Global control 0 */
4162 +       __be32 rsvd0[7];
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];
4173 +};
4174 +
4175 +static inline unsigned int to_mdio_phyaddr_id(unsigned int id)
4176 +{
4177 +       BUG_ON(id > 5);
4178 +
4179 +       return 5 - id;
4180 +}
4181 +
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 */
4197 +};
4198 +
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];
4215 +};
4216 +
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;
4227 +};
4228 +
4229 +static inline void *to_pce_tbl_key(struct vr9_switch_regs *regs,
4230 +                                               unsigned int id)
4231 +{
4232 +       return &regs->pce.core.tbl_key[to_pce_tbl_key_id(id)];
4233 +}
4234 +
4235 +static inline void *to_pce_tbl_value(struct vr9_switch_regs *regs,
4236 +                                               unsigned int id)
4237 +{
4238 +       return &regs->pce.core.tbl_val[to_pce_tbl_value_id(id)];
4239 +}
4240 +
4241 +static inline void *to_mac_ctrl(struct vr9_switch_regs *regs,
4242 +                                       unsigned int id, unsigned int ctrl)
4243 +{
4244 +       struct mac_port *mac = &regs->mac.port[id];
4245 +
4246 +       switch (ctrl) {
4247 +       case 0:
4248 +               return &mac->ctrl_0;
4249 +       case 1:
4250 +               return &mac->ctrl_1;
4251 +       case 2:
4252 +               return &mac->ctrl_2;
4253 +       case 3:
4254 +               return &mac->ctrl_3;
4255 +       case 4:
4256 +               return &mac->ctrl_4;
4257 +       case 5:
4258 +               return &mac->ctrl_5;
4259 +       default:
4260 +               return NULL;
4261 +       }
4262 +}
4263 +
4264 +static inline void *to_mdio_phyaddr(struct vr9_switch_regs *regs,
4265 +                                       unsigned int id)
4266 +{
4267 +       return &regs->mdio.phy_addr[to_mdio_phyaddr_id(id)];
4268 +}
4269 +
4270 +static inline void *to_mii_miicfg(struct vr9_switch_regs *regs,
4271 +                                       unsigned int id)
4272 +{
4273 +       switch (id) {
4274 +       case 0:
4275 +               return &regs->mii.mii_cfg0;
4276 +       case 1:
4277 +               return &regs->mii.mii_cfg1;
4278 +       case 5:
4279 +               return &regs->mii.mii_cfg5;
4280 +       default:
4281 +               return NULL;
4282 +       }
4283 +}
4284 +
4285 +static inline void *to_mii_pcdu(struct vr9_switch_regs *regs,
4286 +                                       unsigned int id)
4287 +{
4288 +       switch (id) {
4289 +       case 0:
4290 +               return &regs->mii.pcdu0;
4291 +       case 1:
4292 +               return &regs->mii.pcdu1;
4293 +       case 5:
4294 +               return &regs->mii.pcdu5;
4295 +       default:
4296 +               return NULL;
4297 +       }
4298 +}
4299 +
4300 +#define VR9_SWITCH_REG_OFFSET(reg)     (4 * (reg))
4301 +
4302 +#define BUILD_CHECK_VR9_REG(name, offset)      \
4303 +       BUILD_BUG_ON(offsetof(struct vr9_switch_regs, name) != (4 * offset))
4304 +
4305 +static inline void build_check_vr9_registers(void)
4306 +{
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));
4332 +}
4333 +
4334 +#define BM_GCTRL_F_SRES                1
4335 +
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
4356 +
4357 +#define MAC_CTRL1_DEFERMODE    (1 << 15)
4358 +#define MAC_CTRL1_SHORTPRE     (1 << 8)
4359 +
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
4365 +
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)
4387 +
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
4404 +
4405 +#define PCDU_RXDLY_SHIFT       7
4406 +#define PCDU_RXDLY_MASK                (0x7 << PCDU_RXDLY_SHIFT)
4407 +#define PCDU_TXDLY_MASK                0x7
4408 +
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)
4417 +
4418 +#define PCE_PCTRL_0_IGSTEN     (1 << 11)
4419 +
4420 +#define FDMA_PCTRL_STEN                (1 << 1)
4421 +#define FDMA_PCTRL_EN          (1 << 0)
4422 +
4423 +#define SDMA_PCTRL_EN          (1 << 0)
4424 +
4425 +#define MDIO_GLOB_CTRL_SE      (1 << 15)
4426 +
4427 +#define MDIO_MDC_CFG1_RES      (1 << 15)
4428 +#define MDIO_MDC_CFG1_MCEN     (1 << 8)
4429 +
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
4436 +
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
4442 @@ -53,6 +53,7 @@
4443                 .align  2;                              \
4444                 .type   symbol, @function;              \
4445                 .ent    symbol, 0;                      \
4446 +               .section .text.symbol,"x";              \
4447  symbol:                .frame  sp, 0, ra
4448  
4449  /*
4450 @@ -62,7 +63,8 @@ symbol:               .frame  sp, 0, ra
4451                 .globl  symbol;                         \
4452                 .align  2;                              \
4453                 .type   symbol, @function;              \
4454 -               .ent    symbol, 0;                       \
4455 +               .ent    symbol, 0;                      \
4456 +               .section .text.symbol,"x";              \
4457  symbol:                .frame  sp, framesize, rpc
4458  
4459  /*
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
4463 --- /dev/null
4464 +++ b/arch/mips/include/asm/gpio.h
4465 @@ -0,0 +1,6 @@
4466 +/*
4467 + * SPDX-License-Identifier:    GPL-2.0+
4468 + */
4469 +
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
4475 --- /dev/null
4476 +++ b/arch/mips/include/asm/lantiq/chipid.h
4477 @@ -0,0 +1,73 @@
4478 +/*
4479 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4480 + *
4481 + * SPDX-License-Identifier:    GPL-2.0+
4482 + */
4483 +
4484 +#ifndef __LANTIQ_CHIPID_H__
4485 +#define __LANTIQ_CHIPID_H__
4486 +
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 */
4498 +};
4499 +
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);
4503 +
4504 +extern void ltq_chip_print_info(void);
4505 +
4506 +#ifdef CONFIG_SOC_XWAY_DANUBE
4507 +static inline int ltq_soc_is_danube(void)
4508 +{
4509 +       return 1;
4510 +}
4511 +#else
4512 +static inline int ltq_soc_is_danube(void)
4513 +{
4514 +       return 0;
4515 +}
4516 +#endif
4517 +
4518 +#ifdef CONFIG_SOC_XWAY_VRX200
4519 +static inline int ltq_soc_is_vrx200(void)
4520 +{
4521 +       return 1;
4522 +}
4523 +
4524 +static inline int ltq_soc_is_vrx200_v1(void)
4525 +{
4526 +       return ltq_chip_version_get() == 1;
4527 +}
4528 +
4529 +static inline int ltq_soc_is_vrx200_v2(void)
4530 +{
4531 +       return ltq_chip_version_get() == 2;
4532 +}
4533 +#else
4534 +static inline int ltq_soc_is_vrx200(void)
4535 +{
4536 +       return 0;
4537 +}
4538 +
4539 +static inline int ltq_soc_is_vrx200_v1(void)
4540 +{
4541 +       return 0;
4542 +}
4543 +
4544 +static inline int ltq_soc_is_vrx200_v2(void)
4545 +{
4546 +       return 0;
4547 +}
4548 +#endif
4549 +
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
4554 --- /dev/null
4555 +++ b/arch/mips/include/asm/lantiq/clk.h
4556 @@ -0,0 +1,30 @@
4557 +/*
4558 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
4559 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4560 + * *
4561 + * SPDX-License-Identifier:    GPL-2.0+
4562 + */
4563 +
4564 +#ifndef __LANTIQ_CLK_H__
4565 +#define __LANTIQ_CLK_H__
4566 +
4567 +/* Symbolic clock speeds */
4568 +enum ltq_clk {
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,
4580 +};
4581 +
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);
4585 +
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
4590 --- /dev/null
4591 +++ b/arch/mips/include/asm/lantiq/config.h
4592 @@ -0,0 +1,164 @@
4593 +/*
4594 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
4595 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4596 + *
4597 + * SPDX-License-Identifier:    GPL-2.0+
4598 + */
4599 +
4600 +#ifndef __LANTIQ_CONFIG_H__
4601 +#define __LANTIQ_CONFIG_H__
4602 +
4603 +/* Memory usage */
4604 +#define CONFIG_SYS_MAXARGS             24
4605 +#define CONFIG_SYS_MALLOC_LEN          1024*1024
4606 +#define CONFIG_SYS_BOOTPARAMS_LEN      128*1024
4607 +
4608 +/* Command line */
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)
4613 +
4614 +#define CONFIG_SYS_HUSH_PARSER
4615 +#define CONFIG_SYS_PROMPT_HUSH_PS2     "> "
4616 +
4617 +/*
4618 + * Enable advanced console features on demand to reduce
4619 + * flash and RAM footprint
4620 + */
4621 +#if defined(CONFIG_LTQ_ADVANCED_CONSOLE)
4622 +#define CONFIG_SYS_LONGHELP
4623 +#define CONFIG_AUTO_COMPLETE
4624 +#define CONFIG_CMDLINE_EDITING
4625 +#endif
4626 +
4627 +/* SPI flash SPL */
4628 +#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
4629 +#define CONFIG_SPL
4630 +#define CONFIG_SPL_SPI_SUPPORT
4631 +#define CONFIG_SPL_SPI_FLASH_SUPPORT
4632 +#define CONFIG_SPI_SPL_SIMPLE
4633 +#endif
4634 +
4635 +#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
4636 +#define CONFIG_SPL
4637 +#endif
4638 +
4639 +/* Common SPL */
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"
4648 +#endif
4649 +
4650 +#if defined(CONFIG_LTQ_SPL_CONSOLE)
4651 +#define CONFIG_SPL_SERIAL_SUPPORT
4652 +#define CONFIG_SPL_LIBCOMMON_SUPPORT
4653 +#endif
4654 +
4655 +#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
4656 +#define CONFIG_LZMA
4657 +#define CONFIG_SPL_LZMA_SUPPORT
4658 +#endif
4659 +
4660 +#if defined(CONFIG_LTQ_SPL_COMP_LZO)
4661 +#define CONFIG_LZO
4662 +#define CONFIG_SPL_LZO_SUPPORT
4663 +#endif
4664 +
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
4673 +
4674 +/* Other U-Boot settings */
4675 +#define CONFIG_TIMESTAMP
4676 +
4677 +/* Default environment */
4678 +#define CONFIG_ENV_CONSOLEDEV                                  \
4679 +       "consoledev=" CONFIG_CONSOLE_DEV "\0"
4680 +
4681 +#define CONFIG_ENV_ADDCONSOLE                                  \
4682 +       "addconsole=setenv bootargs $bootargs"                  \
4683 +       " console=$consoledev,$baudrate\0"
4684 +
4685 +#if defined(CONFIG_NET_DEV)
4686 +#define CONFIG_ENV_NETDEV                                      \
4687 +       "netdev=" CONFIG_NET_DEV "\0"
4688 +#else
4689 +#define CONFIG_ENV_NETDEV                                      \
4690 +       "netdev=eth0\0"
4691 +#endif
4692 +
4693 +#define CONFIG_ENV_ADDIP                                       \
4694 +       "addip=setenv bootargs $bootargs"                       \
4695 +       " ip=$ipaddr:$serverip::::$netdev:off\0"
4696 +
4697 +#define CONFIG_ENV_ADDETH                                      \
4698 +       "addeth=setenv bootargs $bootargs"                      \
4699 +       " ethaddr=$ethaddr\0"
4700 +
4701 +#define CONFIG_ENV_ADDMACHTYPE                                 \
4702 +       "addmachtype=setenv bootargs $bootargs"                 \
4703 +       " machtype=" CONFIG_MACH_TYPE "\0"
4704 +
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"
4711 +
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"
4717 +#else
4718 +#define CONFIG_ENV_WRITE_UBOOT_NOR
4719 +#define CONFIG_ENV_LOAD_UBOOT_NOR
4720 +#endif
4721 +
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"
4727 +
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"
4732 +
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"
4737 +#else
4738 +#define CONFIG_ENV_SF_PROBE
4739 +#define CONFIG_ENV_WRITE_UBOOT_SF
4740 +#define CONFIG_ENV_LOAD_UBOOT_SF
4741 +#endif
4742 +
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
4755 +
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
4760 --- /dev/null
4761 +++ b/arch/mips/include/asm/lantiq/cpu.h
4762 @@ -0,0 +1,34 @@
4763 +/*
4764 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4765 + *
4766 + * SPDX-License-Identifier:    GPL-2.0+
4767 + */
4768 +
4769 +#ifndef __LANTIQ_CPU_H__
4770 +#define __LANTIQ_CPU_H__
4771 +
4772 +enum ltq_boot_select {
4773 +       BOOT_NOR,
4774 +       BOOT_NOR_NO_BOOTROM,
4775 +       BOOT_UART,
4776 +       BOOT_UART_NO_EEPROM,
4777 +       BOOT_SPI,
4778 +       BOOT_NAND,
4779 +       BOOT_PCI,
4780 +       BOOT_MII0,
4781 +       BOOT_RMII0,
4782 +       BOOT_RGMII1,
4783 +       BOOT_UNKNOWN,
4784 +};
4785 +
4786 +enum ltq_boot_select ltq_boot_select(void);
4787 +const char *ltq_boot_select_str(void);
4788 +
4789 +void ltq_pmu_init(void);
4790 +void ltq_ebu_init(void);
4791 +void ltq_gpio_init(void);
4792 +
4793 +void ltq_pll_init(void);
4794 +void ltq_dcdc_init(unsigned int dig_ref);
4795 +
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
4800 --- /dev/null
4801 +++ b/arch/mips/include/asm/lantiq/dma.h
4802 @@ -0,0 +1,94 @@
4803 +/*
4804 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4805 + *
4806 + * SPDX-License-Identifier:    GPL-2.0+
4807 + */
4808 +
4809 +#ifndef __LANTIQ_DMA_H__
4810 +#define __LANTIQ_DMA_H__
4811 +
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 */
4817 +};
4818 +
4819 +enum ltq_dma_burst_len {
4820 +       LTQ_DMA_BURST_2WORDS = 1,
4821 +       LTQ_DMA_BURST_4WORDS = 2,
4822 +       LTQ_DMA_BURST_8WORDS = 3,
4823 +};
4824 +
4825 +struct ltq_dma_desc {
4826 +       u32 ctl;
4827 +       u32 addr;
4828 +};
4829 +
4830 +struct ltq_dma_channel {
4831 +       struct ltq_dma_device *dev;
4832 +       u8 chan_no;
4833 +       u8 class;
4834 +       u16 num_desc;
4835 +       struct ltq_dma_desc *desc_base;
4836 +       void *mem_base;
4837 +       u32 dma_addr;
4838 +};
4839 +
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;
4847 +       u8 port;
4848 +};
4849 +
4850 +/**
4851 + * Initialize DMA hardware and driver
4852 + */
4853 +void ltq_dma_init(void);
4854 +
4855 +/**
4856 + * Register given DMA client context
4857 + *
4858 + * @returns 0 on success, negative value otherwise
4859 + */
4860 +int ltq_dma_register(struct ltq_dma_device *dev);
4861 +
4862 +/**
4863 + * Reset and halt all channels related to given DMA client
4864 + */
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);
4868 +
4869 +/**
4870 + * Map RX DMA descriptor to memory region
4871 + *
4872 + * @returns 0 on success, negative value otherwise
4873 + */
4874 +int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len);
4875 +
4876 +/**
4877 + * Check if new data is available.
4878 + *
4879 + * @returns length of received data, 0 otherwise
4880 + */
4881 +int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index);
4882 +
4883 +int ltq_dma_rx_length(struct ltq_dma_device *dev, int index);
4884 +
4885 +/**
4886 + * Map TX DMA descriptor to memory region
4887 + *
4888 + * @returns 0 on success, negative value otherwise
4889 + */
4890 +int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
4891 +                       unsigned long timeout);
4892 +
4893 +int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
4894 +                       unsigned long timeout);
4895 +
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
4900 --- /dev/null
4901 +++ b/arch/mips/include/asm/lantiq/eth.h
4902 @@ -0,0 +1,35 @@
4903 +/*
4904 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4905 + *
4906 + * SPDX-License-Identifier:    GPL-2.0+
4907 + */
4908 +
4909 +#ifndef __LANTIQ_ETH_H__
4910 +#define __LANTIQ_ETH_H__
4911 +
4912 +#include <phy.h>
4913 +
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),
4919 +};
4920 +
4921 +struct ltq_eth_port_config {
4922 +       u8 num;
4923 +       u8 phy_addr;
4924 +       u16 flags;
4925 +       phy_interface_t phy_if;
4926 +       u8 rgmii_rx_delay;
4927 +       u8 rgmii_tx_delay;
4928 +};
4929 +
4930 +struct ltq_eth_board_config {
4931 +       const struct ltq_eth_port_config *ports;
4932 +       int num_ports;
4933 +};
4934 +
4935 +extern int ltq_eth_initialize(const struct ltq_eth_board_config *board_config);
4936 +
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
4941 --- /dev/null
4942 +++ b/arch/mips/include/asm/lantiq/gpio.h
4943 @@ -0,0 +1,50 @@
4944 +/*
4945 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4946 + *
4947 + * SPDX-License-Identifier:    GPL-2.0+
4948 + */
4949 +
4950 +#ifndef __LANTIQ_GPIO_H__
4951 +#define __LANTIQ_GPIO_H__
4952 +
4953 +enum ltq_gpio_dir {
4954 +       GPIO_DIR_IN = 0,
4955 +       GPIO_DIR_OUT
4956 +};
4957 +
4958 +enum ltq_gpio_od {
4959 +       GPIO_OD_ACTIVE = 0,
4960 +       GPIO_OD_NORMAL
4961 +};
4962 +
4963 +enum ltq_gpio_altsel {
4964 +       GPIO_ALTSEL_CLR = 0,
4965 +       GPIO_ALTSEL_SET
4966 +};
4967 +
4968 +extern int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir);
4969 +extern int gpio_set_opendrain(unsigned gpio, int od);
4970 +
4971 +static inline int gpio_to_port(unsigned gpio)
4972 +{
4973 +       return gpio >> 4;
4974 +}
4975 +
4976 +static inline int gpio_to_pin(unsigned gpio)
4977 +{
4978 +       return gpio & 0xF;
4979 +}
4980 +
4981 +static inline int gpio_to_bit(unsigned gpio)
4982 +{
4983 +       return 1 << gpio_to_pin(gpio);
4984 +}
4985 +
4986 +static inline int gpio_to_gpio(unsigned port, unsigned pin)
4987 +{
4988 +       return (port << 4) | (pin & 0xF);
4989 +}
4990 +
4991 +#include <asm-generic/gpio.h>
4992 +
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
4997 --- /dev/null
4998 +++ b/arch/mips/include/asm/lantiq/io.h
4999 @@ -0,0 +1,37 @@
5000 +/*
5001 + * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
5002 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5003 + *
5004 + * SPDX-License-Identifier:    GPL-2.0+
5005 + */
5006 +
5007 +#ifndef __LANTIQ_IO_H__
5008 +#define __LANTIQ_IO_H__
5009 +
5010 +#include <asm/io.h>
5011 +
5012 +#define ltq_readb(a)           __raw_readb(a)
5013 +#define ltq_writeb(a, v)       __raw_writeb(v, a)
5014 +
5015 +#define ltq_readl(a)           __raw_readl(a)
5016 +#define ltq_writel(a, v)       __raw_writel(v, a)
5017 +
5018 +#define ltq_clrbits(a, clear) \
5019 +       ltq_writel(a, ltq_readl(a) & ~(clear))
5020 +
5021 +#define ltq_setbits(a, set) \
5022 +       ltq_writel(a, ltq_readl(a) | (set))
5023 +
5024 +#define ltq_clrsetbits(a, clear, set) \
5025 +       ltq_writel(a, (ltq_readl(a) & ~(clear)) | (set))
5026 +
5027 +static inline void ltq_reg_dump(const void *addr, const char *desc)
5028 +{
5029 +       u32 data;
5030 +
5031 +       data = ltq_readl(addr);
5032 +       printf("ltq_reg_dump: %s 0x%p = 0x%08x\n",
5033 +               desc, addr, data);
5034 +}
5035 +
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
5040 --- /dev/null
5041 +++ b/arch/mips/include/asm/lantiq/pm.h
5042 @@ -0,0 +1,21 @@
5043 +/*
5044 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5045 + *
5046 + * SPDX-License-Identifier:    GPL-2.0+
5047 + */
5048 +
5049 +#ifndef __LANTIQ_PM_H__
5050 +#define __LANTIQ_PM_H__
5051 +
5052 +enum ltq_pm_modules {
5053 +       LTQ_PM_CORE,
5054 +       LTQ_PM_DMA,
5055 +       LTQ_PM_ETH,
5056 +       LTQ_PM_SPI,
5057 +};
5058 +
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);
5062 +
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
5067 --- /dev/null
5068 +++ b/arch/mips/include/asm/lantiq/reset.h
5069 @@ -0,0 +1,37 @@
5070 +/*
5071 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5072 + *
5073 + * SPDX-License-Identifier:    GPL-2.0+
5074 + */
5075 +
5076 +#ifndef __LANTIQ_RESET_H__
5077 +#define __LANTIQ_RESET_H__
5078 +
5079 +enum ltq_reset_modules {
5080 +       LTQ_RESET_CORE,
5081 +       LTQ_RESET_DMA,
5082 +       LTQ_RESET_ETH,
5083 +       LTQ_RESET_PHY,
5084 +       LTQ_RESET_HARD,
5085 +       LTQ_RESET_SOFT,
5086 +};
5087 +
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);
5091 +
5092 +static inline int ltq_reset_once(enum ltq_reset_modules module, ulong usec)
5093 +{
5094 +       int ret;
5095 +
5096 +       ret = ltq_reset_activate(module);
5097 +       if (ret)
5098 +               return ret;
5099 +
5100 +       __udelay(usec);
5101 +       ret = ltq_reset_deactivate(module);
5102 +
5103 +       return ret;
5104 +}
5105 +
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
5111 @@ -46,7 +46,10 @@
5112  #define CP0_ENTRYLO1 $3
5113  #define CP0_CONF $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
5120  #define CP0_INFO $7
5121  #define CP0_BADVADDR $8
5122 @@ -54,10 +57,19 @@
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
5131  #define CP0_EPC $14
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
5142 @@ -70,7 +82,17 @@
5143  #define CP0_ECC $26
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
5159  
5160 @@ -395,6 +417,12 @@
5161  #define  CAUSEF_BD             (_ULCAST_(1)   << 31)
5162  
5163  /*
5164 + * Bits in the coprocessor 0 EBase register.
5165 + */
5166 +#define EBASEB_CPUNUM          0
5167 +#define EBASEF_CPUNUM          (_ULCAST_(1023))
5168 +
5169 +/*
5170   * Bits in the coprocessor 0 config register.
5171   */
5172  /* Generic bits.  */
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)
5178  }
5179  
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";
5187   */
5188  const unsigned long mips_io_port_base = -1;
5189  
5190 +int __arch_cpu_init(void)
5191 +{
5192 +       /*
5193 +        * Nothing to do in this dummy implementation
5194 +        */
5195 +       return 0;
5196 +}
5197 +int arch_cpu_init(void)
5198 +       __attribute__((weak, alias("__arch_cpu_init")));
5199 +
5200  int __board_early_init_f(void)
5201  {
5202         /*
5203 @@ -106,6 +116,7 @@ static int init_baudrate(void)
5204  typedef int (init_fnc_t)(void);
5205  
5206  init_fnc_t *init_sequence[] = {
5207 +       arch_cpu_init,
5208         board_early_init_f,
5209         timer_init,
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
5214 --- /dev/null
5215 +++ b/board/lantiq/easy50712/Makefile
5216 @@ -0,0 +1,27 @@
5217 +#
5218 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
5219 +#
5220 +# SPDX-License-Identifier:     GPL-2.0+
5221 +#
5222 +
5223 +include $(TOPDIR)/config.mk
5224 +
5225 +LIB    = $(obj)lib$(BOARD).o
5226 +
5227 +COBJS  = $(BOARD).o
5228 +
5229 +SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
5230 +OBJS   := $(addprefix $(obj),$(COBJS))
5231 +SOBJS  := $(addprefix $(obj),$(SOBJS))
5232 +
5233 +$(LIB):        $(obj).depend $(OBJS) $(SOBJS)
5234 +       $(call cmd_link_o_target, $(OBJS) $(SOBJS))
5235 +
5236 +#########################################################################
5237 +
5238 +# defines $(obj).depend target
5239 +include $(SRCTREE)/rules.mk
5240 +
5241 +sinclude $(obj).depend
5242 +
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
5247 --- /dev/null
5248 +++ b/board/lantiq/easy50712/config.mk
5249 @@ -0,0 +1,7 @@
5250 +#
5251 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5252 +#
5253 +# SPDX-License-Identifier:     GPL-2.0+
5254 +#
5255 +
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
5260 --- /dev/null
5261 +++ b/board/lantiq/easy50712/ddr_settings.h
5262 @@ -0,0 +1,54 @@
5263 +/*
5264 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
5265 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5266 + *
5267 + * SPDX-License-Identifier:    GPL-2.0+
5268 + */
5269 +
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
5320 --- /dev/null
5321 +++ b/board/lantiq/easy50712/easy50712.c
5322 @@ -0,0 +1,112 @@
5323 +/*
5324 + * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
5325 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5326 + *
5327 + * SPDX-License-Identifier:    GPL-2.0+
5328 + */
5329 +
5330 +#include <common.h>
5331 +#include <switch.h>
5332 +#include <spi.h>
5333 +#include <asm/gpio.h>
5334 +#include <asm/lantiq/eth.h>
5335 +#include <asm/lantiq/reset.h>
5336 +#include <asm/lantiq/chipid.h>
5337 +
5338 +static void gpio_init(void)
5339 +{
5340 +       /* SPI/CS output (low-active) for serial flash */
5341 +       gpio_direction_output(22, 1);
5342 +
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);
5349 +
5350 +       /* enable CLK_OUT2 for external switch */
5351 +       gpio_set_altfunc(3, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5352 +}
5353 +
5354 +int board_early_init_f(void)
5355 +{
5356 +       gpio_init();
5357 +
5358 +       return 0;
5359 +}
5360 +
5361 +int checkboard(void)
5362 +{
5363 +       puts("Board: " CONFIG_BOARD_NAME "\n");
5364 +       ltq_chip_print_info();
5365 +
5366 +       return 0;
5367 +}
5368 +
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 },
5372 +};
5373 +
5374 +static const struct ltq_eth_board_config eth_board_config = {
5375 +       .ports = eth_port_config,
5376 +       .num_ports = ARRAY_SIZE(eth_port_config),
5377 +};
5378 +
5379 +int board_eth_init(bd_t *bis)
5380 +{
5381 +       return ltq_eth_initialize(&eth_board_config);
5382 +}
5383 +
5384 +static struct switch_device adm6996i_dev = {
5385 +       .name = "adm6996i",
5386 +       .cpu_port = 5,
5387 +       .port_mask = 0xF,
5388 +};
5389 +
5390 +int board_switch_init(void)
5391 +{
5392 +       /* Deactivate HRST line to release reset of ADM6996I switch */
5393 +       ltq_reset_once(LTQ_RESET_HARD, 200000);
5394 +
5395 +       /* ADM6996I needs some time to come out of reset */
5396 +       __udelay(50000);
5397 +
5398 +       return switch_device_register(&adm6996i_dev);
5399 +}
5400 +
5401 +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
5402 +{
5403 +       if (bus)
5404 +               return 0;
5405 +
5406 +       switch (cs) {
5407 +       case 2:
5408 +               return 1;
5409 +       default:
5410 +               return 0;
5411 +       }
5412 +}
5413 +
5414 +void spi_cs_activate(struct spi_slave *slave)
5415 +{
5416 +       switch (slave->cs) {
5417 +       case 2:
5418 +               gpio_set_value(22, 0);
5419 +               break;
5420 +       default:
5421 +               break;
5422 +       }
5423 +}
5424 +
5425 +void spi_cs_deactivate(struct spi_slave *slave)
5426 +{
5427 +       switch (slave->cs) {
5428 +       case 2:
5429 +               gpio_set_value(22, 1);
5430 +               break;
5431 +       default:
5432 +               break;
5433 +       }
5434 +}
5435 diff --git a/board/lantiq/easy80920/Makefile b/board/lantiq/easy80920/Makefile
5436 new file mode 100644
5437 index 0000000..3a547c2
5438 --- /dev/null
5439 +++ b/board/lantiq/easy80920/Makefile
5440 @@ -0,0 +1,27 @@
5441 +#
5442 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
5443 +#
5444 +# SPDX-License-Identifier:     GPL-2.0+
5445 +#
5446 +
5447 +include $(TOPDIR)/config.mk
5448 +
5449 +LIB    = $(obj)lib$(BOARD).o
5450 +
5451 +COBJS  = $(BOARD).o
5452 +
5453 +SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
5454 +OBJS   := $(addprefix $(obj),$(COBJS))
5455 +SOBJS  := $(addprefix $(obj),$(SOBJS))
5456 +
5457 +$(LIB):        $(obj).depend $(OBJS) $(SOBJS)
5458 +       $(call cmd_link_o_target, $(OBJS) $(SOBJS))
5459 +
5460 +#########################################################################
5461 +
5462 +# defines $(obj).depend target
5463 +include $(SRCTREE)/rules.mk
5464 +
5465 +sinclude $(obj).depend
5466 +
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
5471 --- /dev/null
5472 +++ b/board/lantiq/easy80920/config.mk
5473 @@ -0,0 +1,7 @@
5474 +#
5475 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5476 +#
5477 +# SPDX-License-Identifier:     GPL-2.0+
5478 +#
5479 +
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
5484 --- /dev/null
5485 +++ b/board/lantiq/easy80920/ddr_settings.h
5486 @@ -0,0 +1,69 @@
5487 +/*
5488 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
5489 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5490 + *
5491 + * SPDX-License-Identifier:    GPL-2.0+
5492 + */
5493 +
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
5559 --- /dev/null
5560 +++ b/board/lantiq/easy80920/easy80920.c
5561 @@ -0,0 +1,138 @@
5562 +/*
5563 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5564 + *
5565 + * SPDX-License-Identifier:    GPL-2.0+
5566 + */
5567 +
5568 +#include <common.h>
5569 +#include <spi.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>
5575 +
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
5588 +#else
5589 +#define do_gpio_init   0
5590 +#define do_pll_init    0
5591 +#define do_dcdc_init   1
5592 +#endif
5593 +
5594 +static void gpio_init(void)
5595 +{
5596 +       /* SPI CS 0.4 to serial flash */
5597 +       gpio_direction_output(10, 1);
5598 +
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);
5609 +}
5610 +
5611 +int board_early_init_f(void)
5612 +{
5613 +       if (do_gpio_init)
5614 +               gpio_init();
5615 +
5616 +       if (do_pll_init)
5617 +               ltq_pll_init();
5618 +
5619 +       if (do_dcdc_init)
5620 +               ltq_dcdc_init(0x7F);
5621 +
5622 +       return 0;
5623 +}
5624 +
5625 +int checkboard(void)
5626 +{
5627 +       puts("Board: " CONFIG_BOARD_NAME "\n");
5628 +       ltq_chip_print_info();
5629 +
5630 +       return 0;
5631 +}
5632 +
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 },
5646 +};
5647 +
5648 +static const struct ltq_eth_board_config eth_board_config = {
5649 +       .ports = eth_port_config,
5650 +       .num_ports = ARRAY_SIZE(eth_port_config),
5651 +};
5652 +
5653 +int board_eth_init(bd_t * bis)
5654 +{
5655 +       const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
5656 +       const ulong fw_addr = 0x80FF0000;
5657 +
5658 +       ltq_gphy_phy11g_a1x_load(fw_addr);
5659 +
5660 +       ltq_cgu_gphy_clk_src(clk);
5661 +
5662 +       ltq_rcu_gphy_boot(0, fw_addr);
5663 +       ltq_rcu_gphy_boot(1, fw_addr);
5664 +
5665 +       return ltq_eth_initialize(&eth_board_config);
5666 +}
5667 +
5668 +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
5669 +{
5670 +       if (bus)
5671 +               return 0;
5672 +
5673 +       if (cs == 4)
5674 +               return 1;
5675 +
5676 +       return 0;
5677 +}
5678 +
5679 +void spi_cs_activate(struct spi_slave *slave)
5680 +{
5681 +       switch (slave->cs) {
5682 +       case 4:
5683 +               gpio_set_value(10, 0);
5684 +               break;
5685 +       default:
5686 +               break;
5687 +       }
5688 +}
5689 +
5690 +void spi_cs_deactivate(struct spi_slave *slave)
5691 +{
5692 +       switch (slave->cs) {
5693 +       case 4:
5694 +               gpio_set_value(10, 1);
5695 +               break;
5696 +       default:
5697 +               break;
5698 +       }
5699 +}
5700 diff --git a/boards.cfg b/boards.cfg
5701 index aa2ee64..f090726 100644
5702 --- a/boards.cfg
5703 +++ b/boards.cfg
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
5732  
5733  COBJS  := $(COBJS-y)
5734 diff --git a/drivers/dma/lantiq_dma.c b/drivers/dma/lantiq_dma.c
5735 new file mode 100644
5736 index 0000000..a78212a
5737 --- /dev/null
5738 +++ b/drivers/dma/lantiq_dma.c
5739 @@ -0,0 +1,387 @@
5740 +/*
5741 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5742 + *
5743 + * SPDX-License-Identifier:    GPL-2.0+
5744 + */
5745 +
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>
5756 +
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)
5763 +
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)
5767 +
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)
5774 +
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)
5787 +
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)
5795 +
5796 +#define PTR_ALIGN(p, a)                ((typeof(p))ALIGN((unsigned long)(p), (a)))
5797 +
5798 +struct ltq_dma_regs {
5799 +       u32     clc;            /* Clock control */
5800 +       u32     rsvd0;
5801 +       u32     id;             /* Identification */
5802 +       u32     rsvd1;
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 */
5813 +       u32     rsvd2[2];
5814 +       u32     ps;             /* Port select */
5815 +       u32     pctrl;          /* Port control */
5816 +       u32     rsvd3[43];
5817 +       u32     irnen;          /* Interrupt node enable */
5818 +       u32     irncr;          /* Interrupt node control */
5819 +       u32     irnicr;         /* Interrupt capture */
5820 +};
5821 +
5822 +static struct ltq_dma_regs *ltq_dma_regs =
5823 +       (struct ltq_dma_regs *) CKSEG1ADDR(LTQ_DMA_BASE);
5824 +
5825 +static inline unsigned long ltq_dma_addr_to_virt(u32 dma_addr)
5826 +{
5827 +       return KSEG0ADDR(dma_addr);
5828 +}
5829 +
5830 +static inline u32 ltq_virt_to_dma_addr(void *addr)
5831 +{
5832 +       return CPHYSADDR(addr);
5833 +}
5834 +
5835 +static inline int ltq_dma_burst_align(enum ltq_dma_burst_len burst_len)
5836 +{
5837 +       switch (burst_len) {
5838 +       case LTQ_DMA_BURST_2WORDS:
5839 +               return 2 * 4;
5840 +       case LTQ_DMA_BURST_4WORDS:
5841 +               return 4 * 4;
5842 +       case LTQ_DMA_BURST_8WORDS:
5843 +               return 8 * 4;
5844 +       }
5845 +
5846 +       return 0;
5847 +}
5848 +
5849 +static inline void ltq_dma_sync(void)
5850 +{
5851 +       __asm__ __volatile__("sync");
5852 +}
5853 +
5854 +static inline void ltq_dma_dcache_wb_inv(const void *ptr, size_t size)
5855 +{
5856 +       unsigned long addr = (unsigned long) ptr;
5857 +
5858 +       flush_dcache_range(addr, addr + size);
5859 +       ltq_dma_sync();
5860 +}
5861 +
5862 +static inline void ltq_dma_dcache_inv(const void *ptr, size_t size)
5863 +{
5864 +       unsigned long addr = (unsigned long) ptr;
5865 +
5866 +       invalidate_dcache_range(addr, addr + size);
5867 +}
5868 +
5869 +void ltq_dma_init(void)
5870 +{
5871 +       /* Power up DMA */
5872 +       ltq_pm_enable(LTQ_PM_DMA);
5873 +
5874 +       /* Reset DMA */
5875 +       ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_RESET);
5876 +
5877 +       /* Disable and clear all interrupts */
5878 +       ltq_writel(&ltq_dma_regs->irnen, 0);
5879 +       ltq_writel(&ltq_dma_regs->irncr, 0xFFFFF);
5880 +
5881 +#if 0
5882 +       /* Enable packet arbitration */
5883 +       ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_PKTARB);
5884 +#endif
5885 +
5886 +#if 0
5887 +       /* Enable descriptor read back */
5888 +       ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_DRB);
5889 +#endif
5890 +
5891 +       /* Enable polling for descriptor fetching for all channels */
5892 +       ltq_writel(&ltq_dma_regs->cpoll, DMA_CPOLL_EN |
5893 +               (4 << DMA_CPOLL_CNT_SHIFT));
5894 +}
5895 +
5896 +static void ltq_dma_channel_reset(struct ltq_dma_channel *chan)
5897 +{
5898 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5899 +       ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
5900 +}
5901 +
5902 +static void ltq_dma_channel_enable(struct ltq_dma_channel *chan)
5903 +{
5904 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5905 +       ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
5906 +}
5907 +
5908 +static void ltq_dma_channel_disable(struct ltq_dma_channel *chan)
5909 +{
5910 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5911 +       ltq_clrbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
5912 +}
5913 +
5914 +static void ltq_dma_port_init(struct ltq_dma_device *dev)
5915 +{
5916 +       u32 pctrl;
5917 +
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;
5922 +
5923 +       ltq_writel(&ltq_dma_regs->ps, dev->port);
5924 +       ltq_writel(&ltq_dma_regs->pctrl, pctrl);
5925 +}
5926 +
5927 +static int ltq_dma_alloc_descriptors(struct ltq_dma_device *dev,
5928 +                                       struct ltq_dma_channel *chan)
5929 +{
5930 +       size_t size;
5931 +       void *desc_base;
5932 +
5933 +       size = ALIGN(sizeof(struct ltq_dma_desc) * chan->num_desc +
5934 +                       ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
5935 +
5936 +       chan->mem_base = malloc(size);
5937 +       if (!chan->mem_base)
5938 +               return 1;
5939 +
5940 +       memset(chan->mem_base, 0, size);
5941 +       ltq_dma_dcache_wb_inv(chan->mem_base, size);
5942 +
5943 +       desc_base = PTR_ALIGN(chan->mem_base, ARCH_DMA_MINALIGN);
5944 +
5945 +       debug("DMA: mem %p, desc %p\n", chan->mem_base, desc_base);
5946 +
5947 +       /* Align descriptor base to 8 bytes */
5948 +       chan->desc_base = (void *) CKSEG1ADDR(desc_base);
5949 +       chan->dma_addr = CPHYSADDR(desc_base);
5950 +       chan->dev = dev;
5951 +
5952 +       debug("DMA: desc_base %p, size %u\n", chan->desc_base, size);
5953 +
5954 +       /* Configure hardware with location of descriptor list */
5955 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5956 +       ltq_writel(&ltq_dma_regs->cdba, chan->dma_addr);
5957 +       ltq_writel(&ltq_dma_regs->cdlen, chan->num_desc);
5958 +       ltq_writel(&ltq_dma_regs->cctrl, (3 << DMA_CCTRL_TXWGT_SHIFT) |
5959 +               (chan->class << DMA_CCTRL_CLASS_SHIFT));
5960 +       ltq_writel(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
5961 +
5962 +       return 0;
5963 +}
5964 +
5965 +static void ltq_dma_free_descriptors(struct ltq_dma_channel *chan)
5966 +{
5967 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5968 +       ltq_writel(&ltq_dma_regs->cdba, 0);
5969 +       ltq_writel(&ltq_dma_regs->cdlen, 0);
5970 +
5971 +       ltq_dma_channel_reset(chan);
5972 +
5973 +       free(chan->mem_base);
5974 +}
5975 +
5976 +int ltq_dma_register(struct ltq_dma_device *dev)
5977 +{
5978 +       int ret;
5979 +
5980 +       ltq_dma_port_init(dev);
5981 +
5982 +       ret = ltq_dma_alloc_descriptors(dev, &dev->rx_chan);
5983 +       if (ret)
5984 +               return ret;
5985 +
5986 +       ret = ltq_dma_alloc_descriptors(dev, &dev->tx_chan);
5987 +       if (ret) {
5988 +               ltq_dma_free_descriptors(&dev->rx_chan);
5989 +               return ret;
5990 +       }
5991 +
5992 +       return 0;
5993 +}
5994 +
5995 +void ltq_dma_reset(struct ltq_dma_device *dev)
5996 +{
5997 +       ltq_dma_channel_reset(&dev->rx_chan);
5998 +       ltq_dma_channel_reset(&dev->tx_chan);
5999 +}
6000 +
6001 +void ltq_dma_enable(struct ltq_dma_device *dev)
6002 +{
6003 +       ltq_dma_channel_enable(&dev->rx_chan);
6004 +       ltq_dma_channel_enable(&dev->tx_chan);
6005 +}
6006 +
6007 +void ltq_dma_disable(struct ltq_dma_device *dev)
6008 +{
6009 +       ltq_dma_channel_disable(&dev->rx_chan);
6010 +       ltq_dma_channel_disable(&dev->tx_chan);
6011 +}
6012 +
6013 +int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len)
6014 +{
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;
6019 +
6020 +       offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
6021 +
6022 +       ltq_dma_dcache_inv(data, len);
6023 +
6024 +#if 0
6025 +       printf("%s: index %d, data %p, dma_addr %08x, offset %u, len %d\n",
6026 +               __func__, index, data, dma_addr, offset, len);
6027 +#endif
6028 +
6029 +
6030 +       desc->addr = dma_addr - offset;
6031 +       desc->ctl = DMA_DESC_OWN | DMA_DESC_RX_OFFSET(offset) |
6032 +                       DMA_DESC_LENGTH(len);
6033 +
6034 +#if 0
6035 +       printf("%s: index %d, desc %p, desc->ctl %08x\n",
6036 +               __func__, index, desc, desc->ctl);
6037 +#endif
6038 +
6039 +       return 0;
6040 +}
6041 +
6042 +int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index)
6043 +{
6044 +       struct ltq_dma_channel *chan = &dev->rx_chan;
6045 +       struct ltq_dma_desc *desc = &chan->desc_base[index];
6046 +
6047 +#if 0
6048 +       printf("%s: index %d, desc %p, desc->ctl %08x\n",
6049 +               __func__, index, desc, desc->ctl);
6050 +#endif
6051 +
6052 +       if (desc->ctl & DMA_DESC_OWN)
6053 +               return 0;
6054 +
6055 +       if (desc->ctl & DMA_DESC_C)
6056 +               return 1;
6057 +
6058 +       return 0;
6059 +}
6060 +
6061 +int ltq_dma_rx_length(struct ltq_dma_device *dev, int index)
6062 +{
6063 +       struct ltq_dma_channel *chan = &dev->rx_chan;
6064 +       struct ltq_dma_desc *desc = &chan->desc_base[index];
6065 +
6066 +       return DMA_DESC_LENGTH(desc->ctl);
6067 +}
6068 +
6069 +int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
6070 +                       unsigned long timeout)
6071 +{
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);
6077 +
6078 +       while (desc->ctl & DMA_DESC_OWN) {
6079 +               WATCHDOG_RESET();
6080 +
6081 +               if (get_timer(timebase) >= timeout) {
6082 +#if 0
6083 +                       printf("%s: timeout: index %d, desc %p, desc->ctl %08x\n",
6084 +                               __func__, index, desc, desc->ctl);
6085 +#endif
6086 +                       return -1;
6087 +               }
6088 +       }
6089 +
6090 +       offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
6091 +
6092 +#if 0
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);
6095 +#endif
6096 +
6097 +       ltq_dma_dcache_wb_inv(data, len);
6098 +
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);
6102 +
6103 +#if 0
6104 +       printf("%s: index %d, desc %p, desc->ctl %08x\n",
6105 +               __func__, index, desc, desc->ctl);
6106 +#endif
6107 +
6108 +       return 0;
6109 +}
6110 +
6111 +int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
6112 +                       unsigned long timeout)
6113 +{
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);
6117 +
6118 +       while ((desc->ctl & (DMA_DESC_OWN | DMA_DESC_C)) != DMA_DESC_C) {
6119 +               WATCHDOG_RESET();
6120 +
6121 +               if (get_timer(timebase) >= timeout)
6122 +                       return -1;
6123 +       }
6124 +
6125 +       return 0;
6126 +}
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
6142 --- /dev/null
6143 +++ b/drivers/gpio/lantiq_gpio.c
6144 @@ -0,0 +1,329 @@
6145 +/*
6146 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6147 + *
6148 + * SPDX-License-Identifier:    GPL-2.0+
6149 + */
6150 +
6151 +#include <common.h>
6152 +#include <asm/arch/soc.h>
6153 +#include <asm/arch/gpio.h>
6154 +#include <asm/lantiq/io.h>
6155 +
6156 +#define SSIO_GPIO_BASE         64
6157 +
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)
6162 +
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)
6171 +
6172 +#define SSIO_CON1_GPHY2_SHIFT  15
6173 +#define SSIO_CON1_GPHY2_CONFIG ((CONFIG_LTQ_SSIO_GPHY2_MODE & 0x7) << 15)
6174 +
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)
6179 +
6180 +#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
6181 +#define enable_ssio    1
6182 +#else
6183 +#define enable_ssio    0
6184 +
6185 +#define CONFIG_LTQ_SSIO_GPHY1_MODE     0
6186 +#define CONFIG_LTQ_SSIO_GPHY2_MODE     0
6187 +#define CONFIG_LTQ_SSIO_INIT_VALUE     0
6188 +#endif
6189 +
6190 +#ifdef CONFIG_LTQ_SSIO_EDGE_FALLING
6191 +#define SSIO_RZFL_CONFIG       SSIO_CON0_RZFL
6192 +#else
6193 +#define SSIO_RZFL_CONFIG       0
6194 +#endif
6195 +
6196 +struct ltq_gpio_port_regs {
6197 +       __be32  out;
6198 +       __be32  in;
6199 +       __be32  dir;
6200 +       __be32  altsel0;
6201 +       __be32  altsel1;
6202 +       __be32  od;
6203 +       __be32  stoff;
6204 +       __be32  pudsel;
6205 +       __be32  puden;
6206 +       __be32  rsvd1[3];
6207 +};
6208 +
6209 +struct ltq_gpio_regs {
6210 +       u32                             rsvd[4];
6211 +       struct ltq_gpio_port_regs       ports[CONFIG_LTQ_GPIO_MAX_BANKS];
6212 +};
6213 +
6214 +struct ltq_gpio3_regs {
6215 +       u32     rsvd0[13];
6216 +       __be32  od;
6217 +       __be32  pudsel;
6218 +       __be32  puden;
6219 +       u32     rsvd1[9];
6220 +       __be32  altsel1;
6221 +       u32     rsvd2[14];
6222 +       __be32  out;
6223 +       __be32  in;
6224 +       __be32  dir;
6225 +       __be32  altsel0;
6226 +};
6227 +
6228 +struct ltq_ssio_regs {
6229 +       __be32  con0;
6230 +       __be32  con1;
6231 +       __be32  cpu0;
6232 +       __be32  cpu1;
6233 +       __be32  ar;
6234 +};
6235 +
6236 +static struct ltq_gpio_regs *ltq_gpio_regs =
6237 +       (struct ltq_gpio_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
6238 +
6239 +static struct ltq_gpio3_regs *ltq_gpio3_regs =
6240 +       (struct ltq_gpio3_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
6241 +
6242 +static struct ltq_ssio_regs *ltq_ssio_regs =
6243 +       (struct ltq_ssio_regs *) CKSEG1ADDR(LTQ_SSIO_BASE);
6244 +
6245 +static int is_gpio_bank3(unsigned int port)
6246 +{
6247 +#ifdef CONFIG_LTQ_HAS_GPIO_BANK3
6248 +       return port == 3;
6249 +#else
6250 +       return 0;
6251 +#endif
6252 +}
6253 +
6254 +static int is_gpio_ssio(unsigned int gpio)
6255 +{
6256 +#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
6257 +       return gpio >= SSIO_GPIO_BASE;
6258 +#else
6259 +       return 0;
6260 +#endif
6261 +}
6262 +
6263 +static inline int ssio_gpio_to_bit(unsigned gpio)
6264 +{
6265 +       return 1 << (gpio - SSIO_GPIO_BASE);
6266 +}
6267 +
6268 +int ltq_gpio_init(void)
6269 +{
6270 +       ltq_writel(&ltq_ssio_regs->ar, 0);
6271 +       ltq_writel(&ltq_ssio_regs->cpu0, CONFIG_LTQ_SSIO_INIT_VALUE);
6272 +       ltq_writel(&ltq_ssio_regs->cpu1, 0);
6273 +       ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_SWU);
6274 +
6275 +       if (enable_ssio) {
6276 +               ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_GPHY1_CONFIG |
6277 +                       SSIO_RZFL_CONFIG);
6278 +               ltq_writel(&ltq_ssio_regs->con1, SSIO_CON1_US_FPI |
6279 +                       SSIO_CON1_FPID_8HZ | SSIO_CON1_GPHY2_CONFIG |
6280 +                       SSIO_CON1_GROUP_CONFIG);
6281 +       }
6282 +
6283 +       return 0;
6284 +}
6285 +
6286 +int gpio_request(unsigned gpio, const char *label)
6287 +{
6288 +       return 0;
6289 +}
6290 +
6291 +int gpio_free(unsigned gpio)
6292 +{
6293 +       return 0;
6294 +}
6295 +
6296 +int gpio_direction_input(unsigned gpio)
6297 +{
6298 +       unsigned port = gpio_to_port(gpio);
6299 +       const void *gpio_od = &ltq_gpio_regs->ports[port].od;
6300 +       const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
6301 +       const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
6302 +       const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
6303 +
6304 +       if (is_gpio_ssio(gpio))
6305 +               return 0;
6306 +
6307 +       if (is_gpio_bank3(port)) {
6308 +               gpio_od = &ltq_gpio3_regs->od;
6309 +               gpio_altsel0 = &ltq_gpio3_regs->altsel0;
6310 +               gpio_altsel1 = &ltq_gpio3_regs->altsel1;
6311 +               gpio_dir = &ltq_gpio3_regs->dir;
6312 +       }
6313 +
6314 +       /*
6315 +        * Reset open drain and altsel configs to workaround improper
6316 +        * reset values or unwanted modifications by BootROM
6317 +        */
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));
6321 +
6322 +       /* Switch to input */
6323 +       ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
6324 +
6325 +       return 0;
6326 +}
6327 +
6328 +int gpio_direction_output(unsigned gpio, int value)
6329 +{
6330 +       unsigned port = gpio_to_port(gpio);
6331 +       const void *gpio_od = &ltq_gpio_regs->ports[port].od;
6332 +       const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
6333 +       const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
6334 +       const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
6335 +       const void *gpio_out = &ltq_gpio_regs->ports[port].out;
6336 +       u32 data = gpio_to_bit(gpio);
6337 +
6338 +       if (is_gpio_ssio(gpio)) {
6339 +               data = ssio_gpio_to_bit(gpio);
6340 +               if (value)
6341 +                       ltq_setbits(&ltq_ssio_regs->cpu0, data);
6342 +               else
6343 +                       ltq_clrbits(&ltq_ssio_regs->cpu0, data);
6344 +
6345 +               return 0;
6346 +       }
6347 +
6348 +       if (is_gpio_bank3(port)) {
6349 +               gpio_od = &ltq_gpio3_regs->od;
6350 +               gpio_altsel0 = &ltq_gpio3_regs->altsel0;
6351 +               gpio_altsel1 = &ltq_gpio3_regs->altsel1;
6352 +               gpio_dir = &ltq_gpio3_regs->dir;
6353 +               gpio_out = &ltq_gpio3_regs->out;
6354 +       }
6355 +
6356 +       /*
6357 +        * Reset open drain and altsel configs to workaround improper
6358 +        * reset values or unwanted modifications by BootROM
6359 +        */
6360 +       ltq_setbits(gpio_od, data);
6361 +       ltq_clrbits(gpio_altsel0, data);
6362 +       ltq_clrbits(gpio_altsel1, data);
6363 +
6364 +       if (value)
6365 +               ltq_setbits(gpio_out, data);
6366 +       else
6367 +               ltq_clrbits(gpio_out, data);
6368 +
6369 +       /* Switch to output */
6370 +       ltq_setbits(gpio_dir, data);
6371 +
6372 +       return 0;
6373 +}
6374 +
6375 +int gpio_get_value(unsigned gpio)
6376 +{
6377 +       unsigned port = gpio_to_port(gpio);
6378 +       const void *gpio_in = &ltq_gpio_regs->ports[port].in;
6379 +       u32 data = gpio_to_bit(gpio);
6380 +       u32 val;
6381 +
6382 +       if (is_gpio_ssio(gpio)) {
6383 +               gpio_in = &ltq_ssio_regs->cpu0;
6384 +               data = ssio_gpio_to_bit(gpio);
6385 +       }
6386 +
6387 +       if (is_gpio_bank3(port))
6388 +               gpio_in = &ltq_gpio3_regs->in;
6389 +
6390 +       val = ltq_readl(gpio_in);
6391 +
6392 +       return !!(val & data);
6393 +}
6394 +
6395 +int gpio_set_value(unsigned gpio, int value)
6396 +{
6397 +       unsigned port = gpio_to_port(gpio);
6398 +       const void *gpio_out = &ltq_gpio_regs->ports[port].out;
6399 +       u32 data = gpio_to_bit(gpio);
6400 +
6401 +       if (is_gpio_ssio(gpio)) {
6402 +               gpio_out = &ltq_ssio_regs->cpu0;
6403 +               data = ssio_gpio_to_bit(gpio);
6404 +       }
6405 +
6406 +       if (is_gpio_bank3(port))
6407 +               gpio_out = &ltq_gpio3_regs->out;
6408 +
6409 +       if (value)
6410 +               ltq_setbits(gpio_out, data);
6411 +       else
6412 +               ltq_clrbits(gpio_out, data);
6413 +
6414 +       return 0;
6415 +}
6416 +
6417 +int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir)
6418 +{
6419 +       unsigned port = gpio_to_port(gpio);
6420 +       const void *gpio_od = &ltq_gpio_regs->ports[port].od;
6421 +       const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
6422 +       const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
6423 +       const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
6424 +
6425 +       if (is_gpio_ssio(gpio))
6426 +               return 0;
6427 +
6428 +       if (is_gpio_bank3(port)) {
6429 +               gpio_od = &ltq_gpio3_regs->od;
6430 +               gpio_altsel0 = &ltq_gpio3_regs->altsel0;
6431 +               gpio_altsel1 = &ltq_gpio3_regs->altsel1;
6432 +               gpio_dir = &ltq_gpio3_regs->dir;
6433 +       }
6434 +
6435 +       if (altsel0)
6436 +               ltq_setbits(gpio_altsel0, gpio_to_bit(gpio));
6437 +       else
6438 +               ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
6439 +
6440 +       if (altsel1)
6441 +               ltq_setbits(gpio_altsel1, gpio_to_bit(gpio));
6442 +       else
6443 +               ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
6444 +
6445 +       if (dir) {
6446 +               ltq_setbits(gpio_od, gpio_to_bit(gpio));
6447 +               ltq_setbits(gpio_dir, gpio_to_bit(gpio));
6448 +       } else {
6449 +               ltq_clrbits(gpio_od, gpio_to_bit(gpio));
6450 +               ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
6451 +       }
6452 +
6453 +       return 0;
6454 +}
6455 +
6456 +int gpio_set_opendrain(unsigned gpio, int od)
6457 +{
6458 +       unsigned port = gpio_to_port(gpio);
6459 +       const void *gpio_od = &ltq_gpio_regs->ports[port].od;
6460 +
6461 +       if (is_gpio_ssio(gpio))
6462 +               return 0;
6463 +
6464 +       if (is_gpio_bank3(port))
6465 +               gpio_od = &ltq_gpio3_regs->od;
6466 +
6467 +       if (od)
6468 +               ltq_setbits(gpio_od, gpio_to_bit(gpio));
6469 +       else
6470 +               ltq_clrbits(gpio_od, gpio_to_bit(gpio));
6471 +
6472 +       return 0;
6473 +}
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
6480  #endif
6481  
6482 +static inline void *__flash_swap_addr(unsigned long addr)
6483 +{
6484 +       return (void *) addr;
6485 +}
6486 +
6487 +#ifdef CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
6488 +void *flash_swap_addr(unsigned long addr)
6489 +               __attribute__((weak, alias("__flash_swap_addr")));
6490 +#else
6491 +#define flash_swap_addr        __flash_swap_addr
6492 +#endif
6493 +
6494  /*-----------------------------------------------------------------------
6495   */
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)
6498  {
6499         unsigned int byte_offset = offset * info->portwidth;
6500  
6501 -       return (void *)(info->start[sect] + byte_offset);
6502 +       return flash_swap_addr(info->start[sect] + byte_offset);
6503  }
6504  
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
6521 --- /dev/null
6522 +++ b/drivers/mtd/nand/lantiq_nand.c
6523 @@ -0,0 +1,126 @@
6524 +/*
6525 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6526 + *
6527 + * SPDX-License-Identifier:    GPL-2.0+
6528 + */
6529 +
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>
6536 +
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)
6554 +
6555 +#define NAND_WAIT_WR_C         (1 << 3)
6556 +#define NAND_WAIT_RDBY         (1 << 0)
6557 +
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)
6564 +
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 */
6571 +};
6572 +
6573 +static struct ltq_nand_regs *ltq_nand_regs =
6574 +       (struct ltq_nand_regs *) CKSEG1ADDR(LTQ_EBU_NAND_BASE);
6575 +
6576 +static void ltq_nand_wait_ready(void)
6577 +{
6578 +       while ((ltq_readl(&ltq_nand_regs->wait) & NAND_WAIT_WR_C) == 0)
6579 +               ;
6580 +}
6581 +
6582 +static int ltq_nand_dev_ready(struct mtd_info *mtd)
6583 +{
6584 +       u32 data = ltq_readl(&ltq_nand_regs->wait);
6585 +       return data & NAND_WAIT_RDBY;
6586 +}
6587 +
6588 +static void ltq_nand_select_chip(struct mtd_info *mtd, int chip)
6589 +{
6590 +       if (chip == 0) {
6591 +               ltq_setbits(&ltq_nand_regs->con, NAND_CON_NANDM);
6592 +               ltq_setbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
6593 +       } else {
6594 +               ltq_clrbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
6595 +               ltq_clrbits(&ltq_nand_regs->con, NAND_CON_NANDM);
6596 +       }
6597 +}
6598 +
6599 +static void ltq_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
6600 +{
6601 +       struct nand_chip *chip = mtd->priv;
6602 +       unsigned long addr = (unsigned long) chip->IO_ADDR_W;
6603 +
6604 +       if (ctrl & NAND_CTRL_CHANGE) {
6605 +               if (ctrl & NAND_ALE)
6606 +                       addr |= NAND_CMD_ALE;
6607 +               else
6608 +                       addr &= ~NAND_CMD_ALE;
6609 +
6610 +               if (ctrl & NAND_CLE)
6611 +                       addr |= NAND_CMD_CLE;
6612 +               else
6613 +                       addr &= ~NAND_CMD_CLE;
6614 +
6615 +               chip->IO_ADDR_W = (void __iomem *) addr;
6616 +       }
6617 +
6618 +       if (cmd != NAND_CMD_NONE) {
6619 +               writeb(cmd, chip->IO_ADDR_W);
6620 +               ltq_nand_wait_ready();
6621 +       }
6622 +}
6623 +
6624 +int ltq_nand_init(struct nand_chip *nand)
6625 +{
6626 +       /* Enable NAND, set NAND CS to EBU CS1, enable EBU CS mux */
6627 +       ltq_writel(&ltq_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);
6630 +
6631 +       nand->dev_ready = ltq_nand_dev_ready;
6632 +       nand->select_chip = ltq_nand_select_chip;
6633 +       nand->cmd_ctrl = ltq_nand_cmd_ctrl;
6634 +
6635 +       nand->chip_delay = 30;
6636 +       nand->options = 0;
6637 +       nand->ecc.mode = NAND_ECC_SOFT;
6638 +
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;
6642 +
6643 +       return 0;
6644 +}
6645 +
6646 +__weak int board_nand_init(struct nand_chip *chip)
6647 +{
6648 +       return ltq_nand_init(chip);
6649 +}
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
6666 --- /dev/null
6667 +++ b/drivers/net/lantiq_danube_etop.c
6668 @@ -0,0 +1,410 @@
6669 +/*
6670 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6671 + *
6672 + * SPDX-License-Identifier:    GPL-2.0+
6673 + */
6674 +
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>
6686 +
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)
6690 +
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)
6703 +
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)
6708 +
6709 +#define LTQ_PPE_ENETS0_CFG_FTUC                (1 << 28)
6710 +
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
6715 +
6716 +#define LTQ_MDIO_DRV_NAME              "ltq-mdio"
6717 +#define LTQ_ETH_DRV_NAME               "ltq-eth"
6718 +
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 */
6729 +       u32     rsvd0[3];
6730 +       u32     vpid;                   /* VLAN protocol ID */
6731 +};
6732 +
6733 +struct ltq_ppe_enet_regs {
6734 +       u32     mac_cfg;                /* MAC configuration */
6735 +       u32     rsvd0[3];
6736 +       u32     ig_cfg;                 /* Ingress configuration */
6737 +       u32     ig_pgcnt;               /* Ingress buffer used page count */
6738 +       u32     rsvd1;
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 */
6745 +       u32     rsvd2[22];
6746 +       u32     pgcnt;                  /* Page counter */
6747 +       u32     rsvd3;
6748 +       u32     hf_ctrl;                /* Half duplex control */
6749 +       u32     tx_ctrl;                /* Transmit control */
6750 +       u32     rsvd4;
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 */
6757 +};
6758 +
6759 +struct ltq_eth_priv {
6760 +       struct ltq_dma_device dma_dev;
6761 +       struct mii_dev *bus;
6762 +       struct eth_device *dev;
6763 +       int rx_num;
6764 +       int tx_num;
6765 +};
6766 +
6767 +struct ltq_mdio_access {
6768 +       union {
6769 +               struct {
6770 +                       unsigned ra:1;
6771 +                       unsigned rw:1;
6772 +                       unsigned rsvd:4;
6773 +                       unsigned phya:5;
6774 +                       unsigned rega:5;
6775 +                       unsigned phyd:16;
6776 +               } reg;
6777 +               u32 val;
6778 +       };
6779 +};
6780 +
6781 +static struct ltq_ppe_etop_regs *ltq_ppe_etop_regs =
6782 +       (struct ltq_ppe_etop_regs *) CKSEG1ADDR(LTQ_PPE_ETOP_BASE);
6783 +
6784 +static struct ltq_ppe_enet_regs *ltq_ppe_enet0_regs =
6785 +       (struct ltq_ppe_enet_regs *) CKSEG1ADDR(LTQ_PPE_ENET0_BASE);
6786 +
6787 +static inline int ltq_mdio_poll(void)
6788 +{
6789 +       struct ltq_mdio_access acc;
6790 +       unsigned cnt = 10000;
6791 +
6792 +       while (likely(cnt--)) {
6793 +               acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
6794 +               if (!acc.reg.ra)
6795 +                       return 0;
6796 +       }
6797 +
6798 +       return 1;
6799 +}
6800 +
6801 +static int ltq_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
6802 +                               int regnum)
6803 +{
6804 +       struct ltq_mdio_access acc;
6805 +       int ret;
6806 +
6807 +       acc.val = 0;
6808 +       acc.reg.ra = 1;
6809 +       acc.reg.rw = 1;
6810 +       acc.reg.phya = addr;
6811 +       acc.reg.rega = regnum;
6812 +
6813 +       ret = ltq_mdio_poll();
6814 +       if (ret)
6815 +               return ret;
6816 +
6817 +       ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
6818 +
6819 +       ret = ltq_mdio_poll();
6820 +       if (ret)
6821 +               return ret;
6822 +
6823 +       acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
6824 +
6825 +       return acc.reg.phyd;
6826 +}
6827 +
6828 +static int ltq_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
6829 +                               int regnum, u16 val)
6830 +{
6831 +       struct ltq_mdio_access acc;
6832 +       int ret;
6833 +
6834 +       acc.val = 0;
6835 +       acc.reg.ra = 1;
6836 +       acc.reg.rw = 0;
6837 +       acc.reg.phya = addr;
6838 +       acc.reg.rega = regnum;
6839 +       acc.reg.phyd = val;
6840 +
6841 +       ret = ltq_mdio_poll();
6842 +       if (ret)
6843 +               return ret;
6844 +
6845 +       ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
6846 +
6847 +       return 0;
6848 +}
6849 +
6850 +static inline void ltq_eth_write_hwaddr(const struct eth_device *dev)
6851 +{
6852 +       u32 da0, da1;
6853 +
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);
6857 +
6858 +       ltq_writel(&ltq_ppe_enet0_regs->mac_da0, da0);
6859 +       ltq_writel(&ltq_ppe_enet0_regs->mac_da1, da1);
6860 +}
6861 +
6862 +static inline u8 *ltq_eth_rx_packet_align(int rx_num)
6863 +{
6864 +       u8 *packet = (u8 *) NetRxPackets[rx_num];
6865 +
6866 +       /*
6867 +        * IP header needs
6868 +        */
6869 +       return packet + LTQ_ETH_IP_ALIGN;
6870 +}
6871 +
6872 +static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
6873 +{
6874 +       struct ltq_eth_priv *priv = dev->priv;
6875 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
6876 +       int i;
6877 +
6878 +       ltq_eth_write_hwaddr(dev);
6879 +
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);
6883 +
6884 +       ltq_dma_enable(dma_dev);
6885 +
6886 +       priv->rx_num = 0;
6887 +       priv->tx_num = 0;
6888 +
6889 +       return 0;
6890 +}
6891 +
6892 +static void ltq_eth_halt(struct eth_device *dev)
6893 +{
6894 +       struct ltq_eth_priv *priv = dev->priv;
6895 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
6896 +
6897 +       ltq_dma_reset(dma_dev);
6898 +}
6899 +
6900 +static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
6901 +{
6902 +       struct ltq_eth_priv *priv = dev->priv;
6903 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
6904 +       int err;
6905 +
6906 +       /* Minimum payload length w/ CRC is 60 bytes */
6907 +       if (length < 60)
6908 +               length = 60;
6909 +
6910 +       err = ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
6911 +       if (err) {
6912 +               puts("NET: timeout on waiting for TX descriptor\n");
6913 +               return -1;
6914 +       }
6915 +
6916 +       priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
6917 +
6918 +       return err;
6919 +}
6920 +
6921 +static int ltq_eth_recv(struct eth_device *dev)
6922 +{
6923 +       struct ltq_eth_priv *priv = dev->priv;
6924 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
6925 +       u8 *packet;
6926 +       int len;
6927 +
6928 +       if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
6929 +               return 0;
6930 +
6931 +#if 0
6932 +       printf("%s: rx_num %d\n", __func__, priv->rx_num);
6933 +#endif
6934 +
6935 +       len = ltq_dma_rx_length(dma_dev, priv->rx_num);
6936 +       packet = ltq_eth_rx_packet_align(priv->rx_num);
6937 +
6938 +#if 0
6939 +       printf("%s: received: packet %p, len %u, rx_num %d\n",
6940 +               __func__, packet, len, priv->rx_num);
6941 +#endif
6942 +
6943 +       if (len)
6944 +               NetReceive(packet, len);
6945 +
6946 +       ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
6947 +               LTQ_ETH_RX_DATA_SIZE);
6948 +
6949 +       priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
6950 +
6951 +       return 0;
6952 +}
6953 +
6954 +static void ltq_eth_hw_init(const struct ltq_eth_port_config *port)
6955 +{
6956 +       u32 data;
6957 +
6958 +       /* Power up ethernet subsystems */
6959 +       ltq_pm_enable(LTQ_PM_ETH);
6960 +
6961 +       /* Reset ethernet subsystems */
6962 +       ltq_reset_once(LTQ_RESET_ETH, 1);
6963 +
6964 +       /* Disable MDIO auto-detection */
6965 +       ltq_clrbits(&ltq_ppe_etop_regs->mdio_cfg, LTQ_PPE_ETOP_MDIO_CFG_UMM1 |
6966 +                       LTQ_PPE_ETOP_MDIO_CFG_UMM0);
6967 +
6968 +       /* Enable CRC generation, Full Duplex, 100Mbps, Link up */
6969 +       ltq_writel(&ltq_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);
6973 +
6974 +       /* Reset ETOP cfg and disable all */
6975 +       data = LTQ_PPE_ETOP_CFG_OFF0 | LTQ_PPE_ETOP_CFG_OFF1;
6976 +
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;
6980 +
6981 +       if (port->phy_if == PHY_INTERFACE_MODE_RMII)
6982 +               data |= LTQ_PPE_ETOP_CFG_REMII0;
6983 +       else
6984 +               data &= ~LTQ_PPE_ETOP_CFG_REMII0;
6985 +
6986 +       ltq_writel(&ltq_ppe_etop_regs->cfg, data);
6987 +
6988 +       /* Set allowed packet length from 64 bytes to 1518 bytes */
6989 +       ltq_writel(&ltq_ppe_etop_regs->ig_plen_ctrl, (64 << 16) | 1518);
6990 +
6991 +       /* Enable filter for unicast packets */
6992 +       ltq_setbits(&ltq_ppe_enet0_regs->ig_cfg, LTQ_PPE_ENETS0_CFG_FTUC);
6993 +}
6994 +
6995 +int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
6996 +{
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;
7004 +       int ret;
7005 +
7006 +       ltq_dma_init();
7007 +       ltq_eth_hw_init(port);
7008 +
7009 +       dev = calloc(1, sizeof(*dev));
7010 +       if (!dev)
7011 +               return -1;
7012 +
7013 +       priv = calloc(1, sizeof(*priv));
7014 +       if (!priv)
7015 +               return -1;
7016 +
7017 +       bus = mdio_alloc();
7018 +       if (!bus)
7019 +               return -1;
7020 +
7021 +       sprintf(dev->name, LTQ_ETH_DRV_NAME);
7022 +       dev->priv = priv;
7023 +       dev->init = ltq_eth_init;
7024 +       dev->halt = ltq_eth_halt;
7025 +       dev->recv = ltq_eth_recv;
7026 +       dev->send = ltq_eth_send;
7027 +
7028 +       sprintf(bus->name, LTQ_MDIO_DRV_NAME);
7029 +       bus->read = ltq_mdio_read;
7030 +       bus->write = ltq_mdio_write;
7031 +       bus->priv = priv;
7032 +
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;
7045 +
7046 +       priv->bus = bus;
7047 +       priv->dev = dev;
7048 +
7049 +       ret = ltq_dma_register(dma_dev);
7050 +       if (ret)
7051 +               return ret;
7052 +
7053 +       ret = mdio_register(bus);
7054 +       if (ret)
7055 +               return ret;
7056 +
7057 +       ret = eth_register(dev);
7058 +       if (ret)
7059 +               return ret;
7060 +
7061 +       if (port->flags & LTQ_ETH_PORT_SWITCH) {
7062 +               sw = switch_connect(bus);
7063 +               if (!sw)
7064 +                       return -1;
7065 +
7066 +               switch_setup(sw);
7067 +       }
7068 +
7069 +       if (port->flags & LTQ_ETH_PORT_PHY) {
7070 +               phy = phy_connect(bus, port->phy_addr, dev, port->phy_if);
7071 +               if (!phy)
7072 +                       return -1;
7073 +
7074 +               phy_config(phy);
7075 +       }
7076 +
7077 +       return 0;
7078 +}
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
7082 --- /dev/null
7083 +++ b/drivers/net/lantiq_vrx200_switch.c
7084 @@ -0,0 +1,675 @@
7085 +/*
7086 + * Copyright (C) 2010-2011 Lantiq Deutschland GmbH
7087 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
7088 + *
7089 + * SPDX-License-Identifier:    GPL-2.0+
7090 + */
7091 +
7092 +#define DEBUG
7093 +
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>
7108 +
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
7113 +
7114 +#define LTQ_MDIO_DRV_NAME              "ltq-mdio"
7115 +#define LTQ_ETH_DRV_NAME               "ltq-eth"
7116 +
7117 +#define LTQ_ETHSW_MAX_GMAC             6
7118 +#define LTQ_ETHSW_PMAC                 6
7119 +
7120 +struct ltq_mdio_phy_addr_reg {
7121 +       union {
7122 +               struct {
7123 +                       unsigned rsvd:1;
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 */
7130 +               } bits;
7131 +               u16 val;
7132 +       };
7133 +};
7134 +
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,
7139 +};
7140 +
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,
7146 +};
7147 +
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,
7152 +};
7153 +
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,
7158 +};
7159 +
7160 +struct ltq_mii_mii_cfg_reg {
7161 +       union {
7162 +               struct {
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 */
7167 +                       unsigned rsvd:1;
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 */
7173 +               } bits;
7174 +               u16 val;
7175 +       };
7176 +};
7177 +
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,
7184 +};
7185 +
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,
7192 +};
7193 +
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];
7199 +       int rx_num;
7200 +       int tx_num;
7201 +};
7202 +
7203 +static struct vr9_switch_regs *switch_regs =
7204 +       (struct vr9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE);
7205 +
7206 +static inline void vr9_switch_sync(void)
7207 +{
7208 +       __asm__("sync");
7209 +}
7210 +
7211 +static inline int vr9_switch_mdio_is_busy(void)
7212 +{
7213 +       u32 mdio_ctrl = ltq_readl(&switch_regs->mdio.mdio_ctrl);
7214 +
7215 +       return mdio_ctrl & MDIO_CTRL_MBUSY;
7216 +}
7217 +
7218 +static inline void vr9_switch_mdio_poll(void)
7219 +{
7220 +       while (vr9_switch_mdio_is_busy())
7221 +               cpu_relax();
7222 +}
7223 +
7224 +static int vr9_switch_mdio_read(struct mii_dev *bus, int phyad, int devad,
7225 +                                       int regad)
7226 +{
7227 +       u32 mdio_ctrl;
7228 +       int retval;
7229 +
7230 +       mdio_ctrl = MDIO_CTRL_OP_READ |
7231 +               ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
7232 +               (regad & MDIO_CTRL_REGAD_MASK);
7233 +
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);
7238 +
7239 +       return retval;
7240 +}
7241 +
7242 +static int vr9_switch_mdio_write(struct mii_dev *bus, int phyad, int devad,
7243 +                                       int regad, u16 val)
7244 +{
7245 +       u32 mdio_ctrl;
7246 +
7247 +       mdio_ctrl = MDIO_CTRL_OP_WRITE |
7248 +               ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
7249 +               (regad & MDIO_CTRL_REGAD_MASK);
7250 +
7251 +       vr9_switch_mdio_poll();
7252 +       ltq_writel(&switch_regs->mdio.mdio_write, val);
7253 +       ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
7254 +
7255 +       return 0;
7256 +}
7257 +
7258 +static void ltq_eth_gmac_update(struct phy_device *phydev, int num)
7259 +{
7260 +       struct ltq_mdio_phy_addr_reg phy_addr_reg;
7261 +       struct ltq_mii_mii_cfg_reg mii_cfg_reg;
7262 +
7263 +       phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
7264 +
7265 +       switch (num) {
7266 +       case 0:
7267 +       case 1:
7268 +       case 5:
7269 +               mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
7270 +               break;
7271 +       default:
7272 +               mii_cfg_reg.val = 0;
7273 +               break;
7274 +       }
7275 +
7276 +       phy_addr_reg.bits.addr = phydev->addr;
7277 +
7278 +       if (phydev->link)
7279 +               phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_UP;
7280 +       else
7281 +               phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
7282 +
7283 +       switch (phydev->speed) {
7284 +       case SPEED_1000:
7285 +               phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_G1;
7286 +               mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M125;
7287 +               break;
7288 +       case SPEED_100:
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;
7294 +                       break;
7295 +               default:
7296 +                       mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M25;
7297 +                       break;
7298 +               }
7299 +               break;
7300 +       default:
7301 +               phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
7302 +               mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
7303 +               break;
7304 +       }
7305 +
7306 +       if (phydev->duplex == DUPLEX_FULL)
7307 +               phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_ENABLE;
7308 +       else
7309 +               phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
7310 +
7311 +       ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
7312 +
7313 +       switch (num) {
7314 +       case 0:
7315 +       case 1:
7316 +       case 5:
7317 +               ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
7318 +               break;
7319 +       default:
7320 +               break;
7321 +       }
7322 +}
7323 +
7324 +static inline u8 *ltq_eth_rx_packet_align(int rx_num)
7325 +{
7326 +       u8 *packet = (u8 *) NetRxPackets[rx_num];
7327 +
7328 +       /*
7329 +        * IP header needs
7330 +        */
7331 +       return packet + LTQ_ETH_IP_ALIGN;
7332 +}
7333 +
7334 +static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
7335 +{
7336 +       struct ltq_eth_priv *priv = dev->priv;
7337 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
7338 +       struct phy_device *phydev;
7339 +       int i;
7340 +
7341 +       for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
7342 +               phydev = priv->phymap[i];
7343 +               if (!phydev)
7344 +                       continue;
7345 +
7346 +               phy_startup(phydev);
7347 +               ltq_eth_gmac_update(phydev, i);
7348 +       }
7349 +
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);
7353 +
7354 +       ltq_dma_enable(dma_dev);
7355 +
7356 +       priv->rx_num = 0;
7357 +       priv->tx_num = 0;
7358 +
7359 +       return 0;
7360 +}
7361 +
7362 +static void ltq_eth_halt(struct eth_device *dev)
7363 +{
7364 +       struct ltq_eth_priv *priv = dev->priv;
7365 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
7366 +       struct phy_device *phydev;
7367 +       int i;
7368 +
7369 +       ltq_dma_reset(dma_dev);
7370 +
7371 +       for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
7372 +               phydev = priv->phymap[i];
7373 +               if (!phydev)
7374 +                       continue;
7375 +
7376 +               phy_shutdown(phydev);
7377 +               phydev->link = 0;
7378 +               ltq_eth_gmac_update(phydev, i);
7379 +       }
7380 +}
7381 +
7382 +static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
7383 +{
7384 +       struct ltq_eth_priv *priv = dev->priv;
7385 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
7386 +
7387 +#if 0
7388 +       printf("%s: packet %p, len %d\n", __func__, packet, length);
7389 +#endif
7390 +
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;
7393 +
7394 +       return 0;
7395 +}
7396 +
7397 +static int ltq_eth_recv(struct eth_device *dev)
7398 +{
7399 +       struct ltq_eth_priv *priv = dev->priv;
7400 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
7401 +       u8 *packet;
7402 +       int len;
7403 +
7404 +       if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
7405 +               return 0;
7406 +
7407 +#if 0
7408 +       printf("%s: rx_num %d\n", __func__, priv->rx_num);
7409 +#endif
7410 +
7411 +       len = ltq_dma_rx_length(dma_dev, priv->rx_num);
7412 +       packet = ltq_eth_rx_packet_align(priv->rx_num);
7413 +
7414 +#if 0
7415 +       printf("%s: received: packet %p, len %u, rx_num %d\n",
7416 +               __func__, packet, len, priv->rx_num);
7417 +#endif
7418 +
7419 +       if (len)
7420 +               NetReceive(packet, len);
7421 +
7422 +       ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
7423 +               LTQ_ETH_RX_DATA_SIZE);
7424 +
7425 +       priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
7426 +
7427 +       return 0;
7428 +}
7429 +
7430 +static void ltq_eth_gmac_init(int num)
7431 +{
7432 +       struct ltq_mdio_phy_addr_reg phy_addr_reg;
7433 +       struct ltq_mii_mii_cfg_reg mii_cfg_reg;
7434 +
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);
7442 +
7443 +       /* Reset and disable MII interface */
7444 +       switch (num) {
7445 +       case 0:
7446 +       case 1:
7447 +       case 5:
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);
7453 +               break;
7454 +       default:
7455 +               break;
7456 +       }
7457 +
7458 +       /*
7459 +        * - enable frame checksum generation
7460 +        * - enable padding of short frames
7461 +        * - disable flow control
7462 +        */
7463 +       ltq_writel(to_mac_ctrl(switch_regs, num, 0),
7464 +               MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
7465 +
7466 +       vr9_switch_sync();
7467 +}
7468 +
7469 +static void ltq_eth_pmac_init(void)
7470 +{
7471 +       /*
7472 +        * WAR: buffer congestion:
7473 +        * - shorten preambel to 1 byte
7474 +        * - set TX IPG to 7 bytes
7475 +        */
7476 +#if 1
7477 +       ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 1),
7478 +               MAC_CTRL1_SHORTPRE | 7);
7479 +#endif
7480 +
7481 +       /*
7482 +        * WAR: systematical concept weakness ACM bug
7483 +        * - set maximum number of used buffer segments to 254
7484 +        * - soft-reset BM FSQM
7485 +        */
7486 +#if 1
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);
7490 +#endif
7491 +
7492 +       /*
7493 +        * WAR: switch MAC drop bug
7494 +        */
7495 +#if 1
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);
7500 +#endif
7501 +
7502 +       /*
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
7508 +        */
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 |
7511 +               PMAC_HD_CTL_RC);
7512 +
7513 +#if 1
7514 +       ltq_writel(&switch_regs->pmac.rx_ipg, 0x8b);
7515 +#endif
7516 +
7517 +       /*
7518 +        * - enable frame checksum generation
7519 +        * - enable padding of short frames
7520 +        * - disable flow control
7521 +        */
7522 +       ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 0),
7523 +               MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
7524 +
7525 +       vr9_switch_sync();
7526 +}
7527 +
7528 +static void ltq_eth_hw_init(void)
7529 +{
7530 +       int i;
7531 +
7532 +       /* Power up ethernet and switch subsystems */
7533 +       ltq_pm_enable(LTQ_PM_ETH);
7534 +
7535 +       /* Reset ethernet and switch subsystems */
7536 +#if 0
7537 +       ltq_reset_once(LTQ_RESET_ETH, 10);
7538 +#endif
7539 +
7540 +       /* Enable switch macro */
7541 +       ltq_setbits(&switch_regs->mdio.glob_ctrl, MDIO_GLOB_CTRL_SE);
7542 +
7543 +       /* Disable MDIO auto-polling for all ports */
7544 +       ltq_writel(&switch_regs->mdio.mdc_cfg_0, 0);
7545 +
7546 +       /*
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:
7550 +        *
7551 +        *      50 MHz
7552 +        * x = ----------- - 1
7553 +        *      2 * f_MDC
7554 +        */
7555 +       ltq_writel(&switch_regs->mdio.mdc_cfg_1, MDIO_MDC_CFG1_RES |
7556 +               MDIO_MDC_CFG1_MCEN | 5);
7557 +
7558 +       vr9_switch_sync();
7559 +
7560 +       /* Init MAC connected to CPU  */
7561 +       ltq_eth_pmac_init();
7562 +
7563 +       /* Init MACs connected to external MII interfaces */
7564 +       for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++)
7565 +               ltq_eth_gmac_init(i);
7566 +}
7567 +
7568 +static void ltq_eth_port_config(struct ltq_eth_priv *priv,
7569 +                                       const struct ltq_eth_port_config *port)
7570 +{
7571 +       struct ltq_mii_mii_cfg_reg mii_cfg_reg;
7572 +       struct phy_device *phydev;
7573 +       int setup_gpio = 0;
7574 +
7575 +       switch (port->num) {
7576 +       case 0: /* xMII0 */
7577 +       case 1: /* xMII1 */
7578 +               mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
7579 +                                       port->num));
7580 +               mii_cfg_reg.bits.en = port->flags ? 1 : 0;
7581 +
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;
7588 +                       else
7589 +                               /* MII PHY mode, connected to external MAC */
7590 +                               mii_cfg_reg.bits.miimode =
7591 +                                       LTQ_MII_MII_CFG_MIIMODE_MIIP;
7592 +                       setup_gpio = 1;
7593 +                       break;
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;
7599 +                       else
7600 +                               /* RMII PHY mode, connected to external MAC */
7601 +                               mii_cfg_reg.bits.miimode =
7602 +                                       LTQ_MII_MII_CFG_MIIMODE_RMIIP;
7603 +                       setup_gpio = 1;
7604 +                       break;
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;
7609 +                       setup_gpio = 1;
7610 +
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);
7615 +                       break;
7616 +               default:
7617 +                       break;
7618 +               }
7619 +
7620 +               ltq_writel(to_mii_miicfg(switch_regs, port->num),
7621 +                       mii_cfg_reg.val);
7622 +               break;
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:
7629 +                       setup_gpio = 1;
7630 +                       break;
7631 +               default:
7632 +                       break;
7633 +               }
7634 +               break;
7635 +       case 5: /* internal GPHY1 or xMII2 */
7636 +               mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
7637 +                                       port->num));
7638 +               mii_cfg_reg.bits.en = port->flags ? 1 : 0;
7639 +
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;
7645 +                       setup_gpio = 1;
7646 +                       break;
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;
7651 +                       setup_gpio = 1;
7652 +
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);
7657 +                       break;
7658 +               default:
7659 +                       break;
7660 +               }
7661 +
7662 +               ltq_writel(to_mii_miicfg(switch_regs, port->num),
7663 +                       mii_cfg_reg.val);
7664 +               break;
7665 +       default:
7666 +               break;
7667 +       }
7668 +
7669 +       /* Setup GPIOs for MII with external PHYs/MACs */
7670 +       if (setup_gpio) {
7671 +               /* MII/MDIO */
7672 +               gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
7673 +                                       GPIO_DIR_OUT);
7674 +               /* MII/MDC */
7675 +               gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
7676 +                                       GPIO_DIR_OUT);
7677 +       }
7678 +
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,
7682 +                                       port->phy_if);
7683 +               if (phydev)
7684 +                       phy_config(phydev);
7685 +
7686 +               priv->phymap[port->num] = phydev;
7687 +       }
7688 +}
7689 +
7690 +int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
7691 +{
7692 +       struct eth_device *dev;
7693 +       struct mii_dev *bus;
7694 +       struct ltq_eth_priv *priv;
7695 +       struct ltq_dma_device *dma_dev;
7696 +       int i, ret;
7697 +
7698 +       build_check_vr9_registers();
7699 +
7700 +       ltq_dma_init();
7701 +       ltq_eth_hw_init();
7702 +
7703 +       dev = calloc(1, sizeof(struct eth_device));
7704 +       if (!dev)
7705 +               return -1;
7706 +
7707 +       priv = calloc(1, sizeof(struct ltq_eth_priv));
7708 +       if (!priv)
7709 +               return -1;
7710 +
7711 +       bus = mdio_alloc();
7712 +       if (!bus)
7713 +               return -1;
7714 +
7715 +       sprintf(dev->name, LTQ_ETH_DRV_NAME);
7716 +       dev->priv = priv;
7717 +       dev->init = ltq_eth_init;
7718 +       dev->halt = ltq_eth_halt;
7719 +       dev->recv = ltq_eth_recv;
7720 +       dev->send = ltq_eth_send;
7721 +
7722 +       sprintf(bus->name, LTQ_MDIO_DRV_NAME);
7723 +       bus->read = vr9_switch_mdio_read;
7724 +       bus->write = vr9_switch_mdio_write;
7725 +       bus->priv = priv;
7726 +
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;
7739 +
7740 +       priv->bus = bus;
7741 +       priv->dev = dev;
7742 +
7743 +       ret = ltq_dma_register(dma_dev);
7744 +       if (ret)
7745 +               return -1;
7746 +
7747 +       ret = mdio_register(bus);
7748 +       if (ret)
7749 +               return -1;
7750 +
7751 +       ret = eth_register(dev);
7752 +       if (ret)
7753 +               return -1;
7754 +
7755 +       for (i = 0; i < board_config->num_ports; i++)
7756 +               ltq_eth_port_config(priv, &board_config->ports[i]);
7757 +
7758 +       return 0;
7759 +}
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
7775 --- /dev/null
7776 +++ b/drivers/net/phy/lantiq.c
7777 @@ -0,0 +1,238 @@
7778 +/*
7779 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
7780 + *
7781 + * SPDX-License-Identifier:    GPL-2.0+
7782 + */
7783 +
7784 +#define DEBUG
7785 +
7786 +#include <common.h>
7787 +#include <miiphy.h>
7788 +
7789 +#define ADVERTIZE_MPD          (1 << 10)
7790 +
7791 +DECLARE_GLOBAL_DATA_PTR;
7792 +
7793 +/*
7794 + * Update link status.
7795 + *
7796 + * Based on genphy_update_link in phylib.c
7797 + */
7798 +static int ltq_phy_update_link(struct phy_device *phydev)
7799 +{
7800 +       unsigned int mii_reg;
7801 +
7802 +       mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7803 +
7804 +       /*
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
7807 +        */
7808 +       if (phydev->link && mii_reg & BMSR_LSTATUS)
7809 +               return 0;
7810 +
7811 +       if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
7812 +               phydev->link = 0;
7813 +               return 0;
7814 +       } else {
7815 +               /* Read the link a second time to clear the latched state */
7816 +               mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7817 +
7818 +               if (mii_reg & BMSR_LSTATUS)
7819 +                       phydev->link = 1;
7820 +               else
7821 +                       phydev->link = 0;
7822 +       }
7823 +
7824 +       return 0;
7825 +}
7826 +
7827 +/*
7828 + * Update speed and duplex.
7829 + *
7830 + * Based on genphy_parse_link in phylib.c
7831 + */
7832 +static int ltq_phy_parse_link(struct phy_device *phydev)
7833 +{
7834 +       unsigned int mii_reg;
7835 +
7836 +       mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7837 +
7838 +       /* We're using autonegotiation */
7839 +       if (mii_reg & BMSR_ANEGCAPABLE) {
7840 +               u32 lpa = 0;
7841 +               u32 gblpa = 0;
7842 +
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
7847 +                        */
7848 +                       gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
7849 +                       gblpa &= phy_read(phydev,
7850 +                                       MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
7851 +               }
7852 +
7853 +               /* Set the baseline so we only have to set them
7854 +                * if they're different
7855 +                */
7856 +               phydev->speed = SPEED_10;
7857 +               phydev->duplex = DUPLEX_HALF;
7858 +
7859 +               /* Check the gigabit fields */
7860 +               if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
7861 +                       phydev->speed = SPEED_1000;
7862 +
7863 +                       if (gblpa & PHY_1000BTSR_1000FD)
7864 +                               phydev->duplex = DUPLEX_FULL;
7865 +
7866 +                       /* We're done! */
7867 +                       return 0;
7868 +               }
7869 +
7870 +               lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
7871 +               lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
7872 +
7873 +               if (lpa & (LPA_100FULL | LPA_100HALF)) {
7874 +                       phydev->speed = SPEED_100;
7875 +
7876 +                       if (lpa & LPA_100FULL)
7877 +                               phydev->duplex = DUPLEX_FULL;
7878 +
7879 +               } else if (lpa & LPA_10FULL)
7880 +                       phydev->duplex = DUPLEX_FULL;
7881 +       } else {
7882 +               u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
7883 +
7884 +               phydev->speed = SPEED_10;
7885 +               phydev->duplex = DUPLEX_HALF;
7886 +
7887 +               if (bmcr & BMCR_FULLDPLX)
7888 +                       phydev->duplex = DUPLEX_FULL;
7889 +
7890 +               if (bmcr & BMCR_SPEED1000)
7891 +                       phydev->speed = SPEED_1000;
7892 +               else if (bmcr & BMCR_SPEED100)
7893 +                       phydev->speed = SPEED_100;
7894 +       }
7895 +
7896 +       return 0;
7897 +}
7898 +
7899 +static int ltq_phy_config(struct phy_device *phydev)
7900 +{
7901 +       u16 val;
7902 +
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);
7907 +
7908 +       genphy_config_aneg(phydev);
7909 +
7910 +       return 0;
7911 +}
7912 +
7913 +static int ltq_phy_startup(struct phy_device *phydev)
7914 +{
7915 +       /*
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.
7919 +        */
7920 +       ltq_phy_update_link(phydev);
7921 +       ltq_phy_parse_link(phydev);
7922 +
7923 +       debug("ltq_phy: addr %d, link %d, speed %d, duplex %d\n",
7924 +               phydev->addr, phydev->link, phydev->speed, phydev->duplex);
7925 +
7926 +       return 0;
7927 +}
7928 +
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,
7937 +};
7938 +
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,
7947 +};
7948 +
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,
7957 +};
7958 +
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,
7967 +};
7968 +
7969 +static struct phy_driver xrx_genphy_driver = {
7970 +       .name = "Generic PHY at Lantiq XWAY XRX switch",
7971 +       .uid = 0,
7972 +       .mask = 0,
7973 +       .features = 0,
7974 +       .config = genphy_config,
7975 +       .startup = ltq_phy_startup,
7976 +       .shutdown = genphy_shutdown,
7977 +};
7978 +
7979 +int phy_lantiq_init(void)
7980 +{
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;
7986 +
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;
7991 +
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;
7996 +
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;
8001 +
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;
8006 +#endif
8007 +
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);
8013 +
8014 +       return 0;
8015 +}
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
8020 @@ -16,9 +16,10 @@
8021  #include <command.h>
8022  #include <miiphy.h>
8023  #include <phy.h>
8024 -#include <errno.h>
8025  #include <linux/err.h>
8026  
8027 +DECLARE_GLOBAL_DATA_PTR;
8028 +
8029  /* Generic PHY support and helper functions */
8030  
8031  /**
8032 @@ -440,6 +441,16 @@ static LIST_HEAD(phy_drivers);
8033  
8034  int phy_init(void)
8035  {
8036 +#ifdef CONFIG_NEEDS_MANUAL_RELOC
8037 +       INIT_LIST_HEAD(&phy_drivers);
8038 +
8039 +       genphy_driver.config = genphy_config;
8040 +       genphy_driver.startup = genphy_startup;
8041 +       genphy_driver.shutdown = genphy_shutdown;
8042 +
8043 +       genphy_driver.name += gd->reloc_off;
8044 +#endif
8045 +
8046  #ifdef CONFIG_PHY_ATHEROS
8047         phy_atheros_init();
8048  #endif
8049 @@ -455,6 +466,9 @@ int phy_init(void)
8050  #ifdef CONFIG_PHY_ICPLUS
8051         phy_icplus_init();
8052  #endif
8053 +#ifdef CONFIG_PHY_LANTIQ
8054 +       phy_lantiq_init();
8055 +#endif
8056  #ifdef CONFIG_PHY_LXT
8057         phy_lxt_init();
8058  #endif
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);
8080  
8081  /**
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();
8088  
8089         serial_assign(default_serial_console()->name);
8090  }
8091 diff --git a/drivers/serial/serial_lantiq.c b/drivers/serial/serial_lantiq.c
8092 new file mode 100644
8093 index 0000000..07b2f9d
8094 --- /dev/null
8095 +++ b/drivers/serial/serial_lantiq.c
8096 @@ -0,0 +1,263 @@
8097 +/*
8098 + * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
8099 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
8100 + *
8101 + * SPDX-License-Identifier:    GPL-2.0+
8102 + */
8103 +
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>
8110 +
8111 +#if CONFIG_CONSOLE_ASC == 0
8112 +#define LTQ_ASC_BASE                   LTQ_ASC0_BASE
8113 +#else
8114 +#define LTQ_ASC_BASE                   LTQ_ASC1_BASE
8115 +#endif
8116 +
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)
8121 +
8122 +#define LTQ_ASC_MCON_R                 (1 << 15)
8123 +#define LTQ_ASC_MCON_FDE               (1 << 9)
8124 +
8125 +#define LTQ_ASC_WHBSTATE_SETREN                (1 << 1)
8126 +#define LTQ_ASC_WHBSTATE_CLRREN                (1 << 0)
8127 +
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)
8132 +
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)
8137 +
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
8145 +
8146 +#ifdef __BIG_ENDIAN
8147 +#define LTQ_ASC_RBUF_OFFSET            3
8148 +#define LTQ_ASC_TBUF_OFFSET            3
8149 +#else
8150 +#define LTQ_ASC_RBUF_OFFSET            0
8151 +#define LTQ_ASC_TBUF_OFFSET            0
8152 +#endif
8153 +
8154 +struct ltq_asc_regs {
8155 +       u32     clc;
8156 +       u32     pisel;
8157 +       u32     id;
8158 +       u32     rsvd0;
8159 +       u32     mcon;
8160 +       u32     state;
8161 +       u32     whbstate;
8162 +       u32     rsvd1;
8163 +       u8      tbuf[4];
8164 +       u8      rbuf[4];
8165 +       u32     rsvd2[2];
8166 +       u32     abcon;
8167 +       u32     abstat;
8168 +       u32     whbabcon;
8169 +       u32     whbabstat;
8170 +       u32     rxfcon;
8171 +       u32     txfcon;
8172 +       u32     fstat;
8173 +       u32     rsvd3;
8174 +       u32     bg;
8175 +       u32     bg_timer;
8176 +       u32     fdv;
8177 +       u32     pmw;
8178 +       u32     modcon;
8179 +       u32     modstat;
8180 +};
8181 +
8182 +DECLARE_GLOBAL_DATA_PTR;
8183 +
8184 +static struct ltq_asc_regs *ltq_asc_regs =
8185 +       (struct ltq_asc_regs *) CKSEG1ADDR(LTQ_ASC_BASE);
8186 +
8187 +static int ltq_serial_init(void)
8188 +{
8189 +       /* Set clock divider for normal run mode to 1 and enable module */
8190 +       ltq_writel(&ltq_asc_regs->clc, 0x100);
8191 +
8192 +       /* Reset MCON register */
8193 +       ltq_writel(&ltq_asc_regs->mcon, 0);
8194 +
8195 +       /* Use Port A as receiver input */
8196 +       ltq_writel(&ltq_asc_regs->pisel, 0);
8197 +
8198 +       /* Enable and flush RX/TX FIFOs */
8199 +       ltq_setbits(&ltq_asc_regs->rxfcon,
8200 +               LTQ_ASC_RXFCON_RXFITL_RXFFLU | LTQ_ASC_RXFCON_RXFITL_RXFEN);
8201 +       ltq_setbits(&ltq_asc_regs->txfcon,
8202 +               LTQ_ASC_TXFCON_TXFITL_TXFFLU | LTQ_ASC_TXFCON_TXFITL_TXFEN);
8203 +
8204 +       serial_setbrg();
8205 +
8206 +       /* Disable error flags, enable receiver */
8207 +       ltq_writel(&ltq_asc_regs->whbstate, LTQ_ASC_WHBSTATE_SETREN);
8208 +
8209 +       return 0;
8210 +}
8211 +
8212 +/*
8213 + *             fdv       asc_clk
8214 + * Baudrate = ----- * -------------
8215 + *             512    16 * (bg + 1)
8216 + */
8217 +static void ltq_serial_calc_br_fdv(unsigned long asc_clk,
8218 +                                       unsigned long baudrate, u16 *fdv,
8219 +                                       u16 *bg)
8220 +{
8221 +       const u32 c = asc_clk / (16 * 512);
8222 +       u32 diff1, diff2;
8223 +       u32 bg_calc, br_calc, i;
8224 +
8225 +       diff1 = baudrate;
8226 +       for (i = 512; i > 0; i--) {
8227 +               /* Calc bg for current fdv value */
8228 +               bg_calc = i * c / baudrate;
8229 +
8230 +               /* Impossible baudrate */
8231 +               if (!bg_calc)
8232 +                       return;
8233 +
8234 +               /*
8235 +                * Calc diff to target baudrate dependent on current
8236 +                * bg and fdv values
8237 +                */
8238 +               br_calc = i * c / bg_calc;
8239 +               if (br_calc > baudrate)
8240 +                       diff2 = br_calc - baudrate;
8241 +               else
8242 +                       diff2 = baudrate - br_calc;
8243 +
8244 +               /* Perfect values found */
8245 +               if (diff2 == 0) {
8246 +                       *fdv = i;
8247 +                       *bg = bg_calc - 1;
8248 +                       return;
8249 +               }
8250 +
8251 +               if (diff2 < diff1) {
8252 +                       *fdv = i;
8253 +                       *bg = bg_calc - 1;
8254 +                       diff1 = diff2;
8255 +               }
8256 +       }
8257 +}
8258 +
8259 +static void ltq_serial_setbrg(void)
8260 +{
8261 +       unsigned long asc_clk, baudrate;
8262 +       u16 bg = 0;
8263 +       u16 fdv = 511;
8264 +
8265 +       /* ASC clock is same as FPI clock with CLC.RMS = 1 */
8266 +       asc_clk = ltq_get_bus_clock();
8267 +       baudrate = gd->baudrate;
8268 +
8269 +       /* Calculate FDV and BG values */
8270 +       ltq_serial_calc_br_fdv(asc_clk, baudrate, &fdv, &bg);
8271 +
8272 +       /* Disable baudrate generator */
8273 +       ltq_clrbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
8274 +
8275 +       /* Enable fractional divider */
8276 +       ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_FDE);
8277 +
8278 +       /* Set fdv and bg values */
8279 +       ltq_writel(&ltq_asc_regs->fdv, fdv);
8280 +       ltq_writel(&ltq_asc_regs->bg, bg);
8281 +
8282 +       /* Enable baudrate generator */
8283 +       ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
8284 +}
8285 +
8286 +static unsigned int ltq_serial_tx_free(void)
8287 +{
8288 +       unsigned int txfree;
8289 +
8290 +       txfree = (ltq_readl(&ltq_asc_regs->fstat) &
8291 +                       LTQ_ASC_FSTAT_TXFREE_MASK) >>
8292 +                       LTQ_ASC_FSTAT_TXFREE_SHIFT;
8293 +
8294 +       return txfree;
8295 +}
8296 +
8297 +static unsigned int ltq_serial_rx_fill(void)
8298 +{
8299 +       unsigned int rxffl;
8300 +
8301 +       rxffl = ltq_readl(&ltq_asc_regs->fstat) & LTQ_ASC_FSTAT_RXFFL_MASK;
8302 +
8303 +       return rxffl;
8304 +}
8305 +
8306 +static void ltq_serial_tx(const char c)
8307 +{
8308 +       ltq_writeb(&ltq_asc_regs->tbuf[LTQ_ASC_TBUF_OFFSET], c);
8309 +}
8310 +
8311 +static u8 ltq_serial_rx(void)
8312 +{
8313 +       return ltq_readb(&ltq_asc_regs->rbuf[LTQ_ASC_RBUF_OFFSET]);
8314 +}
8315 +
8316 +static void ltq_serial_putc(const char c)
8317 +{
8318 +       if (c == '\n')
8319 +               ltq_serial_putc('\r');
8320 +
8321 +       while (!ltq_serial_tx_free())
8322 +               ;
8323 +
8324 +       ltq_serial_tx(c);
8325 +}
8326 +
8327 +static int ltq_serial_getc(void)
8328 +{
8329 +       while (!ltq_serial_rx_fill())
8330 +               ;
8331 +
8332 +       return ltq_serial_rx();
8333 +}
8334 +
8335 +static int ltq_serial_tstc(void)
8336 +{
8337 +       return (0 != ltq_serial_rx_fill());
8338 +}
8339 +
8340 +static struct serial_device ltq_serial_drv = {
8341 +       .name   = "ltq_serial",
8342 +       .start  = ltq_serial_init,
8343 +       .stop   = NULL,
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,
8349 +};
8350 +
8351 +void ltq_serial_initialize(void)
8352 +{
8353 +       serial_register(&ltq_serial_drv);
8354 +}
8355 +
8356 +__weak struct serial_device *default_serial_console(void)
8357 +{
8358 +       return &ltq_serial_drv;
8359 +}
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
8375 --- /dev/null
8376 +++ b/drivers/spi/lantiq_spi.c
8377 @@ -0,0 +1,666 @@
8378 +/*
8379 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
8380 + *
8381 + * SPDX-License-Identifier:    GPL-2.0+
8382 + */
8383 +
8384 +#include <common.h>
8385 +#include <spi.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>
8393 +
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
8398 +
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)
8403 +
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
8418 +
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)
8422 +
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
8428 +
8429 +#define LTQ_SPI_TXFCON_TXFLU           (1 << 1)
8430 +#define LTQ_SPI_TXFCON_TXFEN           1
8431 +
8432 +#define LTQ_SPI_RXFCON_RXFLU           (1 << 1)
8433 +#define LTQ_SPI_RXFCON_RXFEN           1
8434 +
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)
8438 +
8439 +#define LTQ_SPI_RXREQ_RXCNT_MASK       0xFFFF
8440 +#define LTQ_SPI_RXCNT_TODO_MASK                0xFFFF
8441 +
8442 +#define LTQ_SPI_GPIO_DIN               16
8443 +#define LTQ_SPI_GPIO_DOUT              17
8444 +#define LTQ_SPI_GPIO_CLK               18
8445 +
8446 +struct ltq_spi_regs {
8447 +       __be32  clc;            /* Clock control */
8448 +       __be32  pisel;          /* Port input select */
8449 +       __be32  id;             /* Identification */
8450 +       __be32  rsvd0;
8451 +       __be32  con;            /* Control */
8452 +       __be32  stat;           /* Status */
8453 +       __be32  whbstate;       /* Write HW modified state */
8454 +       __be32  rsvd1;
8455 +       __be32  tb;             /* Transmit buffer */
8456 +       __be32  rb;             /* Receive buffer */
8457 +       __be32  rsvd2[2];
8458 +       __be32  rxfcon;         /* Recevie FIFO control */
8459 +       __be32  txfcon;         /* Transmit FIFO control */
8460 +       __be32  fstat;          /* FIFO status */
8461 +       __be32  rsvd3;
8462 +       __be32  brt;            /* Baudrate timer */
8463 +       __be32  brstat;         /* Baudrate timer status */
8464 +       __be32  rsvd4[6];
8465 +       __be32  sfcon;          /* Serial frame control */
8466 +       __be32  sfstat;         /* Serial frame status */
8467 +       __be32  rsvd5[2];
8468 +       __be32  gpocon;         /* General purpose output control */
8469 +       __be32  gpostat;        /* General purpose output status */
8470 +       __be32  fgpo;           /* Force general purpose output */
8471 +       __be32  rsvd6;
8472 +       __be32  rxreq;          /* Receive request */
8473 +       __be32  rxcnt;          /* Receive count */
8474 +       __be32  rsvd7[25];
8475 +       __be32  dmacon;         /* DMA control */
8476 +       __be32  rsvd8;
8477 +       __be32  irnen;          /* Interrupt node enable */
8478 +       __be32  irnicr;         /* Interrupt node interrupt capture */
8479 +       __be32  irncr;          /* Interrupt node control */
8480 +};
8481 +
8482 +struct ltq_spi_drv_data {
8483 +       struct ltq_spi_regs __iomem *regs;
8484 +
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;
8493 +       const u8 *tx;
8494 +       u8 *rx;
8495 +       int status;
8496 +};
8497 +
8498 +static struct ltq_spi_drv_data *to_ltq_spi_slave(struct spi_slave *slave)
8499 +{
8500 +       return container_of(slave, struct ltq_spi_drv_data, slave);
8501 +}
8502 +
8503 +#ifdef CONFIG_SPL_BUILD
8504 +/*
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.
8508 + */
8509 +static struct ltq_spi_drv_data ltq_spi_slave;
8510 +
8511 +static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
8512 +                                                       unsigned int cs)
8513 +{
8514 +       ltq_spi_slave.slave.bus = bus;
8515 +       ltq_spi_slave.slave.cs = cs;
8516 +
8517 +       return &ltq_spi_slave;
8518 +}
8519 +
8520 +static void ltq_spi_slave_free(struct spi_slave *slave)
8521 +{
8522 +}
8523 +#else
8524 +static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
8525 +                                                       unsigned int cs)
8526 +{
8527 +       return spi_alloc_slave(struct ltq_spi_drv_data, bus, cs);
8528 +}
8529 +
8530 +static void ltq_spi_slave_free(struct spi_slave *slave)
8531 +{
8532 +       struct ltq_spi_drv_data *drv;
8533 +
8534 +       if (slave) {
8535 +               drv = to_ltq_spi_slave(slave);
8536 +               free(drv);
8537 +       }
8538 +}
8539 +#endif
8540 +
8541 +static unsigned int tx_fifo_size(struct ltq_spi_drv_data *drv)
8542 +{
8543 +       u32 id = ltq_readl(&drv->regs->id);
8544 +
8545 +       return (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT;
8546 +}
8547 +
8548 +static unsigned int rx_fifo_size(struct ltq_spi_drv_data *drv)
8549 +{
8550 +       u32 id = ltq_readl(&drv->regs->id);
8551 +
8552 +       return (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT;
8553 +}
8554 +
8555 +static unsigned int tx_fifo_level(struct ltq_spi_drv_data *drv)
8556 +{
8557 +       u32 fstat = ltq_readl(&drv->regs->fstat);
8558 +
8559 +       return (fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >> LTQ_SPI_FSTAT_TXFFL_SHIFT;
8560 +}
8561 +
8562 +static unsigned int rx_fifo_level(struct ltq_spi_drv_data *drv)
8563 +{
8564 +       u32 fstat = ltq_readl(&drv->regs->fstat);
8565 +
8566 +       return fstat & LTQ_SPI_FSTAT_RXFFL_MASK;
8567 +}
8568 +
8569 +static unsigned int tx_fifo_free(struct ltq_spi_drv_data *drv)
8570 +{
8571 +       return tx_fifo_size(drv) - tx_fifo_level(drv);
8572 +}
8573 +
8574 +static void hw_power_on(struct ltq_spi_drv_data *drv)
8575 +{
8576 +       u32 clc;
8577 +
8578 +       /* Power-up mdule */
8579 +       ltq_pm_enable(LTQ_PM_SPI);
8580 +
8581 +       /*
8582 +        * Set clock divider for run mode to 1 to
8583 +        * run at same frequency as FPI bus
8584 +        */
8585 +       clc = (1 << LTQ_SPI_CLC_RMC_SHIFT);
8586 +       ltq_writel(&drv->regs->clc, clc);
8587 +}
8588 +
8589 +static void hw_reset_fifos(struct ltq_spi_drv_data *drv)
8590 +{
8591 +       u32 val;
8592 +
8593 +       val = LTQ_SPI_TXFCON_TXFEN | LTQ_SPI_TXFCON_TXFLU;
8594 +       ltq_writel(&drv->regs->txfcon, val);
8595 +
8596 +       val = LTQ_SPI_RXFCON_RXFEN | LTQ_SPI_RXFCON_RXFLU;
8597 +       ltq_writel(&drv->regs->rxfcon, val);
8598 +}
8599 +
8600 +static int hw_is_busy(struct ltq_spi_drv_data *drv)
8601 +{
8602 +       u32 stat = ltq_readl(&drv->regs->stat);
8603 +
8604 +       return stat & LTQ_SPI_STAT_BSY;
8605 +}
8606 +
8607 +static void hw_enter_config_mode(struct ltq_spi_drv_data *drv)
8608 +{
8609 +       ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_CLREN);
8610 +}
8611 +
8612 +static void hw_enter_active_mode(struct ltq_spi_drv_data *drv)
8613 +{
8614 +       ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETEN);
8615 +}
8616 +
8617 +static void hw_setup_speed_hz(struct ltq_spi_drv_data *drv,
8618 +                               unsigned int max_speed_hz)
8619 +{
8620 +       unsigned int spi_hz, speed_hz, brt;
8621 +
8622 +       /*
8623 +        * SPI module clock is derived from FPI bus clock dependent on
8624 +        * divider value in CLC.RMS which is always set to 1.
8625 +        *
8626 +        *                 f_SPI
8627 +        * baudrate = --------------
8628 +        *             2 * (BR + 1)
8629 +        */
8630 +       spi_hz = ltq_get_bus_clock() / 2;
8631 +
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)
8636 +                       break;
8637 +       }
8638 +
8639 +       ltq_writel(&drv->regs->brt, brt);
8640 +}
8641 +
8642 +static void hw_setup_bits_per_word(struct ltq_spi_drv_data *drv,
8643 +                                       unsigned int bits_per_word)
8644 +{
8645 +       u32 bm;
8646 +
8647 +       /* CON.BM value = bits_per_word - 1 */
8648 +       bm = (bits_per_word - 1) << LTQ_SPI_CON_BM_SHIFT;
8649 +
8650 +       ltq_clrsetbits(&drv->regs->con, LTQ_SPI_CON_BM_MASK, bm);
8651 +}
8652 +
8653 +static void hw_setup_clock_mode(struct ltq_spi_drv_data *drv, unsigned int mode)
8654 +{
8655 +       u32 con_set = 0, con_clr = 0;
8656 +
8657 +       /*
8658 +        * SPI mode mapping in CON register:
8659 +        * Mode CPOL CPHA CON.PO CON.PH
8660 +        *  0    0    0      0      1
8661 +        *  1    0    1      0      0
8662 +        *  2    1    0      1      1
8663 +        *  3    1    1      1      0
8664 +        */
8665 +       if (mode & SPI_CPHA)
8666 +               con_clr |= LTQ_SPI_CON_PH;
8667 +       else
8668 +               con_set |= LTQ_SPI_CON_PH;
8669 +
8670 +       if (mode & SPI_CPOL)
8671 +               con_set |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
8672 +       else
8673 +               con_clr |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
8674 +
8675 +       /* Set heading control */
8676 +       if (mode & SPI_LSB_FIRST)
8677 +               con_clr |= LTQ_SPI_CON_HB;
8678 +       else
8679 +               con_set |= LTQ_SPI_CON_HB;
8680 +
8681 +       /* Set loopback mode */
8682 +       if (mode & SPI_LOOP)
8683 +               con_set |= LTQ_SPI_CON_LB;
8684 +       else
8685 +               con_clr |= LTQ_SPI_CON_LB;
8686 +
8687 +       ltq_clrsetbits(&drv->regs->con, con_clr, con_set);
8688 +}
8689 +
8690 +static void hw_set_rxtx(struct ltq_spi_drv_data *drv)
8691 +{
8692 +       u32 con;
8693 +
8694 +       /* Configure transmitter and receiver */
8695 +       con = ltq_readl(&drv->regs->con);
8696 +       if (drv->tx)
8697 +               con &= ~LTQ_SPI_CON_TXOFF;
8698 +       else
8699 +               con |= LTQ_SPI_CON_TXOFF;
8700 +
8701 +       if (drv->rx)
8702 +               con &= ~LTQ_SPI_CON_RXOFF;
8703 +       else
8704 +               con |= LTQ_SPI_CON_RXOFF;
8705 +
8706 +       ltq_writel(&drv->regs->con, con);
8707 +}
8708 +
8709 +static void hw_init(struct ltq_spi_drv_data *drv)
8710 +{
8711 +       hw_power_on(drv);
8712 +
8713 +       /* Put controller into config mode */
8714 +       hw_enter_config_mode(drv);
8715 +
8716 +       /* Disable all interrupts */
8717 +       ltq_writel(&drv->regs->irnen, 0);
8718 +
8719 +       /* Clear error flags */
8720 +       ltq_clrsetbits(&drv->regs->whbstate, 0, LTQ_SPI_WHBSTATE_CLR_ERRORS);
8721 +
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);
8726 +
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);
8732 +
8733 +       /* Enable master mode and clear error flags */
8734 +       ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETMS |
8735 +                       LTQ_SPI_WHBSTATE_CLR_ERRORS);
8736 +
8737 +       /* Reset GPIO/CS registers */
8738 +       ltq_writel(&drv->regs->gpocon, 0);
8739 +       ltq_writel(&drv->regs->fgpo, 0xFF00);
8740 +
8741 +       /* Enable and flush FIFOs */
8742 +       hw_reset_fifos(drv);
8743 +
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);
8750 +}
8751 +
8752 +static void tx_fifo_write(struct ltq_spi_drv_data *drv)
8753 +{
8754 +       const u8 *tx8;
8755 +       const u16 *tx16;
8756 +       const u32 *tx32;
8757 +       u32 data;
8758 +       unsigned int tx_free = tx_fifo_free(drv);
8759 +
8760 +       while (drv->tx_todo && tx_free) {
8761 +               switch (drv->bits_per_word) {
8762 +               case 8:
8763 +                       tx8 = drv->tx;
8764 +                       data = *tx8;
8765 +                       drv->tx_todo--;
8766 +                       drv->tx++;
8767 +                       break;
8768 +               case 16:
8769 +                       tx16 = (u16 *) drv->tx;
8770 +                       data = *tx16;
8771 +                       drv->tx_todo -= 2;
8772 +                       drv->tx += 2;
8773 +                       break;
8774 +               case 32:
8775 +                       tx32 = (u32 *) drv->tx;
8776 +                       data = *tx32;
8777 +                       drv->tx_todo -= 4;
8778 +                       drv->tx += 4;
8779 +                       break;
8780 +               default:
8781 +                       return;
8782 +               }
8783 +
8784 +               ltq_writel(&drv->regs->tb, data);
8785 +               tx_free--;
8786 +       }
8787 +}
8788 +
8789 +static void rx_fifo_read_full_duplex(struct ltq_spi_drv_data *drv)
8790 +{
8791 +       u8 *rx8;
8792 +       u16 *rx16;
8793 +       u32 *rx32;
8794 +       u32 data;
8795 +       unsigned int rx_fill = rx_fifo_level(drv);
8796 +
8797 +       while (rx_fill) {
8798 +               data = ltq_readl(&drv->regs->rb);
8799 +
8800 +               switch (drv->bits_per_word) {
8801 +               case 8:
8802 +                       rx8 = drv->rx;
8803 +                       *rx8 = data;
8804 +                       drv->rx_todo--;
8805 +                       drv->rx++;
8806 +                       break;
8807 +               case 16:
8808 +                       rx16 = (u16 *) drv->rx;
8809 +                       *rx16 = data;
8810 +                       drv->rx_todo -= 2;
8811 +                       drv->rx += 2;
8812 +                       break;
8813 +               case 32:
8814 +                       rx32 = (u32 *) drv->rx;
8815 +                       *rx32 = data;
8816 +                       drv->rx_todo -= 4;
8817 +                       drv->rx += 4;
8818 +                       break;
8819 +               default:
8820 +                       return;
8821 +               }
8822 +
8823 +               rx_fill--;
8824 +       }
8825 +}
8826 +
8827 +static void rx_fifo_read_half_duplex(struct ltq_spi_drv_data *drv)
8828 +{
8829 +       u32 data, *rx32;
8830 +       u8 *rx8;
8831 +       unsigned int rxbv, shift;
8832 +       unsigned int rx_fill = rx_fifo_level(drv);
8833 +
8834 +       /*
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.
8840 +        */
8841 +       while (rx_fill) {
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);
8847 +
8848 +                       shift = (rxbv - 1) * 8;
8849 +                       rx8 = drv->rx;
8850 +
8851 +                       while (rxbv) {
8852 +                               *rx8++ = (data >> shift) & 0xFF;
8853 +                               rxbv--;
8854 +                               shift -= 8;
8855 +                               drv->rx_todo--;
8856 +                               drv->rx++;
8857 +
8858 +                               if (drv->rx_req)
8859 +                                       drv->rx_req --;
8860 +                       }
8861 +               } else {
8862 +                       data = ltq_readl(&drv->regs->rb);
8863 +                       rx32 = (u32 *) drv->rx;
8864 +
8865 +                       *rx32++ = data;
8866 +                       drv->rx_todo -= 4;
8867 +                       drv->rx += 4;
8868 +
8869 +                       if (drv->rx_req >= 4)
8870 +                               drv->rx_req -= 4;
8871 +               }
8872 +               rx_fill--;
8873 +       }
8874 +}
8875 +
8876 +static void rx_request(struct ltq_spi_drv_data *drv)
8877 +{
8878 +       unsigned int rxreq, rxreq_max;
8879 +
8880 +       if (drv->rx_req)
8881 +               return;
8882 +
8883 +       /*
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.
8887 +        */
8888 +       rxreq = drv->rx_todo;
8889 +       rxreq_max = rx_fifo_size(drv) * 4;
8890 +       if (rxreq > rxreq_max)
8891 +               rxreq = rxreq_max;
8892 +
8893 +       drv->rx_req = rxreq;
8894 +       ltq_writel(&drv->regs->rxreq, rxreq);
8895 +}
8896 +
8897 +void spi_init(void)
8898 +{
8899 +}
8900 +
8901 +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
8902 +                                 unsigned int max_hz, unsigned int mode)
8903 +{
8904 +       struct ltq_spi_drv_data *drv;
8905 +
8906 +       if (!spi_cs_is_valid(bus, cs))
8907 +               return NULL;
8908 +
8909 +       drv = ltq_spi_slave_alloc(bus, cs);
8910 +       if (!drv)
8911 +               return NULL;
8912 +
8913 +       drv->regs = (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE);
8914 +
8915 +       hw_init(drv);
8916 +
8917 +       drv->max_hz = max_hz;
8918 +       drv->mode = mode;
8919 +
8920 +       return &drv->slave;
8921 +}
8922 +
8923 +void spi_free_slave(struct spi_slave *slave)
8924 +{
8925 +       ltq_spi_slave_free(slave);
8926 +}
8927 +
8928 +static int ltq_spi_wait_ready(struct ltq_spi_drv_data *drv)
8929 +{
8930 +       const unsigned long timeout = 20000;
8931 +       unsigned long timebase;
8932 +
8933 +       timebase = get_timer(0);
8934 +
8935 +       do {
8936 +               WATCHDOG_RESET();
8937 +
8938 +               if (!hw_is_busy(drv))
8939 +                       return 0;
8940 +       } while (get_timer(timebase) < timeout);
8941 +
8942 +       return 1;
8943 +}
8944 +
8945 +int spi_claim_bus(struct spi_slave *slave)
8946 +{
8947 +       struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8948 +       int ret;
8949 +
8950 +       ret = ltq_spi_wait_ready(drv);
8951 +       if (ret) {
8952 +               debug("cannot claim bus\n");
8953 +               return ret;
8954 +       }
8955 +
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);
8961 +
8962 +       return 0;
8963 +}
8964 +
8965 +void spi_release_bus(struct spi_slave *slave)
8966 +{
8967 +       struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8968 +
8969 +       hw_enter_config_mode(drv);
8970 +}
8971 +
8972 +int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
8973 +               const void *dout, void *din, unsigned long flags)
8974 +{
8975 +
8976 +       struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8977 +       int ret = 0;
8978 +
8979 +       if (bitlen % 8)
8980 +               return 1;
8981 +
8982 +       if (!bitlen) {
8983 +               ret = 0;
8984 +               goto done;
8985 +       }
8986 +
8987 +       if (flags & SPI_XFER_BEGIN)
8988 +               spi_cs_activate(slave);
8989 +
8990 +       drv->tx = dout;
8991 +       drv->tx_todo = 0;
8992 +       drv->rx = din;
8993 +       drv->rx_todo = 0;
8994 +       hw_set_rxtx(drv);
8995 +
8996 +       if (drv->tx) {
8997 +               drv->tx_todo = bitlen / 8;
8998 +
8999 +               tx_fifo_write(drv);
9000 +       }
9001 +
9002 +       if (drv->rx) {
9003 +               drv->rx_todo = bitlen / 8;
9004 +
9005 +               if (!drv->tx)
9006 +                       rx_request(drv);
9007 +       }
9008 +
9009 +       for (;;) {
9010 +               if (drv->tx) {
9011 +                       if (drv->rx && drv->rx_todo)
9012 +                               rx_fifo_read_full_duplex(drv);
9013 +
9014 +                       if (drv->tx_todo)
9015 +                               tx_fifo_write(drv);
9016 +                       else
9017 +                               goto done;
9018 +               } else if (drv->rx) {
9019 +                       if (drv->rx_todo) {
9020 +                               rx_fifo_read_half_duplex(drv);
9021 +
9022 +                               if (drv->rx_todo)
9023 +                                       rx_request(drv);
9024 +                               else
9025 +                                       goto done;
9026 +                       } else {
9027 +                               goto done;
9028 +                       }
9029 +               }
9030 +       }
9031 +
9032 +done:
9033 +       ret = ltq_spi_wait_ready(drv);
9034 +
9035 +       drv->rx = NULL;
9036 +       drv->tx = NULL;
9037 +       hw_set_rxtx(drv);
9038 +
9039 +       if (flags & SPI_XFER_END)
9040 +               spi_cs_deactivate(slave);
9041 +
9042 +       return ret;
9043 +}
9044 diff --git a/include/configs/easy50712.h b/include/configs/easy50712.h
9045 new file mode 100644
9046 index 0000000..6d7988c
9047 --- /dev/null
9048 +++ b/include/configs/easy50712.h
9049 @@ -0,0 +1,79 @@
9050 +/*
9051 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
9052 + *
9053 + * SPDX-License-Identifier:    GPL-2.0+
9054 + */
9055 +
9056 +#ifndef __CONFIG_H
9057 +#define __CONFIG_H
9058 +
9059 +#define CONFIG_MACH_TYPE       "EASY50712"
9060 +#define CONFIG_IDENT_STRING    " "CONFIG_MACH_TYPE
9061 +#define CONFIG_BOARD_NAME      "Lantiq EASY50712 Danube Reference Board"
9062 +
9063 +/* Configure SoC */
9064 +#define CONFIG_LTQ_SUPPORT_UART                /* Enable ASC and UART */
9065 +
9066 +#define CONFIG_LTQ_SUPPORT_ETHERNET    /* Enable ethernet */
9067 +
9068 +#define CONFIG_LTQ_SUPPORT_NOR_FLASH   /* Have a parallel NOR flash */
9069 +
9070 +#define CONFIG_LTQ_SUPPORT_SPI_FLASH
9071 +#define CONFIG_SPI_FLASH_ATMEL         /* Have an AT45DB321D serial flash */
9072 +
9073 +#define CONFIG_LTQ_SUPPORT_NAND_FLASH
9074 +
9075 +#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH       /* Build NOR flash SPL */
9076 +
9077 +#define CONFIG_LTQ_SPL_COMP_LZO
9078 +#define CONFIG_LTQ_SPL_CONSOLE
9079 +
9080 +/* Switch devices */
9081 +#define CONFIG_SWITCH_MULTI
9082 +#define CONFIG_SWITCH_ADM6996I
9083 +
9084 +/* Environment */
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
9089 +
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)
9100 +#else
9101 +#define CONFIG_ENV_IS_NOWHERE
9102 +#endif
9103 +
9104 +#define CONFIG_ENV_SIZE                        (8 * 1024)
9105 +
9106 +#define CONFIG_LOADADDR                        CONFIG_SYS_LOAD_ADDR
9107 +
9108 +/* Console */
9109 +#define CONFIG_LTQ_ADVANCED_CONSOLE
9110 +#define CONFIG_BAUDRATE                        115200
9111 +#define CONFIG_CONSOLE_ASC             1
9112 +#define CONFIG_CONSOLE_DEV             "ttyLTQ1"
9113 +
9114 +/* Commands */
9115 +#define CONFIG_CMD_PING
9116 +
9117 +/* Pull in default board configs for Lantiq XWAY Danube */
9118 +#include <asm/lantiq/config.h>
9119 +#include <asm/arch/config.h>
9120 +
9121 +#define CONFIG_ENV_UPDATE_UBOOT_NOR                                    \
9122 +       "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
9123 +
9124 +#define CONFIG_EXTRA_ENV_SETTINGS      \
9125 +       CONFIG_ENV_LANTIQ_DEFAULTS      \
9126 +       CONFIG_ENV_UPDATE_UBOOT_NOR
9127 +
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
9132 --- /dev/null
9133 +++ b/include/configs/easy80920.h
9134 @@ -0,0 +1,92 @@
9135 +/*
9136 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
9137 + *
9138 + * SPDX-License-Identifier:    GPL-2.0+
9139 + */
9140 +
9141 +#ifndef __CONFIG_H
9142 +#define __CONFIG_H
9143 +
9144 +#define CONFIG_MACH_TYPE       "EASY80920"
9145 +#define CONFIG_IDENT_STRING    " "CONFIG_MACH_TYPE
9146 +#define CONFIG_BOARD_NAME      "Lantiq EASY80920 VRX200 Family Board"
9147 +
9148 +/* Configure SoC */
9149 +#define CONFIG_LTQ_SUPPORT_UART                /* Enable ASC and UART */
9150 +
9151 +#define CONFIG_LTQ_SUPPORT_ETHERNET    /* Enable ethernet */
9152 +
9153 +#define CONFIG_LTQ_SUPPORT_NOR_FLASH   /* Have a parallel NOR flash */
9154 +
9155 +#define CONFIG_LTQ_SUPPORT_SPI_FLASH
9156 +#define CONFIG_SPI_FLASH_MACRONIX      /* Have a MX29LV620 serial flash */
9157 +
9158 +#define CONFIG_LTQ_SUPPORT_NAND_FLASH
9159 +
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
9165 +
9166 +#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH       /* Build NOR flash SPL */
9167 +
9168 +#define CONFIG_LTQ_SPL_COMP_LZO
9169 +#define CONFIG_LTQ_SPL_CONSOLE
9170 +
9171 +#define CONFIG_SYS_DRAM_PROBE
9172 +
9173 +/* Environment */
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
9178 +
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)
9194 +#else
9195 +#define CONFIG_ENV_IS_NOWHERE
9196 +#endif
9197 +
9198 +#define CONFIG_ENV_SIZE                        (8 * 1024)
9199 +
9200 +#define CONFIG_LOADADDR                        CONFIG_SYS_LOAD_ADDR
9201 +
9202 +/* Console */
9203 +#define CONFIG_LTQ_ADVANCED_CONSOLE
9204 +#define CONFIG_BAUDRATE                        115200
9205 +#define CONFIG_CONSOLE_ASC             1
9206 +#define CONFIG_CONSOLE_DEV             "ttyLTQ1"
9207 +
9208 +/* Commands */
9209 +#define CONFIG_CMD_PING
9210 +
9211 +/* Pull in default board configs for Lantiq XWAY VRX200 */
9212 +#include <asm/lantiq/config.h>
9213 +#include <asm/arch/config.h>
9214 +
9215 +#define CONFIG_ENV_UPDATE_UBOOT_NOR                                    \
9216 +       "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
9217 +
9218 +#define CONFIG_ENV_UPDATE_UBOOT_SF                                     \
9219 +       "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0"
9220 +
9221 +#define CONFIG_EXTRA_ENV_SETTINGS      \
9222 +       CONFIG_ENV_LANTIQ_DEFAULTS      \
9223 +       CONFIG_ENV_UPDATE_UBOOT_NOR     \
9224 +       CONFIG_ENV_UPDATE_UBOOT_SF
9225 +
9226 +#endif /* __CONFIG_H */
9227 diff --git a/include/phy.h b/include/phy.h
9228 index f0f522a..818bd7f 100644
9229 --- a/include/phy.h
9230 +++ b/include/phy.h
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
9241 --- a/spl/Makefile
9242 +++ b/spl/Makefile
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
9249  
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
9256 @@ -2,6 +2,7 @@
9257  /envcrc
9258  /gen_eth_addr
9259  /img2srec
9260 +/ltq-boot-image
9261  /kwboot
9262  /mkenvimage
9263  /mkimage
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
9283  
9284 @@ -195,6 +197,10 @@ $(obj)img2srec$(SFX):      $(obj)img2srec.o
9285         $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
9286         $(HOSTSTRIP) $@
9287  
9288 +$(obj)ltq-boot-image$(SFX):    $(obj)ltq-boot-image.o
9289 +       $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
9290 +       $(HOSTSTRIP) $@
9291 +
9292  $(obj)xway-swap-bytes$(SFX):   $(obj)xway-swap-bytes.o
9293         $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
9294         $(HOSTSTRIP) $@
9295 diff --git a/tools/ltq-boot-image.c b/tools/ltq-boot-image.c
9296 new file mode 100644
9297 index 0000000..75a188c
9298 --- /dev/null
9299 +++ b/tools/ltq-boot-image.c
9300 @@ -0,0 +1,315 @@
9301 +/*
9302 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
9303 + *
9304 + * SPDX-License-Identifier:    GPL-2.0+
9305 + */
9306 +
9307 +#include <stdio.h>
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>
9314 +
9315 +enum image_types {
9316 +       IMAGE_NONE,
9317 +       IMAGE_SFSPL
9318 +};
9319 +
9320 +/* Lantiq non-volatile bootstrap command IDs */
9321 +enum nvb_cmd_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
9329 +};
9330 +
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)
9341 +};
9342 +
9343 +struct args {
9344 +       enum image_types type;
9345 +       __u32           entry_addr;
9346 +       const char      *uboot_bin;
9347 +       const char      *spl_bin;
9348 +       const char      *out_bin;
9349 +};
9350 +
9351 +static void usage_msg(const char *name)
9352 +{
9353 +       fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n",
9354 +               name);
9355 +       fprintf(stderr, " Image types:\n"
9356 +                       "  sfspl  - SPL + [compressed] U-Boot for SPI flash\n");
9357 +}
9358 +
9359 +static enum image_types parse_image_type(const char *type)
9360 +{
9361 +       if (!type)
9362 +               return IMAGE_NONE;
9363 +
9364 +       if (!strncmp(type, "sfspl", 6))
9365 +               return IMAGE_SFSPL;
9366 +
9367 +       return IMAGE_NONE;
9368 +}
9369 +
9370 +static int parse_args(int argc, char *argv[], struct args *arg)
9371 +{
9372 +       int opt;
9373 +
9374 +       memset(arg, 0, sizeof(*arg));
9375 +
9376 +       while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) {
9377 +               switch (opt) {
9378 +               case 'h':
9379 +                       usage_msg(argv[0]);
9380 +                       return 1;
9381 +               case 't':
9382 +                       arg->type = parse_image_type(optarg);
9383 +                       break;
9384 +               case 'e':
9385 +                       arg->entry_addr = strtoul(optarg, NULL, 16);
9386 +                       break;
9387 +               case 'u':
9388 +                       arg->uboot_bin = optarg;
9389 +                       break;
9390 +               case 's':
9391 +                       arg->spl_bin = optarg;
9392 +                       break;
9393 +               case 'o':
9394 +                       arg->out_bin = optarg;
9395 +                       break;
9396 +               default:
9397 +                       fprintf(stderr, "Invalid option -%c\n", opt);
9398 +                       goto parse_error;
9399 +               }
9400 +       }
9401 +
9402 +       if (arg->type == IMAGE_NONE) {
9403 +               fprintf(stderr, "Invalid image type\n");
9404 +               goto parse_error;
9405 +       }
9406 +
9407 +       if (!arg->uboot_bin) {
9408 +               fprintf(stderr, "Missing U-Boot binary\n");
9409 +               goto parse_error;
9410 +       }
9411 +
9412 +       if (!arg->out_bin) {
9413 +               fprintf(stderr, "Missing output binary\n");
9414 +               goto parse_error;
9415 +       }
9416 +
9417 +       if (arg->type == IMAGE_SFSPL && !arg->spl_bin) {
9418 +               fprintf(stderr, "Missing SPL binary\n");
9419 +               goto parse_error;
9420 +       }
9421 +
9422 +       return 0;
9423 +
9424 +parse_error:
9425 +       usage_msg(argv[0]);
9426 +       return -1;
9427 +}
9428 +
9429 +static __u32 build_nvb_command(unsigned cmdid, unsigned cmdflags)
9430 +{
9431 +       __u32 cmd;
9432 +       __u16 tag;
9433 +
9434 +       tag = (cmdid << 8) | cmdflags;
9435 +       cmd = (tag << 16) | (0xFFFF - tag);
9436 +
9437 +       return cpu_to_be32(cmd);
9438 +}
9439 +
9440 +static int write_header(int fd, const void *hdr, size_t size)
9441 +{
9442 +       ssize_t n;
9443 +
9444 +       n = write(fd, hdr, size);
9445 +       if (n != size) {
9446 +               fprintf(stderr, "Cannot write header: %s\n",
9447 +                       strerror(errno));
9448 +               return -1;
9449 +       }
9450 +
9451 +       return 0;
9452 +}
9453 +
9454 +static int write_nvb_dwnld_header(int fd, size_t size, __u32 addr)
9455 +{
9456 +       __u32 hdr[3];
9457 +
9458 +       hdr[0] = build_nvb_command(NVB_CMD_DWNLD, NVB_FLAG_START |
9459 +                                       NVB_FLAG_SDBG);
9460 +       hdr[1] = cpu_to_be32(size + 4);
9461 +       hdr[2] = cpu_to_be32(addr);
9462 +
9463 +       return write_header(fd, hdr, sizeof(hdr));
9464 +}
9465 +
9466 +static int write_nvb_start_header(int fd, __u32 addr)
9467 +{
9468 +       __u32 hdr[3];
9469 +
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);
9473 +
9474 +       return write_header(fd, hdr, sizeof(hdr));
9475 +}
9476 +
9477 +static int open_input_bin(const char *name, void **ptr, size_t *size)
9478 +{
9479 +       struct stat sbuf;
9480 +       int ret, fd;
9481 +
9482 +       fd = open(name, O_RDONLY | O_BINARY);
9483 +       if (0 > fd) {
9484 +               fprintf(stderr, "Cannot open %s: %s\n", name,
9485 +                       strerror(errno));
9486 +               return -1;
9487 +       }
9488 +
9489 +       ret = fstat(fd, &sbuf);
9490 +       if (0 > ret) {
9491 +               fprintf(stderr, "Cannot fstat %s: %s\n", name,
9492 +                       strerror(errno));
9493 +               return -1;
9494 +       }
9495 +
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,
9499 +                       strerror(errno));
9500 +               return -1;
9501 +       }
9502 +
9503 +       *size = sbuf.st_size;
9504 +
9505 +       return fd;
9506 +}
9507 +
9508 +static void close_input_bin(int fd, void *ptr, size_t size)
9509 +{
9510 +       munmap(ptr, size);
9511 +       close(fd);
9512 +}
9513 +
9514 +static int copy_bin(int fd, void *ptr, size_t size)
9515 +{
9516 +       ssize_t n;
9517 +
9518 +       n = write(fd, ptr, size);
9519 +       if (n != size) {
9520 +               fprintf(stderr, "Cannot copy binary: %s\n", strerror(errno));
9521 +               return -1;
9522 +       }
9523 +
9524 +       return 0;
9525 +}
9526 +
9527 +static int open_output_bin(const char *name)
9528 +{
9529 +       int fd;
9530 +
9531 +       fd = open(name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666);
9532 +       if (0 > fd) {
9533 +               fprintf(stderr, "Cannot open %s: %s\n", name,
9534 +                       strerror(errno));
9535 +               return -1;
9536 +       }
9537 +
9538 +       return fd;
9539 +}
9540 +
9541 +static int create_sfspl(const struct args *arg)
9542 +{
9543 +       int out_fd, uboot_fd, spl_fd, ret;
9544 +       void *uboot_ptr, *spl_ptr;
9545 +       size_t uboot_size, spl_size;
9546 +
9547 +       out_fd = open_output_bin(arg->out_bin);
9548 +       if (0 > out_fd)
9549 +               goto err;
9550 +
9551 +       spl_fd = open_input_bin(arg->spl_bin, &spl_ptr, &spl_size);
9552 +       if (0 > spl_fd)
9553 +               goto err_spl;
9554 +
9555 +       uboot_fd = open_input_bin(arg->uboot_bin, &uboot_ptr, &uboot_size);
9556 +       if (0 > uboot_fd)
9557 +               goto err_uboot;
9558 +
9559 +       ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr);
9560 +       if (ret)
9561 +               goto err_write;
9562 +
9563 +       ret = copy_bin(out_fd, spl_ptr, spl_size);
9564 +       if (ret)
9565 +               goto err_write;
9566 +
9567 +       ret = write_nvb_start_header(out_fd, arg->entry_addr);
9568 +       if (ret)
9569 +               goto err_write;
9570 +
9571 +       ret = copy_bin(out_fd, uboot_ptr, uboot_size);
9572 +       if (ret)
9573 +               goto err_write;
9574 +
9575 +       close_input_bin(uboot_fd, uboot_ptr, uboot_size);
9576 +       close_input_bin(spl_fd, spl_ptr, spl_size);
9577 +       close(out_fd);
9578 +
9579 +       return 0;
9580 +
9581 +err_write:
9582 +       close_input_bin(uboot_fd, uboot_ptr, uboot_size);
9583 +err_uboot:
9584 +       close_input_bin(spl_fd, spl_ptr, spl_size);
9585 +err_spl:
9586 +       close(out_fd);
9587 +err:
9588 +       return -1;
9589 +}
9590 +
9591 +int main(int argc, char *argv[])
9592 +{
9593 +       int ret;
9594 +       struct args arg;
9595 +
9596 +       ret = parse_args(argc, argv, &arg);
9597 +       if (ret)
9598 +               goto done;
9599 +
9600 +       switch (arg.type) {
9601 +       case IMAGE_SFSPL:
9602 +               ret = create_sfspl(&arg);
9603 +               break;
9604 +       default:
9605 +               fprintf(stderr, "Image type not implemented\n");
9606 +               ret = -1;
9607 +               break;
9608 +       }
9609 +
9610 +done:
9611 +       if (ret >= 0)
9612 +               return EXIT_SUCCESS;
9613 +
9614 +       return EXIT_FAILURE;
9615 +}
9616 -- 
9617 1.8.3.2
9618